Skip to Content
QBCore docs – powered by Nextra 4
GuidesHow to Set Job on QBCore

How to Set Job on QBCore

Learn how to set player jobs in QBCore, create custom jobs, and manage job permissions effectively.

Overview

Jobs in QBCore define player roles, permissions, and gameplay mechanics. This guide covers setting jobs for players, creating custom jobs, and managing job-related features.

Basic Job Commands

Setting Player Jobs

Admin Command (In-Game):

/setjob [player_id] [job_name] [grade]

Examples:

/setjob 1 police 0 # Set player 1 as police cadet /setjob 2 mechanic 2 # Set player 2 as mechanic supervisor /setjob 3 unemployed 0 # Set player 3 as unemployed

Checking Current Job

Player Command:

/job # Check your current job

Default QBCore Jobs

Available Jobs

Job NameDescriptionGrades
unemployedDefault job for all players0
policeLaw enforcement0-4 (Cadet to Chief)
ambulanceEmergency medical services0-4 (Trainee to Chief)
mechanicVehicle repair services0-3 (Trainee to Boss)
taxiTransportation services0-1 (Driver to Boss)
busPublic transportation0-1 (Driver to Boss)
garbageWaste management0-1 (Worker to Boss)
truckingLogistics and delivery0-1 (Driver to Boss)

Job Grades Explained

Each job has multiple grades (ranks) with different permissions:

  • Grade 0: Entry level, basic permissions
  • Grade 1: Experienced worker, additional permissions
  • Grade 2: Supervisor, management permissions
  • Grade 3: Manager, advanced permissions
  • Grade 4: Boss/Chief, full permissions

Creating Custom Jobs

Step 1: Define Job in Shared Config

Edit qb-core/shared/jobs.lua:

-- Add your custom job ['realestate'] = { label = 'Real Estate', defaultDuty = true, offDutyPay = false, grades = { ['0'] = { name = 'Intern', payment = 50, isboss = false, }, ['1'] = { name = 'Agent', payment = 75, isboss = false, }, ['2'] = { name = 'Senior Agent', payment = 100, isboss = false, }, ['3'] = { name = 'Manager', payment = 125, isboss = true, }, ['4'] = { name = 'CEO', payment = 150, isboss = true, }, }, }, ['delivery'] = { label = 'Delivery Services', defaultDuty = false, offDutyPay = false, grades = { ['0'] = { name = 'Driver', payment = 40, isboss = false, }, ['1'] = { name = 'Supervisor', payment = 60, isboss = true, }, }, }

Step 2: Job Configuration Options

Job Properties:

  • label: Display name for the job
  • defaultDuty: Whether players start on duty by default
  • offDutyPay: Whether players get paid when off duty
  • grades: Job ranks and their properties

Grade Properties:

  • name: Display name for the grade
  • payment: Salary amount per paycheck
  • isboss: Whether this grade has boss permissions

Step 3: Add Job Permissions

Edit your job-specific resources to check for the new job:

-- Example: Check if player has realestate job RegisterNetEvent('realestate:server:checkJob', function() local src = source local Player = QBCore.Functions.GetPlayer(src) if Player.PlayerData.job.name == 'realestate' then -- Player has realestate job TriggerClientEvent('realestate:client:openMenu', src) else TriggerClientEvent('QBCore:Notify', src, 'You are not a real estate agent', 'error') end end)

Server-Side Job Management

Setting Jobs via Script

-- Set player job (server-side) local function SetPlayerJob(source, jobName, grade) local Player = QBCore.Functions.GetPlayer(source) if not Player then return false end local jobInfo = QBCore.Shared.Jobs[jobName] if not jobInfo then return false end local gradeInfo = jobInfo.grades[tostring(grade)] if not gradeInfo then return false end Player.Functions.SetJob(jobName, grade) return true end -- Usage example RegisterNetEvent('admin:server:setJob', function(targetId, jobName, grade) local src = source local Player = QBCore.Functions.GetPlayer(src) -- Check if source has admin permissions if QBCore.Functions.HasPermission(src, 'admin') then if SetPlayerJob(targetId, jobName, grade) then TriggerClientEvent('QBCore:Notify', src, 'Job set successfully', 'success') TriggerClientEvent('QBCore:Notify', targetId, 'Your job has been updated', 'success') else TriggerClientEvent('QBCore:Notify', src, 'Failed to set job', 'error') end end end)

