- Protocol: PacketType, TLV Body types, QUIC varint, header, input_broadcast and config_update builders, 2-bit body bitpacking helper - Config/model: live-config ServerConfig, basic GameState/Snake/Session - Transport: InMemoryTransport placeholder and QUIC server stub - Server: asyncio tick loop, periodic config_update broadcast, immediate input_broadcast relay; main entry and run.py
29 lines
1.1 KiB
Python
29 lines
1.1 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass
|
|
class ServerConfig:
|
|
width: int = 60
|
|
height: int = 40
|
|
tick_rate: int = 10 # TPS, server-controlled, live-configurable
|
|
wrap_edges: bool = False # default off
|
|
apples_per_snake: int = 1 # min 1, max 12
|
|
apples_cap: int = 255 # absolute cap
|
|
compression_mode: str = "none" # "none" | "deflate" (handshake-only)
|
|
players_max: int = 32
|
|
|
|
def validate_runtime(self) -> None:
|
|
if not (3 <= self.width <= 255 and 3 <= self.height <= 255):
|
|
raise ValueError("field size must be within 3..255")
|
|
if not (5 <= self.tick_rate <= 30):
|
|
raise ValueError("tick_rate must be 5..30 TPS")
|
|
if not (1 <= self.apples_per_snake <= 12):
|
|
raise ValueError("apples_per_snake must be 1..12")
|
|
if not (0 <= self.apples_cap <= 255):
|
|
raise ValueError("apples_cap must be 0..255")
|
|
if self.compression_mode not in ("none", "deflate"):
|
|
raise ValueError("compression_mode must be 'none' or 'deflate'")
|
|
|