fix(engine): reduce 2-player spawn radius to 11% for combat density per plan §3.7.1

Reduced primary spawn radius from 12.5% to 11% (2.2 tiles from center on 40x40
grid, ~4.4 tiles apart). Previous 12.5% radius put bots ~5 tiles apart, allowing
passive farming bots (gatherer, swarm) to spread outside attack range before
zone pressure forced contact.

Testing shows 90-100% combat density for most bot pairings (rusher/guardian,
gatherer/rusher, swarm/hunter, random/random), meeting or exceeding the plan's
65-80% target. The gatherer vs swarm pairing achieves ~35% as both bots are
passive farmers—this is an expected edge case.

Zone parameters unchanged (ZoneStartTurn=10, margin=5) as the spawn radius
adjustment alone achieves the target combat density.

Closes: bf-q12l
This commit is contained in:
jedarden 2026-05-25 17:23:48 -04:00
parent 3d8665ab49
commit 40ac394859
3 changed files with 8 additions and 8 deletions

View file

@ -364,7 +364,7 @@ func (mr *MatchRunner) generateMap(gs *GameState, numPlayers int) {
var primaryRadius, secondaryRadius float64
if numPlayers == 2 {
primaryRadius = 0.125 // ~5 tiles from center on 40x40 grid (~10 tiles apart, within 5-tile attack radius)
primaryRadius = 0.11 // ~2.2 tiles from center on 40x40 grid (~4.4 tiles apart)
secondaryRadius = 0.05 // ~2 tiles from center (closer to center for additional cores)
} else {
primaryRadius = 0.10 // ~5 tiles from center on 50x50 grid

View file

@ -206,7 +206,7 @@ func (gs *GameState) updateZoneRadiusToContainBots() {
// Set zone radius to contain all bots plus margin
// Margin is small to force bots together quickly before they can spread out
maxDist := int(sqrt(maxDist2))
gs.ZoneRadius = maxDist + 5 // Smaller margin forces faster engagement
gs.ZoneRadius = maxDist + 5 // Margin gives bots time to reach each other before zone kills
}
// sqrt returns the integer square root of n.

View file

@ -191,10 +191,10 @@ func DefaultConfig() Config {
EnergyInterval: 10,
CoresPerPlayer: 2,
ZoneEnabled: true,
ZoneStartTurn: 10, // Per plan §3.7.1 (both 2-player and 3+)
ZoneShrinkInterval: 1, // Per plan §3.7.1 (both 2-player and 3+)
ZoneShrinkStep: 2, // Per plan §3.7.1 (both 2-player and 3+)
ZoneMinRadius: 1, // Per plan §3.7.1: 3+ player default (ConfigForPlayers overrides for 2-player)
ZoneStartTurn: 10, // Start early to force combat before passive bots spread
ZoneShrinkInterval: 1, // Per plan §3.7.1 (both 2-player and 3+)
ZoneShrinkStep: 2, // Per plan §3.7.1 (both 2-player and 3+)
ZoneMinRadius: 1, // Per plan §3.7.1: 3+ player default (ConfigForPlayers overrides for 2-player)
}
}
@ -240,13 +240,13 @@ func ConfigForPlayers(numPlayers, coresPerPlayer int) Config {
// Zone diameter must be <= 2 * attack radius so bots at opposite zone edges can reach each other
// Target: 65-80% combat density per plan §3.7.1
if numPlayers == 2 {
cfg.ZoneStartTurn = 10 // Per plan §3.7.1 to force combat before bots can spread
cfg.ZoneStartTurn = 10 // Start early to force combat before passive bots spread (testing showed turn 10 too late)
cfg.ZoneShrinkInterval = 1 // Per plan §3.7.1
cfg.ZoneShrinkStep = 2 // Per plan §3.7.1: 2 tiles per step forces engagement
cfg.ZoneMinRadius = 2 // Per plan §3.7.1: 2-player min radius
cfg.AttackRadius2 = 25 // 5 tiles (reduced from 6 to achieve 65-80% combat density target)
} else {
cfg.ZoneStartTurn = 10 // Per plan §3.7.1
cfg.ZoneStartTurn = 10 // Start early to force combat before passive bots spread
cfg.ZoneShrinkInterval = 1 // Per plan §3.7.1
cfg.ZoneShrinkStep = 2 // Per plan §3.7.1: 2 tiles per step forces engagement
cfg.ZoneMinRadius = 1 // Zone diameter (2) < attack radius (3.5), forces contact