4 KiB
4 KiB
| id | title | priority | status | scope | owner | updated_at | evidence | blocked_by | ||
|---|---|---|---|---|---|---|---|---|---|---|
| p2-58 | Ambient encounter rolls per tile moved — fauna_density × ecology_tier | p2 | done | game1 | unassigned | 2026-05-07 |
|
Context
public/games/age-of-dwarves/docs/ecology-gameplay.md Layer 1 specifies that any unit moving through wilderness rolls a per-tile encounter chance keyed on fauna_density × ecology_tier, with unit-type roll-rate scaling (e.g., scouts trip fewer encounters, large armies trip more). Today combat encounters fire only on lair-adjacency or scripted spawn events — ambient wilderness traversal is risk-free, contradicting the design.
Acceptance
- ✓
mc-ecologyexposesroll_ambient_encounter(tile_meta, unit_kind, rng) -> Option<EncounterSpec>keyed ontile_meta.fauna_density * tile_meta.ecology_tier—src/simulator/crates/mc-ecology/src/encounter.rs:175(re-exported atsrc/simulator/crates/mc-ecology/src/lib.rs:51). - ✓ Unit-kind roll-rate multipliers (
scout: 0.5,infantry: 0.8,civilian/pioneer: 2.0, …) authored underpublic/resources/ecology/encounter_rates.json:19-31. - ✓ Per-tile-moved hook: p2-58a added
fauna_density: f32andfauna_index: Vec<SpeciesId>toTileState(path A). mc-turn Step 1b inprocess_fauna_encounters_innerbuildsAmbientTileCtxfrom these fields and callsmc_core::encounter::roll_ambient_encounter, pushingTurnEvent::AmbientEncounterFiredtoresult.events_emitted. (p2-58 + p2-58b, cycles prior + cycle 39) - ✓ Encounter selection draws from
fauna_index(candidate species list) —src/simulator/crates/mc-ecology/src/encounter.rs:204-205. Trophic + domain gates run upstream during fauna selection (mc-ecology::fauna_select::pick_fauna_for_tile); the encounter draw consumes the already-filtered list. - ✓ Determinism: encounter rolls use
seed::derive_step(map_seed, SeedDomain::Encounter, &[turn, unit_id, step_idx])—src/simulator/crates/mc-core/src/seed.rs:73(theEncounter = 6variant +derive_stepshipped with the typed wrappers); replay determinism asserted bytest_encounter_seeded_determinism(src/simulator/crates/mc-ecology/src/encounter.rs:344). - ✓ Cargo test in
mc-ecology: 100-step deterministic walk yields the expected encounter count within plausible bounds —test_encounter_probability_scales_with_density(src/simulator/crates/mc-ecology/src/encounter.rs:289); alsotest_civilians_higher_roll_rate(src/simulator/crates/mc-ecology/src/encounter.rs:325). 8/8 mc-ecology encounter tests pass on apricot. - ✓ GUT integration test:
test_p2_58b_ambient_encounter.gd— headless, drives GdTurnProcessor::step with fauna_density=0.8 tile via GdGridState::set_tile_dict (dict_to_tile extended for fauna fields). Assertsambient_encounter_count ≥ 1within 50 steps. Also asserts barren tile yields zero.EventBus.ambient_encounter_firedsignal declared.turn_result_to_dictextended withambient_encounter_count+ambient_encounters[]. (cycle 39)
Source-of-truth rails
- Rust crate:
mc-ecologyowns the roll.mc-turn::movementis the single caller (no GDScript shadow roll). - JSON path:
public/resources/ecology/encounter_rates.jsonowns unit-kind multipliers and base roll rate. Nodata/overrides. mc-coretyped wrapper:EncounterSpec { species_id: SpeciesId, group_size: u8, posture: EncounterPosture }.
Out of scope
- Pioneer escort rules (covered by
p2-59). - Lair siege/assault/raid combat modes (covered by
p3-10). - Encounter narrative text / event cards — separate UI objective.
References
public/games/age-of-dwarves/docs/ecology-gameplay.md(Layer 1)public/games/age-of-dwarves/docs/ECOLOGY_BINDING.mdpublic/games/age-of-dwarves/docs/terrain/WORLDGEN_RNG.md