Skip to content

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

ExportParametersReturnsWhat it does
GetDetectorSignaturenonetable | falseThe unit's signature while transmitting, false otherwise
IsRadarActivenonebooleanWhether the unit is transmitting
setPlateFlagplate: string, flag: table | nilbooleanAttaches 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.

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

StateReported
Never powered, or stowedfalse
Powered, in transmit holdfalse
Powered, transmittingthe signature
Faulted, or running the cold power-up self-testfalse

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:

  1. The installed skin, if Config.layoutBands names it. An entry naming a band but no frequency takes that band's default, never Config.frequency.
  2. Otherwise Config.band and Config.frequency.
  3. An unknown band becomes Ka, and takes Ka's frequency.
  4. A missing or invalid frequency becomes the band default. nil, a non-number, NaN, zero and anything negative all fall back.
BandDefault frequency
x10.525 GHz
k24.150 GHz
ka34.700 GHz

Changing the radar skin re-resolves the band immediately.

IsRadarActive

The bare boolean form of the same question.

lua
if exports.tRadar:IsRadarActive() then
    -- a beam is on the air
end

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

lua
exports.tRadar:setPlateFlag('12ABC345', {
    level  = 'alert',        -- 'info' | 'warn' | 'alert' | 'unknown'
    label  = 'STOLEN',
    source = 'tCAD',
})

exports.tRadar:setPlateFlag('12ABC345', nil)   -- clears it
FieldTypeRequiredNotes
levelstringnoinfo, warn, alert or unknown. Anything else becomes warn
labelstringyesDrawn on the plate window. Truncated at 64 characters
sourcestringnoWhich 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.

lua
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)
ParameterTypeValue
platestringThe plate as read
sidestring'front' or 'rear'
infotableinfo.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:

ExportArgumentsReturnsWhat it does
addBoloPlateplate: stringbooleanAdds a plate. false if already listed, not a plate, or the list is at its 100-plate ceiling
removeBoloPlateplate: stringbooleanRemoves a plate. false if it was not listed
getBoloPlates—tableA copy of the list, upper-cased
lua
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

CommandArgumentsWhat it does
/tradarnoneOpens the settings dialog
/tradar_deploynoneWalks the unit: deploy, remote, back out. Bound to F5
/tradareditnoneOpens the 3D prop editor. Needs tradar.admin (or tlib.admin) and a vehicle
/tradarforkrear (optional)Strikes the tuning fork. Anything other than rear is the front
/tradar_savenoneSaves the reading on the glass to the radar log. Bound to J
tradar_diagnoneServer console. Versions, config errors, the resolved access gate, the detected framework and inventory, the BOLO count, whether the webhook parsed
cfg
add_ace group.admin command.tradar_diag allow

tradar_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

MappingDefaultDescription in the keybind menu
tradar_deployF5tRadar: Radar: deploy, then remote
tradar_saveJtRadar: 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 export and the other failures these calls produce.
  • CAD and ALPR — the shipped answerer for tradar:plateRead.

Still stuck? Support can answer it directly.

Was this page helpful?