Game Server — это высокопроизводительный асинхронный сервер для многопользовательской игры в жанре «сбор предметов». Игроки управляют собаками, которые перемещаются по картам, собирают разбросанные предметы (лут) и сдают их в специальных офисах для получения очков. Сервер поддерживает одновременную игру множества пользователей, автоматически сохраняет состояние и ведёт таблицу рекордов.
Проект написан на C++17 с использованием Boost.Asio для асинхронной обработки запросов и PostgreSQL для хранения данных о рекордах.
- Многопользовательская игра в реальном времени — несколько игроков могут одновременно находиться на одной карте и взаимодействовать с объектами.
- Динамические карты — каждая карта содержит дороги, здания, офисы и предметы (лут), которые генерируются случайным образом.
- Управление собакой — игрок может менять направление движения (
L,R,U,D), собака движется вдоль дорог с учётом ограничений. - Сбор предметов — при пересечении траектории собаки с предметом он автоматически попадает в рюкзак собаки.
- Сдача предметов в офисах — при посещении офиса все предметы из рюкзака превращаются в очки игрока.
- Таблица рекордов — результаты игроков (имя, очки, время игры) сохраняются в PostgreSQL и доступны через API.
- Автоматическое сохранение состояния — игра периодически сохраняет состояние всех сессий и игроков на диск, а при перезапуске восстанавливает его.
- RESTful API — все игровые действия выполняются через HTTP-запросы в формате JSON.
- Структурированное логирование — логи выводятся в JSON-формате с временными метками для удобного анализа.
- Поддержка статических файлов — сервер может раздавать HTML, CSS, JS для веб-интерфейса.
| Компонент | Технология |
|---|---|
| Язык | C++17 |
| Сетевой движок | Boost.Asio, Boost.Beast |
| Парсинг JSON | Boost.JSON |
| Сериализация | Boost.Serialization (бинарная) |
| Логирование | Boost.Log |
| Работа с БД | libpqxx (PostgreSQL) |
| Пул соединений | Реализован вручную |
| Система сборки | CMake |
| Управление параметрами | Boost.Program_options |
| Документация | README (этот файл) |
Проект разделён на логические слои:
- Слой модели (
model) — содержит классыMap,Road,Building,Office,LostObject— представляет игровой мир. - Слой сессий (
game_session) — управляет состоянием конкретной карты: собаками, предметами, генерацией лута, физикой движения. - Игровой цикл (
ticker) — запускает периодические тики для обновления состояния всех сессий. - Обработка запросов (
request_handler) — разбирает HTTP-запросы, вызывает нужные методы моделей и формирует JSON-ответы. - Сохранение состояния (
data_state) — сериализует текущее состояние всех сессий и игроков в бинарный файл и восстанавливает при старте. - Рекорды (
records) — черезConnectionPoolвыполняет запросы к PostgreSQL для записи и чтения таблицы лидеров. - Логирование (
log) — форматирует записи в структурированный JSON с UTC-временем.
Все сетевые операции выполняются асинхронно на пуле потоков (количество определяется аппаратными возможностями).
Базовый путь: /api/v1/
| Эндпоинт | Метод | Описание |
|---|---|---|
/game/join |
POST | Присоединение к игре. В теле: {"userName":"...", "mapId":"..."}. Возвращает authToken и playerId. |
/game/players |
GET | Список игроков на текущей сессии. Требуется Authorization: Bearer <token>. |
/game/state |
GET | Полное состояние игры (позиции собак, скорости, направления, рюкзаки, предметы на карте). Требуется токен. |
/game/player/action |
POST | Управление движением собаки. Тело: {"move":"L/R/U/D/ "} (пробел — стоп). Требуется токен. |
/game/tick |
POST | Ручной тик (если сервер запущен без автоматических тиков). Тело: {"timeDelta": <ms>}. |
/game/records |
GET | Получение таблицы рекордов. Параметры: start (смещение), maxItems (макс. записей, ≤ 100). |
/maps |
GET | Список всех доступных карт (id, name). |
/maps/{mapId} |
GET | Детальная информация о карте (дороги, здания, офисы, типы лута). |
Все ответы и запросы — в формате JSON.
Для эндпоинтов, требующих аутентификации, передавайте заголовок: Authorization: Bearer <token>.
- Карты содержат дороги (горизонтальные/вертикальные отрезки), здания (декоративные), офисы (точки сдачи лута) и параметры генерации лута.
- Собаки движутся строго по дорогам с постоянной скоростью. При достижении конца дороги останавливаются. Можно задать направление, собака повернёт на ближайшем перекрёстке.
- Предметы появляются на дорогах случайным образом с заданной периодичностью. Каждый предмет имеет тип и вес (влияет на очки).
- Сбор происходит автоматически, когда траектория собаки пересекает предмет в пределах радиуса схвата.
- Сдача — когда собака заходит в офис, все предметы из рюкзака удаляются, а игрок получает очки, соответствующие сумме весов предметов.
- Ретритмент — если собака долго не двигается (время задано в конфиге карты), она «устаёт» и удаляется из игры, а её рекорд сохраняется.
Сервер может сохранять состояние игры в бинарный файл (указывается через --state-file). Сохранение выполняется:
- автоматически с заданным интервалом (
--save-state-period); - при получении сигнала SIGINT/SIGTERM;
- при ручном вызове
/api/v1/game/tick(если сервер запущен без автоматических тиков).
При запуске сервер проверяет наличие файла состояния и, если он существует, восстанавливает все сессии, собак, рюкзаки и предметы в точности как на момент сохранения.
Для хранения рекордов используется таблица retired_players со схемой:
CREATE TABLE retired_players (
id UUID PRIMARY KEY,
name VARCHAR(100) NOT NULL,
score INTEGER NOT NULL,
play_time_ms INTEGER NOT NULL
);