Configuration

Configuration

Rivo Queue works out of the box. Everything below is optional.

There are three files you can edit:

File What it controls
config/config.lua Every setting
config/theme.lua The loading card: banner, icon, colours, buttons
config/locales/en.lua Every message players and admins see

Restart the resource after changing them. queue reload re-reads tiers only.

Secrets

Tokens are never stored in config.lua. Put them in server.cfg or a separate
cfg file you don't share:

set rivo_queue:panelToken   "long-random-value"                      # admin panel
set rivo_queue:discordToken "your-bot-token"                         # Discord roles and checks
set rivo_queue:webhookUrl   "https://discord.com/api/webhooks/..."   # Discord logging

General

Option Default Description
Config.locale 'en' Which file in config/locales/ to use
Config.debug false Extra console output for troubleshooting
Config.consoleInfo true Print a console line when players queue, get in or leave

Slots

Option Default Description
Config.reservedSlots 0 Slots only tiers with reservedSlot = true can use
Config.maxQueueSize 0 Refuse new players once this many are waiting. 0 means unlimited. Tiers with bypassQueue are exempt

The server size is read from sv_maxClients.

Timing

All values are in seconds unless the name ends in Ms.

Option Default Description
Config.cooldown 2 Short processing delay before a player is queued or let in
Config.joinDelay 45 After a server boot, hold everyone this long so resources can start. 0 disables
Config.cardRefreshMs 1000 How often the loading card updates, in milliseconds
Config.connectingTimeout 300 How long an admitted player has to finish loading before their slot is released
Config.queueTimeout 30 Remove a waiting player after this long with no network activity (they closed the game)

Config.deniedHold

How long the "you cannot join" card stays on screen before the connection
closes, per refusal reason. Reasons not listed use default.

Key Default
default 15
ban 2
block 2
throttle 2
alts 8
['queue-full'] 5

Other reasons you can add: identifiers, whitelist, guild, maintenance.

Staged release

Config.stagedRelease controls how players are let in after the startup hold.

Field Default Description
enabled true Turn staged release on or off
players 5 Players admitted per window
everySeconds 10 Length of each window
durationSeconds 120 How long after joinDelay ends the limit applies

While it is active, players go through the queue instead of walking straight
in. Tiers with bypassQueue are not limited.

Reconnect grace

Config.grace controls crash recovery.

Field Default Description
enabled true Turn it on or off
positionSeconds 90 A waiting player who reconnects within this time gets their old position back
slotSeconds 45 An admitted player who crashed while loading has their slot held this long

Ordering

Option Default Description
Config.headLock true The player first in line can't be pushed back by someone who joins later

Config.drift

Waiting players gain points over time so nobody waits forever.

Field Default Description
enabled true Turn it on or off
pointsPerMinute 5 Points gained per minute of waiting
maxPoints 'auto' The most drift points a player can gain. 'auto' stops one point below your cheapest tier, so waiting never beats a paying tier. A number sets a fixed cap

Player UI

Config.ui

Field Default Description
mode 'card' 'card' for the Adaptive Card, 'text' for plain text
showQueueList false Show a list of players ahead on the card
maskNames true Partly hide names in that list, e.g. Kair*
maxPlayersToDisplay 10 How many names the list shows
showEstimatedWait true Show the estimated wait
brandHoldSeconds 3 Show the "You are in" card for this long to players who didn't have to queue. 0 makes joins instant
Option Default Description
Config.displayQueueInHostName true Prefix the server name with the queue size, e.g. [55] My Server

Admin

Option Default Description
Config.adminAce 'rivo_queue.admin' ACE players need to use the queue command. The console always can
Config.kickCooldownSeconds 60 How long queue kick blocks a player from reconnecting. 0 disables
add_ace group.admin rivo_queue.admin allow

Player history

Config.playerHistory keeps one row per player who has connected. The panel's
Users tab and alt detection use it. IP addresses are never stored.

Field Default Description
enabled true Record players. When off, nothing is stored
retentionDays 90 Delete a player's history this many days after they were last seen. 0 keeps it forever

Admin panel

