Skip to content

Layouts

The five tRadar faceplates, the three device classes, how a skin declares what it is, and how to build your own with tLib's data-hud grammar.

A layout is a skin: a folder under layouts/ holding a chassis.png and an inert ui.html. Five ship; more install through tLib's marketplace with no file edit and no restart.

FolderDevice classSizeWhat it is
KBX-2200radar520 × 157Dual-antenna head, both windows each
SLX-1100radar520 × 145Single-antenna compact head
CHX-800radar520 × 131Eight-key control head
PRX-400plate420 × 101Plate reader
RCX-150remote220 × 488Handheld remote, no glass

Players pick a skin per device class in /tradar. Config.defaultRadarLayout, Config.defaultPlateLayout and Config.defaultRemoteLayout set what a new player starts with; an uninstalled name falls back to the first installed skin of that class.

Per-skin bands

Config.layoutBands gives one faceplate its own band, so a server can ship a Ka head and a K head without editing either. Faceplates print the band they are on.

lua
Config.layoutBands = {
    ["KBX-2200"] = { band = "ka", frequency = 34.7 },
    ["SLX-1100"] = { band = "k" },
}

The shipped entries are KBX-2200 34.7 GHz, SLX-1100 35.5 GHz, CHX-800 33.8 GHz. A skin with no entry uses Config.band; omit frequency and the band's own default is used, never Config.frequency.

The same head on X and on K — the lit letter above the target window is the only change, and it is how an officer knows which gun they are holding:

Building your own

A layout declares what it is on its root element. That declaration — never the folder name — puts a skin in the right picker.

html
<div data-radar-device-class="plate" data-radar-width="420" data-radar-height="101">

Bind it to the live view with tLib's data-hud-* grammar.

AttributeWhat it does
data-hud-textPrints a published value
data-hud-ledLights an element from a boolean
data-hud-showShows an element while a value is truthy
data-hud-eqShows an element while a value equals a given one
data-hud-attrCopies a value onto an attribute
data-hud-btnMakes an element a key, naming the action it fires

The action list

data-hud-btn names one of these. Anything else is a build failure.

ActionWhat it does
powerToggles power
xmitToggles the transmitter (hold)
testRuns a self-test. The only way to clear a fault without cycling power
mode:cycleMoving ↔ stationary
unit:cyclemph ↔ km/h
autolock:toggleArms or disarms auto-lock
patrol:blankHides or shows the patrol window
lock:front, lock:rearLocks that antenna's target window
lock:front:fast, lock:rear:fastLocks that antenna's fast window
unlock:allDrops every lock
antenna:front:cycle, antenna:rear:cycleSteps the lane: opposite → both → off → same
plate:lock:front, plate:lock:rearLocks that side's plate window
fork:front, fork:rearStrikes the tuning fork. No shipped skin binds these
plate:copy:front, plate:copy:rearCopies that plate to the clipboard
log:saveSaves the reading on the glass to the log
menuOpens the settings panel
closeHides the HUD

Interference

interference is published whenever the RFI sensor inhibits the target windows. Bind it, or a blanked skin reads as a broken unit:

html
<div class="rfi base">RFI</div>
<div class="rfi on" data-hud-led="interference">RFI</div>

The KBX-2200 and SLX-1100 carry one; the CHX-800 does not, and autolock:toggle is absent from it too. Keep it visually distinct from faulted: the shipped skins use amber for interference, red for a fault.

Blinking and reduced motion

Two shipped skins blink: the KBX-2200 flashes REAR while traffic is overtaking, and the PRX-400 flashes an alert-level plate flag. Nothing else on any face moves — reserve a blink for a state the operator has to act on.

If you do blink, write the reduced-motion variant in the same <style> block, because a skin that blinks and ships no variant keeps blinking:

css
@keyframes myskin-alert { 50% { opacity: 0.3; } }
.myskin .alert.active { animation: myskin-alert 0.7s steps(1, end) infinite; }

@media (prefers-reduced-motion: reduce) {
  .myskin .alert.active {
    animation: none; opacity: 1; text-shadow: 0 0 9px rgba(255, 176, 32, 0.9);
  }
}

Seven-segment digits

The view publishes one character per digit position — front.targetDigits.d0 and so on — and the layout decodes it in CSS with an attribute selector per numeral over seven clip-path bars. Unlit bars sit at 10% opacity, the ghost 888 a dark window shows.

Next

Still stuck? Support can answer it directly.

Was this page helpful?