tELS

Emergency lighting for FiveM. Configured in the vehicle, not in a file.

v1.0FiveM ScriptEscrow Encrypted

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

Three.js LED 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 siren1sirenN 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

Grid-based pattern editor

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:

CategoryConditions
Speedstationary, speed_15, speed_30, speed_60, speed_90
Controlsbrake, handbrake, reverse, turn_left, turn_right, hazards
Horn gestureshorn_tap, horn_hold, horn_double_tap
Doorsdoor_fl/fr/rl/rr, hood, trunk, any_door_open, locked
Occupancydriver_in_veh, passenger_front, passenger_rear, presence, presence_mode
Audio statesiren, main_siren_on, aux_siren_on, rumbler, airhorn, siren_tone_1siren_tone_8
Modescruise, 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: brake AND speed_30 AND lights_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

On this page

Need help?

Ask on Discord