4.7 KiB
Game Pack Subscription Model
Overview
The engine is genre-agnostic. "Every game is a mod." A game pack is a directory under games/ that subscribes to shared content from resources/ and defines game-specific configuration on top.
@magic-civilization/
resources/ ← Shared content library (all games subscribe)
games/
age-of-dwarves/ ← EA: 1 race, no magic
age-of-4/ ← Expansion: 4 races + magic
age-of-16/ ← Full: 16 races, all fusions
engine/
src/worlds/ ← Planet physics definitions (engine-level, not game content)
Load Order
DataLoader.load_theme(id) does a two-pass load:
res://resources/— shared content library (races, tiles, biomes, buildings, worlds, etc.)res://games/{id}/data/— game-specific data; merges into and overrides shared content byid
This means:
- A game pack gets all shared content for free
- It can override any shared entry by providing a file with the same
id - Game-specific data (setup, map types, eras) lives only in the game pack
resources/races/dwarves.json → loaded first (shared definition)
games/age-of-dwarves/data/races/ → game could override (e.g. adjusted stats)
Directory Mapping
| Category | resources/ path |
games/{id}/data/ path |
|---|---|---|
terrain |
tiles/ |
terrain/ |
throne_room |
throne_rooms/ |
throne_room/ |
homeworlds |
worlds/ |
worlds/ |
resources |
natural_resources/ |
resources/ |
world_biomes |
world/biomes/ |
world/biomes/ |
world_fauna |
world/fauna/ |
world/fauna/ |
world_flora |
world/flora/ |
world/flora/ |
world_ecosystem |
world/ecosystem/ |
world/ecosystem/ |
world_traits |
world/traits/ |
world/traits/ |
| (others) | {category}/ |
{category}/ |
game.json Fields
Every game pack has a game.json manifest:
{
"id": "age-of-4",
"name": "Age of Four",
"version": "1.0.0",
"engine_version": ">=1.0.0",
"playable_races": ["high_elves", "humans", "dwarves", "orcs"],
"discipline_count": 5,
"era_count": 10,
"transit_layers": 0,
"settings": { "gender_system": true }
}
playable_races is a UI filter — the engine loads all 16 races from resources/races/ regardless, but the game setup screen only shows the subscribed races. This means AI opponents, diplomacy fallbacks, and stub race data are always available.
Planet Archetypes
Physics definitions live in engine/src/worlds/{archetype}/. They are engine-level, not game content — a game pack cannot override planet physics (yet). Three archetypes exist:
| ID | Name | Gravity | Key features |
|---|---|---|---|
earth |
Earth-like | 1.0g | Full ecology, water cycle, weather, volcanism |
mars |
Mars — Red Planet | 0.38g | Thin CO₂, dust storms, no ecology, CO₂ cycle |
venus |
Venus — Runaway Greenhouse | 0.91g | Dense atmosphere, volcanism, acid clouds |
Gravity is a mechanical field. It propagates into unit stat modifiers at runtime — units native to low-gravity worlds (mars) gain movement and range bonuses on mars-type maps.
Race Homeworlds
Each race definition (resources/races/{id}.json) carries:
{
"homeworld": "khazad_prime",
"terrain_affinity": {
"mountains": { "production": 2, "defense": 15 },
"hills": { "production": 1, "movement_cost_reduction": 1 }
}
}
Each homeworld profile (resources/worlds/{id}.json) carries:
{
"world_archetype": "earth",
"planetary_bonuses": {
"condition": "map_archetype == world_archetype",
"stat_modifiers": { "production": 1, "fortification_rate": 10 },
"gravity_adaptation": { "native_gravity": 1.0 }
}
}
Two bonus layers are separate:
| Layer | Where defined | When it applies |
|---|---|---|
| Terrain affinity | Race (resources/races/) |
Always — wherever those tile types appear |
| Planetary bonus | Homeworld (resources/worlds/) |
Only when map archetype matches homeworld archetype |
Release Tiers
| Game Pack | Races | Magic | Status |
|---|---|---|---|
age-of-dwarves |
1 (Dwarves only) | No | EA release |
age-of-4 |
4 (Elves, Humans, Dwarves, Orcs) | Yes (all 5 schools) | Expansion |
age-of-8 |
8 (+Dark Elves, Fae, Gnomes, Halflings) | Yes + v3 fusions | v3 |
age-of-12 |
12 (+Draconians, Undead, Beastmen, Lizardmen) | Yes + v5 fusions | v5 |
age-of-16 |
16 (all races) | Yes + all 10 fusions | v7/Full |
Each tier is a separate game pack directory. All share the same resources/ library — new races arrive in resources/races/ as stubs and are activated by listing them in playable_races.