r_ffa Configuration
Every r_ffa config.lua option: framework and integrations, currencies and wagers, arena rules, the arena ped, attachments, UI and custom hooks.
All settings live in config.lua. Arenas, public lobbies and weapon sets have their own page:
Creating Arenas.
Framework & integrations
R.Framework = 'auto' -- 'auto' | 'esx' | 'qb' | 'qbox'
R.CoreName = 'es_extended' -- only if you renamed es_extended
R.Inventory = 'ox_inventory' -- 'ox_inventory' | 'qs-inventory' | 'none' (ESX cash handling)
R.Target = 'ox_target' -- 'ox_target' | 'qb-target' | 'none' (TextUI + E)
R.Notify = 'ox_lib' -- 'ox_lib' | 'esx' | 'qb' | 'okok'
R.Ambulance = 'auto' -- 'auto' | 'qbx_medical' | 'wasabi' | 'esx' | 'qb' | 'none'General
R.Debug = false
R.EnableLogs = true -- webhooks in server/sv_custom.lua
R.EnableAutoinsert = true -- creates / migrates the r_ffa table on start
R.Names = 'player' -- 'player' = FiveM name | 'character' = character name
R.Voice = true -- pma-voice radio channel per lobby
R.HideTopHud = true -- hides r_tophud while you are in an arena (the hub leaves it alone)
R.AdminGroup = 'group.admin'
R.Commands = {
leave = 'ffaleave',
admin = 'ffaadmin'
}
R.Keys = {
menu = 'G', -- arena menu
scoreboard = 'TAB' -- hold to show the scoreboard
}Keys are registered with ox_lib keybinds, so players can rebind them in Settings → Key
Bindings → FiveM. R.Names decides what the killfeed, scoreboard and leaderboard show.
Currency & wagers
R.Currency = { symbol = '$', after = false, separator = ',' }
R.Payment = {
cash = true,
bank = true,
credits = true -- r_store credits
}
R.Credits = { resource = 'r_store' }
R.Wager = {
min = 100,
max = 100000,
minKills = 1,
maxKills = 50,
defaultKills = 5,
countdown = 5, -- seconds before every round
responseTime = 30, -- seconds the opponent has to answer
range = 15.0 -- how close the opponent must be
}| Option | What it does |
|---|---|
R.Currency | How money is shown everywhere ($1,000 or 1 000€). |
R.Payment | Which accounts can be wagered. credits only shows up when the r_store resource is running. |
R.Wager.min/max | Allowed wager per player. Both stakes are taken when the challenge is accepted and the winner receives 2×. |
R.Wager.minKills/maxKills | Allowed "first to X kills" range. |
R.Wager.range | The opponent must be within this distance when the challenge is sent and accepted. |
R.Wager.countdown | Frozen countdown before every round of a duel. |
Arena rules
R.Lobby = {
leaveDelay = 5, -- seconds before a player can leave after joining
respawnDelay = 2, -- seconds on the death screen before respawning
spawnProtection = 1.5, -- seconds of invincibility after (re)spawning
outOfBounds = 5, -- seconds to return after leaving the arena zone
weaponSwapCooldown = 3, -- seconds between weapon swaps in the menu
infiniteAmmo = true,
maxHealth = 200,
customMaxPlayers = 32, -- upper limit players can pick for a custom lobby
bucketBase = 3000 -- routing buckets used by the arenas start from here
}
R.Streaks = { 3, 5, 10, 15, 20 } -- announced kill streaksArena ped & blip
R.Join = {
{
Ped = {
Model = 'ig_joeminuteman',
Scenario = 'WORLD_HUMAN_DRUG_DEALER',
Coords = vec4(-257.2, -972.6, 31.2, 250.5)
},
Blip = { enabled = true, sprite = 110, colour = 27, scale = 0.7, label = 'FFA Arena' }
}
}Add more entries for more entrances. Players are always returned to the first entry when they leave an arena.
Attachments
R.Attachments = {
{ key = 'suppressor', label = 'Suppressor', image = 'nui://ox_inventory/web/images/at_suppressor.png', components = { 'COMPONENT_AT_PI_SUPP', ... } },
...
}Each entry is one toggle in the arena menu. The first component in components that fits the
current weapon is used, so one entry covers pistols, SMGs and rifles. image can be any URL or
nui:// path.
UI
R.UI = {
Accent = '#9a27ea',
DefaultAvatar = 'nui://r_ffa/web/build/media/avatar.png' -- when MugShotBase64 is not running
}
R.WeaponImage = 'nui://ox_inventory/web/images/%s.png' -- %s = WEAPON_NAME in uppercaseAccent recolours the whole UI. Weapon images default to ox_inventory's; point R.WeaponImage
at your own inventory's image folder if you use another one. Missing images fall back to an icon.
Hooks (cl_custom.lua / sv_custom.lua)
Both files are outside escrow so you can adapt integrations without touching the core:
| File | Function | When |
|---|---|---|
client/cl_custom.lua | Notify, GetAvatar, JoinVoice, LeaveVoice, RevivePlayer | Notifications, mugshots, pma-voice, revives |
client/cl_custom.lua | OnHubOpened, OnHubClosed, OnArenaEntered, OnArenaLeft | Hide HUDs, disable inventory, weather/clock overrides |
client/cl_custom.lua | OnKillfeed, OnDuelResult | Custom sounds or effects |
server/sv_custom.lua | Log + Webhooks | Discord logging |
server/sv_custom.lua | OnPlayerJoinedLobby, OnPlayerLeftLobby, OnKill, OnDuelFinished | Your own rewards, XP or achievements |
Interface Colours
Every R-Scripts resource shares the same colour tokens, so you can match the UI to your server's branding without touching any code:
R.UI = {
Accent = "#9a27ea", -- icons, bars, badges and highlights
Primary = "#ffffff", -- main action buttons (buy / play / confirm)
PrimaryText = "#000000", -- text on those buttons
NavActive = "", -- selected tab background, "" keeps the neutral default
NavActiveText = "#ffffff", -- selected tab text
}Leave a value empty to keep the shipped look — the defaults above are exactly what you see out of
the box. Accent stays a signal colour (icons, progress bars, badges); Primary is the solid
button colour, so setting it to your brand colour turns every confirm button at once.