growthMask() is the reusable spatial-artifact template: an fbm-ragged growth
front creeping outward from a deterministic seed. The raggedness is load-bearing
-- a clean circle reads as a spotlight, not as spreading crystal.
Moire separates area from intensity: intensity saturates early while the mask
keeps growing with tally, so a big shipment reads as "the maze has spread"
rather than "everything got slightly shimmery". Seeded from the tick the crystal
first landed.
Tremor is ~1/4 of the brownout's judder and fever is a smooth haze against
tremor's random jitter, so dread, fever and seizure stay distinguishable.
Also clamps dt at both ends: a negative dt (clock rewind) turned ease()'s
1-exp(-dt/tau) into a huge negative multiplier and threw eased values into orbit.
Unreachable from main.ts's monotonic clock, but not a landmine worth keeping.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
block: 8x8 quantization on a lattice locked to screen space, so the grid stays
rigid while melt drags the picture underneath it. ring: Gibbs halos, gradient
sampled out to 7px so they ring OUT from edges rather than clinging to them,
oscillating parallel to the edge. moire: two near-identical lattices beating,
with rainbow sheen.
PARAMS 8 -> 11; the ledger, easing, wobble and stats all iterate PARAMS, so the
new classes inherit the existing machine. Wires bricks/coeff-packs to block,
halos/gibbs-wraiths to ring, crystal to moire.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Raw WebGL fullscreen triangle, not three.js: one texture, one pass.
The 8 prototype params keep their tuning verbatim; u_drift, u_brownout
and u_flash are additions. Base feed repaints only when a visible glyph
changes rather than per frame, so the texture upload stays off the hot path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>