850: Пакет/Игровой Сервис
- Работает на основе:
- Совместим с:
Это как умный судья для компьютерных игр, который работает сам по себе. Он следит за всем, что происходит в пошаговых играх, например, в покере. Судья запоминает состояние игры, проверяет ходы игроков, использует специальные «движки» с правилами и сохраняет результаты. Ему неважно, как игроки с ним общаются — через сайт, приложение или что-то ещё.
Игровой Сервис (@idealic/game-service) — это программа-конструктор на Node.js, созданная для проведения пошаговых игр. Изначально она делалась для покера, но её устройство универсально. Она работает как безопасная «песочница», где можно создавать и проверять правила игры, не затрагивая основной сайт или приложение клиента.
Основная архитектура
Сервис построен по принципу «автомата с газировкой». Он не запоминает, кто вы. Вы просто делаете запрос (отправляете ход), а он обрабатывает его и выдаёт результат (новое состояние игры). Сервер получает версию событий от игрока, сверяет её со своей главной версией, проверяет ход и отправляет всем обновлённую информацию.
Подключаемые игровые движки
Сервис не знает правил самой игры. Он как игровая приставка, а правила игры — это картриджи. Можно вставить картридж с покером, а можно — с шахматами.
- Список игр: У сервиса есть список всех «картриджей» (игровых движков), которые он умеет запускать.
- Одинаковый «разъём»: Все «картриджи» должны иметь одинаковый набор команд (
State.advance(),State.join()и т. д.), чтобы приставка понимала, как с ними работать. - Разделение обязанностей:
- Игровой движок (например, покер): Знает правила, проверяет ходы и меняет состояние игры.
- Игровой сервис (этот пакет): Отвечает за всё остальное — связь с игроками через интернет, сохранение игры, управление столами и временем на ход.
«Состояние» как единственный источник правды
Вся информация об игре хранится в одном большом «файле» — Объекте Состояния. Это не просто картинка текущей ситуации, а полная запись всей партии, как ходы в шахматах.
- Обмен без памяти: Клиенты и сервер обмениваются этим «файлом» целиком. Никому не нужно ничего запоминать, вся правда — в этом файле.
- Предсказуемость: В «файле» записано специальное случайное число. Благодаря этому можно в любой момент идеально точно воспроизвести всю игру с самого начала. Это помогает решать споры.
- Взгляд игрока: Сервер умеет показывать каждому игроку свою версию «файла». Например, он скроет карты других игроков, чтобы вы видели только свои.
Уровень для связи с внешним миром
Сервису всё равно, как с ним общаются: через сайт, мобильное приложение или что-то ещё. Все способы общения вынесены в отдельный «переходник» (service.io.ts). Если нужно подключить новый способ, достаточно просто заменить этот «переходник».
- Сохранение игры: Команды
saveGameиloadGameотвечают за хранение главной версии состояния игры. - Управление деньгами:
fetchPlayerStacksиsavePlayerStacksсвязываются с внешними системами кошельков. - Общение в реальном времени:
broadcastToPlayersрассылает обновления всем игрокам (например, через веб-сокеты). - Фоновые задачи:
fetchTimedOutGamesпозволяет проверять, не закончилось ли у кого-то время на ход.
Концепция игровых столов
В этой системе игровые столы — это не что-то постоянное, что хранится в базе данных. Стол существует, пока идёт игра.
- Создание по требованию: Столы создаются, когда они нужны. Если игрок ищет игру (например, «Техасский Холдем, $1/$2») и свободных мест нет, система тут же создаёт новый стол.
- Жизненный цикл:
- Найти: Клиент ищет стол с нужными параметрами. Система находит существующий или создаёт новый.
- Наблюдать: Игрок получает состояние игры и может просто смотреть за происходящим.
- Присоединиться: Игрок отправляет команду
join, чтобы сесть за стол. - Играть: Идёт обычный игровой процесс.
- Завершить: Игроков убирают из-за стола, если у них закончилось время или деньги для следующей раздачи.
Как это работает
Вот как устроен рабочий цикл сервиса:
- Сигнал: Внешнее событие (например, ход игрока) запускает процесс.
- Загрузка: Сервер достаёт из памяти главную, самую правильную версию состояния игры.
- Сверка: Он сверяет данные, которые прислал клиент, со своей версией.
- Ход: Сервис просит игровой движок обработать ход и продолжать игру до тех пор, пока снова не понадобится действие от игрока.
- Завершение: Если раунд закончился, сервис подводит итоги, раздаёт выигрыш и начинает новый раунд.
- Сохранение и рассылка: Новое состояние игры сохраняется и отправляется всем игрокам.