Changelog
v3.4.6 — install.sql Strict-Mode Fix + CarPlay Recovery Polish
2026-04-30
install.sqlError 1067 onlast_login—timestamp DEFAULT NULLwas rejected by MariaDB instances running with strictSQL_MODE. Column is now declaredtimestamp NULL DEFAULT NULLin bothinstall.sqland the auto-create inserver/accounts.lua, so fresh installs without the SQL file also work on strict-mode databasesinstall.sqlError 1075 onhz_carplay_placed— the table hadid INT AUTO_INCREMENTbut only aUNIQUE KEYonplate; MariaDB requires the auto-increment column to be a key. AddedPRIMARY KEY (id). The live auto-create path inserver/placer.luawas already correct, so only the manualinstall.sqlimport was affected- CarPlay no longer left orphaned after a crash — when a violent collision detaches the prop from the parent vehicle, the reconciliation tick's
not-attachedinvariant releases the slot and re-acquires it on the next pass (≤ 500 ms), snapping the screen back onto the same vehicle at its original offsets. Power state is preserved across the cycle viaPoweredOn[cpId]so the DUI turns back on automatically
Upgrade
- Re-import
install.sqlonce after updating —CREATE TABLE IF NOT EXISTSskips already-created tables, only the two previously-failing ones get created - No data migration, no config / event changes
- Enable
Config.Debug = trueto see release reasonnot-attachedlog when a crash detaches a CarPlay
v3.4.5 — Customer-Ticket Bundle (4 fixes)
2026-04-28
- F8 debug spam silenced — three console lines that fired every frame regardless of
Config.Debugare now gated behind it:[HZ-Television] Screen → DRAWSPRITEPOLY,[HZ-TV RT] name=…, andDrawToRenderTargetDebug. Production servers no longer get spammed with internal render diagnostics - Volume sync no longer lost when slider released quickly — the 200 ms throttle on
smarttv_volumeused to drop the final value if you let go of the slider mid-window. Now a trailing-edge send (queued viapendingVolume) guarantees the last value is broadcast to all viewers after the throttle window expires - Kick volume actually mutes — Kick's cross-origin iframe doesn't expose a
postMessagevolume API, so volume 0 was silently ignored. Now the iframe is recreated with?muted=1on the 0 ↔ >0 transition (binary mute toggle — per-percent volume isn't possible on Kick; that's a Kick platform limitation, not the script)
Config.Carplay = { Enabled = true } block in config.lua. Setting Enabled = false skips the hz_carplay item registration, the target option binding, the placer prompt, and the reconciliation tick. Useful if you only want wall / cinema TVs without the in-vehicle CarPlay variant
Upgrade
- No data migration, no breaking changes
- If you want to disable CarPlay only:
Config.Carplay = { Enabled = false }inconfig.lua
v3.4.4 — DB Resilience + Locale Sweep
2026-04-22
- Shipped
install.sqlas a manual fallback. If the auto-CREATE TABLE IF NOT EXISTSstep can't create one or more tables (missingCREATEpermission, STRICT SQL mode, etc.), the server console now printsCREATE TABLE+ points at the bundled file. Run it once with a privileged MySQL user (FAILED: mysql -u … -p) and restart HZ-Television< install.sql - Fail-cleanly login path — when a table is missing at runtime, the
hz_tv:logincallback now returns{ success = false, reason = 'db_not_ready' }instead of throwingTable 'yourdb.hz_tv_sessions' doesn't existmid-query. A red server log warns the admin. Gated via a new_G.HZ_TV_DB_READYflag set after all CREATEs succeed - Resilient DB bootstrap — every
CREATE TABLEcall is now wrapped inpcall; one failure no longer aborts the rest. Each failure prints the exact table name + the error so admins can fix the one that's broken instead of guessing - Hardcoded French strings removed from the server path:
'Joueur' player-name fallback → 'Player'
- 'Ma Playlist' default playlist name (SQL default + Lua fallback) → 'My Playlist'
- 'Comptes — tables DB prêtes' startup log → 'Account tables ready'
Tips
- The install is idempotent —
install.sqlonly containsCREATE TABLE IF NOT EXISTS, so importing it on a healthy database is harmless install.sqlalso covers the two placement tables (hz_television_placed,hz_carplay_placed) in case those were hit by the same permission issue
v3.4.3 — CarPlay Garage Compatibility + Placement Reliability
2026-04-22
- Garage storage — when a garage script (
qs-advancedgarages,cd_garage,loaf-garage, any resource that deletes the parent vehicle) stores the vehicle, the CarPlay prop is now removed instead of orphaning in front of the garage door - Garage retrieval — when the vehicle comes back out with the same plate but a new entity handle, the CarPlay re-attaches automatically at the same offsets; DUI reactivates if the CarPlay was powered on before storage
- Streamer cull / routing-bucket swap — when the parent vehicle leaves the client's streaming range or routing bucket, the pool releases the slot cleanly; prop re-appears on the vehicle when it comes back into view
- Placement race — placing a CarPlay in your own vehicle now always attaches immediately. Previously the placer could silently fail on a negative
FindVehiclecache hit or a pool-not-ready race; the server now broadcastsspawnCarplayto everyone including the placer, and a reconciliation tick retries within ≤ 500 ms if anything still goes wrong - Defensive parent detection — the pool cross-references the attached vehicle against
GetGamePool('CVehicle')rather than trustingDoesEntityExist/IsEntityAttached, which FiveM can keep reporting astruefor several seconds after a garage script actually deletes the vehicle - Debug visibility — set
Config.Debug = trueto see reconciliation decisions in the F8 console (release slot … / re-acquire cpId=…)
v3.4.2 — Dual SQL Support (full oxmysql + mysql-async)
2026-04-21
- Persistence accidentally broke on mysql-async servers because
server/accounts.luacalls the modern oxmysql-only API (MySQL.ready,MySQL.query.await,MySQL.single,MySQL.scalar,MySQL.insert) server/sql_compat.luanow loadsoxmysql/lib/MySQL.luadirectly viaLoadResourceFile+load()when oxmysql is detected, giving HZ-Television the full modern + legacy API- mysql-async fallback adds a
MySQL.readyshim soaccounts.luadoesn't hard-crash (the modern.awaitAPI is still unavailable on mysql-async — install oxmysql for the account system to work) - Loud red error block when neither driver is detected, with install instructions
v3.4.1 — Dual SQL Support + CarPlay Audio Follow
2026-04-20
- Dual SQL support — HZ-Television now auto-detects
oxmysqlormysql-asyncat runtime and synthesizes aMySQL.Async/MySQL.Syncshim on top of whichever is running. Works out of the box on both modern (QBCore v2, QBox) and legacy (QBCore v1, old ESX) stacks — no config change needed - Startup diagnostic line — the server console now prints exactly which SQL driver was detected (
detected oxmysql/detected existing MySQL.Async (mysql-async)), and a loud red error block if neither is ensured beforeHZ-Television - CarPlay audio follows the vehicle — volume and cabin-audio occlusion now use the CarPlay prop's live world position instead of the stored placement coords, so the sound properly fades as another player's CarPlay drives away from you (was stuck at the placement location)
- The hard-coded
@oxmysql/lib/MySQL.luainclude was removed fromfxmanifest.lua— the newserver/sql_compat.luareplaces it
v3.4.0 — Road Guard, Abandon Protection, CarPlay Split
2026-04-19
- Road-placement guard —
Config.Placer.BlockOnRoad(opt-in) raycasts the closest vehicle node while the preview is active. If the prop is on a road, the outline turns red and Enter is blocked. CarPlay in-vehicle placement is exempt - Abandon protection —
Config.Placer.MaxPerPlayerhard cap per identifier +Config.Placer.AutoCleanupDaysfor inactive owners +Config.Placer.AutoCleanupIntervalperiodic tick last_seencolumn onhz_television_placed+hz_carplay_placed, refreshed onplayerJoining— additive migration runs at startup/tvcleanadmin command —list(top 20 owners by inactivity),run(trigger cleanup now),purge(wipe all placements for a player). ACE-gated viaConfig.Placer.CleanupAdminPermission. Alsoexports["HZ-Television"]:RunHZTVCleanup()- CarPlay assets externalized to
HZ-PropsCarplay— the 12 variants (hz_carplay,hz_carplay_1..11) now live in a separate lightweight resource.ensure HZ-PropsCarplayis now required. Calibration moved toHZ-PropsCarplay/calibration.json, loaded and merged at boot - CarPlay gizmo QoL — vehicle frozen + velocity zeroed for the duration of placement, vehicle controls disabled (
keepVehicleControls = false), first-person cam snaps toheading=0 / pitch=0so it faces straight ahead on cockpit-view switch
v3.3.0 — SmartTV Everywhere + Cylindrical Raycast
2026-04-18
- SmartTV on billboards & cinema — full interactive Smart TV UI now runs on cinema screens (
prop_curved_screen_s/m/l) and vanilla GTA V huge billboards (prop_huge_display_01/02) viaConfig.BillboardUseSmartTV - Render-target auto-detection — heuristic
dict == namedetects vanilla render-target textures (silentAddReplaceTexturefails) and switches to the properDrawToRenderTargetpipeline, finally displaying DUI content reliably on huge billboards - Cylindrical cursor raycast — true ray ↔ cylinder intersection math for curved screens, with per-model
Curve = { Radius, Arc, Invert }config. Pre-calibrated from Blender-measured dimensions for the 3 cinema screens.Curve.Invert = truefor props that curve toward the viewer. DynamicRaycastMaxDistance= cam-to-screen distance × 2 /tvcfglive preview overlay — semi-transparent cyan overlay drawn on the prop during calibration. Flat → single quad, curved → 16 arc segments built from the same formula as the raycast (preview = hit-box)- CarPlay cabin audio occlusion (Web Audio) — lowpass BiquadFilter (600 Hz sealed → 2 200 Hz all doors open) + peaking bass shelf at 80 Hz (+6 dB sealed, decays as doors open) + master GainNode (25 % sealed → 70 % open). 80 ms smooth transitions, per-door state (front/rear × L/R), 5 m cabin range, full clean audio for driver + passengers
/tvcfglocalized — 58 locale keys across en / fr / es / de for the admin configurator. Target reach distance bumped 4 m → 25 m for huge billboards- Fixes — huge billboards staying dark (render-target), CarPlay target reverting to "Turn On" while driving (coord-based power check → entity-based), "Power Off" missing on SmartTV-enabled screens, streamer mode not muting newly-activated screens,
/carplayInteract closing SmartTV, AZERTY rotation in gizmo, in-vehicle cam tilt (cam now matches full entity rotation), dashboard bone cascade with pre-calibrated initial offsets, cinema-screen Scale S/M corrected from Blender dimensions
v3.2.0 — CarPlay: In-Vehicle Smart TV
2026-04-17
hz_carplayitem — new inventory item that mounts a Smart TV on any vehicle dashboard. Use it while sitting in the car and a 3D keyboard gizmo takes over- 12 texture-isolated variants (
hz_carplay,hz_carplay_1..11) with a dynamic client-side pool — unlimited placements, 12 closest rendered, each variant has its own TXD so every car gets independent content - Plate-based multi-player sync — placement, power state, content and removal are synced by vehicle plate so everything survives moves, respawns, restarts. Per-vehicle persistence in
hz_carplay_placed - Target options appear dynamically based on power state — Turn On / SmartTV / Interact / Turn Off / Remove
/carplay_on,/carplay(F5),/carplayremovecommands- Also supports static placement — CarPlay props can be placed outside vehicles as regular tabletop screens
- Shared keyboard gizmo module exposed as
exports['HZ-Bridge']:GizmoAttached(entity, parent, boneIndex, initialOffsets, options)— parent-local axes, AZERTY/QWERTY-safe, optional vehicle-control passthrough - Locale hygiene — all CarPlay strings + streamer mode notifications moved to en/fr/es/de locale files
v3.1.0 → v3.1.2 — Perf, Custom Props, Playlist, Routing Buckets
2026-04-09 → 2026-04-10
- Vertex cache —
ComputeSpritePolyData()caches 3D geometry per screen; render thread drops to 2×DrawSpritePolyper frame. 6 TVs on screen = cost of 1 TV before (\~0.02 ms vs \~0.08 ms) - Tighter video sync — heartbeat 15 s → 5 s, viewer resync 30 s → 15 s, drift tolerance 3 s → 1.5 s, anti-rollback 5 s → 2 s, time precision 1 s → 0.1 s
- 9 new custom props —
hz_tv_s/m/l(wall),hz_tv_s/m/l_stand(floor stand),curved_screen_s/m/l(cinema). All original assets, no external packs - Personal playlist — account-linked looping queue (up to 50 items per account), per-item duration, All/Videos-only filter, active indicator, exports
StartPlaylistOnTelevision/StopPlaylistOnTelevision - Full routing bucket support — per-bucket TV state, bucket-scoped events, operator locks per bucket, LB Phone picker filters by bucket, playlist loop runs independently per instance
- Font Awesome fix — CSS
moved to, font paths corrected, woff2 preload added
v3.0.0 — Apple TV Redesign, 14 Platforms, Accounts
2026-04-01
- Smart TV UI rebuilt — tvOS-style home screen (floating dock with rectangular icons, glassmorphism), Control Center (Power, Login/Logout, Settings, Favorites, History, Playlist, Theme), light/dark theme with 80+ overrides, inline URL input, playback bubble with timeline seek
- Account system — login linked to player identifier, favorites / history / per-user settings, persistent via oxmysql
- 14 platforms — Rumble, Odysee, Streamable, Facebook Video, Youku added to the existing YouTube / Twitch / Kick / Bilibili / direct video / images / browser. Fallback logic: unknown URL → native video → browser iframe
- Twitch native SDK —
Twitch.Playerfor volume / mute / pause / play - Real-time video sync — heartbeat system, anti-rollback, viewer resync, exact position on join
- Browser sync — URL, clicks, scroll relayed from operator to viewers
- Billboard NUI control panel — "Ghost Protocol" cyberpunk design, 6 apps, sound-distance slider (10–200 m), screen-off-by-default (DUI created only when content is sent)
- Locale system — separate
config/locales/{en,fr,es,de}.lua, locales embedded in sync events
v2.3.0 — Unlimited TVs (new rendering engine)
2026-03-12
- Rewrote rendering from Scaleform to DrawSpritePoly — DUI texture now rendered as 3D geometry directly (2 triangles per screen), no Flash/GFX intermediate
- Removed the 5-TV engine cap — no more simultaneous-TV limit
- External Flash/GFX texture-renderer dependency dropped — rendering is now fully in-script
- Z-fighting prevention — screen quad offset by 0.002 units along normal
v2.2.0 — Raycast Interaction
2026-03-11
- New free-cursor raycast interaction mode — player stays visible and can look around; cursor interacts directly with the 3D screen surface via ray ↔ plane math
- Legacy locked-camera mode still available via
Config.Display.InteractionMode = 'camera'
v2.1.0 — Apple TV / iOS 26 Visual Pass
2026-03-11
- Full Smart TV CSS rewrite — vivid wallpaper, frosted-glass dock, springy hover animations, label slide-up effect, tvOS-style top pill (clock + avatar)
- Image sync, volume sync, NUI-focus-on-interact, scale-table handling fixes
- Removed
backdrop-filter: blur()for FPS — replaced with opaque backgrounds
v2.0.0 — Multi-Framework + Inventory Placement
2026-02
- Multi-framework Bridge with auto-detection (QBCore / ESX / Standalone)
- Inventory placement system with 3D controls and optional persistence
- Live configurator (
/tvcfg) with 3D gizmo - Billboard support for large outdoor screens
- Distance-based audio with configurable range
- Pre-recorded channels
- Multi-inventory support (ox, qb, qs, ps, codem, origen, core, tgiann)
- Client and server exports for full integration
v1.x — Previous Versions
v1.5.0 (2025-12)
- Added Kick streams support, fixed Twitch sync bug, improved rendering performance
v1.4.0 (2025-10)
- Vimeo and Dailymotion support, fixed display bug on certain TV models,
/tvoffcommand
v1.3.0 (2025-08)
- Improved multi-TV system, fixed persistent sound issue, M3U8 (HLS) support
v1.2.0 (2025-06)
- Twitch livestreams, Power ON/OFF mode, improved player synchronization
v1.1.0 (2025-04)
- Image support (PNG, JPG, GIF), fixed black texture bug on startup, new default TV models
v1.0.0 (2025-02)
- Initial release
Automatic updates: updates are delivered via FiveM Keymaster. You'll receive a Discord notification when a new version is released.
Support for Older Versions
| Version | Support | End of support |
|---|---|---|
| v3.4.x | Active | — |
| v3.3.x | Active | — |
| v3.2.x | Maintenance only | July 2026 |
| v3.1.x and earlier | Not supported | April 2026 |
It is strongly recommended to always use the latest version to benefit from bug fixes and new features.
