Changelog

v1.3.0 — Cinematic Tsunami + Live Config Audit

2026-06-09

> Major update consolidating every change since v1.1.10. The tsunami event was rebuilt around a real audio/visual scenario (sirens, voice, panic), and the hz_lib panel was systematically audited so panel saves apply at runtime instead of waiting for a resource restart.

New Features

  • Cinematic tsunami audio system.
* 3D coastal sirens at 12 PA-speaker points across the map (Vespucci, Paleto, Mt Chiliad, Port LS, etc.). Volume falloff is tuned so each player hears 1–2 sirens at most — no overlap chaos. Hybrid 3D positional audio via xsound (new required dependency, see Upgrade Notes). * PA-filtered voice alerts in 5 languages (EN / FR / ES / DE / PT). The voice runs through a dedicated Web Audio NUI layer that applies a megaphone DSP chain (highpass 500 Hz + lowpass 3500 Hz + 6 dB presence boost at 2 kHz + bullhorn waveshaper distortion + HRTF 3D panner). The voice emanates from the speaker nearest the player at trigger time. * Automatic ducking — sirens fade to 20% of their normal volume while the PSA voice talks, restore on natural MP3 end. Race-free between phase changes (the onended callback checks current source identity before notifying Lua). * Five-second silence before the first PSA voice cuts in. The siren wails alone first to build tension.
  • NPC panic system. When the alarm starts, peds within 250 m scream (PlayPain with painID 6) and flee inland (TaskSmartFleeCoord toward a fixed southern ocean coord). Scan every 1.5 s, dedup via NetworkGetNetworkIdFromEntity, gated to non-player non-vehicle entities. The SetPedFleeAttributes configuration prefers running over cowering so peds never freeze in place.
  • Player buoyancy. When the tsunami water rises above Los Santos building roofs, IsEntityInWater doesn't fire because the engine can't model the volume — players normally just fall through the water. A dedicated buoyancy thread now detects playerZ < waterHeight − 0.5 and applies upward velocity (or a one-shot teleport to surface − 1 m if stuck deep in geometry). Mounted ped configurations 65 and 166 ensure free swim regardless of GTA's volume check.
  • Aftermath modes for Config.Tsunami.Mode:
* 'spectacle' — current behaviour, instant reset 10 s after the recede completes. * 'survival' — water stays at a residual 5 m level for SurvivalDurationMinutes (default 30 min) so the RP can play out the flood. New phaseSurvivalHold() phase between recede and cleanup, pause-aware.
  • Live config via the hz_lib panel for every Tsunami and Tornado timing field. Edit Tsunami.WarningDuration, RiseSpeed, PeakDuration, Mode, SurvivalDurationMinutes etc. directly in the Events tab; the next /tsunami start reads the new value via refreshConfigIntoState() at phase boundaries. No restart required.
  • Tsunami atmosphere section in the panel — Tsunami.Effects.ForceWeather (off by default), WeatherType (CLEAR / EXTRASUNNY / CLOUDS / OVERCAST / FOGGY / SMOG / RAIN / THUNDER), ForceWind, WindSpeed. These were live-readable in code but absent from the panel; now exposed.
  • Tornado timing section in the panel — WarningDuration, ActiveDuration, DissipatingDuration, IntensityRampUp, MovementEnabled (live toggle, can freeze the tornado mid-event), MoveSpeed. The whole Tornado config surface was missing from the panel; now exposed.

