engine/boss

PURPOSE — Owns the spatial container, lifecycle, and stat scaling for a boss fight: spawns the room (shrinking circle or sealed rect), wraps it in an arena helper that bosses use for all spawn placement and containment queries, materializes the boss roster from a BossDef into world enemies with affixes and abilities, and tears the whole encounter down on win, player death, or level exit.

OWNS

  • BossRoom lifecycle: state (closing / locked), center position, target and current footprint (radius for circles, width/height for rects), shape, spawn time.
  • Shrink-easing of the closing-circle room and the per-frame ship-clamp + entity-cull pass driven by the current room boundary.
  • Camera clamp inside the room footprint plus configured margin.
  • Visual room walls (rect: black evenodd-mask cutout with glow stroke; circle: thick ring with inner glow).
  • Terrain clearing inside the room footprint at spawn time, including rebuild of the chunk spatial index.
  • BossArena helper instance (live wrapper over the current room) exposing contains / clampPoint / randomPoint / cardinalPoints / ringPoints / edgePoints / oppositePlayer / radius / diagonal / bounds plus center accessors.
  • Sealed-arena materialization: rect room built in locked state at its final size, four Rapier static cuboid wall colliders with overlapping corners, the _sealedArenaActive global flag, and the matching teardown that drops the wall colliders.
  • Encounter spawn: roster materialization into world.enemies, per-body stamping of isBoss / sharesHealthWithBoss / untargetable / gateGroupId / displayName / barColor / affixes / abilities / behavior, HP and damage multipliers derived from kind tier (mini / boss) and depth fraction across the run sequence.
  • Encounter-shared VFX layer kit (singleton kept across setupVfx and affix re-binding hooks).
  • Active-encounter pointers on GameState: bossArena, bossSpawnProfile, bossEncounterTime, _activeBossDefId, plus the last-sharer death-position snapshot used by win VFX anchoring.
  • Win-path payoff: boss-kill signal fire, supply-pod cascade(s) at the death anchor with optional per-def cascade composition, telemetry phase record, portal materialization on legacy non-boss/mini_boss levels, _bossLevelCleared flag on run-sequence levels.
  • Teardown: culling of all isBoss / sharesHealthWithBoss / _isBossAnchor enemies, conditional removal of arena-tagged enemy bullets, terrain-pattern cull, VFX layer clear, background-loop stop, full reset of encounter-pointer state.
  • Roster position resolution from BossSpawnPosition literals (center / cardinal / ring / random / object-literal arena-relative offset).
  • aiId to runtime behavior string mapping.

READS FROM

  • engine/core for game, ship, world, camera, viewport dimensions, and CFG boss-room tunables.
  • engine/core/utils for lerp / clamp.
  • engine/core/types for BossRoom / BossArena / EnemyEntity / GameState / WorldState.
  • engine/core/signals for the boss_kill fire.
  • engine/physics/rapier-world / rapier-ship / rapier-terrain / rapier-enemies for collider lifecycle and ship body sync.
  • engine/rendering/camera for screen-space conversion in wall rendering.
  • engine/rendering/boss-bg-loop to start and stop the optional pre-baked background animation.
  • engine/world/generation for buildTerrainChunks after splicing terrain.
  • engine/world/props for the supply-pod cascade primitive used by the win payoff.
  • engine/destructibles/terrain-patterns for applyTerrainPattern / cullTerrainPattern.
  • engine/enemies/spawner (GameMaster.spawnEnemy) and engine/enemies/boss-spawn-profile (resetBossSpawnProfile).
  • engine/abilities for createAbilityInstance.
  • engine/vfx/boss-layers for createVfxLayerKit / clearBossVfxLayers.
  • engine/telemetry/collector for director-phase recording.
  • data/bosses for BOSS_DEFS, the def shape, roster entry shape, position variants, and bossDefKind.
  • data/level-progression for kind-tier and depth multipliers, run-length sequences, and sealed-arena dimensions.

PUSHES TO

  • world.enemies (roster spawn + post-spawn enemy stamping; teardown sets alive/hp to dead).
  • world.enemyBullets / world.pickups / world.playerBullets (cull pass).
  • world.terrain / world.floaters plus world.chunks via rebuild (room-footprint clears and sealed-arena strip).
  • world.portal (legacy win path).
  • GameState boss-encounter fields (bossArena, bossSpawnProfile, bossEncounterTime, _activeBossDefId, _pendingBarDamage, _lastBossDeathX/Y, _bossLevelCleared, _sealedArenaActive).
  • Camera target (clamp inside room).
  • Rapier world (ship teleport-keep-velocity on clamp, enemy clear on sealed-arena spawn, arena wall colliders).
  • engine/core/signals: boss_kill on win.
  • Telemetry collector (director-phase entry on supply-pod cascade).
  • Boss-background-loop runtime (start on spawn if def declares an asset, stop on teardown).

