feat(play): a bot plays for a player who drops; tournaments wait, then rule
Casual online games: a player gone 30 s gets a ring on the other screen
(no claim button); at 60 s a bot plays their seat until they are back, and
the game goes on to its natural end. Nobody is handed a win for a drop.
- Chess: the server plays the absent side (game.php standin_move: the
engine near their rating; the caller never picks the move), through the
normal move path, so clock and position checks apply. includes/chess.php
chessApplyUci() applies the engine's move (castling, en passant,
promotion, counters).
- Backgammon: the client still at the table plays the seat with the bot
and publishes each action tagged with the seat it was for; a client that
comes back to actions played for it rebuilds from the snapshot.
- Ludo: three silent turns no longer end a casual game; the table's bot
keeps the seat. Domino already played gone seats; it now never ends a
casual game on a drop.
- A player still away when the game ends is not paid (no AFK farming).
- A "they left" claim while the other player is plainly at the table is
refused by the server in every game.
- Casual tables everyone left 15+ minutes ago are closed by the scheduler
(unpaid), and bot games idle a day; 184 rows had been stuck in progress.
Tournament games: no bot. The tournament sets how long to wait and what
then: a forfeit, or a draw (chess). The ring counts the tournament's wait,
the server checks the absence itself (match_presence), and the scheduler
applies the rule when no client is left to claim it.
Tests: tests/play/standin-api.mjs (server rules, chess), a backgammon
stand-in section; resume, online and tournament suites pass.
Co-Authored-By:
Claude Opus 5.5 <noreply@anthropic.com>
Showing
includes/match-sweep.php
0 → 100644
tests/play/standin-api.mjs
0 → 100644
Please register or sign in to comment