y83 projects / 05 / php + typescript + phaser

Y83 Games — настольные игры в Telegram

в продакшне · 2026

Пять игр в меню: русские и международные шашки, апокачи, поддавки и «Чапаев» с физикой на Rapier. Ещё два движка — шахматы и морской бой — дописаны и ждут включения. Под каждым ходом стоит движок: бот шашек считает альфа-бета с таблицей транспозиций, шахматный анализ запускает настоящий Stockfish в браузере, а партию можно разобрать ход за ходом с оценкой каждой позиции.

бот в Telegram
@y83_checkers_bot
веб-версия
checkers.y83.ru
код
116 441 строка
клиент
47 705 строк TypeScript
движков / игр
7 в коде · 5 в меню

продукт

Игровая платформа с серверной защитой правил

Задача

Сделать игровую площадку, где партия идёт прямо в Telegram, и не скатиться в набор контроллеров: пять разных правил на доске разъезжаются, если у них нет явных границ, а партия в браузере разваливается, если состояние не защищено от гонок.

Решение

Правила живут в value-объектах домена и проверяются на сервере — клиент не может отправить недопустимый ход. Клиент отвечает только за представление и анимацию: пять сцен Phaser, очередь анимаций и очередь ходов на случай обрыва связи.

Следствие

Игру можно выключить и включить одним флагом в таблице games, а движок бота, анализ и повторы не знают, шашки это или шахматы: им нужны только правила и список ходов.

возможности

Что умеет

Семь движков в коде, пять игр в меню, 47 тысяч строк клиента.

Игры

Пять игр в меню

Русские и международные шашки, апокачи, поддавки, «Чапаев». У каждой — свой доменный движок, своя доска и свой клиентский модуль.

  • checkers

Шахматы и морской бой дописаны

Шахматный модуль — 7 665 строк: часы, HUD, дебютная книга, повтор. Обе игры не опубликованы: нет строки в таблице games.

  • chess

«Чапаев» на физике

Rapier вместо Matter.js: гравитация выключена, стен нет — по правилам шашки должны улетать с доски. Трение пересчитано по формуле, а не взято из старого движка.

  • chapaev

Клиент игры

Пять сцен Phaser 4

Сцены регистрируются по типу игры. В партии с ботом сцена не поднимается вообще — лишний рендер не нужен.

  • phaser

20 пиксельных героев над доской

Отдельная сцена на 1 431 строку: два героя с HP реагируют на ходы, у каждого шесть наборов кадров. Текст ников — свой растровый шрифт с транслитерацией кириллицы.

  • battle-strip

7 тем и 14 скинов

Тема собирает скин доски, скин фигур, стиль знаков и эффект взятия. Выбор сохраняется на сервере и приходит в следующей партии.

  • themes

25 эффектов и звук кодом

След, призрак, прыжок, молния, цепная реакция, конфетти, тряска камеры. Звуки не файлы, а буферы, которые генерируются через WebAudio; взятие добавляет вибрацию.

  • effects

Движок и анализ

Бот шашек: альфа-бета

1 347 строк в Web Worker: negamax, итеративное углубение, Zobrist и таблица транспозиций, killer moves, оценка из 10 весов. Пять уровней — от случайного хода до 20 полуходов за 3 секунды.

  • bot

Разбор партии

Каждая позиция оценивается движком, ходы раскладываются по классам от brilliant до blunder, строится eval-график и текстовый вердикт. Считается в воркере, интерфейс не блокируется.

  • analysis

Шахматы на Stockfish

Анализатор поднимает Stockfish 18 из репозитория в воркере и говорит с ним по UCI: позиция туда, bestmove обратно, ход переводится в SAN.

  • stockfish

Апокачи и морской бой

У апокачи своя логика сэндвича и свой воркер с ботом, у морского боя — расстановка кораблей с автораскладкой и карусель выбора клеток.

  • apokachi

Сеть и офлайн

Ход не теряется

При обрыве связи ход встаёт в очередь и уходит при восстановлении. Устаревшие ответы сервера отбрасываются по номеру последовательности — доска не откатывается назад.

  • offline

Поллинг знает, когда не надо

Опрос состояния пропускается, когда идёт анимация, ход текущего игрока, перетаскивание фигуры или отправка хода. Причина пропуска названа явно.

  • poller

Понятная полоса соединения

Свой контроллер: «Переподключение, попытка N», ping/pong, замер RTT, кнопка обновить. Reverb и Laravel Echo с приватными и presence-каналами.

  • websocket

Продукт

Комнаты, чат, рейтинги

Комнаты с кодами и ролями, чат с реакциями и индикатором набора прямо в партии, рейтинг, дружба, недавние соперники.

  • social

История и повторы

Разбор последнего хода соперника прямо в партии и полный повтор отдельной сценой: шашки, шахматы, апокачи. История с фильтрами и постраничной выдачей.

  • replay

Админка

Filament: 7 ресурсов и 8 виджетов, плюс Pulse. Рассылки с расписанием, отзывы, отладочные сессии.

  • admin

Атомарный деплой

GitLab CI: релизный каталог, общие .env и storage, миграции, кэши, переключение симлинка, health-check, хранение 5 релизов.

  • ci/cd

Процесс и инструменты

Инструкция для агента

AGENTS.md описывает архитектуру и рецепт добавления игры из семи шагов. В нём же правило, выросшее из инцидента: не делать git checkout на файле с незакоммиченной работой.

  • agents

Планы с критериями приёмки

План по шахматам: три задачи, у каждой требования, архитектурное решение и критерии приёмки с отметкой о проверке. Рядом — расследования и разбор техдолга.

  • planning

Отладка на 11 вкладок

