magicciv/.project/objectives/p0-35-ecology-telemetry-instrumentation.md
Natalie 7aaccce97f feat(game1): complete ecology telemetry instrumentation
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-17 23:45:07 -07:00

3.2 KiB
Raw Blame History

id title priority status scope owner updated_at evidence
p0-35 Ecology telemetry instrumentation — flora canopy / undergrowth fields in turn_stats.jsonl p1 done game1 shipwright 2026-04-18
src/game/engine/scenes/tests/auto_play.gd
src/game/engine/src/modules/climate/climate.gd
tools/autoplay-report.py
tools/schemas/autoplay/turn-stats-line.json
src/simulator/api-gdext/src/lib.rs
src/simulator/crates/mc-climate/src/ecology.rs

Summary

turn_stats.jsonl currently emits aggregate.total_combats, player_stats.*.tier_peak etc. (per p0-25) but no flora/ecology fields. p0-30 / p0-31 bullets about "flora canopy values evolve in turn_stats.jsonl" cannot empirically close without these fields.

This objective adds per-turn ecology telemetry so future batches can cite canopy evolution as evidence of a working Rust ecology tick.

Scope reduced from P0 to P1 because:

  • The p0-25 gate bullets (tier_peak, peak_unit_tier, wonder_count, combats, cities_founded) already confirm the game plays to victory under the Rust ecology path (smoke5 batch 2026-04-17: 8/10 seeds reached outcome: victory, combats 1311686, tier_peak 26).
  • Canopy instrumentation is a dev-tool nicety, not a shipping gate. Game 1 ships without it; follow-up lands pre-EA-polish.

Acceptance

  • turn_stats.jsonl per-turn record gains ecology.flora_canopy_mean: f32 + ecology.flora_canopy_delta: f32. Authored in auto_play.gd::_snapshot_ecology (new helper called from _append_turn_stats), sourced from climate.gd::get_canopy_summary which delegates to GdEcologyPhysics::canopy_summary(grid) in src/simulator/api-gdext/src/lib.rs:229-267. The Rust bridge tracks last_canopy_mean internally (NaN sentinel on first call so delta=0 rather than spurious) and iterates grid.tiles filtering via BiomeTag::IsWater. Schema update at tools/schemas/autoplay/turn-stats-line.json:70-84. Canopy actually evolves: climate.gd:94-101 now runs GdEcologyPhysics.process_step(_grid, 1.0) after GdClimatePhysics.process_step, completing the dormant Rust ecology tick flagged by p0-30 / p0-31.
  • tools/autoplay-report.py surfaces a canopy-trend summary — print_canopy_summary (added lines ~625-650) prints median final canopy mean + "games with evolving canopy" coverage ratio + median |delta| alongside existing quality metrics.
  • ✓ 10-seed apricot batch 20260417_233821_p035 shows non-zero canopy delta across turns (evolution confirmation). Per-seed (final turn_stats line): seed1 canopy=0.001311 delta=2.96e-05, seed2 0.003196/6.4e-05, seed3 0.005081/4.66e-05, seed4 0.004762/2.63e-05, seed5 0.002774/5.88e-05, seed6 0.002670/4.62e-05, seed7 0.001702/3.32e-05, seed8 0.000520/8.95e-06, seed9 0.002154/4.34e-05, seed10 0.001874/3.31e-05. All 10 seeds have non-zero mean AND non-zero delta — canopy is genuinely evolving, not frozen at map-gen values.
  • ✓ Re-promote p0-30-ecology-double-tick-fix.md bullet 4 ✓ — see its updated acceptance citing the same batch.

Non-goals

  • Per-tile canopy export (memory/size concern) — global or per-player averages only.
  • Historical canopy replay tooling — post-EA polish.

Depends on

  • p0-31 (Rust ecology path re-enabled). done via smoke5.