Table of Contents

Engine-Game Separation

Status: Production Standard


Core Principle

ENGINE provides mechanisms (HOW), GAME defines policy (WHAT).

ENGINE is a reusable foundation. GAME is the specific implementation. The same ENGINE should support different games (space strategy, fantasy conquest, modern warfare) with different policies.


The Separation

ENGINE Layer (Mechanism)

  • Generic primitives and data structures
  • Rendering infrastructure
  • Input handling
  • Networking infrastructure
  • Save/load framework
  • Command execution

ENGINE asks: "How do I store province state?" "How do I render a map?" "How do I process commands?"

GAME Layer (Policy)

  • Game-specific formulas and rules
  • Colors, visuals, UI content
  • AI behavior and goals
  • Victory conditions
  • Balance values

GAME asks: "What is the tax formula?" "What color is France?" "When does a country surrender?"


Why This Matters

Reusability

Same ENGINE can power different games:

  • Grand strategy (EU4-like)
  • Space 4X
  • Fantasy conquest
  • Modern political simulation

Each game implements different policies using the same mechanisms.

Maintainability

Changes to game balance don't touch ENGINE code. Changes to rendering don't affect game rules. Clear boundaries reduce bugs.

Testability

ENGINE mechanisms can be tested in isolation. GAME policies can be tested with mock ENGINE.


Extension Points

ENGINE provides interfaces that GAME implements:

Category ENGINE Provides GAME Implements
Game Systems IGameSystem lifecycle Economy, Buildings, Military
Map Modes IMapModeHandler contract Political, Economic, Diplomatic modes
Commands ICommand interface DeclareWar, BuildBuilding, etc.
Definitions IDefinition loading Building types, unit types, etc.
Rendering IRenderer interfaces Custom borders, fog, effects

Import Rules

Strict hierarchy prevents circular dependencies:

CORE (Simulation):

  • Cannot import Map or Game
  • Pure simulation logic
  • Deterministic operations only

MAP (Presentation):

  • Can import Core
  • Cannot import Game
  • Reads simulation state for rendering

GAME (Policy):

  • Can import Core and Map
  • Defines all game-specific behavior
  • Owns initialization order

Rule: Dependencies flow downward only. CORE → MAP → GAME.


Data Ownership

ENGINE Owns

  • Province state primitives (owner, controller, terrain)
  • Country state primitives (exists, tag)
  • Command processing
  • Event bus
  • Time management

GAME Owns

  • Game-specific province data (development, buildings)
  • Game-specific country data (treasury, relations)
  • All formulas and balance values
  • UI content and styling
  • AI decision making

Initialization Pattern

GAME layer controls all initialization order:

  • ENGINE systems initialize through GAME coordinator
  • Avoids rogue Start/Awake methods
  • Clear dependency chain
  • Predictable load order

Common Mistakes

Putting policy in ENGINE:

  • Tax formula in ENGINE → Should be in GAME
  • Country colors in ENGINE → Should be in GAME
  • Building definitions in ENGINE → Should be in GAME

Putting mechanism in GAME:

  • Province storage reimplemented → Use ENGINE's ProvinceSystem
  • Custom event system → Use ENGINE's EventBus
  • Duplicate rendering logic → Use ENGINE's pluggable renderers

Design Principles

Mechanisms, Not Policy

ENGINE provides generic state access. GAME defines what to do with state.

Flexible, But Opinionated

  • Opinionated: "Use FixedPoint64 for determinism"
  • Flexible: "But you define the formulas"

Abstract Hard Problems

ENGINE solves: determinism, performance, state management, events, persistence. GAME focuses on: gameplay, content, balance.

Zero Game Logic in ENGINE

No game-specific concepts (farms, armies, trade) in ENGINE code. Only generic concepts: provinces, countries, commands, events.


Trade-offs

Aspect Benefit Cost
Strict separation Reusable ENGINE More interfaces to implement
Interface contracts Clear boundaries Indirection overhead
Layer hierarchy No circular deps Can't call "up" the hierarchy

Success Metric

Can you build a different game in one week using the same ENGINE?

If yes: Separation is working. If no: Too much policy leaked into ENGINE.


  • Pattern 1 (Engine-Game Separation): This document
  • Pattern 20 (Pluggable Implementation): How GAME extends ENGINE rendering
  • Pattern 2 (Command Pattern): How state changes flow through layers

Mechanism belongs in ENGINE. Policy belongs in GAME. Never mix them.