- Documentation
- 04Operations
Game alerts
What the game reports on its own — shots fired, robberies, vehicle thefts, 911 calls — reaches dispatch as a call, merged and capped.
Game alerts turn what happens on the server into calls in the dispatch queue: “ATM robbery”, “Shots fired”, “Carjacking”, a citizen calling 911 from their phone… Without anyone typing anything.
ops-game-alert-dispatchYou need the game integration and the supermdt-bridge resource
installed on the server (see Installing the bridge).
Where alerts come from
Section titled “Where alerts come from”SuperMDT doesn’t replace your dispatch script: it works with it. The bridge listens to what your server already reports and sends it to the MDT, without changing any script. Alerts come from:
- Your dispatch script, if you have one: ps-dispatch Tested in game,
or cd_dispatch, qs-dispatch and rcore_dispatch Experimental. When a
robbery or crime script calls it, SuperMDT gets the same alert: code, title, place,
position, description, vehicle, suspect’s sex when the script provides it. By default, its
in-game title becomes the call’s nature (Game title; or Type name, see
Configuring a service’s alerts), in the script’s language
(see The language of titles). core_dispatch is not
supported: it offers nothing to listen to; call the
Alertexport instead. - The bridge’s built-in detections: shots fired, person down, vehicle theft (see The bridge’s detections).
- Framework alerts: the QBCore and Qbox police alert and EMS alert, the
robberies (stores, banks) and the
/911pand/911ecommands. - 911 calls from phones (lb-phone, npwd, sd-phone, gksphone, qs-smartphone): the caller’s message and position become a call, with their name and number (and a link to their citizen record when their character is known).
- Custom scripts, through the bridge’s
Alertexport (see For developers).
See what your server uses
Section titled “See what your server uses”The bridge announces its sources to SuperMDT when it introduces itself, then every 10 minutes and on every settings change. Two places show them:
- Settings › Game › Integrations, Alerts and dispatch row: the dispatch script
listened to (or “No dispatch script detected”), the other listeners that are on (Also
listens to) and those that are off (Listeners off), the phones listened to for 911,
the detections’ state (“on”, “off: ps-dispatch handles them” or “turned off in the game
server configuration”) and the script’s support level, with the same badge as the page’s
other rows. Below, one switch per listener present (see
The bridge’s listeners). If alerts are turned off on the game
server (
Config.Alerts), a warning says so: nothing is sent. The Set up game alerts link leads to the service’s card (below). - Settings › Operations › Game alerts, Where alerts come from box at the top of the card: the same sources, with the name of the detected script, and the How it works link to this page. Until the bridge has announced itself, the box stays general.
game-integrationssupermdt status, in the server console, gives the same detail with its counters, each
listener (“policeAlert (off, default)”) and the alert codes kept.
The bridge’s listeners
Section titled “The bridge’s listeners”A dispatch script such as ps-dispatch already receives the alerts of robbery, drug or death
scripts. If the bridge also listened to the framework police alert, QBCore robberies or
/911p, the same event would arrive twice, or pointless alerts would be added. So, when a
dispatch script is listened to:
| Listener | Default |
|---|---|
| The dispatch script (ps-dispatch, cd_dispatch, qs-dispatch, rcore_dispatch) | always listened to |
Framework police alert (policeAlert), EMS alert (ambulanceAlert), robberies (robberies), /911p and /911e (qbCommands), Qbox 911 relay (relay911) |
off |
| Phone 911 calls (lb-phone, npwd, sd-phone, gksphone, qs-smartphone) | on: ps-dispatch only receives its own /911 and /311 commands, never phone calls or messages (checked in its code) |
Without a dispatch script, nothing changes: every listener present is on.
In Settings › Game › Integrations, Alerts and dispatch row, each listener present on your server has its switch, with its default (“Off by default: ps-dispatch handles it”) or “Set by the organization”. Turn on the one you need, for example a robbery script that only sends its alerts to the framework police alert; Back to default clears your choice. You need the Set up the game permission; each change is written to the audit log and reaches the game within a few seconds: the bridge only hooks the allowed listeners and ignores the events of those that are off.
game-alert-listenersConfig.Alerts.listen and Config.Alerts.phones (config_alerts.lua) keep the last word on
the game server side: a listener set to false is never hooked, whatever SuperMDT says.
Compatible scripts and phones
Section titled “Compatible scripts and phones”Tested in game tried in game on a real server. Verified in code the
signature was read in the script’s published source code, not tried in game yet.
Experimental written from the publisher’s documentation (encrypted
script); check it on your server before relying on it.
supermdt status in the server console lists what is being listened to.
| Script | What is listened to | Status |
|---|---|---|
| ps-dispatch (v2, v3; v1) | ps-dispatch:server:notify event (v1: dispatch:server:notify), including /911 and /311; /911a and /311a stay anonymous (no name, number or license); an alert meant only for jobs that are not emergency services (mechanic…) is not sent |
Tested in game |
| QBCore and Qbox police alert | police:server:policeAlert (qb-policejob, qbx_police) |
Verified in code |
| QBCore and Qbox EMS alert | hospital:server:ambulanceAlert (qb-ambulancejob, qbx_ambulancejob); Qbox: EMS emergency button (hospital:server:emergencyAlert, qbx_radialmenu) and last stand (qbx_medical:server:onPlayerLaststand) |
Verified in code |
| QBCore and Qbox robberies | the robber’s event: qb-storerobbery:server:callCops, qb-bankrobbery:server:callCops, qbx_bankrobbery:server:callCops |
Verified in code |
QBCore /911p and /911e |
QBCore:Server:PreCommandExecution (qb-core), for the qb-policejob and qb-ambulancejob commands |
Verified in code |
Qbox /911p and /911e |
relayed by an on-duty officer’s client (qbx_police, qbx_ambulancejob) | Verified in code |
| cd_dispatch, cd_dispatch3d | cd_dispatch:AddNotification |
Experimental |
| qs-dispatch | qs-dispatch:server:CreateDispatchCall |
Experimental |
| rcore_dispatch | rcore_dispatch:server:sendAlert |
Experimental |
| core_dispatch | nothing to listen to (exports only) | Not supported: call the Alert export |
| npwd | calls to emergency numbers (onCall, 911 and 912 by default), registered again automatically after a restart npwd |
Verified in code |
| sd-phone | Services app messages (sd-phone:server:services:message) and calls to emergency companies (sd-phone:server:call:started); its lb-phone and gksphone imitations are never listened to as well: no duplicates |
Verified in code |
| lb-phone | messages and calls to emergency companies (police, ambulance…); only the real lb-phone, not a resource imitating it | Experimental |
| gksphone (v2) | reports to services (gksphone:services:newReport) |
Experimental |
| qs-smartphone, qs-smartphone-pro | job alerts, SOS messages | Experimental |
QBCore and Qbox robberies
Section titled “QBCore and Qbox robberies”qb-storerobbery, qb-bankrobbery and qbx_bankrobbery warn the police in two steps: the
robber’s client sends an event to the server (callCops), then every on-duty officer
sends the alert back from their own position. The bridge reads the first one: a single
“Robbery” alert, at the robbery’s position (refused if more than 250 m from the robber),
even with no officer on duty. For the next 15 s, the officers’ resends are ignored
(except an officer down). Without this adapter (Config.Alerts.listen.robberies = false),
the same text resent by several officers still makes only one alert. qbx_storerobbery
sends a police alert with no text from the robber’s client: it becomes a robbery.
The /911p and /911e commands
Section titled “The /911p and /911e commands”- QBCore (qb-policejob, qb-ambulancejob): the bridge reads the command when the player
types it (
QBCore:Server:PreCommandExecution, a qb-core server event)./911pbecomes an emergency call (police),/911ean emergency call (medical), with the caller’s name, number and record (these scripts have no anonymous variant), even with no officer on duty. Setting:Config.Alerts.listen.qbCommands. - Qbox (qbx_police, qbx_ambulancejob): these commands fire no event that can be
listened to; they only write to on-duty officers. The bridge’s client, on an on-duty
officer’s machine, relays what it receives. The server checks that the officer is really
on duty and that exactly one player is within 6 m of the point (they become the
caller;
Config.Alerts.relay.callerRadius), keeps only one relay of the same text (15 m, 10 s), and ignores what it already received another way (police or EMS alert) as well as plates flagged by qbx_police’s radars. Setting:Config.Alerts.listen.relay911.
The language of titles
Section titled “The language of titles”An alert’s title comes from the script, in its language: ps-dispatch writes “Discharge
of a firearm” in English. ps-dispatch uses ox_lib’s languages and ships a French translation
(locales/fr.json: “Fusillade”, “Braquage de magasin”…). In server.cfg, before
ensure ps-dispatch:
setr ox:locale frsetr (not set): ps-dispatch alerts are written on the player’s side, which must
receive the setting. ox_lib also lets each player pick their language (/ox_lib); to force
the server language for everyone, add setr ox:userLocales 0.
To stop depending on the script’s language, set the type’s nature to Type name: the call is named “Shots fired”, whatever title is sent (see Configuring a service’s alerts).
Script texts
Section titled “Script texts”A script with no radio code is classified from its text (Config.Alerts.patterns, then
Config.Alerts.keywords in config_alerts.lua), using the real texts of common scripts, in
English and French: “Officer Doe | 12 Down” or “Officier Doe | 12 Au sol” (qb-policejob,
qbx_police) and “Doctor Doe Down” (qbx_ambulancejob) give Officer down; “Storerobbery in
progress” a robbery; “Suspicous activity” (qb-drugs’ real spelling) suspicious activity;
“Civilian Died” or “Civil décédé” a person down. On QBCore, an officer down creates a
police alert and an EMS alert.
The bridge’s detections
Section titled “The bridge’s detections”Each one is turned on or off in config_alerts.lua (Config.AlertDetections). By default
(mode = 'auto'), they only run when no dispatch script is started, so the same thing
is not reported twice.
| Detection | When | Settings |
|---|---|---|
| Shots fired | the player fires a firearm, in the city, near at least one non-player bystander | witness radius, minimum count, “city” zones, excluded zones (Ammu-Nation shooting ranges by default), ignored weapons (taser, extinguisher…), suppressor |
| Person down | the player has been dead or down for 15 s (or per EMS scripts, see below); an on-duty officer becomes “Officer down” | delay, witnesses, recognized states |
| Vehicle theft | breaking into a locked vehicle, carjacking; once per vehicle | witnesses, break-in and carjacking separately |
Person down per EMS script. With qb-ambulancejob (QBCore), the downed character is
revived by the script and GTA does not see them as dead: the bridge reads the character’s
isdead and inlaststand metadata on the server and marks them down itself. With
qbx_medical (Qbox) and esx_ambulancejob (ESX), it reads the isDead state these scripts
set; on ESX, death (esx:onPlayerDeath, until esx:onPlayerSpawn) counts as well.
Carjacking. Trying to get in through the driver’s seat of a vehicle driven by a
living NPC is a carjacking, whether the door is locked or not: qb-vehiclekeys
(Config.LockNPCDrivingCars, on by default) locks an NPC’s car as soon as you try. On the
passenger side it is not a carjacking (a break-in if the vehicle is locked). Armed
carjacking (aiming at the driver) is reported by qb-vehiclekeys and qbx_vehiclekeys
themselves, according to their own probability (“Vehicle theft in progress. Type:
carjack”).
Service jobs on duty (mapped in SuperMDT) trigger neither shots fired nor vehicle theft;
ignoreJobs adds others. Detection runs on the player’s machine, but the server
re-reads the character’s position, the job and the excluded zones, and limits the rate: a
modified client cannot make anything up.
Configuring a service’s alerts
Section titled “Configuring a service’s alerts”In Configuration › Operations, pick the service, then the Game alerts card. You need the Game alerts › Configure permission (command by default).
Received types are SuperMDT’s categories: every alert coming from the game is filed under a type (shots fired, robbery…), which decides whether it is received, its priority and the call nature. Below the card, the alerts actually seen on your server show which type each one goes to.
settings-game-alerts- Turn on Receive game alerts (off by default).
- Choose the received types: shots fired, robbery, vehicle theft, carjacking, person down, officer down, fight, explosion, fire, drug dealing, suspicious activity, emergency call (police), emergency call (medical), other. A police service and a medical service each start from a suggested selection.
- For each type, the settings icon opens its sheet: the call priority and its
nature:
- Game title (default): the title sent by the script (“Discharge of a firearm”), in its language; without a title, the type name;
- Type name: always the type name (“Shots fired”), whatever the script’s language;
- Nature list: a nature from the service’s call types list;
- Call template: a call template (nature, description and standard notes).
- Set merging, the cap and the notification (below), then Save.
Several services can receive the same type: a shootout can create a call at the LSPD and
another at EMS. When the script targets a job (ps-dispatch jobs, cd_dispatch
job_table…), only services of that kind receive it, if some of the receiving services
are of that kind. The priority always comes from the service setting: a script cannot
make all its alerts urgent.
settings-game-alert-kindDetected alerts and their type
Section titled “Detected alerts and their type”Below the service’s alerts, the Detected game alerts card shows what your server
actually sends: each alert code (ps-dispatch’s codeName, rcore_dispatch’s type, the
Alert export’s code…) with a sample title, the script, and how many times it was seen
(“seen 14 times”, and when). For ps-dispatch, the bridge also reads the full list of its
alerts from its files (client/alerts.lua and Config.Blips, with the title in its
language): those that never arrived show as “In the script’s list, not seen yet”. Most seen
first; search by code or title; 20 shown, then Show more (150 codes at most per
organization).
settings-game-alert-codesFor each code, choose the type it goes to:
- Automatic: Shots fired (default): the type found by the bridge (
config_alerts.lua: codes, patterns, keywords); - another type: for example
speedingto Suspicious activity, orhuntingto Other alert; - Ignore: the bridge no longer sends it at all (it stays in the list, with its counter, in case you change your mind).
Your choice wins over config_alerts.lua and applies to the whole organization; each
service then decides whether it receives that type. You need the Set up the game permission to change
an assignment (others see it, locked); each change is written to the
audit log and reaches the game within a few seconds. The bridge
applies the assignment before filtering received types: a code assigned to a type that a
service receives goes out, even if its automatic type was received by nobody.
The bridge groups what it sees: a new code reaches the list in about 15 seconds, counters every 5 minutes, and nothing is sent while nothing changes.
Merging reports
Section titled “Merging reports”Twenty bystanders hearing the same shootout make a single call. Two alerts of the same type, within the merge radius (150 m by default) of the first report and less than the merge window (5 min by default) after the previous report, are merged: the call keeps its place, its counter goes up (“12 reports”) and each report is added to its log (the first 20; after that, only the counter). 0 for the radius or the window: never merge. A closed call receives nothing more: the next alert creates a new call.
The cap
Section titled “The cap”At most 60 calls created by alerts per hour in the service (1 to 500). Beyond that, alerts are ignored until the next hour and the overflow is written once to the audit log (“System ignored game alerts”). Merged reports do not count. On top of that: a limit for the whole organization (120 alerts per minute) and, on the game server, a per-player rate (6 per minute, one of the same type every 10 s, logged in the console when exceeded) and a whole-server rate (60 per minute).
At dispatch
Section titled “At dispatch”The call arrives in the queue with the Game alert icon and, from the second report on, the counter. Its page shows the type and the origin: dispatch script, bridge detection, 911 call or server script, with the resource and the radio code.
ops-game-alert-callFor an important alert (from High priority by default, setting Beep and notification at dispatch), dispatch hears a double beep and sees a notification with Open call, even when the new-call sound is off. Nothing is written continuously to the database: the position is set once, on the call.
For developers
Section titled “For developers”A server script (custom robbery, alarm system…) sends an alert like this:
exports['supermdt-bridge']:Alert({ kind = 'robbery', -- optional: otherwise inferred from code, title, message code = '10-90', title = 'Jewelry store robbery', message = 'Silent alarm triggered', coords = vector3(-630.0, -236.0, 38.0), street = 'Rockford Hills', service = 'police', -- or 'ems', a job, a list gender = 'male', vehicle = { model = 'Sultan', plate = 'AB12CD', color = 'Blue' }, player = source, -- optional: without coords, their position})The export returns true when the alert is sent, otherwise false and the reason
(notReceived: no service receives that type; playerLimit, serverLimit, duplicate,
far…). The same export exists client-side: the alert goes through the server, which checks
it like any player alert (position close to their character, rate). priority is not read:
the priority is the service’s. Types: shooting, robbery, vehicleTheft, carjacking,
personDown, officerDown, fight, explosion, fire, drugs, suspicious,
emergencyCall, medicalCall, other.
A dispatch script’s code is turned into a type by Config.Alerts.codes, then by keywords
(Config.Alerts.keywords): add yours in config_alerts.lua. A code passed to the export is
kept like those of dispatch scripts (under your resource’s name): the organization can assign
it to another type or ignore it from Detected alerts.