# maze32 WebSocket protocol v1 ## Limits and ordering - Endpoint: `/ws`. - At most six WebSocket connections are accepted: two players and four observers. - A text frame is at most 512 bytes. Binary frames are rejected. - Each connection may submit at most 20 messages in a one-second monotonic window. - The gateway uses a fixed 12-entry outgoing queue with 768 bytes per entry. - Client sequence numbers start above zero and strictly increase for the life of one WebSocket connection. Replayed or decreasing values are rejected. - Server sequence numbers strictly increase until reboot. Clients discard stale server messages. All messages use this envelope: ```json {"v":1,"type":"message_type","seq":1,"requestId":"optional","payload":{}} ``` Envelope keys may appear in any order except that `type` must precede `payload`. Unknown and duplicate keys are rejected. `requestId` is optional and is only echoed for correlation; it grants no authority. ## Client messages - `join`: `{"role":"player","name":"..."}` or `{"role":"observer"}`. Player names contain 1–32 UTF-8 bytes, have no control bytes or outer spaces, and are unique within the current lobby. - `restore`: `{"token":"32 lowercase hexadecimal characters"}`. - `suggest_name`: `{}`. - `start`: `{}`. Only connected Player 1 may use it, and both player slots must be connected. - `move`: `{"direction":"north|east|south|west"}`. Only a player in an active, unpaused match may submit movement intent. - `drop_key`: `{}`. Only a player in an active, unpaused match may submit the key-drop intent. - `heartbeat`: `{}` after a session has been joined or restored. ## Server messages - `session`: the private role result containing `role`, `slot`, and temporary `token`. The token is never included in a shared snapshot. - `name_suggestion`: an available humorous Russian player name. - `lobby`: the authoritative phase, revision, readiness, public player slots, connected observer count, and limits. - `countdown`: the single authoritative `[3,2,1]` event with common monotonic `startedAtMs` and `activationAtMs` values. It is sent to both players. - `active`: the exact authoritative activation instant. - `view`: a bounded chunk of a role-specific authoritative game projection. Observer chunks contain the complete maze and both player records, including their connection state; player chunks retain the fog-of-war boundary. - `pause`: identifies the disconnected player slot and its monotonic reconnect deadline. - `resume`: reports that both players are attached and authoritative gameplay has resumed. - `match_result`: reports the terminal winner or draw. - `ack`: successful heartbeat correlation. - `error`: a stable English `code` and Russian player-facing `message`. An observer session can receive snapshots but cannot issue `start`, `move`, or `drop_key`; attempts are rejected with `read_only` where applicable and logged by the gateway. Player tokens reserve their original slot after disconnection so a refresh can restore it. A player disconnect pauses the game for at most 60 seconds; restoration reattaches the same state, while expiry produces a draw. A disconnected observer token may be restored until its bounded slot is reused by a new observer, and observer disconnects never pause the match.