Job-Based Callbacks

-- Get all players with specific job QBCore.Functions.CreateCallback('admin:server:getJobPlayers', function(source, cb, jobName) local players = {} local QBPlayers = QBCore.Functions.GetQBPlayers() for _, player in pairs(QBPlayers) do if player.PlayerData.job.name == jobName then table.insert(players, { source = player.PlayerData.source, name = player.PlayerData.charinfo.firstname .. ' ' .. player.PlayerData.charinfo.lastname, grade = player.PlayerData.job.grade.name }) end end cb(players) end)

Client-Side Job Handling

Job Change Events

-- Listen for job changes RegisterNetEvent('QBCore:Client:OnJobUpdate', function(JobInfo) -- JobInfo contains new job data print('Job changed to: ' .. JobInfo.label) print('Grade: ' .. JobInfo.grade.name) print('Payment: $' .. JobInfo.grade.payment) -- Update UI or other client features TriggerEvent('hud:client:updateJob', JobInfo) end) -- Check player's current job RegisterNetEvent('jobs:client:checkMyJob', function() local PlayerData = QBCore.Functions.GetPlayerData() local jobInfo = PlayerData.job local message = string.format( 'Job: %s\nRank: %s\nPayment: $%d\nOn Duty: %s', jobInfo.label, jobInfo.grade.name, jobInfo.grade.payment, jobInfo.onduty and 'Yes' or 'No' ) TriggerEvent('chat:addMessage', { color = {0, 255, 0}, multiline = true, args = {'Job Info', message} }) end)

Duty System

-- Toggle duty status RegisterNetEvent('jobs:client:toggleDuty', function() local PlayerData = QBCore.Functions.GetPlayerData() local newDutyStatus = not PlayerData.job.onduty TriggerServerEvent('QBCore:ToggleDuty') local status = newDutyStatus and 'on' or 'off' TriggerEvent('QBCore:Notify', 'You are now ' .. status .. ' duty', 'primary') end)

Advanced Job Features

Job-Specific Vehicles

-- Define job vehicles in shared config Config.JobVehicles = { ['police'] = { ['police'] = 'Police Cruiser', ['police2'] = 'Police Buffalo', ['policeb'] = 'Police Bike' }, ['ambulance'] = { ['ambulance'] = 'Ambulance', ['firetruk'] = 'Fire Truck' }, ['mechanic'] = { ['towtruck'] = 'Tow Truck', ['towtruck2'] = 'Flatbed Tow' } } -- Spawn job vehicle RegisterNetEvent('jobs:client:spawnVehicle', function(vehicleModel) local PlayerData = QBCore.Functions.GetPlayerData() local jobVehicles = Config.JobVehicles[PlayerData.job.name] if jobVehicles and jobVehicles[vehicleModel] then -- Spawn vehicle logic here QBCore.Functions.SpawnVehicle(vehicleModel, function(veh) SetEntityHeading(veh, GetEntityHeading(PlayerPedId())) TaskWarpPedIntoVehicle(PlayerPedId(), veh, -1) TriggerEvent('vehiclekeys:client:SetOwner', QBCore.Functions.GetPlate(veh)) end) else TriggerEvent('QBCore:Notify', 'You cannot access this vehicle', 'error') end end)

Job-Based Blips

-- Create blips for job locations local jobBlips = { { job = 'police', coords = vector3(428.23, -984.28, 29.76), sprite = 60, color = 29, label = 'Police Department' }, { job = 'ambulance', coords = vector3(307.39, -1433.52, 29.9), sprite = 61, color = 1, label = 'Hospital' } } -- Show blips based on player job RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() CreateJobBlips() end) RegisterNetEvent('QBCore:Client:OnJobUpdate', function(JobInfo) RemoveJobBlips() CreateJobBlips() end) function CreateJobBlips() local PlayerData = QBCore.Functions.GetPlayerData() for _, blipData in pairs(jobBlips) do if blipData.job == PlayerData.job.name then local blip = AddBlipForCoord(blipData.coords.x, blipData.coords.y, blipData.coords.z) SetBlipSprite(blip, blipData.sprite) SetBlipColour(blip, blipData.color) SetBlipScale(blip, 0.8) SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName('STRING') AddTextComponentString(blipData.label) EndTextCommandSetBlipName(blip) end end end

