Skip to main content
The queue configuration file (config/queue.lua) manages the server queue system, allowing you to create priority queues and customize the connection experience.

Timeout Settings

timeoutSeconds
number
default:"30"
Amount of seconds to wait before removing a player from the queue after disconnecting while waiting.This prevents players from holding queue positions indefinitely if they disconnect.
joiningTimeoutSeconds
number
default:"0"
Amount of seconds to wait before removing a player from the queue after disconnecting while installing server data.
An additional ~2 minutes will be waited due to limitations with how FiveM handles joining players.

Sub-Queue System

Sub-queues allow you to create priority tiers in your queue. Players are sorted by sub-queue priority first, then by join time within each sub-queue.
subQueues
SubQueueConfig[]
Sub-queues from most to least prioritized.Important Rules:
  • Sub-queues are checked in order from first to last
  • The first sub-queue without a predicate function is the default queue
  • If a player doesn’t pass any predicate AND no default queue exists, they cannot join unless a slot is available
SubQueueConfig Type:
---@class SubQueueConfig
---@field name string
---@field predicate? fun(source: Source): boolean
---@field cardOptions? AdaptiveCardTextOptions
Default Configuration:
subQueues = {
    { 
        name = 'Admin Queue', 
        predicate = function(source) 
            return IsPlayerAceAllowed(source, 'admin') 
        end, 
        cardOptions = { color = 'good' } 
    },
    { name = 'Regular Queue' }, -- Default queue (no predicate)
}

Sub-Queue Examples

subQueues = {
    { 
        name = 'Staff Queue',
        predicate = function(source)
            return IsPlayerAceAllowed(source, 'admin')
        end,
        cardOptions = { color = 'good', weight = 'bolder' }
    },
    { 
        name = 'VIP Queue',
        predicate = function(source)
            return IsPlayerAceAllowed(source, 'vip')
        end,
        cardOptions = { color = 'accent' }
    },
    { name = 'Regular Queue' }
}

Adaptive Card Text Options

cardOptions
AdaptiveCardTextOptions
Customize the appearance of text in the adaptive card for each sub-queue.Available Options:
OptionTypeValues
stylestring'default', 'heading', 'columnHeader'
fontTypestring'default', 'monospace'
sizestring'small', 'default', 'medium', 'large', 'extralarge'
weightstring'lighter', 'default', 'bolder'
colorstring'default', 'dark', 'light', 'accent', 'good', 'warning', 'attention'
isSubtlebooleantrue, false
Example:
cardOptions = {
    color = 'good',
    size = 'large',
    weight = 'bolder'
}

Visual Customization

waitingEmojis
string[]
Cosmetic emojis shown along with the elapsed queue time. These cycle to indicate activity.Default:
waitingEmojis = {
    '🕛',
    '🕒',
    '🕕',
    '🕘',
}
You can customize these with any emojis:
waitingEmojis = {
    '⏳',
    '⌛',
    '⏰',
    '⏱️',
}
useAdaptiveCard
boolean
default:"true"
Whether to use the adaptive card generator defined in this config.Set to false to use a simpler text-based queue display.

Custom Adaptive Card

The adaptive card is the visual interface players see while in the queue.
generateCard
function
Generator function for the adaptive card display.Parameters (GenerateCardParams):
  • subQueue (SubQueue) - The sub-queue the player is in
  • globalPos (integer) - Player’s position in the entire queue
  • totalQueueSize (integer) - Total number of players in queue
  • displayTime (string) - Formatted time string showing how long player has been waiting
Returns: table - Adaptive card JSON structureDefault Implementation:The default card shows:
  • “In Line” header
  • “Joining [ServerName]” subheader
  • Visual progress indicator (Queue • • You • • • Server)
  • Sub-queue name, position (X/Y), and wait time
generateCard = function(params)
    local subQueue = params.subQueue
    local pos = params.globalPos
    local size = params.totalQueueSize
    local displayTime = params.displayTime

    local cardOptions = subQueue.cardOptions or {}

    -- Progress bar calculation
    local progressAmount = 7
    local playerColumn = pos == 1 and progressAmount 
        or (progressAmount - math.ceil(pos / (size / progressAmount)) + 1)

    -- Build progress columns
    local progressColumns = {}
    for i = 1, progressAmount + 2 do
        -- Column setup with dots and labels
        -- ...
    end

    return {
        type = 'AdaptiveCard',
        version = '1.6',
        body = {
            -- Title, progress bar, and info display
            -- ...
        },
    }
end

Customizing the Card

You can completely customize the adaptive card appearance:
generateCard = function(params)
    return {
        type = 'AdaptiveCard',
        version = '1.6',
        body = {
            {
                type = 'TextBlock',
                text = 'Queue Position',
                size = 'large',
                weight = 'bolder',
            },
            {
                type = 'TextBlock',
                text = ('%d / %d'):format(params.globalPos, params.totalQueueSize),
                size = 'extralarge',
            },
            {
                type = 'TextBlock',
                text = 'Wait time: ' .. params.displayTime,
                size = 'medium',
            },
        },
    }
end
Learn more about Adaptive Cards at adaptivecards.io

Build docs developers (and LLMs) love