Lis Publica Arcade

Varius Game Server · SignalR

Добавьте мультиплеер в HTML5-игру

Унифицированный сервер комнат для простых аркадных игр. Хост считает игровую логику, игроки передают действия, а сервер доставляет сообщения через SignalR.

Как это устроено

Одна инсталляция обслуживает много независимых комнат. В комнате первый успешно подключившийся игрок становится хостом. Он хранит авторитетное состояние матча и рассылает его другим участникам; клиенты отправляют хосту только свои действия.

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, onPlayerLeft
  • onGameState, onPlayerAction
  • onHostChanged, onBecameHost
  • onMessage, onRoomClosed
  • onConnected, onDisconnected, onError

Игра → сервер

  • JoinRoom(roomId)
  • SetRoomStatus(roomId, status) — только хост
  • SendGameState(roomId, state) — только хост
  • SendPlayerAction(roomId, action)
  • SendMessage(roomId, message)

Жизненный цикл комнаты

  1. Создание. Игра создаёт комнату и показывает её ID друзьям или помещает её в лобби.
  2. Подключение. Первый участник становится хостом. Остальные игроки получают события подключения.
  3. Матч. Хост меняет этап матча через setRoomStatus(room.roomId, 'in_game'), запускает цикл симуляции и вызывает sendGameState; клиенты отправляют input через sendPlayerAction.
  4. Смена хоста. Если хост отключился, сервер выбирает нового из оставшихся игроков и отправляет onHostChanged и onBecameHost.
  5. Очистка. Пустые и неактивные комнаты удаляются фоновым сервисом. После reconnect SDK повторно вступает в сохранённую комнату.

Ограничения и production

  • Состояние комнат хранится в памяти одного процесса: перезапуск удаляет комнаты, а горизонтальное масштабирование потребует общего backplane (например, Redis).
  • Максимум игроков на комнату — от 2 до 100; значение по умолчанию — 40. Для аркад разумно начинать с частоты state около 10 Гц.
  • Сервер не аутентифицирует игроков и не проверяет содержимое state/action. Не используйте его как источник истины для ценных результатов без дополнительной серверной валидации.
  • Статус комнаты меняется только через SignalR Hub: сервер сверяет подключение с текущим хостом комнаты.