API reference
tRadar's exports, events, commands and key mappings: GetDetectorSignature, IsRadarActive, setPlateFlag, and the tradar:plateRead event.
Three client exports, three server exports, one event, six commands, three key mappings.
Client exports
| Export | Parameters | Returns | What it does |
|---|---|---|---|
GetDetectorSignature | none | table | false | The unit's signature while transmitting, false otherwise |
IsRadarActive | none | boolean | Whether the unit is transmitting |
setPlateFlag | plate: string, flag: table | nil | boolean | Attaches a flag to a plate, or clears one |
GetDetectorSignature
This is the whole contract a radar detector reads. tDetector already lists tRadar in its Config.radarResources, so there is nothing to install on either side.
local sig = exports.tRadar:GetDetectorSignature()
-- false, or:
{
active = true, -- always true when a table is returned
band = 'ka', -- 'x' | 'k' | 'ka'
frequency = 34.7, -- GHz, the spot frequency inside that band
mode = 'instant', -- 'instant' | 'constant'
range = 150.0, -- metres this gun can clock an ordinary car
}Those five keys are the whole shape. Silence is false, not a table with active = false.
It reports transmission, not power. A unit is on the air when it is powered and out of transmit hold and not mid-cold-self-test and not faulted.
| State | Reported |
|---|---|
| Never powered, or stowed | false |
| Powered, in transmit hold | false |
| Powered, transmitting | the signature |
| Faulted, or running the cold power-up self-test | false |
mode is derived, not configured. It is 'instant' while the transmitter has been up for less than Config.instantOnWindowMs (4000 ms), and 'constant' after. The clock is stamped on the transmit edge only, so re-stating a state the unit is already in does not restart it; keying off and on again is a new edge and a new burst. Config.instantOnWindowMs = 0 means the unit never claims instant-on.
range is the gun's capability, Config.maxRange (150.0 m). A detector hears a gun at roughly twice that, and tDetector clamps the result to its own Config.detectionRangeMax.
band and frequency are resolved fresh on every call, in this order:
- The installed skin, if
Config.layoutBandsnames it. An entry naming a band but no frequency takes that band's default, neverConfig.frequency. - Otherwise
Config.bandandConfig.frequency. - An unknown band becomes Ka, and takes Ka's frequency.
- A missing or invalid frequency becomes the band default.
nil, a non-number, NaN, zero and anything negative all fall back.
| Band | Default frequency |
|---|---|
x | 10.525 GHz |
k | 24.150 GHz |
ka | 34.700 GHz |
Changing the radar skin re-resolves the band immediately.
IsRadarActive
The bare boolean form of the same question.
if exports.tRadar:IsRadarActive() then
-- a beam is on the air
endBoth are client exports and answer for the local player's unit only. Poll them — there is no event. tDetector reads once per its own Config.radarStateInterval (500 ms).
setPlateFlag
Answers a plate read. Call it from a handler for tradar:plateRead.
exports.tRadar:setPlateFlag('12ABC345', {
level = 'alert', -- 'info' | 'warn' | 'alert' | 'unknown'
label = 'STOLEN',
source = 'tCAD',
})
exports.tRadar:setPlateFlag('12ABC345', nil) -- clears it| Field | Type | Required | Notes |
|---|---|---|---|
level | string | no | info, warn, alert or unknown. Anything else becomes warn |
label | string | yes | Drawn on the plate window. Truncated at 64 characters |
source | string | no | Which resource answered. Defaults to unknown, truncated at 64 |
Use unknown when your lookup timed out, was rate limited or failed — see CAD and ALPR.
A flag applies only to a window currently showing that exact plate, including a locked one. An answer arriving after the car has gone is dropped. The call returns false when plate is not a string, is empty, or is over 8 characters; an over-long label is truncated and still returns true.
Events
tradar:plateRead
Fires on every new plate read. Client-side.
AddEventHandler('tradar:plateRead', function(plate, side, info)
if info.speed > 80 then
exports.tRadar:setPlateFlag(plate, {
level = 'warn',
label = ('%d %s'):format(math.floor(info.speed), info.unit:upper()),
source = 'tCAD',
})
end
end)| Parameter | Type | Value |
|---|---|---|
plate | string | The plate as read |
side | string | 'front' or 'rear' |
info | table | info.plate, info.side, info.vehicle (entity handle), info.speed, info.unit ('mph' or 'kmh') |
The BOLO events (tradar:boloList, tradar:boloAdd, tradar:boloRemove, tradar:boloRequest, tradar:boloHit) and the CAD bridge's two (tradar:plateQuery, tradar:plateAnswer) are internals. Use the server exports below and setPlateFlag instead.
The built-in BOLO list
Officers manage it in the BOLO tab of /tradar, which appears when Config.plateReaderEnabled is on. The list is server-owned, shared, persisted in data.json, and gated on the same access check as the radar.
Call these from a server script:
| Export | Arguments | Returns | What it does |
|---|---|---|---|
addBoloPlate | plate: string | boolean | Adds a plate. false if already listed, not a plate, or the list is at its 100-plate ceiling |
removeBoloPlate | plate: string | boolean | Removes a plate. false if it was not listed |
getBoloPlates | — | table | A copy of the list, upper-cased |
RegisterNetEvent('mdt:boloIssued', function(plate)
exports.tRadar:addBoloPlate(plate)
end)Discord. Config.boloWebhook posts when a plate is added, removed or seen by a reader. Anything that is not a https://discord.com/api/webhooks/... URL is treated as unset and reported at startup.
Commands
| Command | Arguments | What it does |
|---|---|---|
/tradar | none | Opens the settings dialog |
/tradar_deploy | none | Walks the unit: deploy, remote, back out. Bound to F5 |
/tradaredit | none | Opens the 3D prop editor. Needs tradar.admin (or tlib.admin) and a vehicle |
/tradarfork | rear (optional) | Strikes the tuning fork. Anything other than rear is the front |
/tradar_save | none | Saves the reading on the glass to the radar log. Bound to J |
tradar_diag | none | Server console. Versions, config errors, the resolved access gate, the detected framework and inventory, the BOLO count, whether the webhook parsed |
add_ace group.admin command.tradar_diag allowtradar_diag output goes to the server console, and to the caller when there was one. It is safe to paste into a support thread: no credential and no player identity.
/radar and /radarfork are removed.
Key mapping
| Mapping | Default | Description in the keybind menu |
|---|---|---|
tradar_deploy | F5 | tRadar: Radar: deploy, then remote |
tradar_save | J | tRadar: Save the current radar reading |
F5 walks the unit: deploy → open the remote → close the remote. ESC does the third step too, and the unit is stowed from the remote's STOW key, so F5 never switches it off. With Config.remoteEnabled = false the second press stows.
Deploying re-checks access, so it is rate-limited to one call a second. Keypad mode — F5's second press — takes NUI focus with input kept, so you can still drive; the mouse look and attack controls are suppressed while it is up, so the cursor cannot swing your camera or fire out of the window.
The radar log
tradar_save keeps whatever is on the glass — both windows, both plates, any lock, patrol speed, band, unit, and the colour and model of each plate's vehicle — in the Log tab of /tradar. The last 25, newest first, surviving a restart.
It records what the window said: a held window logs the held number, a blanked patrol window logs as blank. Captures are refused, with a reason, when the unit is stowed or the glass empty.
Layout actions
Layouts name actions in data-hud-btn rather than calling exports. The full list is in Layouts.
Next
- Troubleshooting —
No such exportand the other failures these calls produce. - CAD and ALPR — the shipped answerer for
tradar:plateRead.
tRadar
Still stuck? Support can answer it directly.
Was this page helpful?
TIMMYG Studios