Commands#
Robberies Creator registers three in-game commands for staff and one cooldown command that also works from the server console. The first three can be renamed in /robberiesconfig → Commands (restart the resource after renaming).
Command | Who | Description |
|---|---|---|
| Admins | Opens the creator: statistics, the robbery list, the node editor and the admin screen. Anybody else is told they lack permission, and the console prints how to grant it. |
| Admins, or the | Opens the live settings panel. The separate ace lets you give a developer the settings without the creator. |
| Admins | Toggles development mode for you alone: every minigame and quick check passes automatically. Not saved — it ends when you disconnect. |
| Admins and the server console | Clears a robbery's cooldowns in every scope — by id or by name, case-insensitive — or every cooldown with |
Robberies can add commands of their own: a Command trigger registers its chat command as soon as the robbery is saved and enabled, for any player to type.
# From the server console or txAdmin
robberies_clearcooldown all
robberies_clearcooldown "Fleeca Robbery"Events#
For other resources that need to stop a robbery or speak to a player through the creator's own notifications.
Ending a player's robbery
From the client, end the robbery the player is in as a failure — from a radial menu, a phone app, or your own death or jail script.
-- client
TriggerServerEvent('qs-robberies:abortRobbery') -- "player aborted"
TriggerServerEvent('qs-robberies:playerDied') -- "player died"The whole crew is pulled out, a failed attempt is recorded, and everything the robbery spawned is cleaned up.
Notifications
-- server
TriggerClientEvent('qs-robberies:notify', source, 'The vault is open', 'success', 5000)
-- type: info · success · warning · error duration in msListening to triggers
Every time a trigger fires inside a running robbery, a local server event is raised that another server resource can listen to:
-- server
AddEventHandler('qs-robberies:internal:triggerFired', function(info)
-- info.robberyId, info.instanceId, info.nodeId, info.triggerId, info.source, info.data
end)Client export
-- Re-send the current language to the interface, after editing a locale at runtime
exports['qs-robberies-creator']:PushLocale()Custom Nodes#
The real extension point. Add your own actions, conditions and triggers in Lua: they appear in the creator's palette with their own fields, are placed and wired like built-in nodes, and run on the server. Files go in server/custom/nodes/ — editable, not encrypted — and example.lua has one of each to copy.
Create a node file
Copy
server/custom/nodes/example.luato a new file in the same folder and register your node:lua RegisterCustomNode({ kind = 'pay_step_bonus', -- unique id nodeType = 'action', -- 'action' | 'condition' | 'trigger' label = 'Step Bonus', category = 'rewards', -- which palette group it joins icon = 'IoCash', description = 'Pays whoever just completed the step.', fields = { { key = 'amount', type = 'number', label = 'Amount', default = 1000, min = 0 }, { key = 'account', type = 'account-picker', label = 'Account' }, }, handler = function(context, node) local player = RobberyState_GetVariable(context, 'interaction_source') or RobberyState_GetVariable(context, 'source') local amount = tonumber(node.data.amount) or 0 AddPlayerMoney(player, node.data.account or 'cash', amount) return true -- false takes the Fail path end, })Restart the resource
The node shows up in the palette, in the category you named. Errors in the definition are printed to the console at start.
The definition#
Key | What it is |
|---|---|
| Required. A unique id. It must not clash with a built-in node. |
| Required. |
| What the palette shows. |
|
|
| A name from the built-in set — |
| The properties panel. Each value is stored on |
| Runs when the flow reaches the node. An action returns |
| Triggers only. Called every time the robbery loads or is saved. Call |
Field types#
Every field takes key, label, description, default, required and visibleWhen = { key, value }. The same pickers the built-in nodes use are available:
Type | Shows |
|---|---|
| Plain inputs. |
| The in-game location picker. |
| Your inventory's items, your framework's accounts, jobs and grades. |
| Another node of the robbery (a spawned ped, a blip), or a robbery variable. |
| The libraries with previews. |
Reading the robbery#
Handlers receive the robbery's context. Read and write its state with RobberyState_GetVariable(context, key) and RobberyState_SetVariable(context, key, value):
Key | Value |
|---|---|
| The leader's server id. Changes only if the leader disconnects and leadership passes on. |
| The crew member who did the most recent step — a prompt, a minigame, a progress bar, a scene. |
| A variable written by Set Variable or Count Item, with |
| When it started, whether it is an admin Test Start, and where the last trigger fired. |
-- "whoever just did this step", falling back to the leader
local player = RobberyState_GetVariable(context, 'interaction_source')
or RobberyState_GetVariable(context, 'source')The framework bridge's helpers are available too: AddItem, RemoveItem, HasItem, GetItemCount, AddPlayerMoney, GetPlayerMoney, GetPlayerJob and CountPlayersWithJob — so a custom node works on ESX, QBCore and Qbox alike.
A custom trigger#
Starting a robbery from your own script — a phone contract, a job board, a hacker NPC — is a custom trigger. Because setup runs again every time the robbery is saved, register the event once and only remember the start function in it:
local starters = {}
-- Your script: TriggerEvent('myscript:startHeist', playerId, 'bank_job')
AddEventHandler('myscript:startHeist', function(playerId, tag)
local start = starters[tag]
if start then start(playerId) end
end)
RegisterCustomNode({
kind = 'script_start',
nodeType = 'trigger',
label = 'Started by Script',
category = 'triggers',
icon = 'IoTerminal',
fields = {
{ key = 'tag', type = 'text', label = 'Tag', placeholder = 'bank_job' },
},
setup = function(robbery, node, start)
starters[node.data.tag or robbery.id] = start
end,
})Custom_StartRobbery(robberyId, playerId, nodeId) does the same from anywhere on the server, if you already know the robbery and node ids.
About the Messages#
Everything players read comes from locales/, in twenty languages. When you write your own nodes, send your text through the same notification event so it looks like the rest of the robbery, and keep the wording in your own locale file.



