Job Overrides
Job overrides let a single zone apply different protection settings depending on the player's job and grade. For example, on-duty police can keep their weapons and take damage inside a zone that is otherwise fully protected for everyone else, without creating a second overlapping zone.
Overrides are evaluated per player, client-side, every time a player enters the zone or their job changes while inside it.
A job override replaces only the six protection fields listed below. The zone's shape, height bounds, markers, blips, and collisionDisabled (pass-through) are never changed by an override — everyone shares the same physical zone, only the protection behaviour differs.
How Matching Works
Each zone carries a jobOverrides object:
jobOverrides = {
enabled = true, -- Master switch — overrides are ignored entirely when false
jobs = {
-- checked top to bottom; first match wins
{ name = "police", minGrade = 3, ... },
{ name = "ambulance", minGrade = 0, ... }
}
}
When a player enters the zone:
- If
enabledisfalseor thejobslist is empty, the zone's normal settings apply to everyone. - The player's current job is read through the framework bridge (
{ name, grade }). - The
jobslist is scanned top to bottom. The first entry wherenamematches the player's job and the player's grade is ≥minGradeis applied. - If no entry matches, the zone's default protection settings apply.
Matching stops at the first qualifying entry, so entry order decides the outcome. If you list police / minGrade 0 before police / minGrade 5, a grade‑8 officer matches the minGrade 0 entry and never reaches the minGrade 5 one. To tier settings by grade, put the highest minGrade first.
Framework Support
The player's job is resolved by the bridge, so job overrides work across all supported frameworks:
| Framework | Job source | Grade source |
|---|---|---|
| QBCore | PlayerData.job.name | PlayerData.job.grade.level |
| ESX | xPlayer.job.name | xPlayer.job.grade |
| QBox | PlayerData.job.name | PlayerData.job.grade.level |
| No framework / not found | unemployed | 0 |
Overridable Fields
Each entry in jobs accepts the following fields. All protection fields default to the same values as a normal zone if omitted.
| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Internal job name to match — lowercase, no spaces (e.g. police, ambulance), not the job label |
minGrade | number | 0 | Minimum job grade required for this entry to apply |
enableInvincibility | boolean | true | Damage protection for players of this job (no collision/transparency effect) |
enableVehicleInvincibility | boolean | true | Damage protection for vehicles (no collision/transparency effect) |
enableVehicleGhosting | boolean | false | Transparency only — makes in-zone vehicles semi-transparent |
enableGhosting | boolean | false | Transparency only — makes players semi-transparent. Does not affect pass-through |
disableVehicleWeapons | boolean | true | Disable vehicle-mounted weapons |
disableWeapons | boolean | true | Force the player to be unarmed |
disableWeapons forces the player to be unarmed, while disableVehicleWeapons disables vehicle-mounted weapons. They are independent — set one without the other as needed.
Setting Overrides via the Admin Panel
The admin panel is the recommended way to configure job overrides, because it validates and normalizes your input automatically (job names are lowercased and stripped of spaces).
- Open the panel with
/szadminand Create or Edit a zone. - Enable the Job Overrides toggle in the zone form.
- Add a row per job. For each row set the job name, minimum grade, and the protection toggles.
- Save. The overrides are stored with the zone in
data/zones.json.
See Admin Panel for the full interface guide.
Resulting Data Structure
A saved zone stores its overrides like this:
{
"name": "Police HQ",
"type": "circle",
"coords": { "x": 441.0, "y": -981.0, "z": 30.7 },
"radius": 40.0,
"enableInvincibility": true,
"enableGhosting": false,
"jobOverrides": {
"enabled": true,
"jobs": [
{
"name": "police",
"minGrade": 3,
"enableInvincibility": false,
"enableVehicleInvincibility": true,
"enableVehicleGhosting": false,
"enableGhosting": false,
"disableVehicleWeapons": false,
"disableWeapons": false
},
{
"name": "police",
"minGrade": 0,
"enableInvincibility": true,
"enableGhosting": true,
"disableWeapons": true
}
]
}
}
In this example, senior police (grade ≥ 3) keep their weapons and can take damage (so they can fight inside their HQ), while junior police (grade 0–2) and everyone else get the fully-protected default. Note the higher minGrade entry is listed first.
Static Configuration (config.lua)
You can also add jobOverrides directly to a zone in Config.Safezones:
{
name = "Police HQ",
type = "circle",
coords = vector3(441.0, -981.0, 30.7),
radius = 40.0,
enableInvincibility = true,
enableGhosting = false,
jobOverrides = {
enabled = true,
jobs = {
{ name = "police", minGrade = 3, enableInvincibility = false, enableGhosting = false, disableWeapons = false },
{ name = "police", minGrade = 0 }
}
}
}
Unlike the admin panel, jobOverrides written directly in config.lua are not validated or normalized. You must write the name exactly as the framework's internal job name — lowercase and without spaces (e.g. police, not Police or Police Department). A mismatched name matches nobody and the override silently does nothing.
See Also
- Zone Types — Protection Options — the fields job overrides replace
- Collision System — how the protection those fields control actually works
- Admin Panel — configure overrides in-game