Migrating From N4 Queue
Migrating from n4_queue
Short version: rename the resource in your scripts, import one table, delete the
old folder.
The four read exports and addPrio and removePrio keep n4's names and
signatures, so scripts that already call the queue keep working after a
find-and-replace.
1. Your scripts
-- before
local size = exports['n4_queue']:queueSize()
-- after
local size = exports['rivo_queue']:queueSize()
Unchanged in name, arguments, and return shape:
| Export | Note |
|---|---|
queueList() |
Adds tier and score to each row. Existing fields are unchanged. |
queueSize() |
Identical. |
connectingList() |
Identical shape, keyed by identifier. |
connectingSize() |
Identical. |
addPrio(identifier, points, category?) |
Identical. An optional fourth table argument adds label, tier, and expiry. |
removePrio(id) |
Returns true/false rather than a result object. |
removePrio is the one behaviour difference. n4 returned a database result you
would check with result.affectedRows; this returns a boolean:
-- before
local result = exports['n4_queue']:removePrio(id)
if result.affectedRows > 0 then … end
-- after
if exports['rivo_queue']:removePrio(id) then … end
2. Your priority data
If you used n4 with a database
n4's table is queue with (id, identifier, points, category).
Start rivo_queue once so it creates its tables (or run queue.sql), then:
INSERT INTO `rivo_queue_priority`
(`identifier`, `points`, `category`, `created_at`, `created_by`)
SELECT `identifier`, `points`, `category`, UNIX_TIMESTAMP(), 'n4-import'
FROM `queue`;
Every row carries over. n4 has no labels, tiers, or expiry, so those columns
stay empty and you can fill them in later.
Keep the old queue table until you have confirmed the import. Nothing reads it.
If you did not use a database
Your priority came from Discord roles only. Copy the role IDs and point values
from n4's prioRoles into Config.discord.roles:
-- n4
prioRoles = {
{ label = 'VIP', roleId = 111111111111111111, points = 2500 },
{ label = 'Staff', roleId = 222222222222222222, points = 5000 },
}
-- rivo_queue
Config.discord.roles = {
['111111111111111111'] = { points = 2500, label = 'VIP', tier = 'vip' },
['222222222222222222'] = { points = 5000, label = 'Staff', tier = 'staff' },
}
Note the role ID is a string key here, not a number field. Discord IDs are
64-bit and Lua numbers are doubles, so a snowflake stored as a number loses
precision and stops matching.
3. Your config
| n4 | Rivo Queue |
|---|---|
joinDelay |
Config.joinDelay (same meaning) |
cooldown |
Config.cooldown (same meaning) |
displayQueueInHostName |
Config.displayQueueInHostName |
maxPlayersToDisplay |
Config.ui.maxPlayersToDisplay, and set Config.ui.showQueueList = true |
consoleInfo |
Config.consoleInfo |
stackPrio = true |
Config.priorityMode = 'sum' |
stackPrio = false |
Config.priorityMode = 'max' |
discord.enabled |
Config.discord.enabled |
discord.requireIdentifier |
Config.requireIdentifiers = { 'discord' } |
discord.requireInGuild |
Config.discord.requireInGuild |
discord.whitelist + whitelistRoleId |
Config.whitelist.enabled + Config.whitelist.roles = { '…' } |
discord.botToken |
convar rivo_queue:discordToken |
discord.guildId |
Config.discord.guildId |
prioRoles |
Config.discord.roles |
Two differences to watch for:
The queue list is off by default. n4 always shows the first N players. Here
it is opt-in, and names are masked when it is on. SetConfig.ui.showQueueList = true for the old behaviour.
The whitelist takes a list of roles, not a single one. It also accepts ACE
permissions, an identifier list, and "anyone with stored priority". Passing any
one of them is enough. Your single whitelistRoleId becomes a one-element list.
4. Swap them
- Stop the server.
- Remove
ensure n4_queue, addensure rivo_queue. - Delete or move the
n4_queuefolder so it cannot start by accident. - Start, and watch for
[rivo_queue] storage: …in the console. - Run
queue slotsandqueue statusto confirm.
What you gain immediately
Without configuring anything beyond the above:
- Priority rows can expire (
expiresAtinaddPrio's options table, or days inqueue prio addand the panel). - A player who crashes mid-queue keeps their position for 90 seconds.
- Nobody at the front of the queue gets bumped by a late donator.
queue list,queue kick,queue ban,queue pausefrom the console.- Metrics: average and p95 wait, admits per hour, refusals by reason.
- The admin panel, once you set a token.
What to look at next
- Tiers (
Config.tiers). Points decide order; tiers decide who follows
different rules. Give staffbypassQueueso they skip the queue entirely. - Reserved slots (
Config.reservedSlots). Hold back a few slots that only
a reserved tier can use. - Webhook logging (
Config.webhook). Bans, whitelist refusals, admin
actions, and queue milestones in a Discord channel.