PURPOSE

Additive WebGL glow primitives for the new lighting system. Provides a two-quad pattern per glow call (outer color-tinted soft glow plus inner white-hot core) using the pre-baked glow atlas region — a smooth white radial gradient that handles per-pixel falloff. Callers tint the gradient via RGBA multiplication. A separate single-quad aura variant and a Canvas 2D fallback are also exported.

OWNS

  • addGlow(batch, glowRegion, x, y, radius, r, g, b, alpha) — pushes two quads (outer color glow at full radius with alpha × 0.5, inner white-hot core at 70 percent radius with alpha × 0.9).
  • addAura(batch, glowRegion, x, y, radius, r, g, b, alpha) — single soft color quad with no white-hot core, intended for ship and boss “I am here” auras where the inner core would render as a sharp disc.
  • addCanvasGlow(ctx, wx, wy, worldRadius, r, g, b, alpha) — Canvas 2D additive aura that converts world coordinates to screen space via Camera.toSx / Camera.toSy and scales radius by camera.zoom before delegating to glow-stamp.drawGlow.

READS FROM

  • ./sprite-batch — type-only imports of SpriteBatch and AtlasRegion.
  • ./cameraCamera.toSx and Camera.toSy for world-to-screen conversion in the Canvas variant.
  • ../core — singleton camera for camera.zoom.
  • ./glow-stampdrawGlow (aliased as _drawGlow) used by addCanvasGlow.

PUSHES TO

  • The caller-supplied SpriteBatch via batch.add(...) calls. Each WebGL glow call adds two quads (addGlow) or one quad (addAura); position, size, rotation (always 0), atlas region, and tint are encoded as instance data.
  • The caller-supplied CanvasRenderingContext2D indirectly via drawGlow from glow-stamp.

DOES NOT

  • Does not own or manage a sprite batch — the caller passes one in and is responsible for flushing it in 'additive' blend mode.
  • Does not mix normal-blend and additive-blend quads in the same flush; the bridge maintains a dedicated _sbGlows batch that flushes after the main alpha batch.
  • Does not handle sprite batch overflow — drops silently to match SpriteBatch.add behavior (limit is 2048 quads per draw call, equating to 1024 addGlow calls per flush).
  • Does not call ctx.save / ctx.restore or set globalCompositeOperation in addCanvasGlow — the caller must set 'lighter' blending and manage state.
  • Skips work when radius <= 0 or alpha <= 0 (early return).

Signals

  • Radius and alpha guards: both functions early-return on non-positive radius or alpha, so degenerate calls cost nothing.
  • Two-quad layering in addGlow: outer diameter is radius * 2, inner core diameter is radius * 0.7; outer alpha is alpha * 0.5, inner alpha is alpha * 0.9 and is always tinted pure white (1, 1, 1).
  • Color convention: WebGL paths (addGlow, addAura) expect tint components in 0–1 range; the Canvas 2D path (addCanvasGlow) expects 0–255 (passed straight through to drawGlow).
  • addCanvasGlow v5.60.4 correction: the context at boss/ship aura draw sites is in screen space (verified against renderBoss and renderBossRoomWalls, both of which use Camera.toS), so world coordinates must be converted; v5.60.3 incorrectly assumed world-space ctx.
  • Auras (addAura, addCanvasGlow) are intentionally single-quad — the white-hot core looked like a sharp pixellated disc at small radii because the gradient had no room to feather; auras should be given generous radius (for example ship visual size times two).

Entry points

  • addGlow is invoked by the sprite-batch / WebGL glow pipeline for projectiles, hit flashes, and other additive point lights routed through the _sbGlows batch.
  • addAura is invoked for steady “I am here” auras on ships and bosses where the inner core would degrade visually.
  • addCanvasGlow is invoked at the Canvas 2D fallback aura draw sites (renderBoss, renderBossRoomWalls) where the surrounding ctx is already in screen space.

Pattern notes

  • Pre-baked gradient + multiplicative tinting: pushing the falloff math into the atlas region (a smooth white radial gradient) lets every glow color reuse the same texture sample, so per-call cost is just two instance writes for addGlow or one for addAura.
  • Caller-owned batching: the module is stateless — all batching, blend-mode selection, and flushing is the bridge’s responsibility, which keeps glow rendering composable with the rest of the sprite pipeline.
  • Dual-pipeline parity: the WebGL (addGlow / addAura) and Canvas 2D (addCanvasGlow) entry points share the same conceptual model (additive tinted radial gradient at a world position with a world radius), but differ in color range convention and in who handles the world-to-screen transform.
  • Silent overflow matches the broader sprite-batch contract — render systems degrade gracefully rather than throwing under load.