PlayGrid is a real-time multiplayer game platform built on a three-tier architecture: client, server, and shared types.
┌──────────────────────────────┐
│ Client (PixiJS + Vite) │
│ - Game rendering │
│ - User input & UI │
│ - WebSocket to Colyseus │
└──────────────┬───────────────┘
│ WebSocket
│
┌──────────────▼───────────────┐
│ Server (Colyseus + Express) │
│ - Game room orchestration │
│ - State synchronization │
│ - Player management │
│ - Database persistence │
└──────────────┬───────────────┘
│ SQL queries
│
┌──────────────▼───────────────┐
│ Database (PostgreSQL) │
│ - Player profiles │
│ - Match history │
│ - Game configuration │
└──────────────────────────────┘
All game state lives on the server. Players connect via WebSocket using Colyseus, which automatically:
- Serializes server state and sends it to clients
- Merges player actions back to the server
- Maintains a single source of truth
Each game has a dedicated Room class in server/src/rooms/:
- Chess Room — Board state, move validation, player turns
- Checkers Room — Board state, jump detection, king promotion
- Cards Room — Deck, hand state, turn-based actions
Rooms are stateful and handle all game logic.
Games are pluggable via the IGamePlugin interface. To add a new game:
- Create a room class implementing
IGamePlugin - Define game rules and board/state schema
- Register in the server's room dispatcher
- Add client-side rendering component
- Test with E2E tests
See game-systems-design.md for details.
- Player Action → Client listens to input (mouse, keyboard)
- Send Message → Client sends action to server room
- Game Logic → Server validates move and updates state
- Broadcast → Server syncs new state to all players
- Render → Client receives state and re-renders game board
| Component | Technology | Why |
|---|---|---|
| Server | Colyseus | Real-time room-based games with automatic sync |
| Client | PixiJS | High-performance 2D rendering on canvas |
| Build | Vite | Fast dev server and bundling |
| Language | TypeScript | Type safety across monorepo |
| Database | PostgreSQL | Reliable persistence for player data and match history |
| Testing | Vitest + Playwright | Fast unit tests + visual E2E tests |
All types live in shared/src/types/. Client and server both import from here to ensure compatibility:
// shared/src/types/game.ts
export interface IGamePlugin {
name: string;
rules: GameRules;
// ...
}
// server/src/rooms/ChessRoom.ts
import { IGamePlugin } from '@eschaton/shared';
// client/src/game/ChessGame.ts
import { IGamePlugin } from '@eschaton/shared';PostgreSQL tables handle:
- Player accounts and ratings
- Completed matches and results
- Game configuration and rules
Database is initialized on server startup and migrated as needed.
- Start with CONTRIBUTING.md for development setup
- Review
game-systems-design.mdto add a new game - Check
client-architecture.mdfor rendering details