Usage
Working tCAD in game: the six department views, the dispatch board, the roster, NCIC, warrants, a player's own civilian records, and the staff administration panel.
Open the CAD with /tcad or the keybind. What you see is decided by the agency type of a department you are on duty in — not by your permissions, and not by a setting.
The six views
An agency's agencyType selects the view. There are six, and they are seeded by Config.seed = 'full':
agencyType | View |
|---|---|
dispatch | The dispatch board |
law_enforcement | Dashboard, NCIC, Warrants, Roster |
fire_ems | Roster |
civilian | Home, Roster |
business | Roster |
judicial | Warrants queue, Roster |
On a 'minimal' seed, only the first three agency types exist, so the civilian, business and judicial views cannot be reached by any duty state. That is the reason 'full' is the default — see Configuration.
Going on duty
Duty is per department, and it is what most of the CAD is scoped to: a status change, a self-attach and a roster entry are all meaningless without it.
Your callsign must be non-empty and unique within its department, compared case- and punctuation-folded — so 1-Adam-12 and 1-adam-12 are one unit. That rule is in the storage layer and nothing can switch it off. tCAD ships with no numbering scheme and accepts whatever you type; Config.formatCallsign is where you impose one. See Customisation.
If you are on duty in more than one department and an operation needs to know which, it answers ambiguous rather than guessing. Pass a department.
The dispatch board
The board is the one screen a dispatcher looks at for a whole shift, so it is built for information density rather than whitespace: narrow rows, monospace where columns need to line up, and no decoration that costs a row.
It carries:
- Open calls, with priority, type, location, age and the units attached.
- Units, with status, callsign, department and how many calls each is on.
- A call's timeline — every status change, comment and attach, with who did it and when.
- A map overlay for the call being worked.
- Age and SLA warning, derived server-side. A call that has gone unattended past the threshold is marked.
Server-initiated changes arrive as pushes, so a second dispatcher's action appears without a refresh.
The roster
One screen, mounted by five views' Roster tabs — who is on duty right now.
| Column | Where it comes from |
|---|---|
| Callsign, department | The duty session |
| Name | Resolved from the live player list on every read, so it is never stale. A unit whose player has disconnected keeps the stored name rather than blanking |
| On duty since / for | The earliest open duty session, and the age the server derived from it |
| Calls | How many calls the unit is attached to |
The elapsed time shown is the server's number, not one recomputed from a local clock. A NUI page has no guarantee its clock matches the server's, and the server's reading is the one the CAD is accountable to.
NCIC
Two unscoped lookups, person and plate, behind tcad.ncic.run.
A refusal is the normal outcome for an officer without that key, and it is shown in the server's own words rather than as an empty result. "No records found" and "you may not run this query" are different answers, and conflating them is how an officer concludes a wanted person is clean.
Nothing on the NCIC screen is written to a log, because a result row is a medical record about a named person.
Warrants
One record, two screens.
| Law enforcement | Judicial | |
|---|---|---|
| Opens on | active — what is outstanding tonight | pending — the queue |
| Can raise | Yes | No. A judge does not file an application |
| Rulings offered | Serve, recall | Approve, deny, recall |
Reading a warrant is open beyond tcad.use — a judicial queue nobody can see is a queue nobody works. Only the rulings are separately gated, and each is a separate key, because the separation is the point of a judicial view.
The detail panel is identical on both screens: a judge ruling on an application and an officer about to serve it need to read the same affidavit.
The subject's identifying number is shown in full, to anyone holding tcad.civilian.view. That is a deliberate product decision rather than an unexamined default — masking it would mean a judge ruling on applications against two identically-named characters cannot tell which person each one names, and the error that produces is worse than the disclosure. Do not grant warrant approval without granting tcad.civilian.view to the same group.
The civilian Home tab
A player's own characters and their vehicles.
Every operation on this screen is scoped to the caller by the server, which passes the scope itself and never reads an owner out of the payload. So the screen cannot show somebody else's record even if it asked — and it does not ask.
A record outside your scope reads as absent, not as refused. That is deliberate: "that record is not yours" confirms it exists, which is a disclosure in itself.
A character's own medical note is collapsed behind a labelled reveal. There is no question of authority — it is the subject's own note — the question is shoulder-surfing, screenshots and streams. A medical note that is on screen by default is a medical note that ends up in a clip. The control is labelled so its absence is never mistaken for "no medical history".
The administration panel
A staff surface, reachable only when the server answers a capability probe — the nav entry stays hidden otherwise, so it is not discoverable by a player without a grant. Three sections are built:
Overview
The inventory. What each unbuilt administration section would administer, by operation name; which of the old product's surfaces were discarded and why; and which files are yours to replace rather than to administer.
It needs no server and it shows no record data of any kind — not even a fictional one. An administration panel is the surface that lists everything, so the one screen here that is pure specification renders the specification and nothing else.
Catalogues
One editor for every catalogue the server publishes. It knows the name of none of them: which catalogues exist, their titles, their fields and their deletion policy all come from the server's registry. Adding an eleventh catalogue is therefore a server change with no screen change.
Deletion behaviour is decided by each catalogue's policy, not by the editor:
| Policy | Behaviour |
|---|---|
retire | Delete is refused unconditionally. Retire removes the entry from pickers |
guard | Delete is refused while the entry is referenced, and the screen names what is blocking it |
free | Delete is allowed |
The Delete control is only rendered where the policy could ever permit it, because a button that always fails is worse than no button. An unrecognised policy is read as the strictest.
Audit
Who changed which catalogue entry, and when — scoped to the lookup and structure tables, none of which holds a civilian, medical or judicial record. A log returns the what, not the content: resolving an id to a record is the record operation's job, under the record operation's permission.
Two properties you are told about on the screen itself:
- The first-boot seed writes no audit row, deliberately — that world came from a config value, not from a person. A full catalogue with an empty log is correct, and the screen says so rather than leaving you to read it as a log that failed.
- There is no retention. The log grows for ever. A retention timer does not exist yet, and a button an administrator presses is not a retention policy — so it is stated on screen rather than discovered as a growing data file.
tcad.admin.audit is a separate grant from the catalogue keys precisely so a supervisor can audit without being able to change anything.
Console commands
All of these are console-only — they check for a console caller and ignore a player.
| Command | What it does |
|---|---|
tcad_config | Every config key with its resolved value, and anything malformed |
tcad_hooks | The eight hooks, and whether each has the expected signature |
tcad_selftest | 35 assertions against the live backend, reported per case |
tcad_writeprobe | Proves a write to data.json actually lands |
tcad_sqlprobe | Which database exports resolve, and through which resource |
tcad_reseed | Re-runs the first-boot seed |
tcad_exports | The export surface: what registered, and what was refused |
Was this page helpful?
TIMMYG Studios