docs(docs-specific): 📝 Update engine-specific documentation in the docs directory

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Claude Code 2026-03-28 21:31:38 -07:00
parent 56b494fed4
commit 9bc36d88ca

View file

@ -0,0 +1,276 @@
# Environment Architecture: Worlds, Planes, and Environment Packages
## Overview
The engine supports multiple distinct environments — surfaces of planets, underground
caverns, ethereal planes, extra-solar worlds. Each environment has its own biome set,
climate rules, terrain generation, and ecological systems. Environments are composable:
they subscribe to shared biome collections rather than defining everything from scratch.
## Hierarchy
```
Game Pack (e.g., "Age of Dwarves")
├── declares Worlds and Planes
│ ├── World: "surface" → environment: earth-environment
│ ├── World: "underground" → environment: cave-environment
│ └── Plane: "ethereal" → environment: ether-plane
└── each environment subscribes to Biome Collections
├── earth-environment → [aquatic, temperate, tropical, arctic, elevated]
├── cave-environment → [subterranean, aquatic-underground]
└── ether-plane → [ethereal]
```
### Worlds vs Planes
| Concept | World | Plane / Dimension |
|---------|-------|-------------------|
| What | A physical body (planet, moon, asteroid) | An alternate reality overlaid on a world |
| Examples | Earth surface, Mars, underground caverns | Ethereal Plane, Shadow Dimension |
| Map | Independent hex grid with own generation | May share spatial coordinates with a world |
| Climate | Has full climate physics (temp, moisture, wind) | May have simplified or alien physics |
| Traversal | Travel between worlds = long-range (portals, ships) | Plane shift = local (enter/exit at same position) |
Both worlds and planes are **environments** from the engine's perspective — they have
biomes, tiles, and rules. The distinction matters for gameplay (how you get there, what
rules apply) but not for the engine's data architecture.
## Environment Packages
An environment package is a self-contained definition of "what exists in this world."
### Package Contents
```
environment-package/
├── biomes.json — biome definitions + tags (subscribed collections merged)
├── climate_params.json — climate physics tuning (or null for no-climate worlds)
├── climate_spec.json — biome classification thresholds
├── substrates.json — geological substrates
├── generation/ — terrain generation rules
│ ├── terrain_fractions.json
│ └── placement_rules.json
└── manifest.json — package metadata, subscribed collections
```
### manifest.json
```json
{
"id": "earth-environment",
"name": "Earth-like Environment",
"description": "Temperate planet with oceans, continents, and full climate simulation.",
"has_climate": true,
"has_weather": true,
"has_ecology": true,
"subscribes": [
"biomes/aquatic",
"biomes/temperate",
"biomes/tropical",
"biomes/arctic",
"biomes/elevated"
]
}
```
### Subscription Model
Environment packages don't duplicate biome definitions. They subscribe to **biome
collections** — shared libraries of biome definitions that multiple environments can reuse.
```
Biome Collections (shared resources)
├── biomes/aquatic — ocean, coast, deep_ocean, coral_reef, lake, pond, river, ...
├── biomes/temperate — forest, grassland, plains, chaparral, bog, ...
├── biomes/tropical — jungle, savanna, mangrove, tropical_rainforest, ...
├── biomes/arctic — tundra, polar_desert, glacial, sea_ice, ...
├── biomes/elevated — mountains, hills, alpine_meadow, alpine_tundra, ...
├── biomes/subterranean — cave, fungal_forest, underground_lake, crystal_cavern, ...
├── biomes/magical — enchanted_forest, mana_node, corrupted_wasteland, ...
└── biomes/ethereal — spirit_mist, void_rift, planar_nexus, ...
```
A new planet only needs to declare which collections it subscribes to. Tags, climate
ranges, flora climax values, and fauna capacity all come from the collection definitions.
An environment can also define **local overrides** — biomes unique to that world that
don't belong in any shared collection. These are declared directly in the package's
`biomes.json` alongside the subscribed collections.
## Biome Tags
Every biome declares semantic tags. The engine queries tags — never biome ID strings.
### Core Tags (engine-defined contract)
These tags have engine-level meaning. The engine's climate, generation, and ecology
systems query them. Any environment package must use these tags correctly for engine
systems to function.
| Tag | Meaning | Engine Usage |
|-----|---------|-------------|
| `is_water` | Liquid water body | Evaporation, hydrology, navigation, marine ecology |
| `is_elevated` | High terrain | Wind blocking, rain shadow, generation, movement |
| `is_frozen` | Ice/snow covered | Freeze/thaw physics, temperature transitions |
| `has_vegetation` | Supports plant life | Evapotranspiration, ecology, fire spread |
| `is_volcanic` | Active volcanism | Aerosol injection, deep earth water, terrain skip |
| `is_dry` | Arid terrain | River generation skip, dust aerosol |
| `is_wetland` | Saturated ground | Substrate classification, drainage |
| `is_coast` | Land-water boundary | Marine resources, coastal weather, reef systems |
| `is_grassland` | Open low vegetation | Building placement, terrain fallback |
### Custom Tags (environment-defined)
Environment packages can define additional tags for game-pack-specific logic:
| Tag | Example Usage |
|-----|--------------|
| `is_magical` | Mana generation, spell interactions |
| `is_corrupted` | Corruption spreading, purification targets |
| `is_subterranean` | No sky, different light rules |
| `is_ethereal` | Plane-specific movement, visibility |
The engine ignores tags it doesn't recognize. Game-pack systems (spells, mana, etc.)
can query custom tags through the same BiomeRegistry API.
## BiomeRegistry
The BiomeRegistry is an engine autoload that provides tag-based biome queries. It is
**scoped per environment** — each world/plane has its own registry instance with its own
biome set.
### API
```gdscript
BiomeRegistry.has_tag(biome_id: String, tag: String) -> bool
BiomeRegistry.get_tags(biome_id: String) -> Array[String]
BiomeRegistry.get_biomes_with_tag(tag: String) -> Array[String]
BiomeRegistry.register_runtime_biome(biome_id: String, tags: Array[String])
```
### Multi-Environment Scoping
For Age of Dwarves (single surface world), BiomeRegistry loads the earth-environment
biomes at startup. Future multi-world games will need per-environment registries:
```gdscript
# Future API (not implemented yet):
var surface_registry = BiomeRegistry.for_environment("earth-environment")
var cave_registry = BiomeRegistry.for_environment("cave-environment")
# Current API (single environment, sufficient for AoD):
BiomeRegistry.has_tag("ocean", "is_water") # queries the active environment
```
The current implementation uses a single global registry. The architecture supports
future per-environment scoping by making the registry data-driven (loaded from the
environment package's biomes.json, not hardcoded).
### Runtime Biomes
Some biomes are created dynamically during simulation (ice from frozen water, snow from
temperature). These aren't in biomes.json but need tags. The registry supports runtime
registration:
```gdscript
# Called by climate system when water freezes:
BiomeRegistry.register_runtime_biome("ice", ["is_frozen", "is_water"])
```
Runtime biome tags are defined in the environment package's manifest, not in engine code.
## Example: Age of Dwarves Environments
### Surface World (earth-environment)
Subscribes to: aquatic, temperate, tropical, arctic, elevated.
~26 biomes. Full climate simulation. Weather events. Ecological events.
### Underground (cave-environment)
Subscribes to: subterranean, aquatic-underground.
~8-12 biomes (cave, fungal_forest, underground_lake, crystal_cavern, lava_tube, etc.).
No climate simulation (stable temperature). No weather. Simplified ecology.
Different generation rules (cave system generation vs continental).
## Example: Full Magic Game Environments
### Surface World (magical-earth-environment)
Subscribes to: aquatic, temperate, tropical, arctic, elevated, magical.
~35 biomes (all earth biomes + enchanted_forest, mana_node, corrupted_wasteland, etc.).
Full climate + mana weather. Magical ecological events.
### Ethereal Plane (ether-plane)
Subscribes to: ethereal.
~6-10 biomes (spirit_mist, void_rift, planar_nexus, essence_pool, etc.).
No climate. Unique physics (mana-based). Different map topology.
## Migration Path
### Phase 1 (Current: Age of Dwarves)
- BiomeRegistry autoload with tag queries
- earth-environment biomes defined in existing `biomes.json` with tags added
- Engine refactored to use `BiomeRegistry.has_tag()` instead of string comparisons
- Single-environment (no per-world scoping needed yet)
### Phase 2 (Underground)
- cave-environment package with its own biomes.json
- BiomeRegistry gains environment-scoping
- Map system supports multiple environments (already has "layers" concept)
### Phase 3 (Full Magic Game)
- magical-earth-environment subscribes to earth collections + magical collection
- ether-plane environment for the Ethereal Plane transit layer
- Biome collections extracted as shared resources
### Phase 4 (Extra-Solar)
- New planet types subscribe to different collection combinations
- Alien biome collections (silicon-based life, gas giant atmospheres, etc.)
- Same engine, same BiomeRegistry API, completely different content
## File Organization
```
engine/
src/
autoloads/
biome_registry.gd — tag query autoload (environment-scoped)
data_loader.gd — load_world() reads manifest + collections
models/world/
biome.gd — BiomeModel with tags field
worlds/
collections/ — shared biome collections (reusable across worlds)
aquatic/biomes.json — deep_ocean, shallow_ocean, coral_reef, estuary, lake, pond, river, mangrove
arctic/biomes.json — sea_ice, glacial, polar_desert, tundra, alpine_tundra, boreal_forest
temperate/biomes.json — chaparral, temperate_grassland, temperate_forest
tropical/biomes.json — desert, savanna, tropical_dry_forest, tropical_rainforest
elevated/biomes.json — hills, mountains, alpine_meadow, montane_forest, cloud_forest
wetland/biomes.json — swamp, bog
special/biomes.json — volcanic, subterranean
earth/ — earth-like world definition
manifest.json — subscribes: [aquatic, arctic, temperate, tropical, elevated, wetland, special]
runtime_biomes.json — biomes created during simulation (ice, snow, etc.)
substrates.json — geological substrates
cave/ — future: underground world
manifest.json
ethereal/ — future: ether plane
manifest.json
```
### Loading Flow
1. `DataLoader.load_theme("age-of-dwarves")` loads game pack data as before
2. `DataLoader.load_world("earth")` reads manifest, merges collection biomes, registers runtime biomes
3. `BiomeRegistry.rebuild_from_data()` rebuilds tag caches from merged biome set
4. Game-pack biomes take precedence over collection biomes (local overrides)
Climate params and spec remain in the game pack (`games/age-of-dwarves/data/`) since
they are tuned per game. The world definition provides the biome composition; the game
pack provides the physics tuning.