tELS
Emergency lighting for FiveM. Configured in the vehicle, not in a file.
ELS, without the vehicle files
Emergency lighting in FiveM has always meant patterns compiled into a resource. Every flash-rate change, every LED nudge, every siren swap — edit the file, reupload the resource, restart the server.
tELS throws that pipeline out. You sit in the vehicle, run /telsedit, place LEDs on the 3D model with a gizmo, paint patterns on a grid, wire up triggers. Save, and every connected client picks up the change.
Before you install
tELS is not a drop-in replacement for ELS or non-ELS vehicle packs. Existing pattern XMLs do not migrate — the data model is different. You configure each vehicle in-game, or use a vehicle that ships a bundled tels.json.
In-game editor
Position and rotate each LED on the vehicle with a live gizmo. Attach to bones so LEDs follow doors, the hood, the trunk. Group them by location. Click Create from siren bones and tELS auto-generates a starter bar from the vehicle's siren1…sirenN bones in one click.
Multi-select, duplicate, mirror across the centerline. Every LED carries a stable UUID, so renaming or reordering never breaks a saved pattern.
Patterns, not presets
Columns are frames, rows are LEDs. Any color on any LED at any frame. Per-pattern color palettes. Cells marked dimmable interpolate their color into the next frame instead of snapping — the same mechanism real DVI lightbars use.
The pattern previews on the actual vehicle as you edit. What you see in the editor is the pixel output in-game.
Per-pattern flags decide whether it cycles manually, plays only from triggers, holds the GTA emergency-lights flag, holds high beams, restricts to a specific livery, or syncs across every client from a shared network clock.
Triggers that match the real problem
40+ vehicle-state conditions, written as compound AND/OR rules with per-condition negation. Not a token list — the actual inputs emergency lighting needs:
| Category | Conditions |
|---|---|
| Speed | stationary, speed_15, speed_30, speed_60, speed_90 |
| Controls | brake, handbrake, reverse, turn_left, turn_right, hazards |
| Horn gestures | horn_tap, horn_hold, horn_double_tap |
| Doors | door_fl/fr/rl/rr, hood, trunk, any_door_open, locked |
| Occupancy | driver_in_veh, passenger_front, passenger_rear, presence, presence_mode |
| Audio state | siren, main_siren_on, aux_siren_on, rumbler, airhorn, siren_tone_1…siren_tone_8 |
| Modes | cruise, takedown, ta_left/right/center |
Actions overlay a pattern, set the base pattern, change stages, cycle sirens, play airhorn, fire a park chirp, or enable the Arges spotlight.
Example:
brakeANDspeed_30ANDlights_on→ overlay the rear warning pattern. Built in-game in two clicks.
Audio that matches the lights
Eight tone slots per vehicle. Main and aux channels. Airhorn. Rumbler variants. Each tone holds a vanilla GTA sound and an optional server-sided one — players toggle between them in /tels. OISS and WM-style sound packs map to the same slots; switching packs is a config change, not a code change.
Horn gestures become trigger conditions. With hornProgrammable on, the default horn steps out of the way and your triggers drive the audio exclusively.
Runs under load
Built for scenes with several emergency vehicles on screen, not just one:
- Frustum culling, distance LOD, cached bone transforms on the render path.
- Pre-allocated render buffers — zero per-tick allocation.
- Trigger evaluation is native-gated: expensive door, lock, and occupancy natives run only for vehicles whose rules reference them.
- Smart environmental-lighting mode samples frame time and auto-scales between Medium and High at 90/75 fps thresholds.
- Pattern sync rides a shared server clock — every client derives the same frame without per-client coordination.
Share once, deploy everywhere
{ "$ref": "police4", "$all": true }Configure police4 once. Reference its patterns, triggers, and siren from police5, police6, police7. Edit the source and every referencing vehicle updates. Orphans clean up automatically.
Vehicle packs can ship a tels.json inside their resource — tLib's Discovery module picks it up on server start. Server-owner edits always take priority, so customizations survive pack updates.
Integrates through state bags
Every lighting and siren field mirrors to a tels:* state bag. Any script on any client reads current state without a server round-trip:
local on = Entity(veh).state['tels:active']
local tone = Entity(veh).state['tels:sirenTone']
local ta = Entity(veh).state['tels:taMode']Two exports (IsSirenActive, AreLightsActive) cover the common "is this a tELS vehicle" gate for integrations like radio scripts.
Requirements
- FiveM with OneSync (Infinity or Legacy)
- tLib ≥ 0.1
- Lua 5.4 (handled by the manifest)
Start here
1. Installation
Dependencies, server.cfg setup, admin access, and a two-minute quick start from install to lights-on.
2. Editor
Configure any vehicle: LEDs, Arges spotlights, patterns, triggers, sirens.
3. Usage
Every keybind, the /tels settings dialog, stages, modes, and troubleshooting for the questions you can't Google.
Configuration
The data.json schema, vehicle-developer bundling, cross-vehicle references, and server defaults.
HUD Layouts
Build custom HUD overlays with declarative data-hud-* bindings.
API Reference
Exports, state bags, and network events for external scripts.
