More Projectiles Fan

What it is

A legacy run-wide stack that adds extra shots to every weapon’s volley. The stack is tracked under the more_projectiles upgrade counter and clamped 0–20. Each weapon has its own step ladder; the bonus is added on top of the level-based base shot count. How those extra shots are arranged in space is per-weapon, not a single shared fan shape — most weapons send the extras at different enemies rather than fanning angularly, only a few weapons spread the extras as an angular cone or a fixed angular gap.

The step ladder

The getExtraProjectiles(weaponId, H) function reads H = upgradeCounts['more_projectiles'], clamps it to 0–20, and returns a weapon-specific bonus. Weapons not listed below ignore the stack entirely (barrier, fire-trail, defy, railgun-derivative weapons, and every legendary).

WeaponH0H1H2H3H4H5H6H7H8H9H10H11H12H13H14H15H16H17H18H19H20
rifle011122223333344444555
coilgun001112222333334444455
shotgun011122223333344444555
railgun000011111222223333344
missile011122223333344444555
lightning (chain jumps)011122223333344444555
revolver (burst rounds)011122223333344444555
cannon (shells per volley)011222333444555666777
mortar (shells per volley)011122223333344444555
disc (orbiting blades)000011111222223333344
flame (embers per fire)0345688910101212131414161617181920
sweep (orbiting blades)000001111111112222233
line (tesla pairs)000000000111111111222
magnetar (tesla pairs)000000000111111111222
fire-ring (orbiting blades)000001111111112222233
burst (rounds per coordinator)000000000111111111222

The bonus is added on top of the weapon’s base shot count regardless of weapon level. For weapons whose primary count is level-driven (a stepped table like shellCount, chainCount, burstPattern, bladeCount, emberCount, seekerCount, projectileCount), the per-H bonus is added after the level lookup resolves.

How the extras are arranged

The arrangement of extras depends on the weapon’s spread mode. The shot loop in the projectile firing path picks exactly one of four arrangements for each shot index i (0-based) of the total shot count.

ArrangementWhen it appliesGeometry
Multi-targetspreadDeg = 0 and perpendicularLayout = falseEach shot is aimed at a different enemy via the multi-target acquisition routine. No angular fan at all; the extras peel off toward whichever enemies are in range.
Random spreadspreadDeg > 0 and randomSpread = trueEach shot’s angle is aim + (rand − 0.5) × spreadDeg independently — the cone is filled chaotically.
Even angular fanspreadDeg > 0 and randomSpread = falseShots are evenly spaced across the full cone. For i in [0, count − 1], angle is aim + ((i / (count − 1)) − 0.5) × spreadDeg. The total cone width is spreadDeg; the per-shot angular gap is spreadDeg / (count − 1).
Perpendicular layoutperpendicularLayout = trueAll shots travel along the aim direction; spawn positions are offset sideways along the perpendicular axis (see Perpendicular Layout concept). No angular fan.

For homing weapons with no spread, extras get a tiny ±6 px perpendicular spawn jitter so the staggered launch reads as a salvo even though every missile still aims at its own assigned target.

Stagger delay between extras: 0 when perpendicular layout is on, 0 when angular spread is on (spreadDeg > 0), and otherwise staggerDelaySec or 0.1 s if unset. The first shot fires on the same frame as the fire event; extras chain at integer multiples of the delay.

Per-weapon spread values

Most weapons have spreadDeg = 0 and never produce an angular fan. The actual cone widths defined on weapon specs:

WeaponspreadDeg (total cone width)ModeNotes
rifle0Multi-targetEach extra shot aimed at a different enemy. Homing locks per shot.
coilgun0Multi-targetSame as rifle; targets unique enemies.
missile0Multi-targetHoming extras lock onto separate targets.
revolver55Even angular fanWide cone; spread is fixed regardless of shot count.
shotgun18Even angular fanAuto-scales: at count > base the spread widens to keep the per-shot gap constant (see Spread scaling below).
cannon0Perpendicular layoutPositional spread, not angular — see Perpendicular Layout concept.
flame0 (coneWidth = 65°)Random spread in coneThe flame stream uses coneWidth, not spreadDeg. Each ember picks a uniform random angle inside the cone plus an extra ±10° per-ember jitter. The cone widens with shot count (see below).
mortar0Multi-target shellsArc shells; extras target unique enemies.
disc, sweep, fire-ring0OrbitExtras are added as additional orbiting blades, not as a fan.
lightning0ChainThe bonus adds chain jumps to the single chain bullet, not extra bullets.
burst0Sequential burstThe bonus adds rounds to a sequential coordinator burst, not a fan.
line, magnetar0Tesla line pairsThe bonus adds whole tesla-line pairs at a fixed angular offset (see special cases below).
lgd_plasma_arc28Random spread in coneLegendary plasma machine gun; random fill.
All other legendaries0Per-behaviorEach legendary’s behavior handler decides arrangement; most ignore more_projectiles.

