Skip to content

UniQueue

UniQueue is a server-side queue and party system built into the bridge. It handles mission queuing, priority, police requirements, cooldowns, and concurrent task limits. Most Prodigy Studios crime and civ missions use it to control when and how missions start.

How it works

  1. A resource creates a queue with a name, type, police requirement, and concurrency limit.
  2. Players form a party (often linked to a group) and join the queue.
  3. The queue runs periodically: it sorts by priority, checks police and cooldowns, then runs the top party via your callback.
  4. The party is removed and destroyed. When the mission ends and you mark the task complete, the queue enters its cooldown before processing the next party.

Using existing Prodigy resources

You do not need to create queues or parties yourself when using an existing Prodigy Studios mission. The queue is already set up in that resource’s config. This page is for developers building custom missions.

Configuration

UniQueue is configured in config.lua under BridgeConfig.Uniqueue.

lua
BridgeConfig.Uniqueue = {
    MaxOverTimePriority = 30,
    AddOverTimePriorityTime = math.floor(2.5 * 60),
    HoldQueuesOnStartTime = 0,
    PoliceStrengthPerPlayer = 1,
    PoliceJobs = {
        "lspd",
        "police",
        "bsco",
    }
}
OptionTypeDefaultDescription
MaxOverTimePrioritynumber30Max priority points a party can gain from waiting.
AddOverTimePriorityTimenumber150Seconds between each priority point gain.
HoldQueuesOnStartTimenumber0Seconds to hold all queues after server start.
PoliceStrengthPerPlayernumber1Police power per on-duty officer.
PoliceJobsstring[]{ "lspd", "police", "bsco" }Job names that count as police.

Queue types

Every queue and party has a type. A party can only join a queue of the same type.

TypeDescription
"civ"Civilian missions (fishing, mining, farming, etc.).
"crime"Crime missions (robberies, heists, smuggling, etc.).

Server exports

Queue

ExportParametersReturnsDescription
CreateQueue(name, type, requiredPolicePower, maxConcurrentTasks, cooldown)UniQueueCreates a new queue.
GetQueue(name: string)UniQueue?Returns the queue by name, or nil.
GetQueuesByType(type: UniQueueType)table<string, boolean>All queue names of that type.

Party

ExportParametersReturnsDescription
CreateParty(type: UniQueueType)UniQueuePartyCreates a new party.
GetParty(uuid: string)UniQueueParty?Returns the party by UUID, or nil.
GetPartiesByType(queueType: UniQueueType)table<string, boolean>All party UUIDs of that type.
GetPartiesFromPlayer(identifier: string)table<string, boolean>All party UUIDs the player is in.

Creating a queue

lua
local queue = exports["prp-bridge"]:CreateQueue(
    "my_mission",
    "crime",
    4,
    1,
    60
)
ParameterTypeDescription
namestringUnique queue identifier.
typeUniQueueType"civ" or "crime".
requiredPolicePowernumberPolice power required to run (each officer adds PoliceStrengthPerPlayer).
maxConcurrentTasksnumberMax missions from this queue at once.
cooldownnumberSeconds after a task ends before next run.

Queue methods

setExecFunction

Sets the callback run when a party is dequeued and ready to start.

lua
queue.setExecFunction(function(queueName, partyUuid, partyMembers, taskId)
    startMission(partyMembers, taskId)
end)

Task state

The queue marks the task as executing before your callback runs. Call queue.setTaskIsExecuting(taskId, false) when the mission ends to free the slot.

setCheckFunction

Optional validation before execution. Return true to allow, false to skip this party for now.

lua
queue.setCheckFunction(function(queueName, partyUuid)
    local party = exports["prp-bridge"]:GetParty(partyUuid)
    if not party then return false end
    return #party.getMembersAsArray() >= 2
end)

setTaskIsExecuting

Marks the task as complete. Call with false when the mission ends.

lua
queue.setTaskIsExecuting(taskId, false)

stopExec

Cancels execution for a party.

lua
queue.stopExec(partyUuid)

Other queue methods

