diff --git a/src/simulator/crates/mc-ai/src/tactical/thresholds.rs b/src/simulator/crates/mc-ai/src/tactical/thresholds.rs index 95979ac8..99ad03fd 100644 --- a/src/simulator/crates/mc-ai/src/tactical/thresholds.rs +++ b/src/simulator/crates/mc-ai/src/tactical/thresholds.rs @@ -75,15 +75,17 @@ pub fn derived_defense(axes: &BTreeMap) -> i32 { /// to capital-assault commitment. Aggressive clans commit earlier; cautious /// clans wait for real superiority. /// -/// Range: `axis=1` → 2.5 (very cautious), `axis=5` → 2.0 (baseline), -/// `axis=10` → 1.5 (rush-happy). Baseline raised 2026-04-26 from 1.50 to 2.0 -/// (and rush-happy floor from 1.15 → 1.5) per warcouncil cycle-3 finding: -/// games still ended T48-T121 in 50% of seeds because even rush-happy -/// blackhammer (agg=9) needed only ~1.2× superiority before committing, -/// triggering rush-domination before tier-3 tech could research. Higher -/// thresholds give losers economic + tech runway. +/// Range: `axis=1` → 1.80 (very cautious), `axis=5` → 1.50 (post-p0-37+39 +/// tempo baseline), `axis=10` → 1.15 (rush-happy). Baseline raised 2026-04-18 +/// from 1.25 so games reach T250+ — tier-3+ tech chains need the runway. +/// +/// Cycle-3 attempt 2026-04-26 to bump to 1.5/2.0/2.5 was reverted: 10-seed +/// `p0-01-domlerp-20260426_145155` showed median winner_tier_peak DROPPED +/// from 4.0 to 1.5 because higher thresholds let weaker players coast on +/// score victory and one-off rushers (goldvein) still won via opportunism +/// (seed 4 went from T300 → T168). Domination tempo isn't the right lever. pub fn dominance_factor(axes: &BTreeMap) -> f32 { - lerp_axis(axis(axes, "aggression"), 2.5, 2.0, 1.5) + lerp_axis(axis(axes, "aggression"), 1.80, 1.50, 1.15) } /// Hex radius within which a unit bypasses stray-unit chasing to march on @@ -195,9 +197,7 @@ mod tests { #[test] fn dominance_factor_baseline_matches_historical() { let a = axes(&[("aggression", 5)]); - // Baseline raised 2026-04-26 from 1.50 → 2.0 (warcouncil cycle-3 - // rush-domination dampening). See dominance_factor() docs. - assert!((dominance_factor(&a) - 2.0).abs() < 1e-6); + assert!((dominance_factor(&a) - 1.50).abs() < 1e-6); } #[test] @@ -248,7 +248,7 @@ mod tests { #[test] fn empty_axes_match_historical_baseline() { let empty: BTreeMap = BTreeMap::new(); - assert!((dominance_factor(&empty) - 2.0).abs() < 1e-6); + assert!((dominance_factor(&empty) - 1.50).abs() < 1e-6); assert_eq!(capital_approach_hex(&empty), 16); assert!((retreat_hp_fraction(&empty) - 0.40).abs() < 1e-6); assert_eq!(defensive_chase_range(&empty), 12); @@ -310,9 +310,8 @@ mod tests { let insane_high = axes(&[("aggression", 999)]); let df_low = dominance_factor(&insane_low); let df_high = dominance_factor(&insane_high); - // Range bumped 2026-04-26 alongside dominance_factor lerp (1.5–2.5). - assert!(df_low >= 1.49 && df_low <= 2.51); - assert!(df_high >= 1.49 && df_high <= 2.51); + assert!(df_low >= 1.14 && df_low <= 1.81); + assert!(df_high >= 1.14 && df_high <= 1.81); } #[test]