Changelog

v3.4.6 — install.sql Strict-Mode Fix + DashScreen Recovery Polish

2026-04-30

  • install.sql Error 1067 on last_login — timestamp DEFAULT NULL was rejected by MariaDB instances running with strict SQL_MODE. Column is now declared timestamp NULL DEFAULT NULL in both install.sql and the auto-create in server/accounts.lua, so fresh installs without the SQL file also work on strict-mode databases
  • install.sql Error 1075 on hz_dashscreen_placed — the table had id INT AUTO_INCREMENT but only a UNIQUE KEY on plate; MariaDB requires the auto-increment column to be a key. Added PRIMARY KEY (id). The live auto-create path in server/placer.lua was already correct, so only the manual install.sql import was affected
  • DashScreen no longer left orphaned after a crash — when a violent collision detaches the prop from the parent vehicle, the reconciliation tick's not-attached invariant 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 via PoweredOn[cpId] so the DUI turns back on automatically

Upgrade

  • Re-import install.sql once after updating — CREATE TABLE IF NOT EXISTS skips already-created tables, only the two previously-failing ones get created
  • No data migration, no config / event changes
  • Enable Config.Debug = true to see release reason not-attached log when a crash detaches a DashScreen

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.Debug are now gated behind it: [hz_television] Screen → DRAWSPRITEPOLY, [HZ-TV RT] name=…, and DrawToRenderTargetDebug. 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_volume used to drop the final value if you let go of the slider mid-window. Now a trailing-edge send (queued via pendingVolume) guarantees the last value is broadcast to all viewers after the throttle window expires
  • Cross-origin iframe volume actually mutes — some embedded sources expose no postMessage volume API, so volume 0 was silently ignored. Now the iframe is recreated with ?muted=1 on the 0 ↔ >0 transition (binary mute toggle — per-percent volume isn't possible on such sources; a limitation of the embed itself, not the script)
  • DashScreen can be fully disabled — new Config.DashScreen = { Enabled = true } block in config.lua. Setting Enabled = false skips the hz_dashscreen* 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 DashScreen variant

Upgrade

  • No data migration, no breaking changes
  • If you want to disable DashScreen only: Config.DashScreen = { Enabled = false } in config.lua

v3.4.4 — DB Resilience + Locale Sweep

2026-04-22

  • Shipped install.sql as a manual fallback. If the auto-CREATE TABLE IF NOT EXISTS step can't create one or more tables (missing CREATE permission, STRICT SQL mode, etc.), the server console now prints CREATE TABLE <name> FAILED: <reason> + points at the bundled file. Run it once with a privileged MySQL user (mysql -u … -p <db> < install.sql) and restart hz_television
  • Fail-cleanly login path — when a table is missing at runtime, the hz_tv:login callback now returns { success = false, reason = 'db_not_ready' } instead of throwing Table 'yourdb.hz_tv_sessions' doesn't exist mid-query. A red server log warns the admin. Gated via a new _G.HZ_TV_DB_READY flag set after all CREATEs succeed
  • Resilient DB bootstrap — every CREATE TABLE call is now wrapped in pcall; 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.sql only contains CREATE TABLE IF NOT EXISTS, so importing it on a healthy database is harmless
  • install.sql also covers the two placement tables (hz_television_placed, hz_dashscreen_placed) in case those were hit by the same permission issue

v3.4.3 — DashScreen 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 DashScreen 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 DashScreen re-attaches automatically at the same offsets; DUI reactivates if the DashScreen 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 DashScreen in your own vehicle now always attaches immediately. Previously the placer could silently fail on a negative FindVehicle cache hit or a pool-not-ready race; the server now broadcasts spawnDashScreen to 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 trusting DoesEntityExist / IsEntityAttached, which FiveM can keep reporting as true for several seconds after a garage script actually deletes the vehicle
  • Debug visibility — set Config.Debug = true to 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.lua calls the modern oxmysql-only API (MySQL.ready, MySQL.query.await, MySQL.single, MySQL.scalar, MySQL.insert)
  • server/sql_compat.lua now loads oxmysql/lib/MySQL.lua directly via LoadResourceFile + load() when oxmysql is detected, giving HZ-Television the full modern + legacy API
  • mysql-async fallback adds a MySQL.ready shim so accounts.lua doesn't hard-crash (the modern .await API 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 + DashScreen Audio Follow

2026-04-20

  • Dual SQL support — HZ-Television now auto-detects oxmysql or mysql-async at runtime and synthesizes a MySQL.Async / MySQL.Sync shim 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 before hz_television
  • DashScreen audio follows the vehicle — volume and cabin-audio occlusion now use the DashScreen prop's live world position instead of the stored placement coords, so the sound properly fades as another player's DashScreen drives away from you (was stuck at the placement location)
  • The hard-coded @oxmysql/lib/MySQL.lua include was removed from fxmanifest.lua — the new server/sql_compat.lua replaces it

v3.4.0 — Road Guard, Abandon Protection, DashScreen 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. DashScreen in-vehicle placement is exempt
  • Abandon protection — Config.Placer.MaxPerPlayer hard cap per identifier + Config.Placer.AutoCleanupDays for inactive owners + Config.Placer.AutoCleanupInterval periodic tick
  • last_seen column on hz_television_placed + hz_dashscreen_placed, refreshed on playerJoining — additive migration runs at startup
  • /tvclean admin command — list (top 20 owners by inactivity), run (trigger cleanup now), purge <identifier> (wipe all placements for a player). ACE-gated via Config.Placer.CleanupAdminPermission. Also exports["hz_television"]:RunHZTVCleanup()
  • DashScreen assets externalized to hz_televisionprops — the 12 variants (hz_dashscreen, hz_dashscreen_1..11) now live in a separate lightweight resource. ensure hz_televisionprops is now required. Calibration moved to hz_televisionprops/calibration.json, loaded and merged at boot
  • DashScreen gizmo QoL — vehicle frozen + velocity zeroed for the duration of placement, vehicle controls disabled (keepVehicleControls = false), first-person cam snaps to heading=0 / pitch=0 so 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) via Config.BillboardUseSmartTV
  • Render-target auto-detection — heuristic dict == name detects vanilla render-target textures (silent AddReplaceTexture fails) and switches to the proper DrawToRenderTarget pipeline, 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 = true for props that curve toward the viewer. Dynamic RaycastMaxDistance = cam-to-screen distance × 2
  • /tvcfg live 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)
  • DashScreen 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
  • /tvcfg localized — 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), DashScreen target reverting to "Turn On" while driving (coord-based power check → entity-based), "Power Off" missing on SmartTV-enabled screens, silent mode not muting newly-activated screens, /dashscreen Interact 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 — DashScreen: In-Vehicle Smart TV

