285 lines
16 KiB
Markdown
285 lines
16 KiB
Markdown
# TWS T6 Zombies scripts
|
||
|
||
Plutonium T6 versions of the T5 server scripts. Defaults live in the scripts,
|
||
just like T5. The telemetry token is embedded in the reporter script; no
|
||
separate telemetry token config is required. The optional bank and moderation modules each need their own
|
||
private server token.
|
||
|
||
| File | Role | Dependencies |
|
||
| --- | --- | --- |
|
||
| `tws_t6_common.gsc` | Shared HUD values, helpers, paginated `.help`, service window, connection and first-spawn dispatchers | Stock T6 |
|
||
| `tws_t6_hud.gsc` | Unboxed timers, branding, zombies/health and per-player `.hud` visibility toggle | Common 1.4.0+, Plutonium r5334+ |
|
||
| `tws_t6_afk.gsc` | `.afk` / `.back`, protection, movement and weapon blocking | Common 1.4.0+ |
|
||
| `tws_t6_lock.gsc` | Lock at round 20; clear password on game over | Common, HUD |
|
||
| `tws_t6_telemetry.gsc` | Async queued game reports (game_start/heartbeat/round_change/game_end) | tws-t6-gsc-utils |
|
||
| `tws_t6_join.gsc` | `.join` chat command lets a spectator newcomer enter mid-match once | Common |
|
||
| `tws_t6_leaderboard.gsc` | Private map high-round record and every tied holder on connection | Common 1.2.0+, tws-t6-gsc-utils |
|
||
| `tws_t6_bank.gsc` | Persistent shared GUID bank | Common, telemetry, TWS plugin 1.2.0 |
|
||
| `tws_t6_moderation.gsc` | Optional controller-managed bans, mutes and live moderation | Common 1.2.0+, TWS plugin 1.3.0+ |
|
||
|
||
## Install
|
||
|
||
1. Copy the desired modules from the nine `tws_t6_*.gsc` files into
|
||
`Plutonium/storage/t6/scripts/zm/`. Update common along with HUD, leaderboard
|
||
and AFK when those modules are installed.
|
||
2. For telemetry, leaderboard, bank or moderation, install the [tws-t6-gsc-utils build](../plugins/README.md), based on upstream v3.1.1,
|
||
in `Plutonium/plugins/` and restart the server process. Moderation requires
|
||
plugin 1.3.0+ before its script is installed; see [moderation setup](../../docs/moderation.md). The other five scripts
|
||
do not require that plugin.
|
||
3. Ensure the API service's `EC_TELEMETRY_TOKEN` matches the token embedded in
|
||
the reporter; see [authentication setup](../../README.md#telemetry-authentication-t5-and-t6).
|
||
4. Restart the map to load script updates.
|
||
|
||
If upgrading from the earlier leaderboard filename, **remove
|
||
`tws_leaderboard.gsc` from the T6 server script directory** before installing
|
||
`tws_t6_leaderboard.gsc`, so both copies do not load.
|
||
|
||
If upgrading from the old direct-database bank, remove `tws_t6_db.gsc` and
|
||
replace the old `tws_t6_bank.gsc` with this release's file. Remove any
|
||
`exec server.example.cfg` added for that legacy version; configure the new
|
||
Electric Cherry bank using the private per-server token described below.
|
||
|
||
Source `.gsc` files load directly under Plutonium's
|
||
[documented T6 script layout](https://plutonium.pw/docs/modding/loading-mods/).
|
||
Keep the filenames and `scripts/zm` location so shared references resolve.
|
||
To omit telemetry, remove its script; disabling it at runtime does not remove
|
||
its plugin dependency during linking. The same rule applies to leaderboard.
|
||
|
||
## Player bank
|
||
|
||
Bank `2.0.2` requires plugin `1.2.0+` for startup version reporting and bounded
|
||
parser diagnostics. Install the DLL and restart the full server process before
|
||
loading these scripts. Follow the [diagnostic rollout and live checks](../../README.md#bank-diagnostics--tws-14).
|
||
|
||
The optional `tws_t6_bank.gsc` adds `.b`, `.d <amount|all>` and
|
||
`.w <amount|all>` and registers them in help. It requires common and telemetry
|
||
`1.0.0` or newer, the TWS t6 plugin `1.2.0`, Electric Cherry's bank API and
|
||
a private per-server credential. Follow [bank setup and recovery](../../README.md#player-bank-t5-and-t6),
|
||
including a full process restart for the plugin. Bank `2.0.0+` uses only
|
||
`https://ec.thewrightserver.net/api/bank` and ignores `tws_bank_url`.
|
||
Update EC agents to `1.9.1+` first. If the old endpoint differs, follow the
|
||
[endpoint upgrade procedure](../../README.md#upgrading-the-bank-endpoint):
|
||
an EC rebuild must settle legacy journals before the new scripts start.
|
||
When the endpoint already matches, only a map restart is required.
|
||
|
||
Bank `2.0.1` reads the persistent `player.guid` field used by telemetry and
|
||
converts it to a string before requests or journal writes. Existing strings
|
||
are preserved exactly; missing or invalid identities fail privately without
|
||
changing points. Stock T6
|
||
[`callback_playerconnect()`](https://github.com/plutoniummod/t6-scripts/blob/2d8440321602f22f63f5335817110d60ddf223d5/ZM/Core/maps/mp/gametypes_zm/_globallogic_player.gsc)
|
||
populates that field before the `connected` notification. Follow the shared
|
||
[identity and deployment checks](../../README.md#bank-identity-validation).
|
||
|
||
## Core HUD and service window
|
||
|
||
The unboxed core puts match time above round time at the upper left,
|
||
`TWS ZOMBIES | discord.tws.lol` at the top center, and zombies remaining above a
|
||
slim health bar at the bottom center. `N ZOMBIES` is one centered element at
|
||
the health track's midpoint, using uniform font scale `1.25` so the whole group
|
||
stays centered as the digit count changes. Its initial placeholder is
|
||
`-- ZOMBIES`. Current/maximum HP appears to the right of the bar only while
|
||
injured; it disappears at full health. The AFK indicator sits above the zombie
|
||
count. There are no panel backgrounds or timer labels.
|
||
Fullscreen X/Y anchors use the normalized `640 × 480` viewport directly and
|
||
bypass safe-area insets. Font scale is at least `1.0`; verify text fit, stock
|
||
HUD overlap and Plutonium tag clearance at each aspect ratio in-game.
|
||
|
||
The core is created once per connection, including for spectator newcomers
|
||
with placeholders until values are available. Creation does not seed the match
|
||
clock. It persists across death and respawn. Clocks, health and zombie-count
|
||
displays freeze at game over. Health fallbacks only affect the display and
|
||
never modify gameplay max health.
|
||
|
||
The exact, case-insensitive `.hud` command toggles your core and AFK indicator.
|
||
It defaults visible, keeps your choice across death/respawn on the current
|
||
connection/map, and resets visible on reconnect or map restart. Timers and data
|
||
continue updating while hidden; game-over values remain frozen. Help, records
|
||
and the stock HUD are unaffected. `.hud` requires the HUD module.
|
||
|
||
Common provides one unboxed upper-right service area below the Plutonium tag.
|
||
Records are right aligned, with `Map record | Round N` followed by up to three
|
||
holder lines; there is no replay footer or single-page counter. Help displays
|
||
the full nine-command list in aligned rows. Services remain private, leave the
|
||
core in place and work without the HUD module installed. See the
|
||
[shared layout and validation guide](../../README.md#core-hud-and-service-window-t5-and-t6).
|
||
Only the active service view holds HUD elements: 19 for nine-command help
|
||
(20 with a multi-page counter), or four for records (five with a multi-page
|
||
counter). Pages reuse elements; switching views or closing the service releases
|
||
them. Idle services hold no HUD elements, while the controller retains pending
|
||
requests and interruption/resume behavior. Core + AFK use 10 + 1 elements.
|
||
|
||
HUD `1.4.2` requires common `1.4.0+` and
|
||
[Plutonium r5334+](https://plutonium.pw/docs/changelog/#r5334) for its
|
||
`SetTextUnlimited` counter, updated only when the count changes. Deploy the
|
||
updated HUD script and restart the map on r5334+; no full server-process
|
||
restart is required. Older Plutonium revisions need client/server updates and
|
||
full restarts first. AFK `1.2.0` and leaderboard `1.1.0` remain compatible;
|
||
AFK still requires common `1.4.0+`. No new native-plugin or backend requirement.
|
||
|
||
## Map record announcements
|
||
|
||
`tws_t6_leaderboard.gsc` reads the public Electric Cherry API without credentials.
|
||
It works independently of telemetry and HUD, and privately announces records
|
||
once per connection, including newcomers waiting in spectator mode.
|
||
|
||
Map selection uses stock `level.scr_zm_ui_gametype` and
|
||
`level.scr_zm_map_start_location`, falling back to the corresponding
|
||
`ui_gametype` / `ui_zm_mapstartlocation` dvars when absent. For example,
|
||
`zstandard` + `town` selects `t6:zm_transit:town`, while `zclassic` + `transit`
|
||
selects TranZit. Survival, Grief and Turned variants follow Electric Cherry's
|
||
catalogue. An unknown mode/location is logged instead of guessing from the engine
|
||
map. Use `tws_leaderboard_map_key` for a custom registered selection if needed.
|
||
|
||
The plugin must expose `httpPost` (with the GET method override), `jsonParse`,
|
||
`typeof` and `formatString`. [Shared configuration, caching and validation](../../README.md#map-record-announcements)
|
||
apply to both versions. All T6 script filenames use the `tws_t6_` prefix.
|
||
|
||
## Chat commands
|
||
|
||
Type `.help` or `.commands` in chat to see the commands supplied by the loaded TWS modules and
|
||
a short description of each. The list is shown only to the requesting player,
|
||
including spectators who have not spawned. Commands are case-insensitive.
|
||
Help uses the unboxed upper-right service area. All nine installed commands
|
||
fit in one list with command and description columns. Additional registered
|
||
commands use pages of nine rows, with a counter only for multi-page lists.
|
||
Pages advance every 12 seconds and close after the last page. Typing either
|
||
command again returns to page one with a fresh timer. Both engines use
|
||
explicit row positions so T5 does not concatenate newline-separated text.
|
||
|
||
| Command | Description |
|
||
| --- | --- |
|
||
| `.help`, `.commands` | List available commands |
|
||
| `.hud` | Hide or show your core HUD and AFK indicator (HUD module required) |
|
||
| `.afk` | Pause with protection |
|
||
| `.back` | Return from AFK |
|
||
| `.join` | Join mid-round (newcomers only) |
|
||
| `.leaders` | Show the map record again (leaderboard module required) |
|
||
| `.b` | Check bank balance (bank module required) |
|
||
| `.d <amount\|all>` | Deposit points (bank module required) |
|
||
| `.w <amount\|all>` | Withdraw points (bank module required) |
|
||
|
||
Command modules register their commands during `init()` through
|
||
`tws_t6_common::register_help_command(command, description)`. If a module is
|
||
omitted, its commands are omitted from `.help`. Commands follow the order above,
|
||
independent of initialization order. Register new commands alongside their
|
||
module's initialization so the list stays current.
|
||
With all command modules installed, help shows one page of nine commands,
|
||
including the full `.d <amount|all>` / `.w <amount|all>` syntax. Removing HUD
|
||
removes `.hud` from the list.
|
||
The enabled leaderboard module registers `.leaders`, which replays the latest
|
||
cached map record privately. Repeating it restarts the record from the first page;
|
||
help pauses the record's remaining page time and resumes it after the final
|
||
help page. `.leaders` during help replaces the pending record replay from page one.
|
||
|
||
## Defaults, matching T5
|
||
|
||
- HUD values live in `tws_t6_common::common_config()`. That function and
|
||
`ensure_config()` came from T5; they initialize in-script values and do not
|
||
load a config file. Core and service overlays use fullscreen X/Y anchors in
|
||
normalized `640 × 480` coordinates to bypass safe-area insets.
|
||
- AFK uses T5's native `level waittill("say", message, player)` listener.
|
||
`.back` restores movement and weapons immediately, then ends protection after
|
||
two seconds. The T6 control/weapon fix remains in place.
|
||
- Lock uses T5's HUD round/game-over notifications. Default threshold is 20.
|
||
As in T5, it clears `g_password` at startup and game over.
|
||
- Telemetry is enabled by default and posts to
|
||
`https://ec.thewrightserver.net/api/telemetry`. Set `tws_server_id` to the exact,
|
||
case-sensitive Electric Cherry registry name; missing or overlong names
|
||
disable reporting with a console diagnostic. An embedded token matching the service's
|
||
`EC_TELEMETRY_TOKEN` (at least 32 characters) and an HTTPS URL are required as well.
|
||
|
||
The dvars already present in T5 are still supported: `tws_lock_round`,
|
||
`tws_server_id`, `tws_telemetry_url`, and `tws_telemetry_enabled` (`0` disables
|
||
telemetry). Earlier settings still override defaults; remove any old HTTP URL
|
||
override when upgrading. The reporter token lives in `level.telemetry_token`.
|
||
|
||
## Round telemetry
|
||
|
||
Telemetry runs directly in GSC using tws-t6-gsc-utils. Configure the exact Electric
|
||
Cherry registry name and full endpoint in your existing server configuration:
|
||
|
||
```cfg
|
||
set tws_server_id "t6_zombie_town_1"
|
||
set tws_telemetry_url "https://ec.thewrightserver.net/api/telemetry"
|
||
```
|
||
|
||
The script embeds the reporter token in `level.telemetry_token`; it must match
|
||
the API service's `EC_TELEMETRY_TOKEN` environment variable. Follow the shared
|
||
[authentication setup](../../README.md#telemetry-authentication-t5-and-t6). Every
|
||
request includes `Authorization: Bearer <token>` and `Content-Type:
|
||
application/json`. Token rotation requires updating and redeploying both reporter
|
||
scripts. Token and endpoint changes require a map restart.
|
||
|
||
It sends four event types over the life of a match, mirroring the T5 script:
|
||
|
||
| Event | When | Round in payload |
|
||
| --- | --- | --- |
|
||
| `game_start` | First playable spawn | omitted |
|
||
| `heartbeat` | Every 30s while the match is in progress | current round |
|
||
| `round_change` | Every new positive round | new round |
|
||
| `game_end` | `end_game` / `game_ended` / `intermission` | final round |
|
||
|
||
Each event payload includes `event`, `server`, `map`, `match`, `seq`, `round` (except `game_start`)
|
||
and a `players` array with `name`, `guid`, `kills`, `headshots`, `downs`, `revives`
|
||
and `score` plus `score_total` per player in stat reports. `game_start` includes
|
||
only player identity. `guid` reads the persistent `player.guid` field populated
|
||
by T6's stock connection initialization (T5 reads `player getGuid()` directly).
|
||
`kills`/`headshots`/`downs`/`revives` read
|
||
from T6's stock match counters in `player.pers[]`; missing or negative values
|
||
are reported as `0`. `score` is the player's current spendable `player.score`.
|
||
`score_total` reads `player.score_total`, the stock cumulative match score used
|
||
by the final scoreboard. Spending does not reduce it; stock grants can opt out
|
||
of adding to the total. Missing or negative totals report as `0`, independently
|
||
of the balance. Deploy Electric Cherry's receiver support before these scripts;
|
||
older payloads without totals remain valid and their totals are unknown.
|
||
|
||
Stock `end_game` yields before `player_intermission` replaces the balance with
|
||
the total. The reporter serializes both at the first end signal without yielding,
|
||
so retries and replay keep the original balance and total. Custom end sequences
|
||
must emit a supported end signal before overwriting the balance.
|
||
|
||
Delivery uses one in-flight request and a FIFO queue. Every match receives a
|
||
native-generated key; `seq` starts at 1 for `game_start` and increases at capture.
|
||
Start/end snapshots are saved to disk before sending and replayed before the next
|
||
start after map/process restarts. Transport failures, native timeouts, HTTP 429
|
||
and 5xx retain the head with 1–30 second backoff. Other 4xx are terminal. Round
|
||
and heartbeat failures remain best effort; waiting heartbeats collapse to the
|
||
newest snapshot. Acceptance requires 2xx plus the JSON boolean `ok: true`; logs
|
||
include `telemetry.timing.matchId` as `ec_match_id` when available.
|
||
|
||
The TWS plugin still enforces 5-second connection and 15-second transfer deadlines.
|
||
Increase `tws_telemetry_log_level` to `2` for capture/queue/response logging; set to
|
||
`0` for errors and recovery. **Deploy Electric Cherry #144 and the updated native
|
||
plugin before these scripts.** See the shared
|
||
[delivery and rollout notes](../../README.md#telemetry-delivery-and-rollout-t5-and-t6)
|
||
for outbox storage, error handling, limits and live validation.
|
||
|
||
## `.join` for newcomers
|
||
|
||
Late connectors who never got a spawn can type `.join` in chat to leave spectator
|
||
mode before the round ends, once per connection. `.join` is rejected if the player
|
||
has already played, if the game is not running, if no active player is alive, or
|
||
during intermission. The script hooks the stock `spectator_respawn` path via
|
||
`level.custom_spawnplayer`; it does not skip the map-authored spawn callback if
|
||
another mod installed one first.
|
||
|
||
## Validation
|
||
|
||
Run the shared [portable and live HUD checks](../../README.md#hud-validation)
|
||
for core placement, service pagination, record interruptions and command regressions.
|
||
|
||
To compile all nine scripts for T6 PC with gsc-tool:
|
||
|
||
```powershell
|
||
.\tools\check.ps1 -CompilerPath C:\path\to\gsc-tool.exe
|
||
```
|
||
|
||
Compilation does not verify engine/plugin linking or gameplay. T6 differences,
|
||
research sources and live checks are in [NOTES.md](NOTES.md).
|
||
|
||
## Moderation
|
||
|
||
Optional `tws_t6_moderation.gsc` 1.0.0 requires common 1.2.0 and the matching
|
||
plugin 1.3.0. See the [moderation contract](../../docs/moderation.md) for private
|
||
configuration, persistence, action results and deployment checks.
|