Swarm
Forces
Why this and not a looped animation
A baked loop either syncs every bee (uncanny) or rides fixed rails that ignore you. This is N independent agents over a shared turbulence field — it reacts to the cursor and never repeats.
The split that keeps it cheap
Appearance is baked once. beeAtlas(seed) → headings × 2 wingbeat frames of {x,y,c} pixels. Per frame we only pick a heading bin from velocity and stamp — never recompute pixels. Motion is a struct-of-arrays fixed-timestep sim (Swarm.step), the exact shape a WebGPU compute pass / Rust loop wants. Hundreds of bees here in plain JS; the GPU port carries tens of thousands (see fluoddity, 40–120k agents at 60fps).
HTTP API — the portable bake
GET /bees/api/atlas.json?seed=&headings= → the full micro-atlas an engine uploads to a texture.
GET /bees/api/bee.svg?seed=&heading=&wing=&scale= → one bee as an image.
Next tier (optional): true stigmergy
Layer a shared scent field (deposit → diffuse → sense) on top and the swarm self-organizes trails between flowers and the hive — that's the fluoddity loop, ported. Boids-lite is the cheap tier shipped here first.