Overview
Qbox Core provides a comprehensive group management system for creating, modifying, and removing jobs and gangs at runtime. All changes can optionally be persisted to the shared configuration files.
Group Types
--- @enum GroupType
GroupType = {
JOB = 'job' ,
GANG = 'gang'
}
Creating Groups
Create a Single Job
local success , message = exports . qbx_core : CreateJob ( jobName , job , commitToFile )
Parameters:
jobName (string) - Unique job identifier (must be lowercase)
job (table) - Job data containing label, grades, etc.
commitToFile (boolean) - Whether to save to shared/jobs.lua
Returns:
success (boolean) - Whether the operation succeeded
message (string) - Success or error message
Example:
local success , msg = exports . qbx_core : CreateJob ( 'security' , {
label = 'Security Services' ,
type = 'security' ,
defaultDuty = true ,
offDutyPay = false ,
grades = {
[ 0 ] = {
name = 'Guard' ,
payment = 50
},
[ 1 ] = {
name = 'Supervisor' ,
payment = 75 ,
isboss = true ,
bankAuth = true
}
}
}, true )
if success then
print ( msg ) -- "Job 'security' created/updated successfully."
end
Create Multiple Jobs
local success , message = exports . qbx_core : CreateJobs ( newJobs , commitToFile )
Example:
local jobs = {
[ 'delivery' ] = {
label = 'Delivery Driver' ,
defaultDuty = true ,
offDutyPay = false ,
grades = {
[ 0 ] = { name = 'Driver' , payment = 45 },
[ 1 ] = { name = 'Manager' , payment = 60 , isboss = true }
}
},
[ 'mining' ] = {
label = 'Mining Company' ,
defaultDuty = true ,
offDutyPay = false ,
grades = {
[ 0 ] = { name = 'Miner' , payment = 55 },
[ 1 ] = { name = 'Foreman' , payment = 80 , isboss = true , bankAuth = true }
}
}
}
local success , msg = exports . qbx_core : CreateJobs ( jobs , true )
print ( msg ) -- "All jobs created/updated successfully."
Create Gangs
exports . qbx_core : CreateGangs ( newGangs , commitToFile )
Example:
exports . qbx_core : CreateGangs ({
[ 'mafia' ] = {
label = 'The Mafia' ,
grades = {
[ 0 ] = { name = 'Associate' },
[ 1 ] = { name = 'Soldier' },
[ 2 ] = { name = 'Capo' },
[ 3 ] = { name = 'Boss' , isboss = true , bankAuth = true }
}
},
[ 'yakuza' ] = {
label = 'Yakuza' ,
grades = {
[ 0 ] = { name = 'Kobun' },
[ 1 ] = { name = 'Wakashu' },
[ 2 ] = { name = 'Oyabun' , isboss = true , bankAuth = true }
}
}
}, true )
Removing Groups
Remove a Job
local success , message = exports . qbx_core : RemoveJob ( jobName , commitToFile )
Returns:
success (boolean)
message (string) - ‘success’, ‘invalid_job_name’, or ‘job_not_exists’
Example:
local success , msg = exports . qbx_core : RemoveJob ( 'delivery' , true )
if success then
print ( 'Job removed successfully' )
else
print ( 'Error:' , msg )
end
Remove a Gang
local success , message = exports . qbx_core : RemoveGang ( gangName , commitToFile )
Updating Group Data
Update Job Data
Updates job properties without modifying grades.
exports . qbx_core : UpsertJobData ( name , data , commitToFile )
Example:
exports . qbx_core : UpsertJobData ( 'police' , {
label = 'Los Santos Police Department' ,
type = 'leo' ,
defaultDuty = true ,
offDutyPay = false
}, true )
Update Gang Data
exports . qbx_core : UpsertGangData ( name , data , commitToFile )
Example:
exports . qbx_core : UpsertGangData ( 'ballas' , {
label = 'Ballas Gang'
}, true )
Managing Grades
Add or Update Job Grade
exports . qbx_core : UpsertJobGrade ( name , grade , data , commitToFile )
Example:
-- Add a new grade 5 to police
exports . qbx_core : UpsertJobGrade ( 'police' , 5 , {
name = 'Assistant Chief' ,
payment = 175 ,
isboss = true ,
bankAuth = true
}, true )
-- Update existing grade
exports . qbx_core : UpsertJobGrade ( 'police' , 2 , {
name = 'Senior Officer' ,
payment = 110
}, true )
Add or Update Gang Grade
exports . qbx_core : UpsertGangGrade ( name , grade , data , commitToFile )
Example:
exports . qbx_core : UpsertGangGrade ( 'ballas' , 4 , {
name = 'Kingpin' ,
isboss = true ,
bankAuth = true
}, true )
Remove Job Grade
exports . qbx_core : RemoveJobGrade ( name , grade , commitToFile )
Example:
exports . qbx_core : RemoveJobGrade ( 'police' , 5 , true )
Remove Gang Grade
exports . qbx_core : RemoveGangGrade ( name , grade , commitToFile )
Getting Group Data
Get All Jobs
local jobs = exports . qbx_core : GetJobs ()
for jobName , jobData in pairs ( jobs ) do
print ( jobName , jobData . label )
for grade , gradeData in pairs ( jobData . grades ) do
print ( ' Grade' , grade , gradeData . name , '$' .. gradeData . payment )
end
end
Get All Gangs
local gangs = exports . qbx_core : GetGangs ()
Get Specific Job
local policeJob = exports . qbx_core : GetJob ( 'police' )
if policeJob then
print ( 'Found job:' , policeJob . label )
print ( 'Default duty:' , policeJob . defaultDuty )
print ( 'Job type:' , policeJob . type )
end
Get Specific Gang
local ballasGang = exports . qbx_core : GetGang ( 'ballas' )
Client-Side Group Fetching
Clients can fetch the group cache:
-- Client-side
local groups = lib . callback . await ( 'qbx_core:server:getGroups' , false )
local jobs = groups . jobs
local gangs = groups . gangs
File Persistence
When commitToFile is true, changes are written to:
shared/jobs.lua - For jobs
shared/gangs.lua - For gangs
The conversion function formats the data properly:
local function convertGroupsToPlainText ( groupTable , type )
-- Converts groups to formatted Lua code
-- Preserves comments and structure
-- Escapes special characters in strings
end
Example Generated Output
---Job names must be lower case (top level table key)
--- @type table<string , Job>
return {
[ 'police' ] = {
label = 'LSPD' ,
defaultDuty = true ,
offDutyPay = false ,
grades = {
[ 0 ] = { name = 'Recruit' , payment = 50 },
[ 1 ] = { name = 'Officer' , payment = 75 },
[ 2 ] = { name = 'Sergeant' , payment = 100 , isboss = true , bankAuth = true },
},
},
}
Events
Job Update Events
-- Server event
AddEventHandler ( 'qbx_core:server:onJobUpdate' , function ( jobName , job )
if job then
print ( 'Job updated:' , jobName )
else
print ( 'Job removed:' , jobName )
end
end )
-- Client event
RegisterNetEvent ( 'qbx_core:client:onJobUpdate' , function ( jobName , job )
-- Update client-side cache
end )
Gang Update Events
-- Server event
AddEventHandler ( 'qbx_core:server:onGangUpdate' , function ( gangName , gang )
if gang then
print ( 'Gang updated:' , gangName )
else
print ( 'Gang removed:' , gangName )
end
end )
-- Client event
RegisterNetEvent ( 'qbx_core:client:onGangUpdate' , function ( gangName , gang )
-- Update client-side cache
end )
Validation
Group names are automatically validated:
for name in pairs ( jobs ) do
if name ~= name : lower () then
lib . print . error (( 'jobs.lua contains a job name with capital letters: %s' ): format ( name ))
end
end
All job and gang names must be lowercase. Capital letters will generate errors.
Example: Dynamic Job Creation System
-- Create a job creation UI for admins
RegisterCommand ( 'createjob' , function ( source , args )
if not IsPlayerAceAllowed ( source , 'admin' ) then return end
-- Get job data from admin UI
local jobData = {
label = args [ 2 ],
defaultDuty = true ,
offDutyPay = false ,
grades = {}
}
-- Add grades
for i = 0 , 3 do
jobData . grades [ i ] = {
name = 'Grade ' .. i ,
payment = 50 + ( i * 25 )
}
end
-- Create the job
local success , msg = exports . qbx_core : CreateJob ( args [ 1 ], jobData , true )
if success then
print ( 'Job created:' , msg )
else
print ( 'Failed to create job:' , msg )
end
end , true )
-- Example: /createjob delivery "Delivery Services"
Best Practices
Use Lowercase Names Always use lowercase for job and gang names to avoid validation errors.
Commit Important Changes Set commitToFile = true for permanent changes that should survive server restarts.
Validate Before Creating Check if a job/gang exists before creating to avoid accidental overwrites.
Handle Errors Always check the success return value and handle errors appropriately.