Features
This page walks through each module. What an officer sees depends on the permissions of their rank, see Departments and permissions. Pages without permission are hidden from the sidebar.
Shell and search
The MDT opens as a tablet. It has browser-style tabs (back, forward, reload, middle-click to close), collapsible sidebar groups and a notification center. Press Ctrl+F to search across people, plates, reports and pages. Moving the mouse outside the tablet makes it semi-transparent (Config.Ui.fadeOutside).
Dashboard
The dashboard has a welcome bar with the duty toggle, KPI cards with 7-day bars, online employees with a division filter, the mail inbox, the notification center, bulletins and record counters. EMS departments see EMS cards (patients today, open EMS calls, beds, unpaid bills, units on duty, latest reports) and a panel with downed patients when koja-ambulance is linked.
Bulletins are department announcements. Creating them needs bulletins.manage.
Dispatch and voice
Players call with /911, /311 or the anonymous /911a. Officers press F9 for the panic button (10-99). Calls show up with a blip and sound for priority calls.
In the MDT, dispatchers and officers can:
- respond to a call, leave it, close it, add notes;
- create calls manually (with a GPS position) and assign units;
- set their unit status from the unit board (10-8, 10-6, 10-97, 10-23, 10-38, 10-7 and the EMS, fire and DOJ variants);
- set a GPS waypoint to the call.
Field departments (leo, ems, fire by default) receive calls that target them. A call with no target goes to law enforcement only. Extra call codes, including fire codes, come from Config.Dispatch.callCodes.
Dispatcher voice. A radio dispatcher reads new calls, panic alerts and responding units aloud while the officer is on duty, even with the MDT closed. Voice clips ship for English and Polish. If a clip is missing the interface falls back to speech synthesis. Each officer can switch the voice off and set the volume in Settings. Server options are in Config.DispatchVoice.
Gunshot alerts
Gunfire creates a "Shots fired" call (10-71, priority 1) for law enforcement on its own, with a witness as the caller. The call appears 3 to 8 seconds after the shot, and its location is offset by up to 35 meters. Shots near a recent alert are merged into it, and one player can raise at most one alert every 30 seconds. Police on duty, silenced weapons, non-lethal weapons and shooting ranges are ignored. Everything is set in Config.Dispatch.gunshots.
Quick dispatch
A compact overlay on screen for new calls while the MDT is closed. Keys: Y respond, Delete dismiss, Page Up and Page Down to move between calls, Home to show or hide. All keys can be rebound in the FiveM keybind settings. See Config.QuickDispatch.
People
Search by name, phone or ID. A person's file has a photo, flags (armed, gang, parole and the others from Config.ProfileTags), licenses (revoke and reinstate with licenses.revoke), a criminal record summary, vehicles, firearms, warrants, BOLOs, court cases, a photo gallery, fingerprint and DNA data. New citation is available from the file. Medical summary appears for allowed police ranks only when Config.Ems.policeSummary.enabled is on.
Vehicles and ANPR
Plate search with owner link, flags (stolen, wanted, impounded and others), strike points with a limit warning, BOLO and warrant alerts and history. The scan vehicle ahead function reads the vehicle in front of the officer.
ANPR. Plate readers work in two places:
- CCTV cameras read plates in range (
Config.Cameras.anpr). - In-vehicle ALPR on police models (
Config.Anpr.vehicle). A panel shows the front and rear plate with hit history. Keys: toggleF10, lock frontUp, lock rearDown, open in the MDTRight.
A hit (stolen, BOLO, warrant, or a flag from Config.Anpr.hitFlags) can create a dispatch call with code 10-ALPR. Hits are logged to the ANPR log.
Firearms
A serial registry with owner, model and status (stolen, seized, evidence). Other scripts can register weapons with the RegisterWeapon export, see Server exports.
Reports and sentencing
There are eight report types (arrest, citation, traffic collision, vehicle pursuit, investigation, use of force, death investigation, general), each with a template. Reports hold a narrative, officers, suspects, victims and witnesses, vehicles, tags, photos and links to evidence, warrants and cases. A report can be marked restricted so only ranks with incidents.restricted see it.
Sentencing. For each suspect the officer picks charges from the penal code with counts and modifiers (attempted, accessory and similar), sets a reduction percentage and the plea, then processes the suspect. Processing:
- takes the fine from the bank and falls back to cash, and pays the society account;
- sends the player to jail through your jail script;
- adds license points and revokes the license at the limit;
- serves matching arrest warrants automatically.
Rules are in Config.Processing. The suspect must be online and near the officer by default.
Penal code
The 57 charges from shared/penalcode.lua are seeded into the database on first start. After that they are edited in the MDT by ranks with charges.manage (judges and command by default). Each charge has a code, label, category, class (infraction, misdemeanor, felony), fine, months and points.
Citations
Officers write tickets from the Citations page or the New citation button on a person. In game this opens the ticket book (/citation):
- The book opens with the number, date, unit, location and the nearest player and vehicle filled in.
- The officer adds violations (quick chips or search), checks the fields and signs.
- The officer picks who takes the ticket among players in range and tears it off. The server re-checks permission, distance, cooldown and recalculates the fine from the penal code.
- The other player sees the ticket and chooses Sign or Refuse to sign. After the answer, or after the timeout, they get the
citationitem. - File without handing over files the ticket without giving anyone the paper (parking, absent drivers).
Using the item shows the paper, where the violator can pay or contest. Tickets also appear on the person's record and in the citizen web portal under My tickets. Overdue tickets get a late fee. A contest can file a court case. Options are in Config.Citations.
Warrants
Arrest, search, vehicle and bench warrants with an expiry. With Config.Records.warrantsNeedApproval they go through a judge: approve or deny with a note. Warrants can be marked served or cancelled. Expired warrants are closed automatically.
BOLOs
Person, vehicle or general BOLOs with priority and photo. Creating one broadcasts a toast to every unit.
Evidence
An evidence locker with a chain of custody log, status changes, photos and a link to the report. Types come from Config.EvidenceTypes.
Custody (jail and impound)
The Custody page has two parts. Jail lists people serving a sentence with the time left and a history. Impound lists vehicles held in a lot with the fee and hold period. Records also appear on the person and vehicle pages.
- Jail records are created when a suspect is processed in the MDT or a sentence is applied in court. Jail and prison scripts can report their own sentences and releases, see Integrations and the API overview.
- Supervisors can release early, change the term and transfer.
- Impound runs the impound adapter, records the fee and hold and sets the vehicle's impounded flag. Release clears it.
- With
Config.Custody.autoReleaserecords close when the time is up.
Options: Config.Custody.
Court and DOJ
The docket lists cases with defendant, judge, prosecutor, defense, courtroom, hearing date, status, verdict and sentence. Features:
- case management with charges and linked records (reports, evidence, bodycams, warrants, citations, documents);
- hearing scheduling (arraignment, preliminary, motion, trial, sentencing, appeal);
- docket filings and rulings, also from parties assigned to the case;
- carrying out a sentence (fine and jail) for online defendants;
- expungement requests with review, also through the citizen portal;
- a bar registry of attorneys, public defenders, prosecutors and judges;
- warrant approval for judges.
On first start the DOJ departments get four form templates (subpoena, search warrant order, court order, expungement order). Options: Config.Doj.
EMS
Departments with type = 'ems' get a Medical section:
- patient records (medical profile, history, bills, admissions);
- ePCR treatment reports with vitals, body diagram injuries, treatments from a catalog, transport, outcome and crew;
- medical bills charged to bank, then cash, paid to the society;
- a hospital bed board with admissions and discharges.
With koja-ambulance started, the EMS MDT can import live vitals and injuries into an ePCR, show live patient status and ambulance records, follow its duty, mirror its calls and beds, and send bills as koja-ambulance invoices. Configure it in Config.Ems.ambulance.
Fire
Departments with type = 'fire' use dispatch with the fire call codes (structure fire, vehicle fire, brush fire, alarm, rescue, hazmat) and fire unit statuses (including staging). They share the staff modules: roster, mail, calendar, divisions, certifications and forms.
Roster
The employee list shows every member, online and offline, with status, rank, divisions, certificates, weekly hours and duty status. With roster.manage you can promote, demote, fire and hire a nearby player. Hiring uses Config.Roster.hireGrade, firing sets the job to Config.Roster.fireJob. roster.discipline gives rewards and strikes and roster.suspend suspends or reinstates.
A member's profile has a banner and photo, rank, phone, join date, last duty, badge, rewards and strikes, a 7 by 24 duty heatmap, divisions, certificates, permissions and suspension state.
Divisions
Divisions such as Firearms, K-9, SWAT or Traffic exist per department. Each has a head, members, on-duty avatars and import and export templates. My divisions shows in the sidebar. Defaults come from Config.Divisions.
Certifications
Qualifications per division with a status (active, disabled, on hold) and what they unlock. Assign and revoke from a member. Other scripts can check them with the HasCertification export, see Server exports. Defaults come from Config.Certifications.
Forms
A form builder with 8 field types (short text, long text, number, select, checkbox, date, person, image) and up to 50 fields per form. Forms are internal or public. Submissions go to a review queue where reviewers approve or reject with a note. After filing, the filer gets the mdt_document item that shows the signed document. Public forms can be filled by citizens in the web portal.
Internal department email. Compose to officers or whole departments (whole departments need mail.broadcast), with inbox, unread, starred and sent folders, search, reply, reply all, forward, a signature and an important flag. A rich text editor is shared with reports, warrants, BOLOs and bulletins.
Calendar
Department events with attendees, RSVP, reactions and comments, reminders before the start, and court hearings if Config.Calendar.court is on. Creating and editing needs calendar.manage.
CCTV
Security cameras in the world, viewed from the MDT in a separate camera window. Switch between cameras with Q and E, zoom with the scroll wheel, and lock onto a vehicle to read its plate. Cameras are placed in game with a free camera by players holding the koja-mdt.cameras ace. Default cameras are seeded on first start (Config.Cameras.seedDefaults).
Bodycams
Officers start and stop recording with F7 or /bodycam (on, off, rec, stop). Auto start triggers are configurable: sirens, drawn weapon, dispatch attach, panic or going on duty. Supervisors watch live (bodycams.watch) or review sessions with the route, shots and notes (bodycams.view). Sessions are kept for Config.Bodycams.keepDays. With requireItem the officer needs the bodycam item.
Recording uses Config.Bodycams.recording, 8 frames per second by default. See Configuration for the frame rate options and their disk cost.
Live map
A live map showing on-duty field units with their position and heading, for ranks with dispatch.view. Units from departments the viewer may not see are hidden.
Admin panel
Open to holders of the koja-mdt.admin ace (and command, by default) and to ranks with admin.view or admin.manage. It offers:
- departments: edit label, short, colors, logo, jobs, ranks and permission lists; create, remove and reset departments (
Config.Admin.departmentOverrides); - jobs: edit jobs and grades on ESX (
Config.Admin.jobEditing); - officers: change a callsign, force off duty, reset web access;
- system: status of detected integrations, table row counts, online and on-duty counts, web portal state, purge old logs and expired web sessions.
Audit log
Every action is logged to the database (auto purge after Config.Logs.keepDays) and optionally sent to Discord webhooks per category (incidents, warrants, processing, roster, dispatch). Viewing needs logs.view.
Web portal
The resource serves its own web portal through the FXServer HTTP server, no extra hosting needed. It shows the same MDT in a browser or on a phone (responsive layout, can be added to the home screen).
Sign in
- One-time code: type
/mdtwebin game. You get a 6-character code (validConfig.Web.loginCodeMinutesminutes, single use) and the address. - Username and password: in the MDT open Settings, Web access, and set a username (3 to 24 characters: a-z, 0-9,
_,.) and a password (8 or more characters). The same panel lists signed-in devices and lets you sign out one or all.
Officers see the MDT for their current job and rank even while offline. Actions that need a character in game (responding to a call, sentencing, hiring nearby, the duty toggle) are game-only.
Citizen portal. With Config.Web.allowCitizens, any player can sign in to the citizen portal: public forms (job applications, complaints), the status of their submissions, My tickets, expungement requests, and with Config.Web.citizenRecord their own record and licenses.
Address
| Case | Address |
|---|---|
| Default | The relay address https://mdt.kojascripts.com/<server-id>/ when Config.Web.relay.enabled is on. |
| No relay | https://<your-id>.users.cfx.re/<resource>/, built from the web_baseUrl convar. |
| Your own domain | Set Config.Web.publicUrl, for example https://mdt.example.com/, and point a reverse proxy to http://127.0.0.1:30120/koja-mdt/. Set Config.Web.trustProxyHeaders = true so rate limits see real IPs. |
| Local test | http://<server-ip>:30120/koja-mdt/, plain HTTP. |
Config.Web.publicUrl wins over the relay. Sessions last Config.Web.sessionDays days and renew on use, with up to Config.Web.maxSessionsPerAccount devices. Turn the portal off with Config.Web.enabled = false.
Interaction menu
A quick menu on the key Left Alt (command mdtinteract): Ask for ID, Write citation, Run plate, Parking citation, Open MDT. It plugs into a radial menu (koja-police, ox_lib, qb-radialmenu) or a target resource (ox_target, koja-interactions, qb-target) when one is started. Asking for ID prompts the other player, who can accept or refuse, and shows an ID card with licenses and status (warrant, BOLO, unpaid citations). Ranks that can only confirm identity see a limited card. See Config.Interact.
Onboarding tour and tutorials
The first time an officer opens the MDT a short guided tour (the "MDT tour") starts by itself after a moment. It points at the real interface: navigation, search, the notification bell, dispatch, the profile, the tabs and Settings.
Longer hands-on walkthroughs live in Settings, in the Tutorials section. Each one highlights the real buttons and waits for the officer to click them. Only the tutorials the officer has access to through their permissions are shown. The section shows overall progress with a "Next up" suggestion, Start and Replay buttons and a Reset progress button.
| Group | Tutorials |
|---|---|
| Getting started | MDT tour |
| On patrol | Issue a citation, Look up a person, Check a vehicle and plate, Respond to dispatch calls |
| Investigations | Start a search: BOLO, Request a warrant, Write an arrest report, Evidence, jail and impound, Body cameras and recordings |
| Office | Mail and calendar |
| Your department | Court cases and warrant review, ePCR reports and billing, Running a department |
Progress is stored per officer in the settings column of koja_mdt_officers, under settings.tutorials: tour is the version of the intro tour the officer has seen and done is the list of finished tutorial ids. Reset progress clears done but keeps tour, so the first-open tour does not start again.
Settings and language
Settings holds the officer's own callsign, badge and photo (including a selfie and /mdtphoto), the personal accent color, dispatcher voice options, web access and the language. If Config.Languages.playerChoice is on, each player picks their own language and the choice applies to the MDT and to the game notifications they receive. See Translations.