engine/weapons
PURPOSE — Runtime firing system for the player ship: ticks cooldowns and warmup, resolves per-shot stats from weapon specs plus horizontal modifiers, dispatches to the appropriate fire path per weapon behavior/collision mode, spawns and updates in-flight projectiles, and applies on-hit / on-death behavior callbacks.
OWNS
Weaponinstances on the player ship (cooldown timer, cooldown max, fire timer, warmup state, manual-trigger flag, per-slot fire/target mode, empower mult/shots, fire-flash latch).- Active player projectiles in the world (every bullet’s position, velocity, lifetime, hit set, behavior list, weapon-id back-reference, and all per-behavior bullet fields — homing target lock, boomerang return state, mine phase, burst coordinator state, orbit anchor, beam-decay timer, artillery telegraph, etc.).
- Per-shot stat pipeline: scaling-curve level resolution, early-level damage and fire-rate nerfs, legendary baseline multiplier, fire-rate jitter, Star Power damage multiplier, empower decrement, fire-rate-driven
cooldownMaxderivation. - Weapon archetype registry (capability flags per weapon family).
- Bullet behavior registry (named per-frame
update/onHit/onDeathhandlers attached to bullets via_behaviors). - Manual-fire flag (module-level latch read at bullet spawn so manual shots get a homing ramp-in).
- Delayed-shot queue (staggered extra projectiles awaiting their fire moment).
- Bullet recycle bin (allocation pool for spent bullet objects).
READS FROM
data/weaponsforWeaponCoreSpec,WEAPON_MAP, scaling-curve / stepped-stat helpers, weapon damage multiplier, legendary baseline multiplier, extra-projectile resolution.engine/corefor ship state, world state, clock, canvas dimensions, camera, shared module-levelgame/shipreferences, set pool.engine/core/spatial-grid(enemyGrid) for enemy broad-phase queries during targeting, homing, burst lock, mine trigger, AOE finish, and quad-burst hitscan scoring.engine/player/statesfor the Star Power exclusive-state check.- Player upgrade counts on
GameStatefordamage_<tag>/damage_all/more_projectileshorizontal modifiers.
PUSHES TO
engine/combatviadamageEnemy(AOE finish, mine detonation, direct hitscan, ECHO casing-scatter) andapplyChainExplosion.engine/effectsviaspawnFlameZoneandspawnDelayedAoEfor flame-drop / plasma-fire / artillery zones.engine/vfxfor particles, post-FX rings, explosion FX, sonar rings, ship recoil and warmup anticipation, player glow.engine/renderingcamera (shake on fire / hit).engine/audioweapon chimes per slot and damage tag.engine/telemetrycollector for weapon-hit records.
DOES NOT
- Decide which weapon slot fires this frame or pick an aim angle for the orchestrator — the caller passes
aimAngleandslotIndex. (The internalgetAutoAimAnglehelper is consumed only by the module’s own fire paths; the outer loop computes its own primary aim.) - Resolve hit detection or damage math on in-flight projectiles. Collisions and damage application live in
engine/combat; this module only spawns the bullets and runs their per-frame behavior callbacks. - Apply damage filters, affixes, knockback, life steal, shield absorption, or boss caps — all of that lives downstream of
damageEnemy. - Define weapon stats, scaling curves, archetypes by name, or legendary fusion pairs — those are data and live in
data/weapons. - Own the in-game upgrade UI, weapon levelling, or rarity rolls — only consumes the resolved level and
upgradeCounts. - Render projectiles, beams, telegraphs, or HUD indicators — only writes the state those renderers read.
- Track player input or fire-mode toggles — only reads the
_manualTriggerandfireModefields set by the input layer.
Signals fired / Signals watched — none. The module talks to other systems by direct calls (combat, vfx, telemetry, audio, effects); it does not emit or subscribe to engine signals.
Entry points
WeaponManager.fire— per-frame fire attempt for one weapon slot; manages warmup, runs the stat pipeline, dispatches to the correct fire path.WeaponManager.updateCooldowns— ticks every active weapon’s fire timer.WeaponManager.spawnBullet— creates and registers an in-flight projectile from a resolved barrel descriptor.WeaponManager.releaseBullet— returns a spent projectile to the recycle bin.WeaponManager.getAutoAimAngle— internal targeting helper exposed for fire paths that re-aim per sub-shot.WeaponManager.fireProjectiles/fireBeamTrace/fireChainArc/fireBurst/fireFireTrail/fireQuadHitscan/fireArcMortar/fireOrbit/fireFlameStream/fireConeBeamDot/fireLine/fireShieldArc/fireOrbitRing/fireBeamDecay/fireArtilleryRain/firePhoenixAura/fireCarpetBomber— the per-archetype/per-behavior fire paths dispatched fromWeaponManager.fire.WeaponManager.fireChoreography— fire-time VFX, recoil, shake, audio chime.fireWeapon— module-level wrapper used by the engine harness.addWeapon— attach a new weapon instance to a ship.upgradeWeapon— bump a weapon’s level on the ship.updateWeapons— per-frame top-level update of all weapons on a ship.getWeaponStats— read-only lookup of a weapon’s current resolved stats.getWeaponEffectiveRange— acquire-range query used by the auto-aim orchestrator; widens for area-mode weapons.tickDelayedShots— drains the staggered extra-projectile queue once per frame.setManualFireFlag— bridge-side latch toggled before a manual-mode fire so spawned bullets are tagged for homing ramp-in.getEarlyLevelNerf/getPlayerFireRateNerf— exposed for callers that need to mirror the early-level taper.getBulletBinSize— telemetry probe for recycle-bin occupancy.WeaponArchetypes.register/.get/.can/.list/.getModEligibility— capability-flag registry for weapon families.BulletBehaviors.register/.get/.updateBullet/.deathBullet/.hitBullet— registry and dispatcher for per-bullet behavior callbacks.projectileArchetype/beamArchetype/shotgunArchetype/missileArchetype/burstArchetype/orbitWeaponArchetype/teslaArchetype/flakArchetype/lanceArchetype— compatibility lookups that return a registered archetype meta with a hardcoded fallback.
Pattern notes
- Two parallel registries (
WeaponArchetypes,BulletBehaviors) self-register at module load via top-levelregister()calls; consumers index them by string id rather than importing handlers directly. - Bullets carry their behavior list as a string array (
_behaviors); the dispatcher walks it each frame / hit / death. New flight patterns are added by registering a behavior and tagging the spawn template — no changes to the bullet-update loop. - Fire dispatch is a flat
if/elsechain inWeaponManager.firekeyed first ondef.behavior, then ondef.collisionMode, defaulting tofireProjectiles. There is no behavior registry for fire paths — adding one requires editing the chain. - Manual-fire is communicated through a module-level latch (
setManualFireFlag→_nextFireIsManual) read at spawn time, rather than threaded through the fire signature. - Staggered extra projectiles use a module-level
_delayedShotsqueue that the harness must drain viatickDelayedShotseach frame.