Как это устроено
Одна инсталляция обслуживает много независимых комнат. В комнате первый успешно подключившийся игрок становится хостом. Он хранит авторитетное состояние матча и рассылает его другим участникам; клиенты отправляют хосту только свои действия.
1. Комната
Создаётся REST-запросом, получает короткий ID из 6 символов.
2. Хост
Принимает input игроков и публикует актуальный game state.
3. Клиенты
Рисуют полученный state и отправляют собственные действия.
Быстрый старт
Подключите SignalR и файл SDK к странице игры. Замените адрес в примере на адрес развёрнутого сервера.
<script src="https://cdn.jsdelivr.net/npm/@microsoft/signalr@8.0.7/dist/browser/signalr.min.js"></script>
<script src="/path/to/game-server-sdk.js"></script>
<script>
const server = new GameServerClient('https://game-server.lispublica.ru');
const room = await server.createRoom({
type: 'my-game',
maxPlayers: 4,
});
await server.connect(room.roomId);
</script>
SDK находится в комплекте Varius Game Server: SDK/game-server-sdk.js. Для локальной разработки сервер по умолчанию доступен на http://localhost:5000.
JavaScript SDK
| Метод | Назначение |
|---|---|
| createRoom(options) | Создаёт комнату. Options: type, maxPlayers (2–100). |
| connect(roomId) | Открывает SignalR-подключение и вступает в комнату. |
| findRooms(filters) | Ищет комнаты по type и status. |
| setRoomStatus(roomId, status) | Меняет статус текущей комнаты через SignalR. Доступно только хосту. |
| sendGameState(state) | Рассылает состояние. Работает только для текущего хоста. |
| sendPlayerAction(action) | Передаёт действие игрока хосту. |
| sendMessage(message) | Рассылает произвольное сообщение всем участникам. |
| disconnect() | Закрывает текущее соединение. |
server.on('onGameState', (state) => render(state));
server.on('onPlayerAction', ({ playerId, action }) => {
// Вызывается у хоста: примените input игрока к состоянию матча.
applyAction(playerId, action);
});
server.on('onBecameHost', () => {
// После смены хоста продолжите симуляцию из последнего известного state.
startHostLoop();
});
REST API
Базовый путь — /api/room. Ответ комнаты содержит roomId, createdAt, playerCount, maxPlayers, hasHost, roomType и status.
| Запрос | Описание |
|---|---|
| POST /create?type=my-game&maxPlayers=4 | Создать комнату. |
| GET /{roomId} | Получить сведения о комнате. |
| GET /list?type=my-game&status=open | Список комнат с необязательными фильтрами. |
| GET /count | Количество активных комнат. |
| GET /exists/{roomId} | Проверить существование комнаты. |
События SignalR
Hub доступен по адресу /gameHub. При использовании SDK он подключается автоматически.
Сервер → игра
onPlayerJoined,onPlayerLeftonGameState,onPlayerActiononHostChanged,onBecameHostonMessage,onRoomClosedonConnected,onDisconnected,onError
Игра → сервер
JoinRoom(roomId)SetRoomStatus(roomId, status)— только хостSendGameState(roomId, state)— только хостSendPlayerAction(roomId, action)SendMessage(roomId, message)
Жизненный цикл комнаты
- Создание. Игра создаёт комнату и показывает её ID друзьям или помещает её в лобби.
- Подключение. Первый участник становится хостом. Остальные игроки получают события подключения.
- Матч. Хост меняет этап матча через
setRoomStatus(room.roomId, 'in_game'), запускает цикл симуляции и вызываетsendGameState; клиенты отправляют input черезsendPlayerAction. - Смена хоста. Если хост отключился, сервер выбирает нового из оставшихся игроков и отправляет
onHostChangedиonBecameHost. - Очистка. Пустые и неактивные комнаты удаляются фоновым сервисом. После reconnect SDK повторно вступает в сохранённую комнату.
Ограничения и production
- Состояние комнат хранится в памяти одного процесса: перезапуск удаляет комнаты, а горизонтальное масштабирование потребует общего backplane (например, Redis).
- Максимум игроков на комнату — от 2 до 100; значение по умолчанию — 40. Для аркад разумно начинать с частоты state около 10 Гц.
- Сервер не аутентифицирует игроков и не проверяет содержимое state/action. Не используйте его как источник истины для ценных результатов без дополнительной серверной валидации.
- Статус комнаты меняется только через SignalR Hub: сервер сверяет подключение с текущим хостом комнаты.