196 lines
14 KiB
Markdown
196 lines
14 KiB
Markdown
# T6 port notes
|
|
|
|
T6 is ported from T5. Both source trees contain common, HUD, AFK, join, lock,
|
|
telemetry, leaderboard and bank modules; neither includes direct-database modules.
|
|
|
|
## Differences retained for T6 and requested fixes
|
|
|
|
| Area | Difference from T5 | Reason |
|
|
| --- | --- | --- |
|
|
| 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 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 |
|
|
| AFK | Maintain control freeze, disable guns/grenades, guard player state and stale grace threads | Requested movement/shooting fix; retain `.afk` / `.back` and two-second grace |
|
|
| 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 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.
|
|
|
|
Common also listens for `.help` through the native `say` notification, independent
|
|
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. 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`
|
|
releases them before the protection grace period. Restoration is deferred during
|
|
death/laststand/intermission until active play. Other mods controlling the same
|
|
invulnerability or weapon flags can still conflict and need live testing.
|
|
|
|
The existing optional T5 dvars remain. Leaderboard adds the three settings
|
|
documented in the [shared README](../../README.md#map-record-announcements).
|
|
`common_config()` and `ensure_config()` are original T5 in-memory HUD helpers,
|
|
not an external configuration system.
|
|
|
|
## Leaderboard join announcements
|
|
|
|
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-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.
|
|
|
|
T6's active `scr_zm_ui_gametype` / `scr_zm_map_start_location` fields come from
|
|
[stock `_zm.gsc`](https://github.com/plutoniummod/t6-scripts/blob/2d8440321602f22f63f5335817110d60ddf223d5/ZM/Core/maps/mp/zombies/_zm.gsc).
|
|
Mode/location combinations follow the
|
|
[T6 server configurations](https://github.com/xerxes-at/T6ServerConfigs/tree/master/localappdata/Plutonium/storage/t6/gamesettings)
|
|
and Electric Cherry's map catalogue. Unknown selections require an explicit API
|
|
key instead of falling back to another variant sharing the engine map.
|
|
|
|
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
|
|
environment. See the shared README for the live validation cases.
|
|
|
|
## Verified primary sources
|
|
|
|
- [Plutonium loading guide](https://plutonium.pw/docs/modding/loading-mods/): T6
|
|
source scripts load from `storage/t6/scripts/zm`.
|
|
- [Entry-point lifecycle](https://plutonium.pw/docs/modding/gsc/new-scripting-features/):
|
|
`main()` runs early; `init()` runs after gametype startup. Empty `main()` must
|
|
not call `init()` and duplicate initialization.
|
|
- [Plutonium changelog, r2234](https://plutonium.pw/docs/changelog/): documents T6
|
|
`level waittill("say", message, player)`.
|
|
- [Stock T6 Zombies](https://github.com/plutoniummod/t6-scripts/blob/2d8440321602f22f63f5335817110d60ddf223d5/ZM/Core/maps/mp/zombies/_zm.gsc):
|
|
round state, `end_game`, invulnerability, and stock control resets.
|
|
- [Stock zombie utility](https://github.com/plutoniummod/t6-scripts/blob/2d8440321602f22f63f5335817110d60ddf223d5/ZM/Core/maps/mp/zombies/_zm_utility.gsc):
|
|
map-aware enemy counting.
|
|
- [Released plugin HTTP implementation](https://github.com/alicealys/t6-gsc-utils/blob/v3.1.1/src/component/http.cpp):
|
|
global `httpPost(url, options)` takes an options array with `body` and `headers`.
|
|
Its positional README example does not match this implementation.
|
|
Completion is `done(response, success, error)`; success reports transport only.
|
|
- [Plugin JSON implementation](https://github.com/alicealys/t6-gsc-utils/blob/v3.1.1/src/component/json.cpp):
|
|
`jsonSerialize` handles the event payload.
|
|
|
|
Do not create a dummy `http.gsc`. An unresolved `httpPost`/`jsonSerialize` means
|
|
the installed server/plugin must be checked. Installing a DLL requires a full
|
|
server-process restart, not just a map restart.
|
|
|
|
## Telemetry reboot investigation
|
|
|
|
The T5 and T6 implementations are not runtime-verified equivalents. In particular,
|
|
[T6 plugin v3.0.4](https://github.com/alicealys/t6-gsc-utils/blob/v3.0.4/src/component/http.cpp)
|
|
expects `httpPost(url, body, headers)` and notifies only the response body;
|
|
v3.1.1 expects `httpPost(url, options)` and also provides success/error values.
|
|
The current script targets the [TWS build](../plugins/README.md) based on v3.1.1,
|
|
which appends diagnostics and enforces native HTTP deadlines. Switching the function name does not establish
|
|
compatibility with an unknown installed DLL.
|
|
|
|
Console markers identify `main`, `init`, round serialization, HTTP invocation,
|
|
handle return and completion. They do not log the URL or response body. If startup
|
|
fails before `main`, inspect the first linker/plugin error, not the last supervisor
|
|
restart message. If no occupied positive round was observed, this script has not
|
|
called JSON serialization or HTTP yet.
|
|
|
|
Earlier live validation: the operator confirmed successful server startup and
|
|
Fleet delivery with the original direct reporter. The earlier reboot cause was
|
|
not established; logging alone should not be treated as a proven fix.
|
|
|
|
To recover the server while investigating, move `tws_t6_telemetry.gsc` outside the
|
|
autoload directory. The enable dvar cannot bypass unresolved native functions
|
|
at link time. The other four TWS modules can run without telemetry.
|
|
|
|
## Checks
|
|
|
|
### Newcomer eligibility
|
|
|
|
The stock [`_zm_gametype::onspawnplayer`](https://github.com/plutoniummod/t6-scripts/blob/2d8440321602f22f63f5335817110d60ddf223d5/ZM/Core/maps/mp/gametypes_zm/_zm_gametype.gsc)
|
|
can schedule `spawnspectator` after 0.05 seconds while
|
|
[`_globallogic_spawn::spawnplayer`](https://github.com/plutoniummod/t6-scripts/blob/2d8440321602f22f63f5335817110d60ddf223d5/ZM/Core/maps/mp/gametypes_zm/_globallogic_spawn.gsc)
|
|
emits `spawned_player` at frame end. That event alone does not prove gameplay.
|
|
Join `1.0.1` waits 0.1 seconds before checking session state and keeps listening
|
|
after setup spectator spawns. `killed_player` also consumes eligibility so a
|
|
death during that interval cannot restore newcomer access. The common dispatcher
|
|
still starts each registered module once per connection.
|
|
|
|
Run `node tools/check_join.mjs` for portable lifecycle and request fixtures.
|
|
These execute the join script with engine shims, not a GSC VM. Live validation:
|
|
join Farm Survival during round 3 and remain spectating, use `.join` once, then
|
|
try repeated requests, death, and subsequent rounds. On a fresh connection,
|
|
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 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 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.
|
|
T5 semantics intentionally clear an existing password at startup.
|
|
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`, `.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.
|