HZ Scripts

Configuration

All settings live in HZ-Television/config.lua. This page covers every section — general, display, placement, CarPlay, billboards, channels, localization.

Framework / target / menu / notification / inventory detection is handled centrally by HZ-Bridge — see HZ-Bridge Configuration. HZ-Television's 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
}
FormatMeaning
'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

New in v3.4 — road guard + abandon-protection fields below.
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–60
  • AutoCleanupInterval — how often the server re-scans (in hours; 0 = startup only)
  • last_seen column on hz_television_placed and hz_carplay_placed — refreshed on playerJoining and every interaction. Additive migration runs at startup (ALTER TABLE ADD COLUMN IF NOT EXISTS)

/tvclean Admin Command

Sub-commandAction
/tvclean listTop 20 owners by inactivity — identifier, placement count, days inactive
/tvclean runTrigger auto-cleanup pass immediately (honors AutoCleanupDays)
/tvclean purge Wipe ALL placements (TVs + CarPlays) for a specific identifier
Gated via 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

  1. Add an entry keyed by model name to Config.Models
  2. Launch in-game, get near the prop
  3. Run /tvcfg → select the model → the 3D gizmo lets you calibrate Scale / Offset / Rotation live
  4. 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
  5. Save writes the calibration to tv_config.json (persists across restarts)
The live preview overlay uses the same formula as 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 frozenFreezeEntityPosition(vehicle, true) + velocity zeroed, unfrozen on confirm / cancel. No drift
  • Vehicle controls disabled — throttle, brake, steering, handbrake cut (keepVehicleControls = false)
  • First-person cam resetSetGameplayCamRelativeHeading(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
}


After editing config.lua, run restart HZ-Television from the server console — most settings take effect immediately without a full restart.