diff --git a/.project/designs/app/src/pages/TerrainEcology.tsx b/.project/designs/app/src/pages/TerrainEcology.tsx
index d8e488c6..f6807cfe 100644
--- a/.project/designs/app/src/pages/TerrainEcology.tsx
+++ b/.project/designs/app/src/pages/TerrainEcology.tsx
@@ -39,7 +39,14 @@ interface FaunaSpecies {
ecology_tier?: number;
trophic_level?: string;
terrain_affinity?: string[];
+ migration_range?: number;
+ carrying_capacity?: number;
+ food_consumption_per_turn?: number;
+ habitat_min?: number;
+ combat_profile?: { hp: number; strength: number; dexterity: number; constitution: number };
cognitive_profile?: { intelligence: number; can_hold_grudge: boolean };
+ devastation?: { auto_defeat_tier_at_or_below: number; description: string };
+ loot_table?: { legendary?: string[]; rare?: string[]; common?: string[] };
}
interface WildUnit {
@@ -356,16 +363,27 @@ export function TerrainEcologyPage(): ReactElement {
fauna ({faunaOnTerrain.length})
{faunaOnTerrain.length === 0 && none mapped to this terrain}
- {faunaOnTerrain.map(f => (
-
- {f.name}
-
- {f.ecology_tier && tier {f.ecology_tier}}
- {f.trophic_level && {f.trophic_level}}
- {f.cognitive_profile?.can_hold_grudge && ✦ grudge int{f.cognitive_profile.intelligence}}
-
-
- ))}
+ {faunaOnTerrain.map(f => {
+ const isApex = (f.ecology_tier ?? 0) >= 8;
+ const accent = isApex ? "#d95940" : (f.combat_profile ? "#e69933" : "#a07cc9");
+ return (
+
+
+ {f.name}{isApex && ★ apex}
+
+
+ {f.ecology_tier && tier {f.ecology_tier}}
+ {f.trophic_level && {f.trophic_level}}
+ {f.migration_range !== undefined && range {f.migration_range}h}
+ {f.food_consumption_per_turn !== undefined && eats {f.food_consumption_per_turn}/t}
+ {f.combat_profile && hp {f.combat_profile.hp}, str {f.combat_profile.strength}}
+ {f.cognitive_profile?.can_hold_grudge && ✦ grudge int{f.cognitive_profile.intelligence}}
+ {f.devastation && devastates ≤t{f.devastation.auto_defeat_tier_at_or_below}}
+ {f.loot_table?.legendary?.length && ★ {f.loot_table.legendary.length} legendary}
+
+
+ );
+ })}
diff --git a/public/resources/ecology/fauna/species/ancient_green_dragon.json b/public/resources/ecology/fauna/species/ancient_green_dragon.json
new file mode 100644
index 00000000..01cd3793
--- /dev/null
+++ b/public/resources/ecology/fauna/species/ancient_green_dragon.json
@@ -0,0 +1,91 @@
+{
+ "id": "ancient_green_dragon",
+ "name": "Ancient Green Dragon",
+ "description": "A wyrm of canopy and cunning — the smallest of the great dragons by mass, the largest by malice. Speaks dwarven, elf-tongue, kobold; lies in all four.",
+ "tags": [
+ "fauna",
+ "tier_10",
+ "apex_predator",
+ "boss",
+ "poison_breath",
+ "cunning"
+ ],
+ "domain": "land_air",
+ "trophic_level": "apex_predator",
+ "lineage": "true_dragon",
+ "ecology_tier": 10,
+ "traits": [
+ "poison_immune",
+ "flying",
+ "venom_breath_acid",
+ "deceiver",
+ "ancient"
+ ],
+ "habitat_min": 0.5,
+ "migration_range": 12,
+ "carrying_capacity": 0.35,
+ "food_consumption_per_turn": 5,
+ "lifecycle": {
+ "mature_age_turns": 3500,
+ "max_age_turns": null
+ },
+ "terrain_affinity": [
+ "jungle",
+ "tropical_rainforest",
+ "enchanted_forest",
+ "swamp",
+ "bog"
+ ],
+ "combat_profile": {
+ "hp": 680,
+ "strength": 24,
+ "dexterity": 18,
+ "constitution": 22,
+ "attack_type": "acid_breath",
+ "range": 4,
+ "defense": 18,
+ "breath_weapon": {
+ "damage": 45,
+ "area_radius": 1,
+ "cooldown_turns": 2
+ }
+ },
+ "cognitive_profile": {
+ "intelligence": 10,
+ "hostility": "hunting",
+ "can_hold_grudge": true,
+ "grudge_memory_turns": 200
+ },
+ "devastation": {
+ "auto_defeat_tier_at_or_below": 5,
+ "description": "Cunning beyond intimidation — manipulates lesser creatures, sets traps, recruits goblins as pawns. May parley if approached at tier 8+ with appropriate tribute (gold + slaves traditionally)."
+ },
+ "loot_table": {
+ "legendary": [
+ "green_dragon_scale",
+ "green_dragon_heart",
+ "venomous_hoard"
+ ],
+ "rare": [
+ "acid_fang",
+ "wisdom_codex_lost"
+ ],
+ "common": [
+ "acid_etched_bone"
+ ]
+ },
+ "flavor": "It has been planning your death for sixty years. It will not appear hurried about it.",
+ "encyclopedia": {
+ "category": "fauna",
+ "entry_type": "species",
+ "detail_route": "/bestiary",
+ "tags": [
+ "fauna",
+ "tier_10",
+ "boss",
+ "dragon",
+ "poison",
+ "intelligent"
+ ]
+ }
+}
diff --git a/public/resources/ecology/fauna/species/ancient_red_dragon.json b/public/resources/ecology/fauna/species/ancient_red_dragon.json
new file mode 100644
index 00000000..a5e2ac9d
--- /dev/null
+++ b/public/resources/ecology/fauna/species/ancient_red_dragon.json
@@ -0,0 +1,87 @@
+{
+ "id": "ancient_red_dragon",
+ "name": "Ancient Red Dragon",
+ "description": "An ageless wyrm of fire and avarice. Hunts entire valleys; sleeps on hoards built across centuries. Anything below the iron age is prey.",
+ "tags": [
+ "fauna",
+ "tier_10",
+ "apex_predator",
+ "boss",
+ "fire_breath"
+ ],
+ "domain": "land_air",
+ "trophic_level": "apex_predator",
+ "lineage": "true_dragon",
+ "ecology_tier": 10,
+ "traits": [
+ "fire_immune",
+ "flying",
+ "venom_breath_fire",
+ "treasure_hoarder",
+ "ancient"
+ ],
+ "habitat_min": 0.6,
+ "migration_range": 18,
+ "carrying_capacity": 0.45,
+ "food_consumption_per_turn": 8,
+ "lifecycle": {
+ "mature_age_turns": 5000,
+ "max_age_turns": null
+ },
+ "terrain_affinity": [
+ "mountains",
+ "volcano"
+ ],
+ "combat_profile": {
+ "hp": 850,
+ "strength": 32,
+ "dexterity": 12,
+ "constitution": 26,
+ "attack_type": "fire_breath",
+ "range": 4,
+ "defense": 22,
+ "breath_weapon": {
+ "damage": 60,
+ "area_radius": 2,
+ "cooldown_turns": 3
+ }
+ },
+ "cognitive_profile": {
+ "intelligence": 9,
+ "hostility": "hunting",
+ "can_hold_grudge": true,
+ "grudge_memory_turns": 100,
+ "pack_behavior": null
+ },
+ "devastation": {
+ "auto_defeat_tier_at_or_below": 5,
+ "description": "Any unit of tier 5 or lower facing this dragon alone is destroyed without contest. Tier 6-7 stand a chance only with prepared positions and ranged support. Tier 8+ (steam-era weapons, mithril alloys) can engage as a coordinated company."
+ },
+ "loot_table": {
+ "legendary": [
+ "red_dragon_scale",
+ "red_dragon_heart",
+ "ancient_hoard_treasure"
+ ],
+ "rare": [
+ "dragon_fang",
+ "dragon_fire_gland"
+ ],
+ "common": [
+ "scorched_bone"
+ ]
+ },
+ "flavor": "It does not raid the village. It owns the village. The villagers simply weren't told.",
+ "encyclopedia": {
+ "category": "fauna",
+ "entry_type": "species",
+ "detail_route": "/bestiary",
+ "tags": [
+ "fauna",
+ "tier_10",
+ "boss",
+ "dragon",
+ "fire"
+ ]
+ }
+}
diff --git a/public/resources/ecology/fauna/species/ancient_white_dragon.json b/public/resources/ecology/fauna/species/ancient_white_dragon.json
new file mode 100644
index 00000000..2a99434c
--- /dev/null
+++ b/public/resources/ecology/fauna/species/ancient_white_dragon.json
@@ -0,0 +1,89 @@
+{
+ "id": "ancient_white_dragon",
+ "name": "Ancient White Dragon",
+ "description": "A wyrm of glacier and silence. Stalks the frozen wastes, freezing prey solid. Cold older than the dwarven kingdoms.",
+ "tags": [
+ "fauna",
+ "tier_10",
+ "apex_predator",
+ "boss",
+ "cold_breath"
+ ],
+ "domain": "land_air",
+ "trophic_level": "apex_predator",
+ "lineage": "true_dragon",
+ "ecology_tier": 10,
+ "traits": [
+ "cold_immune",
+ "flying",
+ "venom_breath_cold",
+ "stealth_snow",
+ "ancient"
+ ],
+ "habitat_min": 0.7,
+ "migration_range": 14,
+ "carrying_capacity": 0.3,
+ "food_consumption_per_turn": 6,
+ "lifecycle": {
+ "mature_age_turns": 4000,
+ "max_age_turns": null
+ },
+ "terrain_affinity": [
+ "ice",
+ "snow",
+ "polar_desert",
+ "alpine_tundra",
+ "tundra"
+ ],
+ "combat_profile": {
+ "hp": 720,
+ "strength": 28,
+ "dexterity": 14,
+ "constitution": 24,
+ "attack_type": "cold_breath",
+ "range": 4,
+ "defense": 20,
+ "breath_weapon": {
+ "damage": 50,
+ "area_radius": 2,
+ "cooldown_turns": 3
+ }
+ },
+ "cognitive_profile": {
+ "intelligence": 7,
+ "hostility": "hunting",
+ "can_hold_grudge": true,
+ "grudge_memory_turns": 80
+ },
+ "devastation": {
+ "auto_defeat_tier_at_or_below": 5,
+ "description": "Cold breath shatters armor. Pre-iron units freeze without dealing a strike."
+ },
+ "loot_table": {
+ "legendary": [
+ "white_dragon_scale",
+ "white_dragon_heart",
+ "frozen_hoard"
+ ],
+ "rare": [
+ "frost_fang",
+ "frostmaw_gland"
+ ],
+ "common": [
+ "ice_riven_bone"
+ ]
+ },
+ "flavor": "You hear the wing-beat. Then nothing. The cold takes your hearing first.",
+ "encyclopedia": {
+ "category": "fauna",
+ "entry_type": "species",
+ "detail_route": "/bestiary",
+ "tags": [
+ "fauna",
+ "tier_10",
+ "boss",
+ "dragon",
+ "cold"
+ ]
+ }
+}