# Player moderation **Players → Moderation** provides player search, warnings, private messages, kicks, announcements, bans, mutes, case records and private history. Restrictions can cover a server, a game or the fleet. Saving a restriction records the policy; the coverage table shows whether game runtimes have synchronized it. ## Access Administrators manage all moderation controls and configure integrations. Moderators can read private history, create notes/cases, send live actions, and issue server/game restrictions lasting at most seven days. They can revoke their own server/game restrictions originally lasting at most seven days. Applying or revoking permanent, longer or fleet restrictions, and revoking another staff member's restriction, require Administrator access. These limits also apply after an administrator becomes a Moderator. Super Viewers can inspect moderation but cannot change it. Operators and Viewers cannot read private moderation data. Moderator does not grant fleet operation, script, plugin, credential or account-management privileges. Assign Moderator through **Admin → Users**. Existing users retain their roles; changing a role revokes that user's sessions. Each service rechecks current authorization, including immediately before delivering a queued live action. ## Player identity and restrictions Select a player from Moderation, a live scoreboard or a player profile. Search matches known aliases as well as GUIDs. A display name never identifies a restriction target. Manually entered GUIDs can have case records and restrictions before gameplay is observed; their first/last seen dates remain **Not recorded**. IDs remain strings. Numeric game IDs are normalized without losing precision; T6 RCON hexadecimal IDs have a separate conversion rule. Historical chat links search for the raw log identity because its encoding is not assumed. Confirm a known player identity before applying a restriction. Fleet restrictions require the same numeric account ID to have been observed in both games. Otherwise use game scope. Every restriction has a player-visible reason, optional private note, scope, expiry, creator and revision. Reasons and live messages must fit in 240 UTF-8 bytes. The native adapter replaces console control characters in displayed text. Overlapping restrictions remain independent: revoking one mute does not cancel another active mute. Revocation requires a reason and the current revision; concurrent changes require refreshing before another decision. Server scope follows a logical server registration across instance replacement or rebuild. Deleting and later registering the same server name creates a new registration, which does not inherit the old server-scoped restriction. Game/fleet policies apply to every connected compatible runtime in that scope, including newly provisioned servers. A new runtime must synchronize before it has a complete policy; provisioning readiness alone does not prove moderation coverage. The initial limit is 1,000 active restrictions across the controller. ## Enable the game integration The controller requires `EC_PUBLIC_URL` to be a public HTTPS origin. The host agent must advertise `moderation.configure` (agent 1.11.0+). Install the matching TWS moderation script 1.0.0, common 1.2.0+, and TWS native plugin 1.3.0+ from `tws-zombies-scripts` for each game. New native plugins require a full game-server process restart. Use the normal release/beta workflow and validate one T5 Zombies and one T6 Zombies instance before fleet rollout. New launches/rebuilds on capable agents receive a private moderation config when `EC_PUBLIC_URL` is configured. Existing instances can use **Enable integration** in Moderation. This queues a typed operation that writes the fixed private config and loads its dvars, without restarting gameplay. Existing startup persistence uses the verified private bank config; older instances without that bootstrap must be rebuilt. Installed moderation scripts retry missing configuration. The private file `configs/electric_cherry_moderation.cfg` contains the HTTPS endpoint, generation and a separate per-instance credential. It is excluded from shared artifacts, file reads, drift scans, logs and operation receipts. Game credentials are distinct from bank, telemetry and host credentials. They only authorize the active immutable instance generation; retirement/rebuild revokes the previous generation's access. Older agents retain ordinary server launches, but cannot provide this integration. Coverage states describe runtime communication: - **Policy current:** a fresh runtime supports both bans and mutes and has acknowledged the current policy revision. - **Pending:** the runtime is connected but has not acknowledged the latest revision or does not support both bans and mutes. - **Offline:** no runtime synchronization has arrived for more than 15 seconds. - **Unavailable:** this instance generation has not connected. Policy current is not proof that an engine mute command took effect. The runtime reports supported capabilities; unsupported live actions stay unavailable. Native kick/mute command behavior and voice/text suppression require testing on the deployed Plutonium build. A disconnected host cannot receive a new ban or revocation until it reconnects. ## Live actions and offline enforcement Live actions expire after 30 seconds and target the runtime's exact player connection. A reconnect, reused slot, changed generation or revoked moderator access prevents stale dispatch. Browser retries preserve the request identity. The native adapter journals one-time actions before dispatch and never executes the same action ID twice, including after restart. Queued actions can become delivered, confirmed, failed, expired or unknown. An expired undelivered action did not run. Unknown means delivery occurred but the result could not be established; do not assume the action failed. A durable late receipt can resolve an unknown outcome. Confirmation of a message means server dispatch, not proof the recipient read it. Kick confirmation requires an observed disconnect. The native runtime caches the complete applicable policy on persistent storage, scoped to the server, endpoint, generation and credential fingerprint. Cached bans/mutes continue through controller outages and expire using the host clock. Keep host time synchronized. A ban disconnects a player after connecting; it is not a pre-authentication admission filter. The shared connection handler and a 500 ms reconciliation loop enforce it, retrying still-connected banned players every five seconds. No native `ban.txt` entries are rewritten. Preserve `tws-moderation/t5/` or `tws-moderation/t6/` in the game working directory. The cache includes an increasing runtime session counter that prevents an older process from replacing the active player roster. Losing or rolling back this cache requires a generation rebuild with a new credential before synchronization can resume; re-enabling the same integration does not reset the counter. Corrupt caches and failed durable writes stop new actions and require operator investigation. A controller restored to an older policy revision cannot silently replace a newer cached revision; review the restore and integration before resetting its cache or credentials. ## Cases, evidence and review Create a case for a report, investigation or appeal. Each case has a dedicated, shareable page with the player identity, evidence, staff notes, linked restrictions, and an activity timeline. These pages require moderation access. Give a case a priority and assign it to an eligible administrator or moderator. Filter the case queue by status, priority, or assignment; active cases appear first, ordered by priority and most recent update. Move active cases between **Open**, **In review**, and **Escalated**, recording a reason for workflow changes. Close a case with one of these outcomes: **Resolved**, **Dismissed**, **Warning issued**, **Restriction applied**, **No action needed**, **Duplicate**, **Appeal upheld**, or **Appeal denied**. Every decision requires a reason. Reopen a closed case when new evidence or an appeal needs review; earlier decisions remain in its history. Editing case details does not reopen a case. Apply a ban or mute directly from an active case. The case fixes the target game and GUID and records the resulting restriction alongside the evidence. The same role, scope, and duration limits apply as elsewhere in Moderation. Applying a restriction leaves the case active so staff can finish reviewing it. Selecting a closure outcome records a decision; it does not itself send a warning, create a restriction, or revoke one. Linked restrictions can be revoked separately with the required permission and reason, including after a case closes. Reopening a case also leaves its restrictions in place. Check enforcement coverage after applying or revoking a restriction. Staff notes are explicitly labeled as notes. In match chat, select up to 100 messages and choose **Attach to case** to open a case or add them to an existing case for the selected subject. Select at least one message from that subject; messages from other participants can be selected alongside it. Each attachment preserves selected messages and, by default, three surrounding messages on either side, with names, GUIDs, original timing, and highlighted subject messages. The selection preview shows the excerpt before saving. Server verification uses stable archived message identifiers; repeated text remains separate occurrences, and attaching the same selected messages again does not duplicate evidence. Exact-text attachments remain available and include every matching occurrence, without the former ten-occurrence limit. Snapshots remain readable after source-match cleanup. Unknown or estimated timestamps remain such; the snapshot does not turn them into exact observations. Unarchived or already deleted chat cannot be attached as verified evidence. Case decisions, edits, and restrictions check the current revision; refresh before retrying a decision if another staff member has changed the case. Evidence, restrictions and append-only moderation events survive source-match cleanup and server deletion. They currently have no automatic retention cleanup. Authentication audit cleanup does not remove moderation history. Correct decisions by reopening, adding notes, or revoking restrictions; there is no history-erasing delete endpoint. Leaderboard disqualification, bank balance changes, automatic escalation and a public report/appeal portal are separate features. This workflow supports staff review of reports and appeals without exposing private evidence publicly. ## Development and acceptance Controller tests cover permission boundaries, migrations, idempotency, exact instance credentials, stale connections, expired actions, late receipts, restriction expiry/revocation, policy coverage and evidence preservation. Agent tests cover private configuration delivery and secret redaction. Companion native tests exercise real policy/journal code and adapters with engine shims. Before deploying, build the x86 native plugins on Windows and validate both games: duplicate names, account reconnects, slot reuse, kick reasons, voice/text mute/unmute, overlapping restrictions, map/process restart, new server policy sync, expiry, revocation, controller outage and persistent-storage failure. Portable tests cannot establish the live Plutonium ABI or engine behavior. Package and offline-sign the agent release before publishing it; local builds remove any stale manifest signature and do not sign or deploy the release.