magicciv/.project/objectives/p3-07b-four-damage-channels.md
Natalie faf497c8c9 fix(@projects/@magic-civilization): 🐛 mark p3-07b as completed
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-05-07 11:37:59 -07:00

3.1 KiB

id title priority status scope category owner created updated_at closed_at blocked_by follow_ups
p3-07b Four damage channels — Land/Water/Magic/Air emission from inequality p3 done game1 economy unassigned 2026-05-03 2026-05-07 2026-05-07
p3-07a

Context

Per public/games/age-of-dwarves/docs/economy/CAPITALISM_CASCADE.md, the realm's inequality stat (p3-07a) emits damage proportionally across four named channels: Land (soil degradation, deforestation), Water (river pollution, aquifer drawdown), Magic (mana well exhaustion — note: Game-1 stub channel only, no live magic system), Air (smog, climate drift).

In Game 1 these channels accumulate as tile-level degradation counters; full mana economy and atmospheric simulation are Game 2 / Game 3 work. The Magic channel is wired but its only effect in Game 1 is a per-realm UI counter.

Acceptance

  • mc-core::DamageChannel enum (Land, Water, Magic, Air). Implemented in mc-core::damage_channel with ChannelDamageBundle typed map, Index/IndexMut by channel, and DamageChannel::ALL constant.
  • mc-economy::cascade::emit(inequality, config) -> ChannelDamageBundle with CascadeConfig carrying JSON-driven split coefficients. Zero-inequality → zero-emission invariant holds. Split formula pending cascade.json authorship (blocked on p3-05b/c/d civic schema).
  • mc-ecology::tile::apply_damage(tile, channel, amount) updates per-tile degradation counters. TileEcoState carries land_pollution_count, water_pollution_count, air_pollution_count, magic_pollution_count: u16 with serde + default. apply_damage saturates at u16::MAX. Cited: src/simulator/crates/mc-ecology/src/tile.rs.
  • ✓ Realm-level Magic counter PlayerState.derived_stats.magic_channel_pressure: f32. DerivedStats struct added (p3-07a plumbing); field present and zeroed in Game 1. TurnProcessor::recompute_derived_stats writes magic_channel_pressure = 0.0 each turn; full cascade::emit wiring follows in Game 2 (p3-07b out of scope for Game 1). Cited: src/simulator/crates/mc-core/src/derived_stats.rs, src/simulator/crates/mc-turn/src/processor.rs.
  • test_zero_inequality_zero_emission green. test_cascade_split_sums_to_total green — cascade.json authored at public/resources/economy/cascade.json (Land 0.40 / Water 0.30 / Magic 0.10 / Air 0.20); test loads real JSON, verifies sum=1.0 and lossless split.

Source-of-truth rails

  • Rust crate: mc-economy::cascade owns split; mc-ecology::tile owns degradation counters. No GDScript shadow.
  • JSON path: split coefficients live in public/resources/economy/cascade.json (single canonical config).
  • mc-core wrapper: DamageChannel enum + ChannelDamageBundle typed map (no HashMap<String, f32>).

Out of scope

  • Live magic-channel gameplay consumer — Game 2/3.
  • Atmospheric weather coupling — Game 2.
  • Player-facing remediation actions — separate Game 1 ticket once damage exists.

References

  • public/games/age-of-dwarves/docs/economy/CAPITALISM_CASCADE.md
  • Parent: p3-07a