Skip to content

Game alerts

What the game reports on its own — shots fired, robberies, vehicle thefts, 911 calls — reaches dispatch as a call, merged and capped.

On this page04
  1. Where alerts come from
  2. Configuring a service’s alerts
  3. At dispatch
  4. For developers

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.

A game alert reaches dispatch: beep, notification and a marked call

You need the game integration and the supermdt-bridge resource installed on the server (see Installing the bridge).

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:

  1. 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 Alert export instead.
  2. The bridge’s built-in detections: shots fired, person down, vehicle theft (see The bridge’s detections).
  3. Framework alerts: the QBCore and Qbox police alert and EMS alert, the robberies (stores, banks) and the /911p and /911e commands.
  4. 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).
  5. Custom scripts, through the bridge’s Alert export (see For developers).

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.
Settings › Game › Integrations, with the “Alerts and dispatch” row

supermdt status, in the server console, gives the same detail with its counters, each listener (“policeAlert (off, default)”) and the alert codes kept.

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.

The bridge’s listeners, one by one, in Settings › Game › Integrations

Config.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.

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

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.

  • QBCore (qb-policejob, qb-ambulancejob): the bridge reads the command when the player types it (QBCore:Server:PreCommandExecution, a qb-core server event). /911p becomes an emergency call (police), /911e an 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.

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 fr

setr (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).

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.

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.

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.

Configuration › Operations › Game alerts
  1. Turn on Receive game alerts (off by default).
  2. 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.
  3. 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).
  4. 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.

A type’s sheet: call priority and nature (Game title, Type name, list, template)

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).

The alerts detected on the server and the type each one goes to

For 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 speeding to Suspicious activity, or hunting to 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.

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.

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).

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.

A game alert call and its merged reports

For 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.

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.