Состояние, чат, очередь ходов, вебсокет, консоль, производительность, ошибки, анализ бота, сеть, ходы, обзор. Плюс счётчик FPS и памяти с перехватом запросов.

  • debug

Визуальный стенд

Каталог эффектов вынесен в отдельный экран: каждый эффект можно запустить отдельно от партии и отладить. Плюс дизайн-лаб и стайлгайд.

  • tools

как работает

Путь хода

01

Проверка на сервере

Ход уходит в домен, применяется к серверной доске и отклоняется с текстом ошибки, если он недопустим.

02

Событие

Доменное событие уходит в вебсокет-канал сессии — второй игрок получает его без опроса сервера.

03

Анимация

Клиент проверяет номер последовательности, кладёт ход в очередь анимаций и рисует его с эффектом и звуком.

04

Полоса боя

По той же событийной ленте герои реагируют на партию: атака, попадание, смена HP, финальная поза.

05

Разбор

Партия остаётся в истории: её можно пересмотреть ход за ходом и прогнать через анализатор.

результаты

116k

строк своего кода

PHP 51 499 + TypeScript 48 738 + Blade 16 204
47,7k

строк клиента

199 файлов TypeScript в Web App
7

движков в коде

пять игр опубликованы в меню
296

тестов

115 PHPUnit + 181 Vitest
25

эффектов

плюс 6 типов взятия и 20 героев
9

шагов деплоя

атомарное переключение симлинка

Цифры сверены с релизом 20260814121948 (30.09.2026).

экраны

Как это выглядит

Скриншоты будут добавлены позже; список экранов — реальный состав интерфейса.

листайте вбок · 9 экранов

Хаб

Хаб

пять игр, вход в комнату по коду

Партия с ботом

Партия с ботом

сцена Phaser, выбор сложности и цвета

Полоса боя

Полоса боя

пиксельные герои, HP, нотация хода

Панель внешности

Панель внешности

7 тем, 14 скинов, эффекты взятия

Чат в партии

Чат в партии

плавающая панель, реакции, набор текста

Повтор с анализом

Повтор с анализом

eval-график и классификация ходов

Шахматы

Шахматы

часы, HUD, список ходов, название дебюта

«Чапаев»

«Чапаев»

физика на Rapier, рогатка, HUD бойца

Стенд эффектов

Стенд эффектов

каталог анимаций отдельно от партии

технологии

Из чего собрано

Сервер

  • PHP 8.3
  • Laravel 13
  • PostgreSQL 16
  • Redis + Horizon
  • sqids

Клиент

  • TypeScript 6
  • Phaser 4.2
  • Rapier.js 0.19
  • Stockfish 18 (WASM)
  • Laravel Echo + pusher-js

Telegram и реалтайм

  • telegram-bot-sdk 3
  • Telegram Web App
  • Laravel Reverb
  • Broadcasting

Инфраструктура

  • nginx + php8.3-fpm
  • GitLab CI + Runner
  • Supervisor
  • Filament 5
  • Laravel Pulse
  • Vitest 4
  • Tailwind 4

этапы

Что сделано и что дальше

этап 1

Шашки и лобби

четыре варианта шашек, лобби, вебсокеты, реалтайм

этап 2

Продуктовая обвязка

комнаты, чат, рейтинги, история, повторы, бот-соперник

этап 3

Клиент как движок

Phaser-сцены, темы, эффекты, звук, полоса боя, анализ, Stockfish

этап 4

Шахматы и морской бой

код готов, не опубликованы — ждут включения в меню

этап 5

Сквозной прогон в CI и расширение турнирного контура

вынос 296 локальных тестов (115 PHPUnit + 181 Vitest) в обязательный пре-деплой гейт GitLab Runner

вопросы

Частые вопросы

Сколько игр?

Семь движков в коде: четыре варианта шашек, «Чапаев», морской бой и шахматы. В меню сейчас пять — шахматы и морской бой дописаны, но им нет строки в таблице games, поэтому они не видны игроку. Включаются одним флагом.

Что значит «клиент как движок»?

Игровая логика в браузере самостоятельна: свой движок бота на альфа-бете с таблицей транспозиций, свой анализатор партии с оценкой каждой позиции, свой UCI-клиент к Stockfish. Всё это считается в Web Worker, чтобы интерфейс не подвисал. Правила при этом остаются на сервере — клиент только показывает.

Шахматы готовы?

По коду — да: домен на 1 163 строки, клиент на 7 665, часы, HUD, дебутная книга на 34 дебюта, анализ на Stockfish, повтор. План по правкам правил закрыт полностью, все три задачи проверены. Не опубликованы.

Что с надёжностью?

Ход, отправленный при обрыве связи, встаёт в очередь и уходит после восстановления. Устаревшие ответы отбрасываются по номеру последовательности, иначе медленный ответ откатывал бы доску назад. Таймаут хода проверяется на сервере по расписанию.

Как деплоится?

GitLab CI: lint (Pint и tsc), сборка, затем деплой из master в релизный каталог, общие .env и storage симлинками, миграции и кэши под artisan down, атомарное переключение симлинка, рестарт сервисов, health-check по домену, хранение пяти последних релизов.

Y83 Games

Есть вопрос по проекту?

Игровая площадка в Telegram — бот @y83_checkers_bot: пять игр в меню и семь движков в коде. Сервер — PHP 8.3 и Laravel 13 с DDD: правила живут в value-объектах, ходы идут через Reverb WebSockets с SequenceGuard и MoveQueue, выкладка атомарная в 9 шагов. Клиент — вычислительные воркеры: Phaser 4.2, бот на альфа-бета с Zobrist-хешированием, разбор партий на Stockfish 18 WASM по UCI и физика Rapier 2D.

@xipovski xipovski@gmail.com
следующий проект Y83 FileCode