DOES NOT

  • Decide when to start a boss encounter, which def to spawn, or which level kind the player is in — the run sequencer / bridge layer drives that and assigns game.bossRoom before calling spawnBoss.
  • Run the boss’s AI, ability cooldowns, affix update loop, projectile flight, damage application, or health-bar rendering — owned by enemies / abilities / affixes / combat / HUD.
  • Compute or apply per-shot damage, knockback, life steal, or hit reactions — only stamps an enemy damageMult expando at spawn.
  • Select aim or fire weapons for the boss roster — abilities and AI behaviors drive that downstream.
  • Track player input, dodge state, or HUD interaction.
  • Render the boss bar, portal VFX, or supply-pod props — only triggers their spawn / lifecycle hooks.
  • Define boss content (rosters, affixes, abilities, terrain patterns, rewards, scaling constants) — those are data and live in data/bosses and data/level-progression.
  • Maintain Rapier physics primitives beyond colliders directly tied to the room/arena boundary.
  • Persist any encounter state across runs — every field is cleared on teardown.

Signals firedboss_kill on the win path (carrying xp / currency / def id from the def’s reward block).

Signals watched — none.

Entry points

  • spawnBossRoom — materializes a closing-circle BossRoom centered on the player, sized against viewport and boss zoom, and clears terrain inside the final footprint.
  • updateBossRoom — per-frame: advances the shrink ease while closing, clamps the ship inside the boundary, and runs the entity cull (every frame while closing, throttled once locked).
  • clampCameraToRoom — post-Camera.update clamp of the camera target to the room footprint plus configured margin.
  • renderBossRoomWalls — draws the visual walls for the current room shape (rect mask cutout or circle ring with inner glow).
  • spawnSealedArena — builds a locked rect BossRoom around the ship, strips biome terrain and floaters, registers the four wall colliders, and flips _sealedArenaActive.
  • teardownSealedArena — drops the wall colliders and clears the sealed-arena flag.
  • sealedArenaPlayerSpawn — returns the player spawn point for a sealed-arena level.
  • createBossArena — wraps a live BossRoom in the BossArena helper interface used by spawn placement, affixes, abilities, and AI.
  • spawnBoss — materializes a BossDef into the world: applies the def’s terrain pattern, instantiates the roster with kind-tier and depth-scaled HP / damage, stamps boss flags / gate group / affixes / abilities / behavior, arms the spawn profile, and triggers the def’s setupVfx and optional background loop.
  • onBossEncounterEnd — single teardown path branched by reason (win / player_death / level_exit): culls roster bodies and arena-tagged bullets, fires the win signal, runs the supply-pod cascade(s), materializes the legacy portal where applicable, clears encounter state, stops the background loop.
  • getSharedBossVfxKit — exposes the singleton VFX layer kit so out-of-module affix hooks rebind layers against the same instance.

Pattern notes

  • The BossArena is the only sanctioned source of spawn coordinates inside a boss fight — bosses, affixes, abilities, and AI all route through its helpers so no consumer needs to know the room shape, screen size, or world position of the arena center.
  • contains queries the room’s current footprint (so leash and cull track the contracting wall) while clampPoint / randomPoint / cardinalPoints / ringPoints / edgePoints query the target footprint (so placements don’t drift while the room is closing).
  • The cull pass exempts isBoss and sharesHealthWithBoss enemies plus _isBossAnchor flagged bodies so the closing wall never silently deletes anchor positions the boss’s affixes depend on.
  • Object-literal BossSpawnPosition values are arena-relative offsets applied to arena.cx / arena.cy, not absolute world coordinates — boss data files never see the arena’s world position.
  • The sealed arena shares BossRoom / BossArena infrastructure with the closing-circle path; it just spawns already-locked at final size with rect shape and adds Rapier wall colliders whose corners overlap to prevent diagonal push-through.
  • Encounter-end is one funnel for three outcomes; the win-path branches inside it (signal fire, supply-pod cascade, portal materialization or run-level clear flag), and every exit clears the same encounter-pointer fields so subsequent encounters never inherit stale state.
  • The win-VFX anchor is resolved by a priority chain (last-sharer death snapshot from damage.ts → any still-alive isBoss enemy → arena center) so asymmetric rosters anchor on the correct visual focal point.
  • Manual fire dispatch for the cascade composition reads def.rewardCascadeTypes with a fallback to the default supply-pod cascade list, letting individual bosses tune their reward identity without changing the cascade primitive.