feat(lobby): enter the game immediately and wait for the opponent inside it
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 45s
CI / gate (pull_request) Successful in 1s
CI / deploy (pull_request) Successful in 1m4s

Quick auto-match no longer waits on a separate screen: Enqueue opens a real game seating the caller with an empty opponent seat (new game status 'open') and the player enters it at once. A second human searching the same variant+rule joins that open game; otherwise a background reaper seats a robot after a 90s + random 0-90s wait, pushing a new in-app opponent_joined event that fills the opponent card and re-enables resign and chat in place.

Matchmaking state is now the open games in the database (the in-memory pool, lobby.poll and lobby.cancel are gone), serialised by a per-bucket advisory lock. While a game is open the starter may move on their turn, but resign, chat and nudge are refused; the lobby and opponent card show "searching for opponent".

Schema edited in the baseline (no prod data): 'open' status, nullable game_players.account_id for the empty seat, and a games.open_deadline_at stamp; jet code regenerated.
This commit is contained in:
Ilia Denisov
2026-06-12 16:00:22 +02:00
parent 10dc1f0d48
commit c305363ccd
42 changed files with 1248 additions and 768 deletions
+12 -8
View File
@@ -42,9 +42,9 @@ nudge) приходят от бота **этой партии** — по язы
авто-подбор; без друзей, статистики и истории); заброшенный гость, не вошедший ни
в одну игру и простаивавший дольше окна удержания, удаляется сборщиком. Пока приложение открыто, клиент
держит живой стрим и получает обновления в реальном времени — ход соперника, ваш ход,
чат, nudge и найденный матч. Каждое обновление приходит самим событием и применяется на месте без
перезагрузки — доска обновляется бесшовно, а найденная или приглашённая игра открывается мгновенно. Когда приложение **закрыто**, выбранные внеприложенческие
события (ваш ход, конец партии, nudge, найденный матч, приглашение или заявка в друзья)
чат, nudge и подключение соперника к игре, в которой вы ждёте. Каждое обновление приходит самим событием и применяется на месте без
перезагрузки — доска обновляется бесшовно, а приглашённая игра открывается мгновенно. Когда приложение **закрыто**, выбранные внеприложенческие
события (ваш ход, конец партии, nudge, приглашение или заявка в друзья)
приходят вместо этого **уведомлением в Telegram** — если только игрок не оставил
уведомления только в приложении (настройка профиля, **включена по умолчанию**).
Уведомление «ваш ход» называет соперника и пересказывает его последний ход — слово и
@@ -87,9 +87,13 @@ nudge) приходят от бота **этой партии** — по язы
читаются как «Scrabble»/«Скрэббл», а Erudit — «Erudite»/«Эрудит» (по языку интерфейса),
и это же имя выносится в заголовок экрана игры. Это ограничивает только **старт** новой игры — и авто-подбор, и
приглашение друга, — поэтому игрок по-прежнему видит и играет существующие игры на
любом языке. Авто-подбор (всегда 2 игрока)
встаёт в пул по варианту и сводится со следующим ожидающим человеком; через 10 с
без человека подставляется робот. Для русских игр (авто-подбор или приглашение) на экране
любом языке. Авто-подбор (всегда 2 игрока) сразу **помещает вас в игру, и вы ждёте соперника прямо
в ней**: если ваш ход — вы уже можете ходить, иначе просто рассматриваете свои фишки. Пока соперник не
присоединился, на карточке соперника (и в строке игры в лобби) написано **«Поиск соперника...»**, а
сдача, чат и nudge недоступны. Другой игрок, ищущий тот же вариант и правило, присоединяется к вашей
игре; если такого нет — через **1,53 минуты** свободное место занимает робот, так что игра всегда
стартует, и экран новой игры подсказывает, что можно закрыть приложение на время ожидания и вернуться
позже. Для русских игр (авто-подбор или приглашение) на экране
новой игры есть опция **«Несколько слов за ход»** (по умолчанию **выключена**): выключена —
упрощённое **правило одного слова**: настоящим словом должно быть только слово, выложенное
вдоль линии хода, а случайные перпендикулярные слова игнорируются и не засчитываются;
@@ -126,8 +130,8 @@ nudge) приходят от бота **этой партии** — по язы
предпросмотр счёта и отправка доступны лишь в собственный ход.
### Робот-соперник
Если авто-подбор не находит человека за десять секунд, свободное место занимает
робот-соперник, и партия стартует без ожидания. Он задуман неотличимым от человека:
Если авто-подбор не находит человека за время ожидания (1,5–3 минуты), свободное место в игре,
в которой вы уже ждёте, занимает робот-соперник. Он задуман неотличимым от человека:
один раз за партию решает, играть ли на победу (примерно в 40% случаев, так что
человек выигрывает большинство партий), целится в близкий счёт, а не в разгром или
поддавки, и ходит с человеческим темпом — чаще короткие раздумья, изредка долгие, и