Installation
Installation
The short version
- Put the
rivo_queuefolder in yourresourcesdirectory. - Add
ensure rivo_queuetoserver.cfg. - Remove or stop any other queue resource.
- Restart.
You now have a working queue. Everything below is optional and can be added
later without reinstalling.
Before you start
Stop your old queue
Two queue resources both handling playerConnecting will conflict on every
connection. Remove the old one first.
hardcap
hardcap is a stock resource that kicks players as soon as the server is full,
so it cannot run alongside a queue.
Rivo Queue stops it on start and logs that it did. To handle it yourself, setConfig.autoStopHardcap = false and stop it in your own config.
Player slots
The queue reads sv_maxClients. If the queue admits too many or too few
players, check that value first.
First run
Start the server and watch the console:
[rivo_queue] storage: json
[rivo_queue] stopped hardcap, it cannot run alongside a queue (Config.autoStopHardcap)
[rivo_queue] online, 64 slots, 0 reserved
Then check it from the console:
queue status
queue slots
When something looks wrong, check queue slots first. It shows what the queue
thinks capacity is:
12/64 online | 2 connecting | 0 admitting | 0 held | 0 reserved | 50 free | 0 queued
connecting counts players who are past the queue but not loaded yet, usually
because they are downloading content. They hold a slot that GetPlayers()
cannot see. If the server looks empty but nobody can get in, this is usually
the cause.
Secrets
Every token is read from a convar, so it lives in a file you keep out of
version control instead of in config.lua.
Add to cfg/local.cfg (or your equivalent):
set rivo_queue:discordToken "…" # Discord bot token, for role priority
set rivo_queue:webhookUrl "…" # Discord webhook, for logging
set rivo_queue:panelToken "…" # admin panel token
Make sure that file is not committed. If a bot token is ever posted somewhere
public, reset it.
Priority
There are five ways to grant priority, and you can use all of them at once.
Start with the one that needs the least setup.
1. A hardcoded list (no setup)
config/config.lua:
Config.priorityList = {
['license:0123…'] = { points = 10000, label = 'Owner' },
['discord:1234…'] = 2500,
}
Good for owners and a few staff. Works even when everything else is down.
2. ACE permissions (works with your admin system)
add_ace group.admin rivo_queue.staff allow
To let staff run the queue command in game (the console never needs this):
add_ace group.admin rivo_queue.admin allow
## only if your server enforces FiveM's own command ACL as well:
add_ace group.admin command.queue allow
Config.acePriority = {
['rivo_queue.staff'] = { points = 100000, label = 'Staff', tier = 'staff' },
['rivo_queue.vip'] = { points = 2500, label = 'VIP', tier = 'vip' },
}
Works with any admin resource that grants ACE principals.
3. txAdmin staff (on by default)
Config.txAdmin.enabled is true by default. Anyone with a txadmin.*
permission is detected as staff. No files are read and there is no coupling to
txAdmin's data format.
txAdmin bans need no setup. txAdmin refuses banned players in its own deferral,
before this resource is reached.
4. Stored rows (most common)
Granted at runtime and kept in a JSON file, or MySQL if you have it.
queue prio add license:0123… 2500 tebex 30
This adds 2500 points in category tebex, expiring in 30 days. From code:
exports['rivo_queue']:addPrio('discord:1234…', 5000, 'donation', {
label = 'Gold',
tier = 'vip',
expiresAt = os.time() + 30 * 86400,
})
5. Discord roles
Needs a bot. See below.
Discord
Only needed for role-based priority, guild membership checks, or a role
whitelist. Everything else works without it.
Creating the bot
- https://discord.com/developers/applications → New Application.
- Bot → Reset Token → copy it.
- Under Privileged Gateway Intents, enable Server Members Intent.
- OAuth2 → URL Generator: scope
bot, no permissions needed beyond the
default. Open the URL and add it to your server.
The bot only needs to read members. It does not send messages and never
connects to the gateway. The resource makes one HTTP request per player and
caches the result.
Configuring
cfg/local.cfg:
set rivo_queue:discordToken "your-token"
config/config.lua:
Config.discord = {
enabled = true,
guildId = '000000000000000000',
roles = {
['111111111111111111'] = { points = 5000, label = 'Founder', tier = 'staff' },
['222222222222222222'] = { points = 2500, label = 'VIP', tier = 'vip' },
},
}
To get role and guild IDs, turn on developer mode in Discord, then right-click →
Copy ID.
Checking it works
queue status
discord: on | 14 cached
If it says off, the token or the guild id is missing. If the console showsDiscord rejected the bot token, the token is wrong or the bot is not in that
guild.
When Discord goes down
Priority fails open: players can still connect but lose their Discord perks
for that connection. Cached roles are reused for as long as the outage lasts.
Whitelist and guild gates fail closed, otherwise an outage would switch
your whitelist off. Non-Discord whitelist routes are checked first, so anyone
passing by ACE or the identifier list is unaffected.
Database (optional)
Skip this unless you have thousands of priority rows or want them in the same
database as the rest of your data.
Have
oxmysqlrunning and started beforerivo_queue.Leave
Config.storage = 'auto', or set it to'mysql'to be explicit.The tables are created from
queue.sqlon first start. Only run it yourself
if your database user has no CREATE grant (then setConfig.mysqlAutoMigrate = false).
Check which backend is in use:
queue status
storage: mysql
With 'auto', oxmysql is used when it is running and the JSON file otherwise.
If the database is unreachable at start, the resource logs the reason and falls
back to JSON instead of refusing to run.
Admin panel
- Generate a token:
openssl rand -hex 32 set rivo_queue:panelToken "…"incfg/local.cfg.- Restart, then open
http://your-server-ip:30120/rivo_queue/.
Read Admin panel before you expose that port to the internet.
Discord logging
set rivo_queue:webhookUrl "https://discord.com/api/webhooks/…"
Config.webhook.enabled = true
Then:
queue webhook test
This posts one of each event type so you can check the styling right away.
Categories are toggled individually in Config.webhook.events. traffic is
off by default because it can mean hundreds of messages an hour on a busy
server.
Troubleshooting
Nobody can join, but the server looks empty.
Run queue slots and look at connecting. Players stuck downloading hold
slots. Config.connectingTimeout (default 300s) releases them.
Everybody is queued even though there is space.sv_maxClients is probably lower than you think, or Config.reservedSlots is
holding capacity back.
Priority is not applying.queue prio list <identifier> shows the stored rows. Rows match on any
identifier the player presents, so a row keyed on discord: still works for a
license-tracked player, as long as they have Discord running.
Staff perks stopped working.
Run queue status. If Discord is rate limited or the token was rejected,
role-based tiers will be missing. ACE and config list sources are not affected.
The queue does nothing at all.
Check that hardcap is stopped and no other queue resource is running.