Skip to main content

Overview

The core simulation is the heart of OpenFront - a completely deterministic game engine that runs identically on all clients. It is written in pure TypeScript with zero external dependencies. Key Principles:
  • Deterministic - Same inputs always produce same outputs
  • Pure - No side effects, randomness, or I/O
  • Thread-safe - Runs in worker threads
  • Portable - Works in browser, Node.js, and offline
The core must remain 100% deterministic. Never add:
  • Math.random() (use seeded RNG)
  • Date.now() (use tick counters)
  • External npm packages
  • File I/O or network calls
  • Non-deterministic algorithms

Architecture Diagram

Intent-Execution Model

The core uses a two-phase architecture:

Phase 1: Intents

Intents are player requests that may or may not be valid:
File: src/core/Schemas.ts

Phase 2: Executions

Executions are validated actions that modify game state:
Example: Attack Execution File: src/core/execution/PlayerExecution.ts
The intent-execution split ensures that invalid player actions don’t crash the game. Intents can fail validation, but executions always succeed.

Game State

GameImpl

File: src/core/game/GameImpl.ts The main game state container:

Player State

File: src/core/game/PlayerImpl.ts

Unit System

File: src/core/game/UnitImpl.ts Units represent structures and military assets:
Unit Types:

Spatial Indexing

File: src/core/game/UnitGrid.ts Units are stored in a spatial grid for efficient queries:

GameRunner

File: src/core/GameRunner.ts Orchestrates turn execution:
The GameRunner processes turns in batches to catch up if the client falls behind the server. It executes up to 4 ticks before yielding to avoid blocking the worker thread.

Execution Types

Structure Executions

Building construction and upgrades: File: src/core/execution/FactoryExecution.ts

Combat Executions

Attack and defense mechanics: File: src/core/execution/PlayerExecution.ts

AI Nation Executions

Bot behavior: File: src/core/execution/NationExecution.ts
AI Modules: File: src/core/execution/nation/
  • NationStructureBehavior.ts - Building placement AI
  • NationWarshipBehavior.ts - Naval strategy
  • NationNukeBehavior.ts - Nuclear weapon usage
  • NationAllianceBehavior.ts - Diplomacy decisions

Pathfinding

The core includes multiple A pathfinding* variants for different unit types.

Pathfinding Types

PathFinder Interface

File: src/core/pathfinding/PathFinder.ts

Example: Water Pathfinding

File: src/core/pathfinding/algorithms/AStar.Water.ts

Railroad Network

File: src/core/game/RailNetwork.ts Railroads form a graph structure for train pathfinding:

Game Updates

The core sends binary packed updates to the rendering thread for efficiency.

Update Types

File: src/core/game/GameUpdates.ts

Packed Tile Updates

Packing Format:
Binary packing reduces update size by 80% compared to JSON, critical for large maps with 40,000 tiles.

Determinism Guarantees

Seeded Random Number Generator

File: src/core/Util.ts

Hash Computation

State hashing for desync detection:

Determinism Checklist

Before adding new code to src/core/, verify:
  • ✅ No Math.random() (use SeededRandom)
  • ✅ No Date.now() (use tick counter)
  • ✅ No external imports (pure TypeScript only)
  • ✅ No floating point errors (use integers)
  • ✅ No object iteration (order not guaranteed)
  • ✅ Arrays sorted before iteration
  • ✅ Maps iterated in sorted key order

Testing Strategy

Determinism Tests

Replay Tests

Replays verify determinism by re-executing recorded games:

Performance Optimization

Object Pooling

Spatial Partitioning

Units are indexed in a grid for O(1) spatial queries instead of O(n) iteration.

Tick Budget

Worker thread limits execution time per tick:

Next Steps

Client Architecture

How the client renders game updates

Server Architecture

How the server relays turns