Skip to main content

Overview

The OpenFront client uses a multi-threaded architecture that separates game simulation from rendering:
  • Main Thread - UI, rendering (PixiJS), user input handling
  • Worker Thread - Core simulation, pathfinding, game logic
This separation ensures smooth 60 FPS rendering even during heavy simulation work.

Architecture Diagram

Core Components

ClientGameRunner

The main orchestrator that coordinates all client systems. File: src/client/ClientGameRunner.ts
Responsibilities:
  • Lifecycle management (start, stop)
  • Coordinating worker ↔ renderer communication
  • Handling user input events
  • Managing connection state

Worker Thread Communication

The client communicates with the worker thread via WorkerClient. File: src/core/worker/WorkerClient.ts

Sending Turns to Worker

Receiving Game Updates

Game updates use transferable buffers for zero-copy data transfer between threads, improving performance for large state updates.

Worker Thread Implementation

File: src/core/worker/Worker.worker.ts The worker runs the core simulation and processes turns:
Turn Execution Flow:
  1. Main thread sends Turn via postMessage
  2. Worker queues turn in game runner
  3. Worker executes up to 4 ticks before yielding
  4. Worker sends GameUpdate batch back to main thread
  5. Main thread renders updates
The worker uses a batching strategy (MAX_TICKS_BEFORE_YIELD = 4) to avoid flooding the main thread while catching up on missed turns.

Rendering System

GameRenderer

The renderer uses PixiJS for hardware-accelerated WebGL rendering. File: src/client/graphics/GameRenderer.ts

Rendering Layers

The renderer is organized into layers that render independently:

Transform Handler

File: src/client/graphics/TransformHandler.ts Handles camera controls and coordinate transformations:

Input Handling

InputHandler

File: src/client/InputHandler.ts Processes mouse and keyboard input:

Intent Generation

User actions generate intents that are sent to the server:

Network Transport

Transport Layer

File: src/client/Transport.ts Manages WebSocket connection to game server:

Message Types

Server → Client:
  • lobby_info - Lobby state and player list
  • prestart - Game is about to start, begin loading
  • start - Game started, includes GameStartInfo
  • turn - Turn data with bundled intents
  • desync - Hash mismatch detected
  • error - Connection or validation error
Client → Server:
  • join - Join game lobby
  • rejoin - Reconnect to existing session
  • intent - Player action (attack, build, etc.)
  • hash - State hash for desync detection
  • turn_complete - Tick executed successfully

GameView

Provides a read-only view of game state to the rendering thread. File: src/core/game/GameView.ts
GameView is read-only. Never modify game state from the main thread. All mutations must happen in the worker thread via Executions.

UI Components

The client includes numerous UI components built with Web Components:

Example: Build Menu

File: src/client/graphics/layers/BuildMenu.ts

Key UI Elements

  • Leaderboard - Player rankings and stats (src/client/graphics/layers/Leaderboard.ts)
  • BuildMenu - Structure construction (src/client/graphics/layers/BuildMenu.ts)
  • ChatDisplay - In-game chat (src/client/graphics/layers/ChatDisplay.ts)
  • RadialMenu - Quick actions (src/client/graphics/layers/RadialMenu.ts)
  • ControlPanel - Game controls (src/client/graphics/layers/ControlPanel.ts)

Performance Optimization

Efficient State Updates

Game updates use binary packed buffers instead of JSON:

Rendering Optimizations

  • Culling - Only render visible tiles
  • Sprite batching - Batch similar sprites in single draw call
  • Dirty regions - Only redraw changed areas
  • Object pooling - Reuse PixiJS objects

Frame Profiler

File: src/client/graphics/FrameProfiler.ts Tracks rendering performance:

Error Handling

The client handles various error scenarios:

Desync Detection

Clients compute state hashes and send to server for comparison:
If hashes don’t match, server sends desync message.

Connection Recovery

Worker Errors

Development Tools

Performance Overlay

File: src/client/graphics/layers/PerformanceOverlay.ts Displays real-time metrics:
  • Tick execution time
  • Network latency
  • Frame rate
  • Memory usage

Diagnostic Mode

File: src/client/utilities/Diagnostic.ts Enables debug visualizations:
  • Pathfinding routes
  • Attack ranges
  • Territory borders
  • Network packets

Next Steps

Server Architecture

Learn how the server relays intents

Core Simulation

Understand the deterministic engine