From 6f44b0539b58957c04accb0ebcd3f5ce00b8a5ea Mon Sep 17 00:00:00 2001 From: Restart2008 Date: Fri, 24 Oct 2025 21:16:38 -0700 Subject: [PATCH] NukeWars: vertical banding for spawn distribution to avoid top/bottom clumps --- src/core/execution/SpawnExecution.ts | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/core/execution/SpawnExecution.ts b/src/core/execution/SpawnExecution.ts index 2a7303e09..a5bbfee71 100644 --- a/src/core/execution/SpawnExecution.ts +++ b/src/core/execution/SpawnExecution.ts @@ -107,7 +107,33 @@ export class SpawnExecution implements Execution { ? -minDistToTeam * spreadFactor : 0; - const score = d + centerDistance * biasFactor + teamDistanceScore; + // Additionally, distribute spawns vertically into bands so we avoid + // many spawns congregating at the top or bottom of the map. + let bandScore = 0; + try { + const team = player.team(); + if (team) { + const teamPlayers = this.mg + .players() + .filter((pp) => pp.team() === team) + .sort((a, b) => a.smallID() - b.smallID()); + const teamIndex = teamPlayers.findIndex((pp) => pp === player); + const teamCount = Math.max(1, teamPlayers.length); + const numBands = Math.max(1, Math.round(Math.sqrt(teamCount))); + const desiredBand = Math.floor( + (teamIndex / teamCount) * numBands, + ); + const y = this.mg.y(t); + const bandIndex = Math.floor((y / this.mg.height()) * numBands); + const bandPenalty = 24; // tunes vertical spread strength + bandScore = Math.abs(bandIndex - desiredBand) * bandPenalty; + } + } catch (e) { + bandScore = 0; + } + + const score = + d + centerDistance * biasFactor + teamDistanceScore + bandScore; if (score < bestScore) { bestScore = score; best = t;