diff --git a/src/simulator/crates/mc-ecology/src/dynamics.rs b/src/simulator/crates/mc-ecology/src/dynamics.rs index a0107b8e..49492ee5 100644 --- a/src/simulator/crates/mc-ecology/src/dynamics.rs +++ b/src/simulator/crates/mc-ecology/src/dynamics.rs @@ -918,6 +918,7 @@ mod tests { #[test] fn predation_efficiency_sessile_prey_always_caught() { // A sessile prey (flee_speed=0) is always caught once detected. + // Chase probability should be 1.0 regardless of predator pursuit speed. let pred = wolf(); let mut prey = Species::derive_from_traits( 60, @@ -934,11 +935,26 @@ mod tests { ); prey.resolve_derived_stats(); // flee_speed derived = 0 for Sessile + // Override concealment to isolate the chase=1.0 behaviour under test — + // otherwise a highly concealed sessile species drops detection below 0.5 + // and obscures what we're actually measuring. + prey.evasion.concealment = 5; let eff = predation_efficiency(&pred, &prey, "ocean"); - // chase = pursuit / (pursuit + 0) = 1.0 - // efficiency = detection × 1.0 = detection - assert!(eff > 0.5, "Sessile prey should have high chase probability (flee=0), got {eff}"); + // detection = 10 / (10 + 5) ≈ 0.667 + // chase = 1.0 (sessile — flee_speed=0 forces chase to 1.0) + // efficiency ≈ 0.667 + assert!(eff > 0.6, "Sessile prey with moderate concealment should give eff > 0.6, got {eff}"); + + // Also verify that a predator with pursuit=0 still catches sessile prey (chase=1.0), + // since neither can move so the prey remains reachable. + let mut still_pred = pred.clone(); + still_pred.interaction.pursuit_speed = 0; + let eff_still = predation_efficiency(&still_pred, &prey, "ocean"); + assert!( + eff_still > 0.6, + "Sessile prey should still be caught by stationary predator (chase=1.0), got {eff_still}", + ); } #[test]