Jobs are saved by job key
Last updated
May be stale
This page was last updated ago, on 4 October 2026. Check what it says against the code before relying on it.
Status: Accepted · 2026-10-04 · charted by #2187
A job's index is handed out in registration order, so adding, removing or reordering a job shifts every index after it, and its display name changes with renames and spelling fixes. Anything that saved either one silently starts pointing at a different job, or at none: spawn points and keypad saves stored display names, and keypad duplicator data stored indices inside players' own saves.
The decision
- Every job has a job key, a literal written at its registration: lowercase
snake_case, containing at least one letter, never changed once shipped, and never reused by another job. A duplicate key is a load-time error. - The index never leaves the process. It stays the runtime identity the engine needs; anything saved, or typed into configuration by staff, names the job by its key.
- Saved data whose key no longer resolves is kept and ignored, with one warning per key, never deleted: the job may only be absent on this server.
- Saved data looks a key up exactly. Commands people type into may accept a key alongside today's forgiving name match; saved data never goes through that match.
Rejected alternatives
Derive the key from the display name or a command name
It needs no new argument, but a derived key moves when its source is renamed, which is the drift this decision exists to remove.
Keep saving display names, matched exactly
Exact matching fixes the ambiguity of today's substring lookup but not renames, and display names are player-facing text that is expected to change.
Name jobs by their TEAM_* global
The globals are stable within the source code, which is why configuration written as code is already safe, but they exist only in source: saved data can't hold a Lua symbol, and the global's value is the index.
Consequences
Old saves migrate lazily: a saved value that isn't a key falls back to an exact, case-insensitive display-name match, or is read as an index when it is a number, and the next save writes keys. The fallback stays until a tracked removal, because a map's file may not be loaded for months. An old duplicator save whose indices have already shifted can't be repaired, because nothing recorded which job it meant.