4.7 KiB
Rust Is The Simulation Source Of Truth
Load when: touching anything under src/simulator/, adding/changing simulation logic, wiring GDScript to physics, building GDExtension or WASM, or answering "where should this calculation live?"
The engine is genre-agnostic. All game content and display text comes from game packs. The fantasy game "Age of Dwarves" is the default pack.
Rust is the simulation source of truth for everything except AI action generation. Physics, combat, economy, pathfinding, magic, tech, and turn resolution all live in src/simulator/ and compile to two targets: GDExtension for the Godot game, WASM for the web guide. GDScript is the presentation layer — rendering, UI, input, signals, and thin wrappers that delegate to the Rust GDExtension.
AI exception (one of one)
AI action generation is currently implemented in GDScript at src/game/engine/src/modules/ai/simple_heuristic_ai.gd. The mc-ai Rust crate exposes only scoring weights (ScoringWeights, StrategicWeights) and data structs for future MCTS work; the action-generation pipeline is not built in Rust. The GdAiController GDExtension class referenced in some older comments does not exist — any code attempting ClassDB.instantiate("GdAiController") would return null. AiTurnBridge.run(player) calls SimpleHeuristicAi.process_player(player) directly.
Canonical content store
JSON game packs remain the canonical content store. Stats, costs, effects, thresholds — all in public/games/age-of-dwarves/data/*.json. Neither Rust nor GDScript hardcodes game content.
- UI labels resolve through
ThemeVocabulary.lookup(engine_key)— never hardcode theme strings - Sprites resolve through
ThemeAssets.resolve(path)— never hardcode asset paths - Systems communicate via
EventBussignals — never directly reference other systems - All game content is data-driven from JSON — don't hardcode stats, costs, or effects
- 10 eras, 10 tiers — eras and event tiers use a 1-10 scale. Era count and names are game-pack-driven (defined in
eras.json, not the engine). Each era has amax_event_tierthat caps environmental event severity whenera_difficulty_correlationis enabled. Units, spells, buildings use content tiers defined by the game pack. Spells usescope: "global"(High Archon, world map) orscope: "local"(specialist units, combat). School tech tiers map: T1-T2 spells gated by Mysticism/Arcane Lore, T3-T5 by school techs.
Compile-target topology
public/games/age-of-dwarves/data/climate_spec.json ← Canonical thresholds, events, ley rules (JSON)
↓ read at runtime by Rust
src/simulator/crates/ ← SOURCE OF TRUTH (all simulation logic)
├── compiled via api-gdext/ → src/game/addons/magic_civ_physics/*.so/.dll
│ ↓ loaded by Godot
│ src/game/engine/src/modules/climate/climate.gd ← thin GDExtension wrapper
└── compiled via api-wasm/ → .local/build/wasm/ (NOT src/simulator/pkg/ —
↓ imported by web worker build output never under src/,
public/games/age-of-dwarves/guide/src/simulation/ see build-output-locations.md)
simulation.worker.ts
Build commands
# WASM (web guide)
cd src/simulator && bash build-wasm.sh
# GDExtension (Godot game, Linux dev)
cd src/simulator && bash build-gdext.sh
In practice these run on the RUN host via ssh — see canonical-commands.md.
Rules
- All simulation changes go in Rust (
src/simulator/crates/) — never in GDScript or TypeScript, except AI action generation, which currently lives insrc/game/engine/src/modules/ai/simple_heuristic_ai.gd. - Never hardcode thresholds — read from
climate_spec.jsonand other JSON data files. - Ecological events require a seed — deterministic PRNG seeded per-turn.
- Golden test vectors verify WASM output matches expected results.
- GDScript climate/combat/magic/economy files are thin wrappers — they call
GdClimatePhysics,GdEcologyPhysics, etc. via GDExtension. No physics logic lives in GDScript.
Crate responsibilities
| Crate | Owns |
|---|---|
mc-core |
GridState, TileState, BiomeRegistry, hex algorithms |
mc-climate |
ClimatePhysics, EcologyPhysics, atmosphere, spec evaluator |
mc-mapgen |
MapGenerator |
mc-combat |
CombatResolver |
mc-magic |
SpellSystem, ManaPool, Archons (Game 2) |
mc-economy |
EmpireEconomy |
mc-city |
CityGrowth |
mc-happiness |
happiness pool |
mc-culture |
CultureAccumulation |
mc-tech |
TechWeb graph |
mc-ai |
AI scoring weights + data structs (not action generation) |
mc-turn |
TurnProcessor |