feat(observer): add observer mode and disconnect recovery

This commit is contained in:
2026-09-05 21:19:52 +03:00
parent d042c3ce90
commit ffdaa299bc
23 changed files with 988 additions and 43 deletions
+19 -6
View File
@@ -33,10 +33,12 @@ is only echoed for correlation; it grants no authority.
- `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.
No Milestone 005 maze or movement messages are implemented by this milestone.
## Server messages
- `session`: the private role result containing `role`, `slot`, and temporary
@@ -47,10 +49,21 @@ No Milestone 005 maze or movement messages are implemented by this milestone.
- `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`. Player
tokens reserve their original slot after disconnection so a refresh can restore
it. A disconnected observer token may be restored until its bounded slot is
reused by a new observer.
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.