MethodReturnsDescription
getName()stringQueue name.
getNumOfExecTasks()numberNumber of running tasks.
isExecAtFullCapacity()booleanWhether at max concurrent tasks.
getUsedPolicePower()numberPolice power used by running tasks.
add(party){ success, error? }Adds a party.
remove(party)Removes a party.
setPartyPriority(party, priority)Sets party priority.
getPartyPriority(partyUuid)number?Party priority.
getPartyPosition(partyUuid)number?Position in queue.
isPartyIn(partyUuid)booleanWhether party is in this queue.
setCooldown(cooldown)Sets cooldown in seconds.
clearCooldown()Clears cooldown.
setBlocked(blocked)Blocks or unblocks the queue.
isBlocked()booleanWhether the queue is blocked.

Creating a party

lua
local party = exports["prp-bridge"]:CreateParty("crime")

Adding members

lua
local result = party.addMember(playerIdentifier)
if not result.success then
    print(result.error)
end

One party per type

A player can only be in one party per type. Adding them to a second "crime" party will fail if they are already in one.

Removing members

lua
party.removeMember(playerIdentifier)

Party methods

MethodReturnsDescription
getUUID()stringParty UUID.
setUUID(uuid)Sets UUID (e.g. for group link).
getType()UniQueueTypeParty type.
getPosition()numberQueue position (0 if not in a queue).
getEnterId()numberEntry order ID.
getPriority()numberCurrent priority.
setPriority(priority)Sets priority.
addMember(identifier){ success, error? }Adds a member.
removeMember(identifier)Removes a member.
getMembers()table<string, UniQueuePartyMember>All members.
getMembersAsArray()string[]Member identifiers.
destroy()Destroys the party.

Priority

Parties are sorted by priority (highest first). Same priority: first in, first out.

  • Every AddOverTimePriorityTime seconds, a waiting party gains 1 priority (up to MaxOverTimePriority).
  • You can set priority with queue.setPartyPriority(party, priority) or party.setPriority(priority).

Groups integration

The bridge’s group system can create and manage UniQueue parties. When using groups, you usually do not create parties manually.

lua
local group = exports["prp-bridge"]:GetGroupFromMember(source)
group.createUniqueueParty("crime")
local result = group.enterUniqueue("my_mission")
if not result.success then
    print(result.error)
end

When members join or leave the group, they are added to or removed from the party automatically.

Player disconnect

When a player disconnects or their character unloads, they are removed from all parties they were in.

Events

EventParametersDescription
prp-bridge:uniqueue:partyDestroyed(partyUuid: string)Fired when a party is destroyed.

Admin commands

All commands require group.admin.

CommandParametersDescription
/uni_findplayer<identifier>Find all parties for a player.
/uni_setprio<partyUuid> <priority>Set party priority.
/uni_rmfromque<partyUuid> <queueName>Remove party from queue.
/uni_setblocked<queueName> <0|1>Block (1) or unblock (0) a queue.
/uni_setcooldown<queueName> <seconds>Set queue cooldown.
/uni_clearcooldown<queueName>Clear queue cooldown.
/uni_totalblock<0|1>Block or unblock all queues.
/uni_cleartask<queueName> <taskId>Clear a stuck task.
/uni_devmodeToggle debug logging.

Full example

Click to expand full example
lua
local queue = exports["prp-bridge"]:CreateQueue("bank_heist", "crime", 4, 1, 120)

queue.setExecFunction(function(queueName, partyUuid, partyMembers, taskId)
    for _, identifier in ipairs(partyMembers) do
        local player = getPlayerByIdentifier(identifier)
        if player then
            TriggerClientEvent("bank_heist:start", player)
        end
    end
    activeHeists[partyUuid] = taskId
end)

queue.setCheckFunction(function(queueName, partyUuid)
    local party = exports["prp-bridge"]:GetParty(partyUuid)
    if not party then return false end
    return #party.getMembersAsArray() >= 2
end)

function endHeist(partyUuid)
    local taskId = activeHeists[partyUuid]
    if taskId then
        queue.setTaskIsExecuting(taskId, false)
        activeHeists[partyUuid] = nil
    end
end