2026-04-17

  • hz_dashscreen item — 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_dashscreen, hz_dashscreen_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_dashscreen_placed
  • Target options appear dynamically based on power state — Turn On / SmartTV / Interact / Turn Off / Remove
  • /dashscreen_on, /dashscreen (F5), /dashscreenremove commands
  • Also supports static placement — DashScreen props can be placed outside vehicles as regular tabletop screens
  • Shared keyboard gizmo module exposed as exports['hz_lib']:GizmoAttached(entity, parent, boneIndex, initialOffsets, options) — parent-local axes, AZERTY/QWERTY-safe, optional vehicle-control passthrough
  • Locale hygiene — all DashScreen strings + silent 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× DrawSpritePoly per 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 <link> moved to <head>, font paths corrected, woff2 preload added

v3.0.0 — UI Redesign, Expanded Sources, 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
  • Expanded source support — additional playback modes added to the existing direct video / images / web content
  • Native player SDK — supported stream sources expose a player API for 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 — 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 live-stream source support, fixed a sync bug, improved rendering performance

v1.4.0 (2025-10)

  • Additional embedded video sources, fixed display bug on certain TV models, /tvoff command

v1.3.0 (2025-08)

  • Improved multi-TV system, fixed persistent sound issue, M3U8 (HLS) support

v1.2.0 (2025-06)

  • Live-stream sources, 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

VersionSupportEnd of support
v3.4.xActive—
v3.3.xActive—
v3.2.xMaintenance onlyJuly 2026
v3.1.x and earlierNot supportedApril 2026
It is strongly recommended to always use the latest version to benefit from bug fixes and new features.