How to Build a Job/Employment Script for a GTA Roleplay Server With AI
A job system is the backbone of almost every GTA roleplay server: it decides who gets paid, who can clock on, what menus and items each role can access, and how players climb a career ladder. Whether you want a trucker, fisherman, taxi driver, or a fully whitelisted police force, the underlying pattern is the same register the job with your framework, gate actions behind a job and grade check, pay players on a timer or per task, and give bosses a menu to hire, fire, and promote.
This guide walks through that pattern for both ESX and QBCore (and QBox, which shares QBCore's API). You do not need to be a Lua expert. PlayDeck teaches you to build exactly this kind of script with AI: you describe the job, the pay structure, and the duty zone, and you steer the AI as it writes the framework-correct Lua then you test it and ship it on Tebex.
Step 1: Register the job with your framework
Every framework keeps a list of jobs with named grades (ranks) and salaries. In QBCore, jobs live in qb-core/shared/jobs.lua as a table: each job has a label, optional defaultDuty/offDutyPay flags, and a grades table where each grade has a name, a payment value, and sometimes an isboss flag. In ESX, jobs and grades live in two SQL tables jobs and job_grades and you insert rows (or use the esx_jobs creator) to define them.
Pick a unique lowercase job name (the internal key, e.g. 'trucker') and human-readable labels for each grade. The grade index matters: grade 0 is the entry rank, and the highest grade with isboss/boss permissions can access the bossmenu. Keep salaries balanced against your server economy an entry job paying more than a heist is a fast way to break your market.
- QBCore: add the job to shared/jobs.lua, then restart qb-core
- ESX: insert into the jobs and job_grades tables, then restart es_extended
- QBox: same shared/jobs.lua structure as QBCore
- Always set isboss only on the grade that should manage the company
Step 2: Set the player's job and check it server-side
To assign a job, QBCore uses Player.Functions.SetJob('trucker', 0) and ESX uses xPlayer.setJob('trucker', 0). The critical rule: never trust the client. Decide who can take a job and pay them on the server. Read the player object on the server, check Player.PlayerData.job.name (QBCore) or xPlayer.job.name (ESX), and the grade level before allowing any paid action.
For an open job like trucker, you let a player set their own job from a sign or ox_target zone. For a whitelisted job like police, you only grant it via an admin command or a management menu so randoms cannot give themselves a badge. This server-side gate is the single most important security decision in the whole script a job check on the client is trivially bypassed by anyone running a menu.
Step 3: Add duty, paychecks, and a job menu
Most jobs have a duty toggle so players only earn while clocked on. QBCore exposes Player.Functions.SetJobDuty(true/false) and fires onDuty state to your HUD; ESX servers usually track duty with a flag you set when the player enters the depot. Pay on a server-side timer (QBCore's paycheck runs from qb-management/qb-bank funds) or pay per completed task (e.g. each delivery), crediting money with xPlayer.addAccountMoney('bank', amount) or Player.Functions.AddMoney('bank', amount).
Build the job menu with ox_lib's registerContext/showContext or qb-menu, and trigger it from an ox_target zone on the depot ped or marker. Gate each menu option behind the grade check so only managers see hire/fire. This is where steering an AI shines: you describe 'a trucker depot ped with a menu to go on duty, take a delivery, or (managers only) open the bossmenu,' and the AI scaffolds the target zone, the menu, and the server events you review the job/grade checks and test.
Step 4: Build the bossmenu (hire, fire, promote)
A company needs management. QBCore ships qb-management for society funds and many servers use qb-bossmenu; ESX uses esx_society plus a bossmenu resource. The bossmenu lets the boss grade hire nearby players (SetJob with grade 0), fire employees, change grades, view the society balance, and withdraw/deposit company money. Each of these is a server event that re-checks isboss before acting a fired employee must not be able to fire the boss back.
Keep money flowing through the society account, not the boss's personal wallet, so the economy stays auditable. Log every hire, fire, and withdrawal. When you describe this flow to an AI, be explicit that every management action validates the caller's grade on the server; that one instruction prevents the most common exploit in player-made job scripts.
Frequently asked questions
Do I need a separate script for every job?
No. Most servers build one reusable job framework (duty, paycheck, bossmenu) and define new jobs as config entries plus the framework's jobs table. Only jobs with unique gameplay like a heist or fishing minigame need their own logic on top.
ESX or QBCore for a custom job?
Both are mature and free. QBCore (and QBox, its modern fork) has a slightly cleaner job/grade API and a large script ecosystem; ESX has the largest install base and more legacy scripts. Pick whichever your server already runs never mix frameworks in one job script.
How do I make a job whitelisted (like police)?
Don't let players set the job themselves. Grant it only through an admin command or an in-game management menu that checks permissions server-side, and store the assignment in the framework so it persists across relogs.
Where does paycheck money come from?
Open jobs usually pay from the server economy on a timer or per task. Company-style jobs pay from a society/management account that the business funds through its own work, which keeps money creation under control.
Can AI really write a working ESX/QBCore job?
Yes, when you steer it. The AI knows the SetJob/addAccountMoney patterns; your job is to give it the exact job name, grades, pay, and duty zone, then verify the server-side job and grade checks. That review step is exactly what PlayDeck trains you to do.