# DarkRP Jobs, Done Properly

Where jobs actually belong, what every field does, and the five mistakes that cost an evening. Including the one that overwrites a job with no error at all.

- Platform: Garry's Mod
- Canonical page: https://devtoolsgg.com/guides/gmod/darkrp-jobs

DarkRP is configured by editing Lua, and the single most common way to break a
server is editing the wrong Lua. This guide covers where jobs actually belong,
what each field does, and the mistakes that produce the errors you will
otherwise spend an evening on.

## Never edit DarkRP itself

The gamemode ships a folder called `darkrpmodification`. That is where your
changes go.

```text
garrysmod/addons/darkrpmodification/lua/darkrp_customthings/
    jobs.lua
    entities.lua
    shipments.lua
    doorgroups.lua
    ...
```

Edit `gamemodes/darkrp` directly and your work is deleted by the next update.
Edit `darkrpmodification` and it survives, because updating DarkRP never touches
that addon.

> [!IMPORTANT]
> If you do not have `darkrpmodification`, install it before anything else. It
> is a separate download from DarkRP itself, and editing the gamemode "just
> until I install it properly" is how people lose a weekend.

## The shape of a job

A job is a call to `DarkRP.createJob`, assigned to a `TEAM_` global:

```lua
TEAM_POLICE = DarkRP.createJob("Police Officer", {
    color = Color(25, 25, 170, 255),
    model = {"models/player/police.mdl", "models/player/police_fem.mdl"},
    description = [[Keep the peace and arrest criminals.]],
    weapons = {"arrest_stick", "unarrest_stick", "stunstick", "weaponchecker"},
    command = "policeofficer",
    max = 4,
    salary = 65,
    admin = 0,
    vote = true,
    hasLicense = true,
    candemote = true,
    category = "Civil Protection",
})
```

The [DarkRP Job Generator](/gmod/darkrp-job) writes this for you, including the
whitelist variant, and it will not let you produce a `TEAM_` name that is not a
valid Lua global. Worth understanding anyway, because you will read other
people's jobs constantly.

### What each field is actually for

| Field | Meaning |
|---|---|
| `color` | The colour in the scoreboard and above the head. |
| `model` | One string, or a table. A table gives players a choice. |
| `description` | Shown in the F4 menu. Long brackets, not quotes. |
| `weapons` | Spawn loadout, by weapon class. |
| `command` | Types as `/policeofficer`. Letters and digits only. |
| `max` | 0 means unlimited. 4 means four at a time. |
| `salary` | Paid every payday interval. |
| `admin` | 0 everyone, 1 admins, 2 superadmins. |
| `vote` | Whether players vote the job in. |
| `hasLicense` | May give gun licences. |
| `candemote` | Whether this job can be demote-voted. |

Weapon classes are not guessed: the [weapon class list](/gmod/list/weapons) is
every class the game registers, and it tells you which ones only exist when
Half-Life: Source is mounted.

## The five mistakes that cost an evening

### 1. Two jobs sharing a TEAM name

```lua
TEAM_POLICE = DarkRP.createJob("Police Officer", { ... })
TEAM_POLICE = DarkRP.createJob("Police Chief", { ... })
```

The second silently overwrites the first. No error, one missing job, and a
confusing hour. Every job needs its own global.

### 2. A `]]` inside a description

```lua
description = [[Guard the vault [[loot]] and stay alert.]],
```

The string ends at the first `]]`, and everything after it becomes syntax the
parser cannot make sense of. Use `[==[ ... ]==]` when the text contains
brackets, or avoid them.

### 3. A model that is not mounted

A job pointing at a model your server does not have spawns players as an error
sign. The [player model list](/gmod/list/player-models) is every model Garry's
Mod registers by default; anything else has to be in an addon that is actually
installed on the **server**, not only on your own client.

### 4. Editing while the server runs

DarkRP reads these files at startup. Saving `jobs.lua` on a live server changes
nothing until it restarts, which is why "my job is not showing up" is usually
answered by restarting.

### 5. A command with a space or a dash

```lua
command = "police officer",
```

`command` becomes a chat command. Spaces, dashes and accents break it. Letters
and digits, nothing else.

> [!TIP]
> When a job does not appear, read the server console at startup rather than
> guessing. DarkRP prints a clear error with the file and line for anything it
> could not load.

## Categories, so the F4 menu is not a wall

Once you pass ten jobs the menu needs grouping. A category is created once and
then referenced by name:

```lua
DarkRP.createCategory{
    name = "Civil Protection",
    categorises = "jobs",
    startExpanded = true,
    color = Color(25, 25, 170, 255),
    canSee = fp{fn.Id, true},
    sortOrder = 101,
}
```

The `category` field on a job must match `name` **exactly**, including case. A
mismatch does not error; the job simply lands in the default group. The
[category generator](/gmod/darkrp-category) keeps them consistent.

## Whitelisting a job

Two ways, and they are not equivalent.

**The built-in whitelist** is `customCheck`, run when someone tries to take the
job:

```lua
customCheck = function(ply)
    return table.HasValue({"vip", "admin", "superadmin"}, ply:GetUserGroup())
end,
CustomCheckFailMsg = "This job is reserved for VIP members.",
```

Always set `CustomCheckFailMsg`. Without it the player is refused with no
explanation and asks you instead.

**The `admin` field** is simpler but blunter: `admin = 1` limits the job to
admins, with no message and no room for a donator rank.

## Once jobs work

- [Door groups](/gmod/darkrp-doorgroup), so only police can own the PD. Note the
  function is the global `AddDoorGroup`, not a `DarkRP.create` call.
- [Agendas](/gmod/darkrp-agenda), the objective text a boss writes for their
  team.
- [Shipments and entities](/gmod/darkrp-shipment) for what the gun dealer sells.
- [Demote groups](/gmod/darkrp-demotegroup), so demotion from one police job
  bars the others too.


## How to cite

DarkRP Jobs, Done Properly, devtoolsgg.com. https://devtoolsgg.com/guides/gmod/darkrp-jobs