Job-Based Permissions

-- Check job permissions function HasJobPermission(source, requiredJob, minGrade) local Player = QBCore.Functions.GetPlayer(source) if not Player then return false end local playerJob = Player.PlayerData.job -- Check job name if playerJob.name ~= requiredJob then return false end -- Check minimum grade if minGrade and playerJob.grade.level < minGrade then return false end -- Check if on duty (optional) if not playerJob.onduty then return false end return true end -- Usage in server events RegisterNetEvent('police:server:accessArmory', function() local src = source if HasJobPermission(src, 'police', 2) then -- Player is police with grade 2+ TriggerClientEvent('police:client:openArmory', src) else TriggerClientEvent('QBCore:Notify', src, 'Insufficient permissions', 'error') end end)

Admin Tools

Job Management Menu

Create an admin menu for job management:

-- Admin job menu RegisterNetEvent('admin:client:jobMenu', function() local PlayerData = QBCore.Functions.GetPlayerData() if QBCore.Functions.HasPermission(PlayerData.source, 'admin') then local jobOptions = {} for jobName, jobData in pairs(QBCore.Shared.Jobs) do local gradeOptions = {} for grade, gradeData in pairs(jobData.grades) do table.insert(gradeOptions, { title = gradeData.name .. ' (Grade ' .. grade .. ')', description = 'Payment: $' .. gradeData.payment, event = 'admin:client:setJobGrade', args = {job = jobName, grade = tonumber(grade)} }) end table.insert(jobOptions, { title = jobData.label, description = 'Set player to ' .. jobData.label, menu = 'job_grades_' .. jobName, submenu = gradeOptions }) end TriggerEvent('qb-menu:client:openMenu', jobOptions) end end)

Bulk Job Operations

-- Set multiple players to same job RegisterCommand('setjobmultiple', function(source, args, rawCommand) if not QBCore.Functions.HasPermission(source, 'admin') then return end local jobName = args[1] local grade = tonumber(args[2]) if not jobName or not grade then TriggerClientEvent('QBCore:Notify', source, 'Usage: /setjobmultiple [job] [grade]', 'error') return end -- Get all online players local QBPlayers = QBCore.Functions.GetQBPlayers() local count = 0 for _, player in pairs(QBPlayers) do if player.PlayerData.job.name == 'unemployed' then player.Functions.SetJob(jobName, grade) count = count + 1 end end TriggerClientEvent('QBCore:Notify', source, 'Set ' .. count .. ' unemployed players to ' .. jobName, 'success') end, 'admin')

Troubleshooting

Common Issues

Job not saving after restart:

  • Check database connection
  • Verify job exists in shared/jobs.lua
  • Check for script errors in console

Grade permissions not working:

  • Ensure grade number matches config
  • Check isboss property for boss permissions
  • Verify permission checks in scripts

Players not getting paid:

  • Check paycheck script is running
  • Verify job payment amounts
  • Ensure players are on duty if required

Debug Commands

-- Debug player job info RegisterCommand('debugjob', function(source, args, rawCommand) if not QBCore.Functions.HasPermission(source, 'admin') then return end local targetId = tonumber(args[1]) or source local Player = QBCore.Functions.GetPlayer(targetId) if Player then local job = Player.PlayerData.job print('=== JOB DEBUG ===') print('Player: ' .. Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname) print('Job: ' .. job.name .. ' (' .. job.label .. ')') print('Grade: ' .. job.grade.level .. ' (' .. job.grade.name .. ')') print('Payment: $' .. job.grade.payment) print('Boss: ' .. tostring(job.isboss)) print('On Duty: ' .. tostring(job.onduty)) print('=================') end end, 'admin')

Best Practices

  1. Job Naming: Use clear, descriptive job names
  2. Grade Structure: Create logical progression in grades
  3. Permissions: Use appropriate permission checks
  4. Documentation: Document custom jobs and their features
  5. Testing: Test job changes on development server first

Conclusion

Job management is crucial for roleplay servers. Proper job setup enables diverse gameplay experiences and helps organize your server community effectively.


Need more help? Join our GitHub discussions  or check out more QBCore tutorials.

Last updated on