
Multiplayer Chess
In ProgressMultiplayer Chess is a full-stack real-time chess platform built on raw WebSockets rather than a game-hosting library. A dedicated WS server handles matchmaking, move broadcasting, and draw offers, while chess.js validates every move server-side to prevent illegal moves or cheating. Games are persisted to a separate Express + Prisma + PostgreSQL service after every move, so a disconnected player can reconnect and resume an in-progress game exactly where they left off — and spectators can join a live game via its own WebSocket channel without needing to be a player.
Why I Built This
I wanted to go beyond a typical chess UI clone and actually build the real-time infrastructure myself — connection handling, reconnection/resume logic, and state authority — instead of leaning on a game framework that hides all of that.
Role
Full Stack Developer
Duration
2 months
Status
In Progress
Tech Stack
Key Features
- Real-time gameplay over raw WebSockets with server-authoritative move validation via chess.js
- JWT-authenticated WebSocket connections for matchmaking and gameplay
- Live spectator mode via a dedicated WebSocket channel, separate from player connections
- Draw offer / response flow between players
- Game state persistence with move-by-move board snapshots, so games survive a disconnect
- Automatic game resume on reconnect — rejoins an in-progress match from its last saved state
Challenges & Solutions
- Designed a server-authoritative architecture where the WebSocket game server is the single source of truth for board state, with chess.js rejecting any invalid move before it's broadcast
- Split gameplay and persistence into two services — a stateful WS game server and a stateless Prisma/Postgres API — and kept them in sync via internal HTTP calls on every move
- Handled reconnect logic: detecting a returning authenticated user, checking for an active game tied to their user ID, and rehydrating the in-memory game from its last persisted FEN and move count
- Managed multiple WebSocket upgrade paths (game, spectate, heartbeat) on a single HTTP server based on the request path
What I Learned
- Building real-time systems directly on the ws library instead of a higher-level socket framework — connection lifecycle, upgrade handling, and broadcasting
- Designing for server authority in a multiplayer game to prevent client-side state tampering
- Splitting a real-time service from a persistence service and reasoning about consistency between them