Config.panel controls the web panel at http://your-server-ip:30120/rivo_queue/.
It stays closed until rivo_queue:panelToken is set. See Admin panel.

Field Default Description
enabled true Serve the panel
tokenConvar 'rivo_queue:panelToken' Convar holding the token
rateLimit 240 Requests allowed per address per window
rateWindowSeconds 60 Length of the rate limit window

Maintenance

Option Default Description
Config.maintenance.defaultAllowTiers { 'staff' } Tiers allowed to connect during queue pause

Metrics and alerts

Option Default Description
Config.milestones { 25, 50, 100, 200 } Queue sizes announced once when reached
Config.longWaitSeconds 1800 Announce anyone who has waited this long. 0 disables

Discord webhook

Config.webhook posts events to a Discord channel. Set the URL with the
rivo_queue:webhookUrl convar, then run queue webhook test.

Field Default Description
enabled false Turn logging on
urlConvar 'rivo_queue:webhookUrl' Convar holding the webhook URL
url '' Fallback URL if the convar is not set
username 'Rivo Queue' Name shown on messages
avatar nil Avatar image URL
batchSeconds 5 Messages are grouped and sent this often
maxBuffered 200 Oldest messages are dropped past this many waiting to send

events

Field Default What it posts
denial true Refused connections and alt flags
admin true Kicks, bans, priority changes, maintenance
milestone true Queue size milestones and long waits
traffic false Every queued and admitted player. Busy servers will post a lot

style

Field Default Description
format 'v2' 'v2' for Discord Components V2, 'embed' for classic embeds
compact false One line per event instead of a block
accent see config Accent colour per event kind, as 0xRRGGBB
icons see config Emoji per event kind. '' hides one
titles {} Override a heading, e.g. titles = { denied = 'Refused' }
thumbnail nil Image URL shown beside each message
showIdentifier true Show the player's identifier under each message
showTimestamp true Show a relative time under each message
footer nil Extra text added under each message
separators true Divider line between heading and body

Event kinds for accent, icons and titles: denied, flagged, admin,
milestone, longWait, queued, admitted.

Environment

Option Default Description
Config.autoStopHardcap true Stop the hardcap resource on start, since it kicks players the queue is holding

Identity

Option Default Description
Config.primaryIdentifier 'license' The identifier each player is tracked by
Config.identifierFallback { 'license2', 'fivem', 'discord', 'steam', 'ip' } Used in order if the primary is missing
Config.requireIdentifiers {} Refuse players missing any of these, e.g. { 'discord' }

Messages for discord, steam and license are included. For any other kind,
add an errMissing_<kind> line to your locale file.

Bans

Option Default Description
Config.bans.enabled true Check the built-in ban list on connect

txAdmin bans are handled by txAdmin itself before Rivo Queue runs.

Whitelist

Config.whitelist refuses anyone who doesn't pass at least one of its checks.

Field Default Description
enabled false Turn the whitelist on
roles {} Discord role IDs, e.g. { '123456789012345678' }. Needs Config.discord set up
ace 'rivo_queue.whitelist' Players with this ACE pass
identifiers {} Identifiers that pass, e.g. { ['license:abc123'] = true }
anyPriority false Anyone with a stored priority row passes

If Discord can't be reached, players who rely on a role to pass are asked to try
again. Players who pass another way are not affected.

Connection throttle

Config.throttle refuses players who reconnect too many times in a short window.

Field Default Description
enabled true Turn it on or off
windowSeconds 60 Length of the window
maxPerWindow 10 Connection attempts allowed per window

Alt detection

Config.altDetection looks for one person using several accounts.

Field Default Description
enabled false Turn it on
mode 'flag' 'flag' logs and marks the player in the panel. 'deny' refuses them
signals.concurrent true Two accounts connecting at the same time with the same Discord
signals.tokens true Two accounts connecting at the same time with the same hardware
signals.discord true A Discord account previously seen with a different license. Needs Config.playerHistory enabled

Run it in 'flag' mode for a while before switching to 'deny'. Shared PCs and
households can trigger it.

Priority

Config.priorityList

Hardcoded priority by identifier. A number is points, a table sets more fields.

