Files
maze32/docs/PROTOCOL.md
T

4.6 KiB
Raw Blame History

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:

{"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"}.
  • 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.
  • restart: {}. Only connected Player 1 may reset a finished match, and both players must be connected. Sessions are preserved while a new authoritative maze and game state are created.
  • leave: {}. Revokes only the authenticated sending session. A player leaving any non-waiting match phase, including a finished result, cancels that match and returns remaining sessions to the waiting lobby; observer and waiting-lobby departures release only that session.
  • 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.
  • 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. Each projected cell carries compact Player 1 and Player 2 trail ownership masks for its east and south edges only when both edge endpoints are authorized.
  • 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.
  • reset: reports the authoritative return from a finished match to the waiting lobby.
  • ack: successful heartbeat correlation. A heartbeat acknowledgement has payload.command set to heartbeat and a bounded integer payload.handlingMs measured only by the ESP monotonic clock while it prepares that acknowledgement.
  • 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.

Runtime diagnostics

GET /diagnostics returns bounded operational counters and internal-memory samples without exposing session tokens, Wi-Fi credentials, or hidden maze state. Counters cover connection and queue high-water marks, sent/dropped/ failed messages, malformed and rate-limited input, accepted game commands, match cycles, maximum WebSocket handler/send duration, and current/minimum internal free heap and largest block. The response also publishes the fixed limits used by the Milestone 010 physical stress client.