Improvements

  • Tsunami flow rewritten so WARNING is a sirens + voice phase only — the flood water layout (Amplitude=120 swell) now loads at RISING when the wave actually arrives, not at WARNING. No more giant amplitude waves on a still-calm ocean during the alert.
  • Realistic tsunami defaults. Config.Tsunami.Effects.ForceWeather defaults to false (keep current sky), no camera shake at WARNING, no blue screen overlay, no dark timecycle modifier. Real tsunamis can hit under blue sky (Tōhoku 2011, Indian Ocean 2004). Set ForceWeather = true with WeatherType = 'THUNDER' for the disaster-movie feel.
  • "Stop (gradual)" drains in 10 seconds flat regardless of starting height. Previous behaviour used riseSpeed inverse which gave 4 minutes of huge waves on receding water for a 200 m tsunami. Unusable.
  • Tsunami water layout rebuilt around the InfinityNL/waterworld approach — single giant WaveQuad at Amplitude=120 plus a CalmingQuad with fDampening=0.01 that overrides GTA's vanilla harbor/river dampeners. Waves render uniformly across the whole map.
  • Panel schema cleaned of 18 dead fields that had no runtime readers (auto-thunder blackout subsystem doesn't exist, wind gusts subsystem doesn't exist, SyncInterval, DefaultWeather, WeatherChangeInterval, ZoneCheckInterval, PredictiveLoadDistance, SeasonAutoStart, DefaultSeasonPreset, SyncRealWorldSeasons, TemperatureMode, HeatPeakHour, etc.). Roughly 92% of saves now apply live without a restart.
  • Time freeze transition — clicking "Apply time" with Immediate unchecked while the clock is frozen now runs the smooth fast-forward instead of snapping. The freeze is temporarily suspended for the transition duration, then restored at target via endTimeTransition.
  • hz_lib panel mirrorserver/bridge_panel.lua now maps PascalCase panel keys to the camelCase runtime keys the legacy modules read (Config.StartTimeConfig.startUpTime, Config.FreezeTimeGlobalState.freezeTime, Config.UseRealTimeConfig.useRealTime, etc.). The applyTemperatureBridge() and applyLiveThreadStarters() helpers also re-hydrate the cached HzTemperature.Config and restart per-system threads when an Enabled flag flips back to true.
  • NPC panic + tsunami buoyancy mounted automatically when Config.Tsunami.PedsCanSwim = true (already the default).

Bug Fixes

  • Sun visibly flashed every 3 seconds under FOGGY and SMOG weather. SetTimecycleModifier('FoggyHills') was being re-applied on every effects tick. Now idempotent — tracked via appliedTimecycleWeather local so the natives only fire when the active weather actually changes.
  • Time speed (Config.TimeScale) panel value was read as raw milliseconds instead of a multiplier. A panel default of 1.0 was running the clock roughly 4 000 × too fast. Now converted correctly as ms = fileBaseline / multiplier, with a MIN_SCALE = 1000 ms safety floor so a runaway value can never make the clock unplayable.
  • Events panel showed IDLE after closing and reopening the panel mid-event. The view subscribed to viewData updates but never asked the server for current state on mount. Added requestData to the schema's events allowlist and an invoke('requestData') on mount in hz_lib/web/src/views/hz_weather/Events.tsx.
  • Map weather changes (admin → Set all zones) were not refreshing the panel zone list. setZoneWeather / setAllZonesWeather / freezeWeather / setBlackout now push a fresh zones + weather snapshot via updateZones / updateWeather to the panel admin source.
  • Rapid weather changes caused a transition flash — fast-forward bumped from 5 s to 20 s of immobility, plus cancelTransition() now settles the engine on the current weather (SetWeatherTypePersist) before the next transition starts so the fade doesn't get cut mid-stride.
  • Antarctique zone crash report — defensive nil-guard added to two unguarded HzTemperature.CalculateTemperature callsites in forecast.lua (lines 299 and 364), plus client-side per-zone pcall in LoadZones so one bad entry never breaks the whole load (mirrors the server pcall pattern from v1.1.8).
  • Per-player locale honoured even when the hz_lib panel default 'en' overrides the file. The FILE_LOCALE is captured at script load before the bridge merge so a server with Config.Locale = 'fr' in config/config.lua actually plays French voice phases.

Upgrade Notes

  • New required dependency: xsound for the tsunami sirens. Add ensure xsound before ensure hz_weather in your server.cfg. The voice phases use a separate Web Audio NUI layer (no extra dependency beyond xsound for the sirens).
  • Sounds bundle ships with the assethz_weather/sounds/ contains the siren MP3 + four voice phases × five locales (around 12 MB total). Listed in the fxmanifest files block. Escrow users: re-download from Keymaster, the bundle is part of the asset.
  • flood.xml replaces the vanilla water layout while a tsunami is active. If you ship your own custom water mods, test the interaction.
  • Tsunami sirens at 12 hardcoded coordinates. If you have a custom map mod that adds coastline, edit Config.Tsunami.Sounds.SirenPoints in config/config.lua to add your points.
  • Drop-in replace, no DB migration. Existing saved tsunami / blackout / freeze states in hz_weather_config are honoured.
  • If you were on any v1.2.x build, update directly to 1.3.0 — no intermediate version required.

qs-hzweather v2.0.0 — QS Smartphone V3 Compatibility

2026-05-26

> This release is for the qs-hzweather addon resource only — the core HZ-Weather server resource is unchanged. Follow the migration steps below if you upgraded QS Smartphone to V3.