Config.priorityList = {
    ['license:abc123'] = { points = 10000, label = 'Owner', tier = 'staff' },
    ['discord:123456789012345678'] = 2500,
}

Config.priorityMode

Value Effect
'sum' (default) Add up every matching row
'max' Use only the highest row

Config.acePriority

Priority from ACE permissions, in the same format.

Config.acePriority = {
    ['rivo_queue.vip'] = { points = 2500, label = 'VIP', tier = 'vip' },
}
add_ace group.vip rivo_queue.vip allow

Config.txAdmin

txAdmin admins are detected through the ACE txAdmin gives them.

Field Default Description
enabled true Give txAdmin admins priority
ace 'txadmin.menu.viewer' The permission to check
points 50000 Points given
label 'Staff' Label shown on the card
tier 'staff' Tier given

Config.discord

Priority, whitelist and membership checks from your Discord server. Setup steps
are in Installation.

Field Default Description
enabled false Turn Discord features on
guildId '' Your Discord server ID
tokenConvar 'rivo_queue:discordToken' Convar holding the bot token
token '' Fallback token if the convar is not set. Not recommended
requireInGuild false Refuse players who are not in your Discord server
cacheSeconds 300 How long a player's roles are cached
timeoutMs 5000 Give up on a Discord lookup after this long
roles {} Role ID to priority, in the same format as priorityList
roles = {
    ['123456789012345678'] = { points = 5000, label = 'Founder', tier = 'founder' },
    ['234567890123456789'] = 2500,
},

Tiers

Config.tiers lists your tiers, best first. A player gets the best tier named by
any of their priority rows.

Field Description
name ID used in priority rows, e.g. 'vip'
points Minimum points for anyone in the tier
bypassQueue Skip the queue whenever a slot they can use is free
reservedSlot Can use Config.reservedSlots
skipJoinDelay Ignore the startup hold
badge Name shown on the card and in the panel
Config.tiers = {
    { name = 'staff',   points = 100000, bypassQueue = true, reservedSlot = true, skipJoinDelay = true, badge = 'Staff' },
    { name = 'founder', points = 25000,  reservedSlot = true, badge = 'Founder' },
    { name = 'vip',     points = 2500,   badge = 'VIP' },
}

Storage

Option Default Description
Config.storage 'auto' 'auto' uses MySQL when oxmysql is running, otherwise JSON. 'json' or 'mysql' forces one
Config.storageFile 'data/priority.json' JSON file for priority rows
Config.banFile 'data/bans.json' JSON file for bans
Config.identityFile 'data/identities.json' JSON file for player history
Config.storageFlushMs 1000 JSON writes are grouped over this many milliseconds
Config.mysqlTablePrefix 'rivo_queue_' Prefix for the MySQL tables
Config.mysqlAutoMigrate true Create the MySQL tables on start. Turn off if your database user can't create tables, and run queue.sql yourself
Config.pruneIntervalMinutes 30 How often expired rows are deleted. 0 disables

Theme

config/theme.lua styles the loading card.

Field Default Description
banner nil Image at the top of the card. nil uses your server's banner_detail convar, false hides it, or set a URL
icon nil Small image beside the server name. Must be a public HTTPS URL
backgroundImage nil Full card background image
serverName nil Name shown on the card. nil uses sv_hostname
colors see file Text colours: heading, position, muted, good, warning, error
positionStyle 'emphasis' Background style behind the position number
buttons {} Link buttons, e.g. { { label = 'Discord', url = 'https://discord.gg/yourinvite' } }
credit true Show a small "powered by Rivo Queue" line

Loading cards use FiveM's Adaptive Card colours, so colors accepts 'default',
'dark', 'light', 'accent', 'good', 'warning' or 'attention'.
positionStyle accepts 'default', 'emphasis', 'good', 'attention',
'warning' or 'accent'.

Translations

  1. Copy config/locales/en.lua to a new file, e.g. de.lua.
  2. Change Locales['en'] to Locales['de'] and translate the text.
  3. Set Config.locale = 'de'.

Keep the {placeholders} as they are. Lines starting with log use %s and
%d in a fixed order, so keep those in the same order. Missing lines fall back
to English.

View Rivo Queue