Add fixed core HUD and shared service window for T5 and T6

This commit is contained in:
2026-10-14 15:55:22 -04:00
parent d15bc50b7d
commit 929bf0354b
18 changed files with 1973 additions and 804 deletions
+58 -27
View File
@@ -1,7 +1,7 @@
# T6 port notes
T6 is ported from T5. Both source trees contain common, HUD, AFK, join, lock,
telemetry and leaderboard modules; neither includes bank or database modules.
telemetry, leaderboard and bank modules; neither includes direct-database modules.
## Differences retained for T6 and requested fixes
@@ -9,7 +9,7 @@ telemetry and leaderboard modules; neither includes bank or database modules.
| --- | --- | --- |
| Paths | `maps/mp/_utility`, `scripts/zm/tws_t6_common` | T6 namespaces and requested filenames |
| Loading | No T5 `zombiemode` dvar gate; each module has `main()` and `init()` | Zombies-only folder loading; avoid r5346 missing-main warnings |
| HUD positioning | Fullscreen screen anchors, same 10-unit margin | Requested fix for inset HUD |
| HUD positioning | Fullscreen upper-right anchors, fixed core and service-window geometry | Keep clear of top-edge overlays and stock scores/ammo without moving the core for services |
| HUD rendering | Precached white shader, local max-health fallback, floating-point ratio, `getPlayers()` | T6 rendering/state handling without changing player max health |
| Enemy count | Stock `_zm_utility::get_current_zombie_count()` plus queued zombies | Uses the map's zombie team and enemy filters |
| Timers | Seed elapsed time for late joiners; stop round watcher/reset on game over | T6 timer behavior; keep frozen timers frozen |
@@ -17,7 +17,7 @@ telemetry and leaderboard modules; neither includes bank or database modules.
| Telemetry | Global `httpPost(url, options)`; T5-parity queue + heartbeat + game_start/end + watchdog + log-level dvar; per-player `guid` comes from the persistent `player.guid` field (T5 uses `player getGuid()` directly); per-match `kills`/`headshots`/`downs`/`revives` read from `player.pers[]`, with missing or negative values reported as `0` | Stock T6 connection initialization populates `.guid` before notifying `connected`; stock `initpersstat` / `incpersstat` maintain match counters in `player.pers[]`, whereas T5 uses `player.stats[]`. Payload keys match T5 for downstream shape parity |
| Join | Port of T5 `tws_t5_join.gsc`; uses `level.spawnplayer` / `level.custom_spawnplayer` (lowercase) and `maps\mp\zombies\_zm::spectator_respawn`; readiness gated on `self.sessionstate == "spectator"` instead of T5's `self.initialized` | T6 stock spectator respawn hook lives in `_zm.gsc`; `self.initialized` is a T5 SP zombiemode marker that T6 stock does not populate the same way |
Common retains the T5 HUD constants, helpers and first-spawn dispatcher.
Common provides matching T5/T6 HUD layout constants, helpers and first-spawn dispatcher.
HUD again owns the `hud_game_over` notification fan-out. Lock again waits on HUD
notifications, applies T5's random password, and clears it on startup/game over.
The added password-preservation dvars and independent lock watcher are gone.
@@ -26,11 +26,30 @@ Common also listens for `.help` through the native `say` notification, independe
of first-spawn initialization so newcomers can view commands while spectating.
Each loaded command module registers its command and description with
`register_help_command()` during `init()`. Lazy registry initialization preserves
registrations regardless of module initialization order. Help uses client HUD
elements below the health bar, sharing the HUD's anchors to avoid overlap with
timers, zombie count and health numbers. Text is created once per connection and
reused; each request restarts a 12-second visibility timer. Disconnect cleanup
is independent of that timer. The command handlers retain their existing listeners.
registrations regardless of module initialization order. Common owns one reusable
service window beneath the fixed core. Help uses four commands per page in stable
order, with 12 seconds per page and automatic dismissal after the final page.
`.help` / `.commands` restart at page one. Help pauses record page time, and a
`.leaders` request during help replaces the pending replay from page one. Service
state prevents old requests from closing newer displays. Disconnect and game-end
cleanup are independent of page timing. The command handlers retain their
existing listeners, and help/records work without the HUD module.
Help reuses two multiline text columns and a muted command-column backdrop.
The service has 19 nonarchived elements independent of command/page count;
core + AFK use 15 + 1 archived elements. Hidden elements still occupy slots.
The [T6 player HUD structure](https://github.com/skiff/t6-gsc-helper/blob/50ff6cb7397c9376894a195f48118d1743812d1d/src/game/structs.hpp#L184)
has 31 slots in each bucket; it does not establish current Plutonium stock HUD
usage. Keep the live overlap/element-budget checks alongside the portable checks.
The core is created on connection for waiting spectators with placeholders, while
timer updates retain the existing spawn/round lifecycle. Connection-time creation
must not seed the match clock. Current/maximum HP remains visible at full health;
the former co-op name row is removed and AFK uses a reserved footer. Opening a
service never changes core position or height. HUD `1.2.0`, leaderboard `1.1.0`
and AFK `1.0.1` require matching common `1.2.0+`; deploy the changed scripts
together and restart the map. This introduces no native-plugin/backend dependency
or full server-process restart requirement.
AFK again listens to the native `say` notification, so it no longer needs plugin
chat registration. The additional T6 controls are only held while AFK; `.back`
@@ -49,7 +68,7 @@ The module is `tws_t6_leaderboard.gsc` in T6 and `tws_t5_leaderboard.gsc` in T5.
Common's existing
connection listener now also dispatches optional connection handlers after a
one-frame yield. Leaderboard waits for player readiness and uses a level-owned
HTTP cache, independent of the first-playable-spawn handlers. T6 spectators keep
HTTP cache, independent of the first-spawn handlers. T6 spectators keep
`hasSpawned` false, so T6 readiness uses session state and the intro-screen flag;
T5 sets `hasSpawned` for both playable and spectator spawns.
@@ -60,9 +79,10 @@ Mode/location combinations follow the
and Electric Cherry's map catalogue. Unknown selections require an explicit API
key instead of falling back to another variant sharing the engine map.
Validation for this change: 135 fixture/static checks pass using the actual
data-handling functions from both scripts with JavaScript engine-value shims.
All seven T6 scripts compile and assemble using a local Intel macOS driver built
Historical validation for the initial leaderboard change: 135 fixture/static
checks passed using the actual data-handling functions from both scripts with
JavaScript engine-value shims. All seven then-current T6 scripts compiled and
assembled using a local Intel macOS driver built
from gsc-tool 1.5.1 sources. PowerShell was unavailable, so `check.ps1` itself was
not executed here. T5 compilation and live plugin/gameplay checks were not run;
gsc-tool has no T5 backend. The production API could not be reached from this
@@ -137,15 +157,17 @@ wait for a normal round-start spawn, die, and verify `.join` is rejected.
Also check a round-1 participant, reconnecting, disconnect during setup, and
game over. Repeat on another T6 map; compile with the checker below first.
Local: `tools/check.ps1` compiles all seven files for T6 PC and checks shared
references and entry points. It requires PowerShell and gsc-tool. The `.help`
change passed the static entry-point/reference checks, but compilation and live
gameplay were not run. Compiler success does not certify runtime linking.
Local: `tools/check.ps1` compiles all eight files for T6 PC and checks shared
references and entry points. It requires PowerShell and gsc-tool. Run the
[shared HUD checks](../../README.md#hud-validation) for core/service behavior and
command regressions. Compiler success does not certify runtime linking.
Live checks after deploying:
1. Join, late-join, die/respawn, and reconnect: one HUD per player, correct corner
position, health/Juggernog changes, zombies remaining, timers frozen at game over.
1. Join, late-join, die/respawn, and reconnect: one core per player, fixed
upper-right position, spectator placeholders without an early clock start,
visible full/damaged HP, health/Juggernog changes, zombies remaining, and
timers frozen at game over. Test safe-area settings and different resolutions.
2. `.afk` blocks movement, shooting and grenades; `.back` restores them. Try rapid
toggles, a round transition, death/respawn and game over.
3. Lock fires at the threshold and clears on game over/restart. HUD must be installed.
@@ -153,12 +175,21 @@ Live checks after deploying:
4. Telemetry sends the initial occupied round and each new round to the existing
endpoint. Check server ID/player count, same-round joins and an unreachable API.
5. Repeat on the actual server maps, especially afterlife and special-enemy rounds.
6. Type `.help` and `.HELP` before first spawn, during play and while AFK: see
`.help`, `.afk`, `.back` and `.join` with descriptions, only on the requesting
player's screen below the health bar. Take damage so health numbers appear
and verify they do not overlap help. Repeat the command before 12 seconds
elapse: one list should remain visible until 12 seconds after the latest
request. Reopen after expiry and reconnect; verify no duplicates or leftovers.
Remove the AFK or Join module, restart the map and confirm its commands are
absent. Restore the modules and confirm `.afk`, `.back` and `.join` still
behave as before.
6. Type `.help`, `.HELP` and `.commands` before first spawn, during play and
while AFK: four commands per page, only on the requesting player's screen,
without moving or resizing the core. Verify 12 seconds per page and dismissal
after the final page; repeat on page two to restart page one. Remove optional
modules and restart the map to confirm their commands are absent. Restore
the modules and confirm their command behavior is unchanged.
7. Interrupt a record with help and check that its remaining page time resumes.
Repeat `.leaders` during help; only the latest replay should start from page
one after help closes. Check long names across pages, no records and
unavailable records. Reopen after expiry, disconnect/reconnect and end the
game during a service; verify no duplicates or leftovers. Repeat without HUD.
The stock T6 [HUD initialization](https://raw.githubusercontent.com/plutoniummod/t6-scripts/main/ZM/Core/maps/mp/gametypes_zm/_hud.gsc)
sets a nominal font height of 12; the corresponding
[font helper](https://raw.githubusercontent.com/plutoniummod/t6-scripts/main/ZM/Core/maps/mp/gametypes_zm/_hud_util.gsc)
uses `int(level.fontheight * fontscale)` for its height. The portable HUD checks
use that nominal box to prevent holder-row and AFK-footer overlaps. Exact glyph
extents and multiline spacing still need live validation, especially on T5.