Skip to main content

Overview

The OpenFront server is a stateless relay that coordinates turn synchronization between clients. It does not run game simulation - that happens entirely client-side. Key Characteristics:
  • Relays player intents between clients
  • Manages lobby state and player connections
  • Clustering support for horizontal scaling
  • WebSocket-based real-time communication
  • Low memory footprint (~100MB per worker)

Architecture Diagram

Process Model

Master-Worker Clustering

The server uses Node.js cluster module for multi-process architecture. File: src/server/Server.ts

Master Process

File: src/server/Master.ts The master process:
  • Serves static files (HTML, JS, assets)
  • Routes API requests to workers
  • Manages worker lifecycle (fork, restart on crash)
  • Handles health checks
The master process automatically restarts crashed workers, providing fault tolerance for the server cluster.

Worker Process

File: src/server/Worker.ts Each worker process:
  • Runs an Express HTTP server
  • Runs a WebSocket server
  • Manages multiple game sessions via GameManager
  • Handles WebSocket connections and message routing
Port Assignment:
  • Master: Port 3000
  • Worker 0: Port 3001
  • Worker 1: Port 3002
  • Worker N: Port 3001 + N

Game Session Management

GameManager

File: src/server/GameManager.ts Manages multiple concurrent game sessions:

GameServer

File: src/server/GameServer.ts Represents a single game session:
The GameServer manages the turn clock that synchronizes all clients. Each turn bundles all intents received during the tick interval.

Game Phases

Phase Transitions:
  1. Lobby - Players join, configure settings
  2. Active - Game starts, turn loop begins
  3. Finished - Winner declared, game archived

WebSocket Communication

Connection Handling

File: src/server/Worker.ts:280-507

Client Object

File: src/server/Client.ts

Message Flow

Client → Server:
Server → Client:

API Endpoints

Game Management

Health & Status

Game Archives

Only singleplayer games can be archived via this endpoint. Multiplayer games are archived automatically by the server when they end.

Authentication & Authorization

JWT Verification

File: src/server/jwt.ts

Turnstile (Bot Protection)

File: src/server/Turnstile.ts Cloudflare Turnstile verification for bot prevention:

Desync Detection

Clients send state hashes to detect simulation divergence:
Hash mismatches indicate non-deterministic behavior in the core simulation. This is a critical bug that must be fixed.

Load Balancing & Routing

Worker Assignment

Games are assigned to workers using consistent hashing:
This ensures:
  • Same game always routes to same worker
  • Even distribution across workers
  • No shared state needed between workers

Path Prefixes

Requests include worker ID in path:

Matchmaking Integration

File: src/server/Worker.ts:535-593 Workers poll the matchmaking API to receive game assignments:

Monitoring & Observability

Metrics

File: src/server/WorkerMetrics.ts OpenTelemetry metrics for monitoring:

Logging

File: src/server/Logger.ts Structured logging with Winston:

Configuration

File: src/core/configuration/Config.ts Server configuration from environment variables:

Deployment

Environment Variables

Docker

Performance Tuning

Connection Limits

Memory Management

Next Steps

Client Architecture

Learn how clients render and input handling

Core Simulation

Understand the deterministic game engine