Architecture Philosophy
OpenFront employs a unique architecture where the game simulation runs entirely client-side in worker threads, while the server acts solely as a relay for player intents. This design ensures:- Deterministic gameplay - All clients simulate the same game state
- Low server costs - Server only relays messages, doesn’t run game logic
- Offline capability - Singleplayer games run completely locally
- Anti-cheat via consensus - Multiple clients verify game state
System Components
The game is split into four main components:Client
Handles rendering, UI, and runs the core simulation in a worker thread
Server
Relays intents between clients using WebSockets and Express
Core Simulation
Deterministic, pure TypeScript game engine with no external dependencies
API
Closed-source Cloudflare Worker handling auth, stats, and monetization
Architecture Diagram
Data Flow
The core game loop follows an intent-execution model:Intent → Execution Flow
- User Action - Player performs action (attack, build, move)
- Intent Creation - Client creates an “Intent” object
- Send to Server - Intent sent via WebSocket to game server
- Bundle Intents - Server collects all intents for current tick
- Relay Turn - Server sends bundled “Turn” to all clients
- Execution - Each client’s core creates “Execution” objects
- State Update - Executions modify game state deterministically
- Render - Core sends GameUpdates to rendering thread
Intents are requests from players, while Executions are validated actions that modify game state. This separation ensures determinism across all clients.
Turn Synchronization
Key Design Principles
1. Determinism
The core simulation (src/core/) is completely deterministic:
- No
Math.random()- uses seeded RNG - No
Date.now()- uses tick counters - No external dependencies - pure TypeScript
- Identical input → identical output across all clients
2. Thread Separation
The client uses a multi-threaded architecture:- Main thread - UI, rendering, user input (60 FPS)
- Worker thread - Core simulation (variable tick rate)
- Communication via
postMessagewith transferable buffers
3. Server as Relay
The server never runs game logic:- No validation of intents (handled by core)
- No game state storage (state lives in clients)
- Only coordinates turn synchronization
- Clustering support via Node.js cluster module
4. Progressive Enhancement
Game modes build on the architecture:- Singleplayer - No server, fully offline
- Private lobbies - Custom server relay
- Public matchmaking - Managed by API + server
- Replays - Replay intents through core
Technology Stack
Client
- TypeScript - Type-safe game logic
- PixiJS - WebGL rendering
- Web Workers - Threaded simulation
- Vite - Build tooling
Server
- Node.js - Runtime environment
- Express - HTTP server
- ws - WebSocket library
- cluster - Process management
Core
- Pure TypeScript - No runtime dependencies
- Custom pathfinding - A* variants for land/sea/air/rail
- Binary protocols - Efficient state updates
Performance Characteristics
Client Performance
- Simulation runs at variable tick rate (200-1000ms per tick)
- Rendering at 60 FPS independent of simulation
- Large maps: 200x200 tiles, 400+ AI nations
- Worker thread prevents UI blocking
Server Scalability
- Stateless relay design scales horizontally
- Clustering across CPU cores
- Low memory footprint (~100MB per worker)
- WebSocket connections pooled per game
File Structure
Next Steps
Client Architecture
Deep dive into rendering and worker threads
Server Architecture
WebSocket relay and clustering
Core Simulation
Deterministic game engine internals