Sep 21, 2026

Mythic Keep: a data-driven colony sim

A RimWorld- and Dwarf Fortress-style colony sim in Godot, built around a data-defined body model, LOD tick staggering and field physics over active sets.

  • Godot
  • GDScript
  • Simulation
  • Performance
  • Procedural generation

Overview

Mythic Keep is a colony simulation in the tradition of RimWorld and Dwarf Fortress, built in Godot 4.3+ in GDScript. Its colonists are procedurally generated fantasy characters with genetic lineages: genomes inherited across generations, bodies assembled from data-defined parts, and needs that depend on their biology. Around them sits a multi-level tile world with construction, rooms, temperature, water, fire, collapsing floors, a job system and d20-based combat.

Status: MVP. The simulation core, world, jobs, equipment, social layer, combat, medical layer and save/load are complete and wired into a playable demo with a main menu, inspector panels and a first player command bar. Art is placeholder tints; the art pipeline is under way.

Engineering specs

Area Implementation Purpose
Data model Immutable Resource defs, per-pawn compiled modifier arrays, packed live state New content is a .tres file, with no code change
Body Slots filled by parts; stats derived from part health and size Losing a leg halves speed because the leg provides speed
LOD scheduling FULL / COARSE / DORMANT buckets with scaled time spans Most pawns off-screen cost a fraction of a full tick
World Six z-levels, AStarGrid2D per level, versioned path invalidation Stairs, digging and doors without per-tick replanning
Physics fields Temperature, water, fire over per-level active sets Only changed cells and their neighbours are simulated

Technical deep dive

The data model has three layers. Definitions (genes, traits, needs, body parts, buildings, materials, recipes, actions) are Godot Resource files that a registry discovers at startup and indexes densely. Effects are generic dictionaries such as a need’s decay multiplier, so the engine never knows what “hunger” or “cold” means. Each pawn compiles its genes, traits, life stage, career and equipment into index-addressed float arrays once per change, and the hot loops read only those. Live state for needs and stats lives in shared row stores, so the needs pass is one flat loop over the store without touching a pawn object.

Stats are never stored as a true value; they are derived from the body. A body is a set of slots filled by parts, each providing stats scaled by its health fraction. A missing limb is an empty slot, prostheses are parts that don’t heal, and a medical layer adds pain-driven consciousness states with hysteresis, rare hits to vital organs, and bleeding that clots. Damage is queued during the update phase and applied in a resolve phase, so every system sees one body state per tick.

The tick runs in input, update and resolve phases on a fixed-step accumulator. Pawns sit in LOD buckets: those on the viewed z-level every tick, those on other levels every 4 ticks, and those off the map every 20, each simulated with a span equal to its stride so a coarse pawn’s needs decay by the same total (this is tested). Coarse pawns bank movement credit and hop whole waypoints at the same average speed. Procedural generation is a module behind one entry point: a noise-based world map of elevation, temperature, moisture, biomes and rivers, then a local site laid out from the chosen cell.

Rendering is two MultiMesh draws, one for pawns and one for items. A save round-trips the whole world, and a test checks that a loaded world steps on identically for 200 ticks.

Key challenge: keeping a deep simulation affordable in pure GDScript. The project kept a numbered list of the bottlenecks a naive design would hit, with the mitigation for each: dirty flags instead of per-tick recomputation, bitmask environment tags, a damaged-slot list instead of body scans, and incremental room and connectivity rebuilds that brought a wall edit from 25-97 ms down to about 1 ms regardless of map size. On the reference benchmark of 1,000 pawns, a realistic mix of LODs runs at about 3.5 ms per tick, roughly 7% of one core at 20 ticks per second.

← All projects