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.
| Folder | Device class | Size | What it is |
|---|---|---|---|
KBX-2200 | radar | 520 × 157 | Dual-antenna head, both windows each |
SLX-1100 | radar | 520 × 145 | Single-antenna compact head |
CHX-800 | radar | 520 × 131 | Eight-key control head |
PRX-400 | plate | 420 × 101 | Plate reader |
RCX-150 | remote | 220 × 488 | Handheld 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.
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.
<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.
| Attribute | What it does |
|---|---|
data-hud-text | Prints a published value |
data-hud-led | Lights an element from a boolean |
data-hud-show | Shows an element while a value is truthy |
data-hud-eq | Shows an element while a value equals a given one |
data-hud-attr | Copies a value onto an attribute |
data-hud-btn | Makes 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.
| Action | What it does |
|---|---|
power | Toggles power |
xmit | Toggles the transmitter (hold) |
test | Runs a self-test. The only way to clear a fault without cycling power |
mode:cycle | Moving ↔ stationary |
unit:cycle | mph ↔ km/h |
autolock:toggle | Arms or disarms auto-lock |
patrol:blank | Hides or shows the patrol window |
lock:front, lock:rear | Locks that antenna's target window |
lock:front:fast, lock:rear:fast | Locks that antenna's fast window |
unlock:all | Drops every lock |
antenna:front:cycle, antenna:rear:cycle | Steps the lane: opposite → both → off → same |
plate:lock:front, plate:lock:rear | Locks that side's plate window |
fork:front, fork:rear | Strikes the tuning fork. No shipped skin binds these |
plate:copy:front, plate:copy:rear | Copies that plate to the clipboard |
log:save | Saves the reading on the glass to the log |
menu | Opens the settings panel |
close | Hides 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:
<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:
@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
- API reference — the exports and events.
- Configuration —
Config.layoutBandsand the layout defaults.
tRadar
Still stuck? Support can answer it directly.
Was this page helpful?
TIMMYG Studios