FAQ
General
Is the script compatible with my framework?
HZ-Television supports QBCore, QBox, ESX and Standalone. Detection is handled by HZ-Bridge — configure once there and HZ-Television (+ every other Hz-Script) inherits automatically.
Can I have multiple TVs with different content at the same time?
Yes — this is one of the main selling points. Every nearby TV renders its own independent content (no 5-screen cap since v2.3, no 12-TV cap since the DrawSpritePoly rewrite). Even the CarPlay feature — every vehicle with a hz_carplay item gets its own texture-isolated variant so driving past 12 cars in traffic = 12 different Smart TVs.
How many players can watch the same TV?
Unlimited. Real-time sync is handled via plate-based and coords-based events (5 s heartbeat, 1.5 s drift tolerance, 0.1 s precision, instant seek/play/pause). Late joiners get the exact playback position on connect.
What about routing buckets / instances?
Fully bucket-aware since v3.1.2. TVs, billboards, operator locks, and playlist loops are all isolated per instance. Two TVs at the same coords in different instances never collide.
Does it use a lot of resources?
Client idle: ~0.01 ms. Six active on-screen TVs: ~0.03 ms (cached DrawSpritePoly vertex data). Server: ~0.00 ms. See Performance.
Installation
Error: "Resource HZ-PropsCarplay not found"
HZ-PropsCarplay ships bundled with your HZ-Television download (v3.4+) but must be ensured separately in server.cfg. Add ensure HZ-PropsCarplay before ensure HZ-Television. Without it, the 12 CarPlay prop variants don't stream and CarPlay placement silently hangs at lib.requestModel.
Error: "Menu system not detected"
The script requires ox_lib (recommended) or qb-menu + qb-input. Install one and ensure it before HZ-Bridge (which itself starts before HZ-Television).
TV items don't appear in my inventory
You must manually add the items to your inventory's items file. Pre-configured snippets are in HZ-Television/items/:
ox_inventory.txt→ox_inventory/data/items.luaqb-inventory.txt→qb-core/shared/items.lua(orqbx_core/shared/items.lua)qs-inventory.txt→qs-inventory/shared/items.lua
Complete server restart required after adding items (not just
restart HZ-Television).
I'm using ak47_inventory — items show but don't trigger when used
ak47_inventory isn't in HZ-Bridge's auto-detected list (ox_inventory, qb-inventory, qs-inventory, ps-inventory, codem-inventory, origen_inventory, core_inventory, tgiann-inventory). The bridge falls back to ESX native, but ak47 intercepts use-item events before ESX sees them, so RegisterUsableItem never fires.
Fix per the ak47_inventory docs: wire the callback directly inside the item definition with server.onUse. Open your ak47 items config (typically ak47_inventory/shared/items.lua or ak47_inventory/configs/items.lua) and add:
["hz_carplay"] = {
name = "hz_carplay",
label = "CarPlay Screen",
weight = 3000,
type = "item",
close = true,
server = {
onUse = function(source, item)
TriggerClientEvent('HZ-Television:useItem', source, { name = 'hz_carplay' })
end,
},
},
Repeat for hz_television_screen if you also use the wall / cinema TVs. Drop the matching .png into your ak47 UI images folder. Then ensure ak47_inventory and ensure HZ-Television.
SQL Error 1067 or 1075 when importing install.sql
Both are strict-mode MariaDB rejections fixed in v3.4.6:
- Error 1067 on
last_login—timestamp DEFAULT NULLrequires an explicitNULLdeclaration in strict mode. Nowtimestamp NULL DEFAULT NULL - Error 1075 on
hz_carplay_placed— theid AUTO_INCREMENTcolumn needed aPRIMARY KEY. Now declared
install.sql. CREATE TABLE IF NOT EXISTS skips already-created tables, so only the two previously-failing ones get created. No data migration.
Generic_texture_renderer_gfx — do I need it?
No. Since v2.3 the rendering engine usesDrawSpritePoly directly. The old scaleform dependency is gone.
How do I update?
- Download latest from keymaster.fivem.net
- Back up your
config.luaandtv_config.json - Replace every file except those two
- Check the Changelog for new config keys
- Restart the server
ensure HZ-PropsCarplay to server.cfg, and review the new Config.Placer.BlockOnRoad / MaxPerPlayer / AutoCleanupDays fields.
CarPlay (v3.2+)
How do I place a CarPlay in my car?
- Put the
hz_carplayitem in your inventory - Get in a vehicle (driver seat)
- Use the item — a preview prop spawns on the dashboard and a keyboard gizmo takes over
- Arrow keys = position, Scroll = height, Q/D (or A/D) = rotate, Z/S (or W/S) = tilt, Enter = confirm, Escape = cancel
- Once placed, use your target system (ox\_target / qb-target) on the car to Turn On CarPlay → Smart TV
The vehicle drifts while I'm fine-tuning the gizmo
Fixed in v3.4 — the vehicle is now automatically frozen for the duration of the gizmo (FreezeEntityPosition + velocity zeroed + controls disabled). Unfrozen on confirm / cancel.
The cam doesn't face forward when I use the CarPlay item
Fixed in v3.4 — first-person cam now snaps to heading=0 / pitch=0 on cockpit-view switch, regardless of where the player was aiming before.
Why don't I hear the CarPlay when I'm outside the car?
Intentional — CarPlay is cabin audio, not a PA speaker. The Web Audio occlusion pipeline (v3.3) fades out completely past 5 m from the vehicle. Inside the car (driver + passengers), audio is fully clean and unfiltered. Listeners in a 5 m bubble outside get a lowpass-filtered, volume-attenuated version depending on how many doors are open.
Adjust Config.Carplay.AudioCabinRange if you want a different bubble size.
Can I have more than 12 CarPlays on the map?
Yes — unlimited placements. Each client renders the 12 nearest (one per texture-isolated variant), so beyond 12 simultaneously visible on the same client the farther ones are invisible until you approach.
I don't want the in-vehicle CarPlay feature at all
Disable it cleanly via config.lua (v3.4.5+):
Config.Carplay = { Enabled = false }
This skips the hz_carplay* RegisterUsableItem loop, the target option registration, the placer prompt, the reconciliation tick — everything CarPlay-specific. Wall / cinema / billboard TVs continue to work normally.
My CarPlay sometimes falls off after a violent crash
Fixed in v3.4.6 — the reconciliation tick's not-attached invariant detects when IsEntityAttached(prop) returns false (the prop got detached by collision physics), releases the slot, and re-acquires it on the next pass (≤ 500 ms). The prop snaps back onto the same vehicle at its original offsets, and the DUI reactivates automatically because PoweredOn[cpId] is preserved across the release.
Enable Config.Debug = true to see the release reason (not-attached) in the F8 console.
Usage
Screen is black or nothing displays
Checklist:- Is the TV powered on? (Turn On via target menu)
- Has the model been calibrated? Use
/tvcfgnear the prop — the live cyan preview overlay shows exactly where the cursor hit-box sits - For vanilla huge billboards, add the model to
Config.BillboardUseSmartTV(v3.3 render-target auto-detection handles them automatically) - Test with a simple YouTube video first, not a livestream
- Check F8 for JS errors
Cursor clicks are off / miss the icons
- Flat props: use
/tvcfgand adjust Scale / Offset / Rotation. The cyan overlay is the exact hit-box. - Curved props: make sure the model has a
Curve = { Radius, Arc, Invert }entry and that the arc overlay (16 cyan segments) aligns with the real surface. SetCurve.Invert = truefor props that curve toward the viewer.
No sound / sound too low
- Power the TV on
- Get closer — volume decreases linearly between
MinSoundDistanceandMaxSoundDistance - Raise
Config.Display.MaxSoundDistancefor a larger audio range - For CarPlay: audio only plays inside the car (+ a 5 m bubble around it)
YouTube / Twitch doesn't play
YouTube: some videos have embed disabled by the uploader or regional restrictions. Test the URL in a normal browser in incognito — if it doesn't play in an embed there, it won't play in-game either. Twitch / Kick: only live channels. Format:https://twitch.tv/channel or https://kick.com/channel. V3 uses the native Twitch SDK, so volume / pause / mute work natively.
Other players don't see my Web Browser content (login required sites)
Every player's TV is its own independent CEF browser instance with its own cookies and login session. The script syncs the URL to all viewers, but not the login state — that's a fundamental browser-isolation limit of how DUIs work, not a script bug.
- Public streams (YouTube live, Twitch, Kick, direct
.m3u8/.mp4links) → sync perfectly to every player, no login needed. Recommended for "watch together" use cases (sports, World Cup, news streams) - Subscription / login-required services (Disney+, beIN, Prime Video, paid streams, account-gated content) → cannot be synced. Each player would need to log into their own account on their own client, which defeats the watch-together idea
Late joiners don't see the video / browser content
Real-time sync (5 s heartbeat, 1.5 s drift tolerance) catches them when they stream the TV in — they get the current playback position automatically.
If you're seeing late joiners get a blank screen on browser mode specifically, the issue is usually a race between DUI creation and the first SetDuiUrl call when the player streams in. Make sure your HZ-Television is up to date (the late-join browser sync was hardened in recent versions with retry passes).
Other things to check:
- OneSync must be enabled (
set onesync oninserver.cfg) - If you're inside a routing bucket, both players need to be in the same bucket — the sync events are bucket-scoped on purpose
Configuration
How do I add a custom TV / billboard model?
- Add an entry in
Config.Modelskeyed by model name with a reasonable starting Scale / Offset / Rotation - Load in-game, get close to the prop
- Run
/tvcfg→ pick the model → calibrate with the 3D gizmo; the cyan overlay shows the hit-box in real time - For curved screens, tick Curve + set Radius / Arc / Invert
- Save — values are written to
tv_config.json
How do I block players from placing props on roads?
Enable the v3.4 road guard:
Config.Placer.BlockOnRoad = true
The placement preview outline turns red when aiming at a road surface and Enter is blocked. CarPlay in-vehicle placement is always exempt — that's the point of CarPlay.
How do I prevent inactive players from leaving TVs behind forever?
Use the v3.4 abandon-protection fields:
Config.Placer = {
MaxPerPlayer = 5, -- hard cap per owner
AutoCleanupDays = 45, -- remove after 45 days inactive
AutoCleanupInterval = 6, -- re-scan every 6 hours
}
Also available on demand via /tvclean run (admin command) or exports['HZ-Television']:RunHZTVCleanup().
How do I wipe all placements for a specific player?
/tvclean purge <identifier>
Also: /tvclean list shows the top 20 owners by inactivity to help you find abandoned accounts.
Placed TVs disappear on restart
Enable persistence:
Config.Placer.Persistence = true
Requires oxmysql. Tables hz_television_placed and hz_carplay_placed are created (+ migrated for the last_seen column) automatically.
How do I add pre-recorded channels?
Config.Channels = {
{ name = 'Weazel News', url = 'https://www.youtube.com/watch?v=...', category = 'news' },
{ name = 'LS Rock Radio',url = 'https://www.youtube.com/watch?v=...', category = 'music' },
}
Appears as a "Channels" section in the Smart TV UI.
Permissions
Reserve TVs / placement for admins only
Config.Permissions = {
UseTV = 'admin',
PlaceTV = 'admin',
}
Job-based gating
Config.Permissions = {
UseTV = 'job:police,ambulance',
PlaceTV = 'job:estate',
}
Format: 'job:jobname' or 'job:job1,job2' for multiple.
Advanced / Integration
TVs don't sync between players
Enable OneSync — set onesync on in server.cfg. Also make sure you're on a reasonably recent FiveM build (2802+).
Lag / stutter with many TVs
Since v3.1 the rendering engine caches vertex data, so 6 on-screen TVs cost about the same as 1 TV pre-cache. If you still hit issues, lower Config.Display.RenderDistance (e.g. 30 m) and Config.Display.DefaultRange (e.g. 20 m).
Error "Failed to load video" in F8
Usually an embed restriction, regional block, or deleted video. Test the URL in a normal browser with incognito. If the URL needs browser rendering, pass mode = 'browser' when calling PlayVideoOnTelevision.
How do I disable billboards entirely?
Remove billboard models from Config.BillboardUseSmartTV AND from Config.Models. The vanilla GTA V billboards (prop_huge_display_01/02) will then fall back to their default render-target content (which is usually nothing in-game).
How do I integrate with esx\_property / qb-houses?
Use server events to gate placement — see Exports & Events for full examples.
AddEventHandler('HZ-Television:placeTV', function(model, coords, heading)
local src = source
if not exports['esx_property']:IsPlayerInOwnedProperty(src) then
TriggerClientEvent('esx:showNotification', src, 'You must be in your property')
CancelEvent()
end
end)
Emergency broadcast on all TVs
Use PlayVideoOnTelevision over the list from GetAllPlacedTVs — see the Exports examples.
