Netcode
Authoritative Server Model
Dracor uses a fully authoritative server architecture built on Colyseus. The game server is the single source of truth for all game state. Clients never simulate game logic — they send input messages describing what the player intends to do, and the server decides the outcome. This design makes cheating architecturally impossible rather than merely detectable.
Input-Based Messaging
Clients send lightweight input messages rather than position updates. A movement message contains the direction vector and whether the player is sprinting — not the resulting position. The server applies the movement according to its own simulation, checking for collisions, speed limits, and valid state transitions.
Message Types
- MoveInput — Direction vector (x, z) + sprint flag. Server applies velocity and collision.
- ActionInput — Action type (attack, interact, use item) + target ID. Server validates range, cooldowns, and resources.
- ChatMessage — Text content + channel. Server validates length, rate limits, and broadcasts to the appropriate scope.
Fixed Tick Simulation
The game server runs its simulation loop at a fixed 20Hz tick rate (50ms per tick). Every tick, the server processes all queued inputs, updates entity positions, resolves combat, checks triggers, and produces a new world state snapshot. This fixed rate ensures deterministic behavior regardless of server load fluctuations.
20 Hz
Server tick rate
50 ms
Tick interval
50
Players per room
Client-Side Interpolation
Since the server only sends state at 20Hz, the client interpolates between received snapshots to produce smooth 60fps visuals. Entity positions are linearly interpolated between the two most recent server states. The client renders slightly in the past (one tick of buffer) to always have two snapshots available for interpolation. This approach produces visually smooth movement even on connections with moderate jitter.
Binary Delta Synchronization
Colyseus uses schema-based binary serialization with automatic delta encoding. Only fields that changed since the last tick are transmitted. A full room state might be several kilobytes, but a typical tick delta is measured in bytes. This keeps bandwidth under 5KB/sec per connected player, making the game playable on mobile data connections.
- Schema-based serialization with automatic change tracking
- Binary encoding — no JSON overhead on the wire
- Under 5KB/sec bandwidth per connected player
- Room-based horizontal scaling — rooms are independent processes
State Persistence
The game server writes character state snapshots to Supabase every 30 seconds and on disconnect. Position, health, inventory, and quest progress are persisted so players resume exactly where they left off. On room creation, the server loads the latest snapshot for each joining character. This decouples persistence from the tick loop — the simulation runs in memory at full speed, and database writes happen asynchronously on a separate timer.