Run lobbies' games on the server

The server now runs every lobby's sandbox and queued games as rooms, stepped at
the tick rate on one thread. Players send controls ahead of time, late ones repeat
their last, and everyone in a room gets back the controls it played, its events
and checksums. Games start from sandbox queues, players return when they leave,
and play-again moves them to a fresh room. Protocol version 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shweetandClaude Opus 5.5 committed 2026-11-08 02:04:36 -05:00
1 parent 9613e85706
commit 655332778c
5 files changed
+585 -97

No files matched your search

+36 -1
View File
@@ -27,7 +27,7 @@
#include <string_view>
#include <type_traits>
constexpr int PROTOCOL_VERSION = 2;
constexpr int PROTOCOL_VERSION = 3;
constexpr int LOBBY_MEMBERS_MAX = 4;
constexpr int LOBBY_CODE_LENGTH = 4;
// Letters only, without I and O, so codes are easy to read out and type.
@@ -38,6 +38,41 @@ constexpr int KICK_REASON_MAX = 60;
constexpr const char SERVER_URL_DEFAULT[] = "wss://shweetz.net/smack-a-brother/ws";
constexpr int SERVER_URL_LENGTH = 128;
// Binary messages between a game and the server once it's in a lobby, each starting with its type. A room is one
// online game (a lobby's sandbox, or a game queued in it), numbered by the server.
//
// Game to server:
// PACKET_PROFILE Profile the fighter this player brings into the lobby
// PACKET_INPUTS room, ack, first, Uint16 count, Controls* this player's controls from a tick on, and the last
// tick it has confirmed
// PACKET_QUEUE Uint8 isOpen, Rules queue a game in the sandbox, or stop queueing it
// PACKET_CHAT Uint16 length, text
// PACKET_TYPING Uint8 isTyping
// PACKET_RENAME Uint16 length, text
//
// Server to game:
// PACKET_STATE room, tick, state the game this player is in now, as a tick starts
// PACKET_EVENT room, serial, RoomEvent the room's events, numbered from 0, in order
// PACKET_FRAMES room, lead, first, Uint16 count, then for each tick: Uint16 events, Uint8 fighters, Controls*
// every fighter's controls as the server played them,
// once the events before them are in, and how early
// (in ticks) this player's last controls came
// PACKET_CHECKSUM room, tick, Uint32 the room's state as that tick starts
// PACKET_CHAT from, Uint16 length, text and the same for typing and renames
enum PacketType : unsigned char
{
PACKET_PROFILE = 1,
PACKET_INPUTS,
PACKET_QUEUE,
PACKET_CHAT,
PACKET_TYPING,
PACKET_RENAME,
PACKET_STATE,
PACKET_EVENT,
PACKET_FRAMES,
PACKET_CHECKSUM
};
// Packets are plain values one after another, as they sit in memory (every platform agrees on these layouts).
struct PacketWriter
{