Placement Strategies
Boss spawn profiles spawn pressure-add waves at arena-relative positions. The SpawnPosition union ('cardinal' | 'ring' | 'random' | 'edge_random' | 'opposite_player') picks the geometry; the runtime in engine/enemies/boss-spawn-profile.ts (resolvePositions) routes each value through BossArena helpers so adds always land inside the active encounter footprint. All five strategies are arena-relative — none accept absolute world coordinates.
cardinal
Spawns on the four cardinal pads at 0.7 * arena.radius() (N/E/S/W). When count exceeds 4 the indices wrap, so a count of 5 reuses the first cardinal point. Used by heavy_pressure (5 gunners) and the opening wave of crescendo (2 gunners). Best for predictable arrival lanes the player can rotate to clear.
ring
Evenly spaces count points around a circle at 0.7 * arena.radius() via arena.ringPoints(count, 0.7). Unlike cardinal, the ring scales to any count without duplication. Used by storm (8 gunners at once) and the phase-2/3 escalations of crescendo (4 and 6 gunners). Designed for burst panic — full encirclement that forces the player to break out before re-engaging the boss.
random
Drops each add at an independent uniform point inside the arena interior via arena.randomPoint() per spawn. No clustering, no spacing guarantees — two adds can land on top of each other. Currently unused by the v1 profile library but available for chaotic harassment patterns.
edge_random
Pulls count evenly-spaced perimeter points from arena.edgePoints(count), then rotates the whole set by a random offset so successive waves do not keep landing on the same spots. Used by light_pressure (3 orbs every 8s) — dribble-in pressure from the arena rim where the player notices them late but has time to react.
opposite_player
Mirrors the player across arena center to a base point at 0.85 * arena.radius() (via arena.oppositePlayer), then clusters the adds around that base with per-add jitter: a random angle and a distance of 30 + Math.random() * 30 pixels (i.e. 30–60 px). When count === 1 the jitter distance collapses to 0, so a single add lands exactly on the mirrored point. Used by beacon_clearers (2 chargers) — adds appear on the far side of the arena so the player has to choose between staying on the boss or pivoting to intercept.
Reference
- Data:
data/spawn-profiles.ts—SpawnPositionunion and the five v1 profiles that consume it (light_pressure,heavy_pressure,beacon_clearers,storm,crescendo). - Runtime:
engine/enemies/boss-spawn-profile.ts—resolvePositionsswitch and arena-helper plumbing. - Related: boss-spawn-profile concept, sealed-arena-geometry concept.