ADR-0014 · Каталог ботов «сыграть с человеком» — ленивое создание игры по клику
Статус: предложено · 2026-07-23 (эпик play-api + SPA, issue TBD). Развивает ADR-0009 (Bot-API), опирается на ADR-0013 (webhook) и ADR-0010 (тиры идентичности).
Контекст. Serverless/webhook-боты на Cloud Run со scale-to-zero (gcp/expectimax-onnx-3, gcp/scala-monte-carlo, cloudflare) не могут держать постоянный лоббийный seek: у seek’а TTL (~2 мин, Lobby), его надо поллить и перевыставлять, а у scale-to-zero процесса нет фонового цикла — он просыпается только на входящий вебхук. House-боты держат стендинг-сики только потому, что это всегда-живые процессы. При этом play-api уже доставляет ходы на вебхук для любой игры, где место занял бот (Webhooks-deliverer), независимо от того, как игра создана. Значит «организатор игры» существует — не хватает лишь ленивого триггера от человека, дружащего со scale-to-zero.
Решение. Каталог доступных ботов + ленивое создание игры по клику. Бот помечается флагом open_to_humans (независим от on_ladder); каталог = выборка по флагу, живой seek не держим. Человек кликает бота → play-api будит его handshake’ом (scale-to-zero просыпается) и проверяет живость → человек конфигурирует игру → play-bot сажает игру гость+бот через существующую GameRegistry.create; вебхук-deliverer дальше гоняет ходы сам. Keeper’ы/стендинг-сики для этих ботов не нужны.
Детали:
- Флаг
open_to_humans(миграция + store). Ставится и ботским токеном (POST /bot/open-to-humans, как ladder-join), и админ-путём — админ-путь обязателен: покрывает ботов без сохранённого токена (напр.expectimax-onnx-3). - Поле
descriptionу бота — для карточки каталога (алгоритм/платформа). - Эндпоинты:
GET /lobby/bots(каталог:team/name/rating/rd/provisional/description);POST /lobby/bots/{team}/{name}/wake(handshake →{alive}, кэш ~30–60 c, щедрый таймаут под cold start);POST /lobby/play-bot {team,name,timeControl,color}(гостевой; timeControl обязателен,Unlimitedотклоняется). - Конфиг игры: время (обязательно) — пресеты
1m+1s,3m+3s,5m,5m+5s(дефолт),10m,10m+10s(микс Fischer/SuddenDeath); цветRandom(деф.) /White/Black; стартовый DFEN — форвард-совместимый параметр на будущее (нужна поддержка старта комнаты из произвольного DFEN — вне MVP). - UX: панель конфига показываем сразу (с дефолтами), кнопку «Старт» активируем по
alive— человек выбирает опции, пока бот холодно стартует (JVM+ONNX ~секунды); задержку 1-го хода прячем pre-warm’ом (handshake на клике) и статусом «бот просыпается…». - Лимит: 1 живая human-vs-bot игра на гостя (bounds Cloud Run от спама).
Границы MVP. House-ботов не мигрируем — их open-tables/сики оставляем как есть, пока нет живого трафика (так проще; объединение с каталогом — позже). Каталог наполняем вебхук-ботами (у них сейчас вообще нет способа звать людей). DFEN-старт — позже. Переключение >1 игры у гостя — позже (пока лимит 1; понадобится список «мои активные игры» + навигация).
Последствия.
- Ноль работы в простое для serverless-ботов: бот молчит, пока не кликнули; cold start на 1-м ходу поглощают часы. Без keeper’а/Scheduler’а и без per-op токен-возни (у стендинг-сика токен нужен на каждый перевыпуск).
- Liveness-по-клику: игру против уснувшего/мёртвого бота не сажаем (нет форфейтов на старте).
- Масштабируется: каталог из N ботов в простое = $0; N стендинг-сиков требовали бы N keeper’ов.
- Цена: продуктовая фича play-api + SPA (сервер + фронт), не правка ботов — боты уже готовы (вебхук играет любую игру). Разбиваем на маленькие PR-ы.
- Двойной способ выставить флаг оставляет админ-путь как обязательный (решает кейс
expectimax-onnx-3с утерянным токеном).
Альтернативы (отклонены).
- Стендинг-сик + Cloud Scheduler keeper на каждого serverless-бота — работает и play-api не трогает (быстрый тактический шаг), но: платный per-op токен, фантомные столы против уснувших ботов, N keeper’ов + N Scheduler-джоб на N ботов. Годится как временная мера, не как модель.
--min-instances 1+ in-process keeper (как house-боты) — простой код, но выходит из always-free: инстанс крутится 24/7 и тарифицируется.- Не звать людей вовсе (только ладдер) — теряем human-vs-bot для serverless-ботов; те же веса человек может сыграть лишь через house-стол (
oracle v3).