mancala/docs/specs/game-history/requirements.md
Halit Aksoy b94c9336dd docs: document game history and update the TODO
- Backend README: DATABASE_URL, VALKEY_URL, the new routes and how the
  backend behaves when Postgres or Valkey is down
- TODO: drop the fixed spectator and memory bugs, add game history on
  mobile, a page with all games, single-instance limits, backups and the
  new .env variables
- Spec marked as implemented, all tasks ticked
2026-10-16 00:36:48 +03:00

90 lines
5.4 KiB
Markdown

# Game history and live games: requirements
Status: implemented on branch `feature/game-history` (based on `feature/keycloak-auth`).
Scope: backend and web app. The mobile app is out of scope (see `TODO.md`).
## Goals
Every game is saved. Players can come back to a game in progress, see their past games, watch popular games live
from the home page, and step through the moves of any game, finished or in progress.
## Terms
- **Live game**: a game that is being played right now.
- **Finished game**: a game that has ended for any reason (see R3).
- **Spectator**: a user, other than the two players, who has the game page open. Home page previews do not count.
- **Popularity**: number of spectators; for finished games, the highest number of spectators the game had at once.
## Requirements
### R1. Every game is saved
- R1.1 When a game ends, it is stored permanently with its players (id, name, guest flag), result, end reason,
start and end time, every move (player, pit, board after the move, rule events, time of the move), final
board, peak spectator count and number of distinct spectators.
- R1.2 Games in progress survive a backend restart or deploy: after the backend starts again, players who reconnect
continue from the same position, with the same turn.
- R1.3 If the database or the cache is unreachable, games can still be played. A game that could not be saved
when it ended is saved later, once the database is reachable again.
### R2. Ongoing game
- R2.1 A logged-in user (guest or account) who is a player in a live game sees, at the top of the home page, a
banner with the opponent's name, whose turn it is, and a **Continue** button that opens the game.
- R2.2 This works from any device or browser where the user is logged in with the same identity.
- R2.3 Starting a new game while a game is in progress is not possible: the user is told they have a game in
progress and is offered to continue it.
### R3. How games end
- R3.1 **Completed**: the game ends by the rules; the player with more stones in their store wins, or it is a draw.
- R3.2 **Left**: a player who leaves the game loses; the other player wins.
- R3.3 **Timeout**: if the player whose turn it is has been offline for 5 minutes while the opponent is online,
the opponent wins. While the opponent is offline on their turn, the waiting player sees a countdown.
- R3.4 **Inactive**: if both players have been offline for 30 minutes, the game ends without a winner.
### R4. Home page: live and popular games
- R4.1 The home page shows up to 5 live games, most spectated first, each as a preview of the real board with the
players' names and the spectator count.
- R4.2 Previews update live as moves are made, without reloading the page.
- R4.3 If no game is live, the same section shows the 5 most spectated finished games instead, titled as popular
games rather than live games.
- R4.4 Clicking a live game opens it in spectator mode; clicking a finished game opens its replay (R7).
- R4.5 Viewing previews does not change any game's spectator count.
### R5. Home page: my recent games
- R5.1 A logged-in user sees their last 3 finished games in a separate section: opponent, result from their point
of view (won / lost / draw, and why if the game did not end by the rules), final score, date and a preview of the
final board.
- R5.2 Clicking a game opens its replay.
### R6. Move history during a live game
- R6.1 Players and spectators of a live game see the list of moves made so far. Each entry shows the move number,
the player, the pit, and what happened: extra turn, capture, stones added to the player's store, game over.
- R6.2 New moves are appended as they happen.
- R6.3 Selecting a move (or using the arrow keys) shows the board as it was after that move. A banner says which
move is shown and offers **Back to live**. The game keeps going in the background.
- R6.4 While an earlier position is shown, the pits cannot be played. If it becomes the user's turn, the banner says
so.
### R7. Replay of a finished game
- R7.1 Opening a finished game shows its final position, the result and a **Watch from start** button.
- R7.2 Controls: first move, previous move, play/pause, next move, last move, speed (1x, 2x, 4x), and a timeline to
jump to any move. Arrow keys step through moves, space plays or pauses.
- R7.3 Stepping forward animates the move the same way as in a live game; jumping (backwards, timeline, move list)
shows the position without animation.
- R7.4 The move list from R6.1 is shown and can be used to jump to a move.
- R7.5 A link can point to a specific move (`?move=12`).
- R7.6 A player who replays their own game sees the board from their side.
- R7.7 The game's duration is shown.
### R8. Visibility and privacy
- R8.1 Finished games are public: anyone with the link can open them, and popular finished games appear on the
home page with the players' names.
- R8.2 "My recent games" and the ongoing-game banner are only shown to the user they belong to.
- R8.3 Ids of players who use the legacy userKey login (the current mobile app) are secrets. They are never exposed
in finished games, popular lists or live previews; a derived public id is shown instead.
## Out of scope (TODO)
- Mobile app support.
- A page with all of a user's games (only the last 3 are shown).
- Showing deleted accounts differently.
- Live game previews and lists across several backend instances (the backend runs as a single instance).