Breaking

  • Target phone changed: qs-smartphone-proqs-smartphone. QS Smartphone V3 ships under the resource name qs-smartphone (no -pro). qs-hzweather v2.0.0 depends on it. If you're still on V2 (Pro), stay on qs-hzweather v1.x — see the legacy V2 section.
  • One-line manual edit required in qs-smartphone/config/main.lua. V3 keeps native apps (phoneApplications) and custom apps (customApps) in two separate routing tables — same-id registration does not override the native (the native always wins). To make our app the only Weather, comment out { id = 'weather', label = 'Weather', icon = 'weather.webp', category = 'Information & Reading' } in Config.PhoneApplications. Reversible by uncommenting. Full instructions in Phone Weather Apps.
  • addCustomApp payload shape changed for V3. The old { app, image, ui, label, job, blockedJobs, timeout, ... } is replaced by { id, label, icon, category, creator, description, age, appStoreOnly, sizeMb, iframe = { url }, custom = { enabled, sourceResource, bridge = { enabled, allowedOrigins } } }. qs-hzweather v2.0.0 already uses the new shape — no action needed unless you forked the resource.

Bug Fixes

  • Iframe rendering blank white screen on V3. The V1.x bundle relied on qs-smartphone-pro flipping the body's visibility / display via an app-opened postMessage. V3 doesn't send that signal, so the page-level CSS guard (body { visibility: hidden; display: none }) was never released. App.tsx now sets document.body.style.visibility = 'visible' and display = 'block' unconditionally in the mount effect (mirrors V3's phone-custom-react starter template).
  • Robust registration: tries addCustomApp first, falls back to updateCustomApp('weather', payload) if the id is already taken. The fallback path is mostly future-proofing — current V3 behaviour is that the native and custom spaces are disjoint, so the manual config edit is still required.

Improvements

  • fxmanifest.lua slimmed down: removed ui_page (V3 loads our UI as an iframe under our resource's cfx-nui- origin, no top-level NUI needed) and the legacy title/description were refreshed.
  • Console error line now points at the troubleshooting doc when both registration paths fail: addCustomApp failed (X) and updateCustomApp failed (Y). Check INSTALL.md step 3 (disable native weather in qs-smartphone/config/main.lua).
  • INSTALL.md in the resource folder now documents V3 only, with a clear "How the override works" section and a troubleshooting table.

Upgrade Notes

  • If you're still on QS Smartphone Pro V2: do not install qs-hzweather v2.0.0 — stay on v1.x.
  • If you're moving to V3:
1. Stop and remove qs-smartphone-pro. 2. Install qs-smartphone V3 from Quasar Store. 3. Replace qs-hzweather v1.x with v2.0.0+ from Keymaster. 4. Comment out the native weather entry in qs-smartphone/config/main.lua (step 3 of Phone Weather Apps → QS Smartphone V3). 5. ensure qs-smartphone then ensure qs-hzweather — order matters. 6. (Once, optional) TRUNCATE phone_metadata; TRUNCATE phone_app_store; if V2 phone state is interfering with V3.

v1.1.10 — Escrow Panel Fix + Time Speed Hotfix

2026-05-27

Bug Fixes

  • Day/night cycle ran way too fast after switching to the hz_lib panel — clouds and sun whipping across the sky. The panel's "Time speed" is a multiplier but was being read as raw milliseconds, running the clock ~4000x too fast. Now converted correctly + a safety floor so it can never run unplayably fast again.
  • HZ-Weather panel didn't load on escrow builds (parse error near '<\1>') — the panel schema file wasn't whitelisted from encryption, so hz_lib read ciphertext. Now in escrow_ignore.

Improvements

  • Panel "Time speed" is now relative to your config baseline: 1.0 = unchanged, 2.0 = 2x faster, 0.5 = half speed. Default 1.0 no longer alters your configured day length.
  • Stale time-scale values from a previous run are rejected on boot.

v1.1.9 — Live Panel Sync + Night Scale + English Notifs + Blackout Guards

2026-05-26

Bug Fixes

  • hz_lib panel edits had no effect at runtimetime.lua cached values at boot and never re-read them. Now listens to hz_weather:configChanged and refreshes the active scale immediately (no restart needed).
  • Night speed multiplier never engaged at the boundary hours (22:00 and 06:00 exactly) — both branches missed due to a >/> typo. Now uses inclusive start, exclusive end.
  • Time freeze toggle wasn't persisted — closing and reopening the panel showed the wrong state. Now saved to DB immediately and restored on restart.
  • Config.BlackoutEnabled = false was purely cosmetic — admin toggles, exports, and boot-time restore all ignored it. Now properly enforced everywhere.
  • Zone config crashes no longer take down the whole server — bad entries are skipped with a clear log, the rest loads. The offending zone name is printed so you know what to fix.

Improvements

  • All admin panel notifications translated to English (~30 strings in admin / tsunami / tornado). Was hardcoded French regardless of locale setting.
  • All client debug logs translated to English (weather / wind / temperature / effects). Config.Debug = true output is now readable for EN servers.
  • hz_lib panel naming bridged to file config keys — UseNightSpeedMultiplier, NightSpeedMultiplier, NightTime.beginning/ending, UseRealTime, TimeScale all flow through correctly.
  • Admin panel "Sync with real time" indicator now reads the actual source (panel override + config file fallback), no longer stuck at false.

v1.1.8 — Zone Editor Circle Support + Blackout Exceptions Fix

2026-05-15

New Features

  • Circle zones in the admin panel zone editor — the in-game editor (/hzpanel → Hz-Weather → Zones) was polygon-only. New + Circle button alongside + Polygon lets admins create circle zones directly: click the map to drop the center, drag the radius slider in the inspector (50–5000 m, live preview), set name / weather / colour, save. Existing config-defined circle zones (e.g. Cayo Perico) now also render on the editor canvas — they were invisible before because the canvas only drew shapes with an explicit points[] array.

Bug Fixes

  • Cayo Perico circle drawn at the wrong size on the admin map — the previous render used <circle r=radius/SCALE_X> which ignores Mercator stretch at high latitudes. Cayo sits at game Y ≈ -5150, projected lat ≈ -87°, where 1 m on Y is ~35× larger than 1 m on X in pixel space. The circle now renders as a true projected ellipse using local px-per-meter ratios on each axis, matching what the player sees in-world. Both the editor canvas and the read-only Map view use the same logic so they always agree.
  • Config.BlackoutExceptions never worked — the shipped default values (Pillbox Hospital, Mission Row PD, Sandy Shores Sheriff, Paleto Bay Sheriff) are GTA-native zone labels, but the client check compares against the current HZ-Weather zone slug (vinewood, los_santos, ...). The two namespaces never matched, so no zone ever kept its lights during a blackout. The field is now a constrained multi-select picker (new enum-multi hz_lib field type), choices are the 10 HZ-Weather zone slugs from config/zones.lua, default is empty.
  • Polygon-only handles (vertex drag, edge-insert click, right-click delete, cursor preview line, "drop point #N" banner) used to render for circle drafts too — they're now properly gated so a circle draft only shows its center marker + outline.

Breaking — config migration

  • Config.BlackoutExceptions defaults changed from { 'Pillbox Hospital', 'Mission Row PD', 'Sandy Shores Sheriff', 'Paleto Bay Sheriff' } (broken — silently no-op) to {} (empty). If you want LS or any region to stay lit during a blackout, re-tick the corresponding HZ-Weather zones in the admin panel (or set the values directly in config/config.lua). Available slugs: paleto, mont_josiah, sandy_shores, banham_canyon, vinewood_hills, vinewood, tataviam_mountains, palomino_highlands, los_santos, cayo_perico.
  • Granularity is now region-wide (selecting los_santos keeps the whole city lit, not one building). If you need per-building exceptions, run a custom client-side override against GetNameOfZone().

Improvements

  • Two new client NUI callbacks (upsertZone, deleteZone) forwarding to the existing server events. Required for the new circle creation / radius edit flow in the admin panel.
  • When the admin clicks À ma position while in a circle draft, the player's current coords drop directly as the center, so the only remaining step is the radius slider.

Upgrade Notes

  • If you previously relied on BlackoutExceptions to keep hospitals / PDs lit, the feature was a no-op — nothing to migrate, but you'll want to set up the new region-level exceptions if you actually use blackouts.
  • If you add a DB-backed zone via the editor and want it as a blackout exception, also add its slug to the choices array in bridge_schema.lua (the panel won't auto-discover DB-created zones in the multi-select yet).
  • Requires hz_lib v1.1.0+ for the enum-multi field type to render correctly. Older hz_lib versions will fall back to a generic string input but the field will save / load fine.

v1.1.5 — Temperature Hysteresis + Client-Side Locales

2026-04-22

Bug Fixes

  • Fixed cold/heat notification spam near the threshold — when the temperature oscillated around coldThreshold (e.g. 9 °C → 7 °C → 9 °C…), the notification re-fired on every flip and the colour overlay flashed. Replaced the simple on/off flag with a 2 °C hysteresis band + a 2-minute cooldown between notifications. Once the player enters the Cold state, the temperature must rise to coldThreshold + 2 before exiting. Symmetric for Heat.
  • Fixed client-side strings being stuck in French regardless of Config.Locale — the cold / heat notification titles (Froid / Chaleur) were hardcoded. Added a lightweight client-side locale loader that reads config/locales/<Config.Locale>.lua at boot and exposes a global L(key, fallback) helper. Notification titles now localize correctly in all 12 shipped languages (en / fr / es / de / it / ja / ko / pl / pt / ru / tr / zh).

Improvements

  • New client script client/locale.lua — loads the resource's own translation table on boot, falls back to English if the configured locale isn't found. Reusable by any other client-side string that needs localization
  • 2 new locale keys added to every shipped language: cold_notif_title, heat_notif_title
  • Config.Debug = true HUD overlay now exposes coldActive / heatActive (the sticky hysteresis state) instead of the old on-fire-once flags

Upgrade Notes

  • Config untouched — no migration needed
  • If you've translated the locale files yourself, add these 2 keys to your custom file so the notifications aren't blank

v1.1.4 — Forecast Sync & Phone App Fixes

2026-04-09

New Features

  • Forecast transition steps — When an admin overrides a zone's weather, the forecast now generates smooth intermediate steps instead of an instant jump (e.g. EXTRASUNNY → CLEAR → CLOUDS → OVERCAST → RAIN)
  • Full vSync compatibility — Garages and scripts using vSync:requestSync / vSync:updateWeather now work out of the box
  • Debug overlay — Enable Config.Debug = true to display an on-screen panel showing GTA actual weather vs HZ expected, sync status, zone, transition state, temperature

Bug Fixes

  • Fixed weather snapping instantly when crossing zones — transitions are now smooth everywhere with 25s fade per step
  • Fixed cold/heat notification spam — one notification per state change instead of repeating
  • Fixed weather flash on season/admin weather change — smooth 15s transition only
  • Fixed StateBag re-applying same weather causing desync with GTA engine
  • Fixed admin zone weather change not updating in Forecast tab
  • Fixed sunrise/sunset hardcoded to 6:00/20:00 — now synced from Config.NightTime
  • Fixed sun arc not tracking game time during night hours
  • Fixed QS Smartphone Pro weather app not opening (NUI iframe rendering + resource name resolution)
  • Fixed phone weather app showing 0 locations on map and zone list (isActive nil handling)

Improvements

  • Smooth zone-to-zone transitions with distance-based multi-step blending
  • Added 400ms debounce to prevent ghost transitions when crossing zone gaps
  • Forecast updates now sent only to admins (reduced bandwidth)
  • Weather sync optimized for zone players (others use GlobalState automatically)
  • QS Smartphone Pro app now overrides the native Weather app — same icon, same slot, no conflict

v1.1.0 — Phone Apps & Forecast System

2026-03-15

New Features

  • Phone Weather Apps — Dedicated weather apps for LB Phone and QS Smartphone Pro with interactive satellite map, animated backgrounds, hourly forecast, sun tracker, wind & season cards
  • Forecast System — Real-time weather prediction engine exposed via exports and callbacks for phone apps, HUDs, and third-party resources
  • Admin Forecast Panel — New tab to view, edit, insert, and remove upcoming weather entries with live countdown and timeline
  • Admin weather changes from the map now update the forecast in real-time

Bug Fixes

  • Fixed weather flashes caused by double sync (StateBag + individual event) during season weather changes
  • Fixed SetWeatherTypePersist snapping weather instantly instead of smooth transition
  • Fixed temperature notifications ("Chaleur" / "Froid") spamming every 20 seconds — now notifies once per threshold crossing
  • Fixed forecast broadcast targeting all players instead of admins only
  • Fixed season weather cycle overwriting admin changes at startup (3s init guard)

Improvements

  • Season weather sync now only sends individual events to players inside zones (players outside use GlobalState automatically)
  • Reduced unnecessary network traffic from forecast updates
  • 12 locales supported (en, fr, es, de, it, pt, ru, pl, tr, ja, ko, zh)

v1.0.0 — Initial Release

2026-02-13

  • Dynamic weather engine with 13 weather types and smooth transitions
  • Unlimited weather zones with seamless blending
  • Season system with 4 presets and automatic cycling
  • Per-zone dynamic temperature with day/night curves
  • Natural disasters: Tornado and Tsunami
  • Gameplay effects (traction, visibility, player effects, lightning, blackout)
  • Wind system with dynamic gusts
  • Time management with multiple modes
  • Admin panel (React NUI) with 6 tabs
  • In-game HUD
  • 50+ exports for developers
  • Embeddable weather map for phone integration
  • Backward compatibility with qb-weathersync and cd\_easytime
  • Multi-framework support (QBCore, ESX, QBX, Standalone)
  • English and French localization