PURPOSE

Registry of vector polygon shape definitions used as a fallback when sprite rendering is not available. Each named shape is a collection of polygons with optional fill and stroke style keys (resolved by the draw layer against the active palette). Ported from the legacy 08a-ship-sprites.js Shapes section.

OWNS

  • Polygon interface — points array pts: Array<[number, number]> plus optional fill and stroke style keys.
  • ShapeDef interface — { polys: Polygon[] }.
  • Shapes object — registry with private _s record, def(name, data) to register, and get(name) to look up (returns null when missing).
  • Player shape: player (triangle hull, engine block, bright accent).
  • Pickup shapes: xp_canister (hex), coin (irregular hex).
  • Station shape: genesis (diamond + inner square).
  • v2 enemy archetype shapes: orb (octagon), charger (forward wedge), shooter (boxy hull with gun mount), mortar (squat body with top-mounted launcher).
  • City-set enemy shapes: gunner (square crate), field (long hauler with inner block), sniper (angular body with long barrel), racer (elongated speed wedge).

READS FROM

Nothing. Pure data module with a small in-module registry.

PUSHES TO

Nothing directly. The registry is mutated only by the Shapes.def calls inside this file at module load.

DOES NOT

  • Does not render. No canvas, no draw calls, no transforms, no color resolution.
  • Does not resolve style keys to actual colors — fill and stroke are string keys consumed by the draw layer.
  • Does not own scale, rotation, or position; points are in local unit space.
  • Does not maintain a frame-by-frame state or pool.
  • Does not handle sprites, atlases, or batched rendering.
  • Does not expose a removal or clear API.

Signals

None. No events, no observers, no listeners.

Entry points

  • Shapes.def(name, data) — register a shape under a string key.
  • Shapes.get(name) — retrieve a ShapeDef or null if unregistered.
  • Module side effects on import register all built-in shapes listed under OWNS.

Pattern notes

  • Polygon points are authored in local unit space (roughly -1..1) so callers can apply an entity-specific scale.
  • Style fields are color keys (e.g. playerDim, enemy, enemyDark, xp, coin, stationLight) rather than literal CSS colors, except for two hard-coded #111111 inner blocks on the shooter, mortar, field, and sniper shapes.
  • Registry uses string keys with no enum; lookups by unknown name return null rather than throwing.
  • Legacy mine shape and pre-v2 enemy shapes were removed; the file documents these deletions in comments.
  • Consumed by the rendering draw layer (engine/rendering/draw.ts) for the player fallback and shape-keyed entities, and by the enemy-orbit VFX (engine/vfx/enemy-orbit.ts) which reads shape polygons to drive its effect.