http3 game server supporting QUIC and WebTransport to stream game operations and state
The server is built in rust, using the wtransport crate to handle the WebTransport http3 specifics.
The server is stateful, keeping track of a single game's state in memory and the connected clients player states.
The server is multi-threaded on top of tokio, handling multiple clients concurrently.
Each client can open 1 bidirectional stream channel with the server. The client and server then exchange streamed binary data that follows the connect4000 binary communication protocol.
The client creates and sends "commands" to the server, which the server will use to mutate game state. The server can also send "views" to the client, which are binary stream representations of game state.
- Client connects to server
- Server a handshake view
- Server sends a
Joinedview a. Includes player id and color - Server sends a
Snapshotview a. A continuous stream of the full game snapshot state
- Client sends a
PlayCoincommand to server - Server a handshake view
- Server sends a
Joinedview - Server sends a
Snapshotview
Joined: 0
Snapshot: 1
PlayCoin: 2Header: # 1 byte:
type: 2 # 1 byte
Body: 0 # 8 bytes - The u64 column index to play the coin intoHeader: # 25 bytes
type: 1 # 1 byte
winner_id: 0 # 8 bytes
columns: 2 # 8 bytes
rows: 2 # 8 bytes
Body: # (column_count * row_count) bytesNote: The body of the Snapshot view is a binary representation of the game.
This is a dense grid as a 2D array of bytes, where each byte represents an empty space, or a coin.
Starting with byte 0, we have the 1st space in the first column. All bytes up to byte
row_countare spaces in the first column. If we needed to read all of the coins in the 3rd column, we would start at byterow_count _ 2and readrow_countbytes from there.Any non-zero byte represents a coin instead of an empty space.
Header: # 1 byte
type: 0 # 1 byte
Body: # 9 bytes
player_id: 0 # 8 bytes
color: 0 # 1 byte