3.8 KiB
3.8 KiB
| id | title | priority | status | scope | category | owner | created | updated_at | k_of_n | blocked_by | evidence | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| p2-63 | mc-flora generation: migrate biome filter to substrate_climate-aware path | p2 | done | game1 | ecology | simulator-infra | 2026-05-04 | 2026-05-13 | 4/4 |
|
Summary
Authored flora JSON files have migrated from a top-level biomes: [...]
array to the substrate_climate ontology
(see p2-52-substrate-flora-cover-ontology-split.md). The biome-filter
loop in mc-flora/src/generation.rs was not updated, so the
AuthoredSpeciesFile.biomes field is now empty for every authored file
and the candidate-pool query returns nothing.
Two pre-existing regression tests in mc-flora document the gap:
load_authored_returns_species_for_known_biome(generation.rs:645)generate_flora_for_biome_more_species_with_authored_files(generation.rs:695)
Both fail because the biome filter at generation.rs:508-510 still
checks raw.biomes.iter().any(|b| b == biome_id) while the JSON now
encodes biome eligibility through substrate_climate blocks the loader
does not currently inspect.
Acceptance
cargo test -p mc-flora load_authored_returns_species_for_known_biomegreen. Evidence: generation.rs:653 — passes via terrain_affinity[] inclusion path (acacia lists 'savanna'). 65/65 mc-flora tests green 2026-05-13.cargo test -p mc-flora generate_flora_for_biome_more_species_with_authored_filesgreen. Evidence: generation.rs:703 — grassland yields >5 species; authored species pulled in via both substrate_climate intersection (e.g. chanterelle for soil T 2-3 P 1) and terrain_affinity (e.g. acacia).- No behavioural regression in flora generation: existing
all_authored_flora_species_deserializeand other passing tests remain green. Evidence: cargo test -p mc-flora 65/65 pass. mc-ecology downstream 324/324 + 8/8 + 6/6 pass. - No new stringly-typed substrate IDs in code — substrate matching
flows through typed structs introduced in p2-52 wherever possible.
Evidence: generation.rs
SubstrateClimateEntrymirrorsmc-ecology::flora_select::SubstrateClimateEntry; predicate intersection viaSubstrateClimateEntry::intersects(typed range comparison, no string matching).BiomeSubstrateClimateMapdeserialised asHashMap<String, Vec<SubstrateClimateEntry>>. The four substrate strings (substrate names) are unavoidable because the substrate enum itself is stringly-keyed in mc-core grid::TileState (substrate_id: String) — that decision is upstream of p2-63 and outside this objective's scope.
Notes
- Owner field is
unassigned; pick up viamcp__objectives__objective_assign. - Touch surface is intentionally narrow: the filter loop and the
AuthoredSpeciesFiledeserializer.