Spread scaling with shot count

Two weapons flag scaleSpreadWithCount = true: shotgun and flame. When set, the effective spread is spreadDeg × actualCount / baseCount, holding the per-shot angular gap constant. Examples:

WeaponBase countBase spreadCount at H1Effective spread at H1
Shotgun (L1)518°621.6°
Shotgun (L20)1318°1419.4°
Flame (L1)15 embers65° cone18 embers78° cone

All other weapons with non-zero spread (revolver 55°, lgd_plasma_arc 28°) keep the cone width fixed regardless of count, so adding shots makes the volley denser, not wider.

Special cases

Barrier

The barrier’s max active arc count is fixed by weapon level alone: 1 arc at L1, 2 at L7, 3 at L13+. The barrier fire path explicitly ignores the more_projectiles stack — its custom code does not call getExtraProjectiles. New arcs spawn at the angle that maximizes distance to existing arcs, each arc spans about 100° of a circle around the ship, and the fire-rate cooldown is the regeneration bottleneck rather than the active cap.

Fire-trail

Fire-trail drops a single stationary damage zone at the ship’s position each fire event. It has no entry in the step table and ignores the stack — adding more_projectiles ranks produces no extra zones.

Tesla lines (line, magnetar)

Tesla-line weapons interpret each bonus as an additional whole line pair fired at a fixed angular offset of 15° between consecutive pairs, centered on the aim direction. The total number of line pairs is 1 + extraLines; pair li fires at offset −15° × (total − 1) / 2 + li × 15°. This is the only weapon family that uses a baked 15° angular fan — every other angular-fan weapon reads its spread from spreadDeg.

Cannon (perpendicular line)

Cannon adds shells to a perpendicular line, not a cone. The center of the line sits at the ship; shells are spaced 18 px apart along the axis perpendicular to aim. All shells travel along the same heading and land in a parallel line at the target. Cannon also rolls a 25% double-shot chance per fire — when it procs, the entire perpendicular volley fires twice.

Deployables that cap active count

Mortar, fire-ring, and a few other weapons enforce a max-active cap via maxActive. For those, more_projectiles raises the cap by the same step amount rather than adding shots to a single fire event. The fire still produces shellCount (or equivalent) shells per volley; the cap controls how many independent shells/zones can exist in the world at once.

Sources of stacks

The more_projectiles upgrade no longer appears on level-up reward cards. The only in-game source is the Echo Generator artifact, which adds 1 or more stacks when triggered.

EXTRACT-CANDIDATEs

  • EXTRACT-CANDIDATE: concepts/spread.md — A dedicated spread/cone concept page should consolidate the angular fan formula (t × spreadRad, with t in [−0.5, +0.5]), the randomSpread variant, the scaleSpreadWithCount rule, and contrast with perpendicular layout and multi-target acquisition.
  • EXTRACT-CANDIDATE: concepts/multi-target-acquisition.md — The _multiTargetAngles path used by every spreadDeg = 0 weapon deserves its own concept page covering target search, per-shot target assignment, and the 6 px perpendicular spawn jitter for homing salvos.
  • EXTRACT-CANDIDATE: concepts/tesla-line.md — Already exists; should add the 15° per-pair fan offset and the 1 + extraLines formula explicitly.
  • EXTRACT-CANDIDATE: concepts/horizontal-modifiers.md — Already exists; its More Projectiles table is the source of truth and this page consumes it. Cross-link.
  • EXTRACT-CANDIDATE: weapons/shotgun.md and weapons/flame.md — Per-weapon pages should call out scaleSpreadWithCount and walk through an example shot-count → effective-spread calculation.
  • EXTRACT-CANDIDATE: weapons/barrier.md and weapons/fire-trail.md — Per-weapon pages should explicitly note these two weapons ignore the more_projectiles stack.
  • EXTRACT-CANDIDATE: artifacts/echo-generator.md — The only current source of more_projectiles stacks; should link back here for the step ladder consequences.