Configuration
All settings live in HZ-Television/config.lua. This page covers every section — general, display, placement, CarPlay, billboards, channels, localization.
config.lua no longer contains a Bridge section.General
Config.Locale = 'en' -- 'en' | 'fr' | 'es' | 'de'
Config.Debug = false -- detailed console logs
Permissions
Config.Permissions = {
ConfiguratorCommand = 'admin', -- /tvcfg
BillboardCommand = 'admin', -- /billboard
UseTV = 'everyone', -- interact with any TV
PlaceTV = 'everyone', -- place from inventory
}
| Format | Meaning |
|---|---|
'everyone' | anyone can use |
'admin' | framework / ACE admins only |
'job:police' | single job gate |
'job:ambulance,police' | multi-job gate (comma-separated) |
Display & Audio
Config.Display = {
MaxSoundDistance = 15.0, -- meters; max range to hear TV
MinSoundDistance = 2.0, -- meters; full volume range
DefaultVolume = 0.5, -- 0.0 – 1.0
RenderDistance = 50.0, -- meters; cut render past this
DefaultRange = 25.0, -- detection range (v3.1+)
InteractionMode = 'raycast', -- 'raycast' (free cursor) | 'camera' (locked)
RaycastMaxDistance = 5.0, -- auto-bumped to cam-distance × 2 on large props
SpritePolyScaleMultiplier = 32.0, -- internal render scale factor
ClockMode = 'game',-- 'game' | 'real'
}
Volume decreases linearly between MinSoundDistance (max volume) and MaxSoundDistance (silent).
TV Placement & Abandon Protection
Config.Placer = {
Enabled = true,
Persistence = true, -- requires oxmysql
-- Abandon protection (v3.4)
MaxPerPlayer = 0, -- 0 = unlimited; N = hard cap per identifier
AutoCleanupDays = 0, -- 0 = disabled; N = auto-remove after N days inactive
AutoCleanupInterval = 6, -- hours between cleanup ticks (0 = startup only)
CleanupAdminPermission = 'admin',-- ACE perm for /tvclean
-- Road guard (v3.4)
BlockOnRoad = false, -- true = red preview + block Enter when on road
-- CarPlay in-vehicle placement is always exempt
-- Legacy
AllowPickup = true,
OnlyOwnerPickup = true, -- admin can always pick up
-- Item → model mapping (pre-filled with the 10 shipped items)
Items = {
['hz_tv_s'] = 'hz_tv_s',
['hz_tv_m'] = 'hz_tv_m',
['hz_tv_l'] = 'hz_tv_l',
['hz_tv_s_stand'] = 'hz_tv_s_stand',
['hz_tv_m_stand'] = 'hz_tv_m_stand',
['hz_tv_l_stand'] = 'hz_tv_l_stand',
['curved_screen_s'] = 'prop_curved_screen_s',
['curved_screen_m'] = 'prop_curved_screen_m',
['curved_screen_l'] = 'prop_curved_screen_l',
['hz_carplay'] = 'hz_carplay', -- CarPlay — 11 more variants auto-registered
},
}
Road Guard
Checks GetClosestVehicleNode around the preview coords. If the prop sits on a road:
- Outline turns red (instead of the normal cyan)
- Enter / Confirm is blocked — the player must move the prop off the road first
- CarPlay in-vehicle placement is exempt (the whole point of CarPlay is to mount on a moving vehicle)
Abandon Protection
Prevents long-running servers from filling up with TVs and CarPlays left behind by players who never come back.
MaxPerPlayer— hard cap per owner identifier. On CarPlay, upserts-on-plate count as replace (same car re-placement doesn't increment)AutoCleanupDays— owners who haven't connected in N days get their placements removed. Recommended 30–60AutoCleanupInterval— how often the server re-scans (in hours;0= startup only)last_seencolumn onhz_television_placedandhz_carplay_placed— refreshed onplayerJoiningand every interaction. Additive migration runs at startup (ALTER TABLE ADD COLUMN IF NOT EXISTS)
/tvclean Admin Command
| Sub-command | Action |
|---|---|
/tvclean list | Top 20 owners by inactivity — identifier, placement count, days inactive |
/tvclean run | Trigger auto-cleanup pass immediately (honors AutoCleanupDays) |
/tvclean purge | Wipe ALL placements (TVs + CarPlays) for a specific identifier |
Config.Placer.CleanupAdminPermission (ACE). Also exports["HZ-Television"]:RunHZTVCleanup().
TV Models
Each interactive screen is an entry in Config.Models keyed by model name:
Config.Models = {
['hz_tv_m'] = {
Offset = vector3(0.0, -0.02, 0.55),
Scale = { x = 0.42, y = 0.236 }, -- half-width / half-height
Rotation = { x = 0.0, y = 0.0, z = 0.0 },
RenderTexture = { dict = 'hz_tv_m', name = 'hz_tv_m_screen' },
},
-- Curved cinema screen (v3.3)
['prop_curved_screen_m'] = {
Offset = vector3(0.0, -0.2, 2.7),
Scale = { x = 2.80, y = 1.575 },
Rotation = { x = 0.0, y = 0.0, z = 0.0 },
Curve = {
Radius = 23.00, -- physical arc radius (meters)
Arc = 25.11, -- arc sweep angle (degrees)
Invert = false, -- true = concave toward viewer
},
RenderTexture = { dict = 'prop_curved_screen_m', name = 'curved_screen_m' },
},
-- Vanilla GTA V huge billboard (render-target auto-detected)
['prop_huge_display_01'] = {
Offset = vector3(0.0, 0.15, 0.0),
Scale = { x = 8.0, y = 4.5 },
Rotation = { x = 0.0, y = 0.0, z = 0.0 },
RenderTexture = { dict = 'big_disp', name = 'big_disp' }, -- same dict/name = render target
},
}
Adding a Custom Model
- Add an entry keyed by model name to
Config.Models - Launch in-game, get near the prop
- Run
/tvcfg→ select the model → the 3D gizmo lets you calibrate Scale / Offset / Rotation live - For curved props, enable the cylindrical ray-cast: tick Curve, set Radius + Arc + (optionally) Invert. A live cyan arc overlay shows the exact hit-box
- Save writes the calibration to
tv_config.json(persists across restarts)
RaycastTVCylinder — so "the cyan arc aligned with the prop surface" ↔ "clicking is accurate". If the overlay is off, so is the cursor.SmartTV on Billboards & Cinema (v3.3)
Opt-in per-model: which billboard / cinema screens run the full Smart TV UI instead of the cyberpunk Ghost-Protocol billboard panel.
Config.BillboardUseSmartTV = {
-- Curved cinema screens — always opt-in
['prop_curved_screen_s'] = true,
['prop_curved_screen_m'] = true,
['prop_curved_screen_l'] = true,
-- Vanilla GTA V huge billboards — auto render-target detection in v3.3
['prop_huge_display_01'] = true,
['prop_huge_display_02'] = true,
-- Add any other RenderTexture model here to enable Smart TV on it
}
Anything not in this list keeps the classic Ghost Protocol NUI panel (still fully functional for set-and-forget billboards).
CarPlay (v3.2 + v3.3 audio + v3.4 gizmo QoL)
CarPlay doesn't live in Config.Placer.Items alone — the dedicated config block tunes placement UX, audio occlusion, and the gizmo.
Enable / Disable CarPlay (v3.4.5)
Master switch — set Enabled = false to skip the entire CarPlay feature (item registration, target options, placer prompt, reconciliation tick). Wall / cinema / billboard TVs are unaffected.
Config.Carplay = {
Enabled = true, -- v3.4.5+; set false to disable the in-vehicle CarPlay variant entirely
}
Cabin Audio Occlusion (v3.3)
The Web Audio pipeline inside the CarPlay DUI simulates RAGE's native vehicle sound filter (lowpass + bass shelf) because DUI audio bypasses the engine's own occlusion. No config usually needed — the defaults match RAGE's behavior — but the ranges can be tuned:
Config.Carplay = {
Enabled = true, -- v3.4.5+; master switch
AudioCabinRange = 5.0, -- meters; beyond this, listeners outside the car hear silence
SealedLowpass = 600, -- Hz cutoff when all doors closed
OpenLowpass = 2200, -- Hz cutoff when all doors open
SealedBassBoost = 6, -- dB peaking shelf at 80 Hz when sealed (decays as doors open)
SealedGain = 0.25, -- master volume multiplier when sealed
OpenGain = 0.70, -- master volume multiplier all doors open
TransitionMs = 80, -- linearRampToValueAtTime smoothing for door-state changes
}
Placement UX (v3.4)
While the keyboard gizmo is open in a vehicle:
- Vehicle frozen —
FreezeEntityPosition(vehicle, true)+ velocity zeroed, unfrozen on confirm / cancel. No drift - Vehicle controls disabled — throttle, brake, steering, handbrake cut (
keepVehicleControls = false) - First-person cam reset —
SetGameplayCamRelativeHeading(0.0)+SetGameplayCamRelativePitch(0.0, 1.0)so the cam faces forward regardless of where the player was aiming before
Pre-recorded Channels
Config.Channels = {
{
name = 'Weazel News',
url = 'https://www.youtube.com/watch?v=example',
category = 'news', -- optional grouping in the Smart TV UI
thumbnail = 'https://...', -- optional card image
},
{
name = 'Los Santos Rock Radio',
url = 'https://www.youtube.com/watch?v=jfKfPfyJRdk',
category = 'music',
},
}
Appears as a "Channels" section in the Smart TV home screen. Channels respect routing buckets and multi-player sync like any URL content.
Local Media
Host MP4 / MP3 files directly in HZ-Television/media/ and expose them as a "Local Media" section in the Smart TV and the LB Phone companion app:
Config.LocalMedia = {
{ title = "Server Intro", file = "intro.mp4", type = "video" },
{ title = "Ambient Radio", file = "radio.mp3", type = "audio" },
{ title = "Event Clip", file = "event.mp4", type = "video" },
}
One tap plays the file on the current TV. Great for server intros, event clips, ambient radio loops, custom ads.
Streamer Mode
One-tap mute for all nearby TVs — for content creators who need to cut game audio from their stream without touching other players' experience.
Config.Streamer = {
Enabled = true,
DefaultMute = false,
ToggleCommand = 'streamermode', -- /streamermode
AffectsNewScreens = true, -- auto-mute newly-detected screens (v3.3)
}
Controllable from other scripts via exports["HZ-Television"]:SetStreamerMode(true/false) — see Exports.
Commands
Config.Commands = {
Configurator = 'tvcfg', -- open live gizmo calibrator
Billboard = 'billboard', -- edit nearby billboard content
Carplay = 'carplay', -- F5 keybind — interact with CarPlay in current vehicle
CarplayOn = 'carplay_on', -- power on + open SmartTV
CarplayRemove = 'carplayremove', -- remove CarPlay from current vehicle
Cleanup = 'tvclean', -- admin cleanup CLI (v3.4)
Streamer = 'streamermode', -- toggle streamer mode
}
Discord Webhooks (optional)
Config.Webhooks = {
Enabled = false,
PlaceTV = 'https://discord.com/api/webhooks/...',
ConfigTV = 'https://discord.com/api/webhooks/...',
Cleanup = 'https://discord.com/api/webhooks/...', -- v3.4 /tvclean audit log
}
Advanced Examples
Strict RP Server
Config.Permissions = {
ConfiguratorCommand = 'admin',
BillboardCommand = 'job:police,admin',
UseTV = 'everyone',
PlaceTV = 'job:estate,admin',
}
Config.Placer = {
Persistence = true,
MaxPerPlayer = 3, -- tight cap
AutoCleanupDays = 30, -- sweep after 30 days inactive
AutoCleanupInterval = 6,
BlockOnRoad = true, -- prevent road clutter
OnlyOwnerPickup = true,
}
Creative / Sandbox Server
Config.Permissions = {
ConfiguratorCommand = 'everyone',
BillboardCommand = 'everyone',
UseTV = 'everyone',
PlaceTV = 'everyone',
}
Config.Placer = {
Persistence = true,
MaxPerPlayer = 0, -- unlimited
AutoCleanupDays = 0, -- disabled
BlockOnRoad = false,
OnlyOwnerPickup = false, -- anyone can pick up
}
config.lua, run restart HZ-Television from the server console — most settings take effect immediately without a full restart.