ants/CLAUDE.md

81 lines
3.7 KiB
Markdown

# ants-simulation
GPU-accelerated ant colony simulation. ants navigate via pheromone trails, all computed in GLSL fragment shaders rendered to offscreen textures. uses WebGL2 features (MRT, GLSL3).
## stack
- three.js (0.173) — WebGL2 renderer, render targets, MRT, shader materials
- lil-gui — runtime parameter tweaking
- vite — dev server and build
- biome — lint + format
- bun — runtime, test runner, package manager
- typescript
## commands
- `just check` — lint, typecheck, test (the gate for all work)
- `bun run dev` — start dev server
- `bun run build` — production build to `build/`
- `bun test` — run tests
## architecture
all simulation logic runs on the GPU via ping-pong render targets. no JS-side simulation loop — `Renderer.ts` orchestrates render passes and manages all WebGLRenderTargets.
### render pipeline (per frame)
1. `WorldBlurScene` — diffuse + decay pheromones (3 channels: toHome, toFood, repellent, each with independent blur radius and decay rate)
2. clear `antsPresenceRenderTarget` (ant-ant spatial queries, stub)
3. `AntsComputeScene` — per-ant state via MRT (writes 2 textures simultaneously)
4. `AntsDiscretizeScene` — maps continuous ant positions to discrete world grid cells
5. `WorldComputeScene` — merges ant deposits into world pheromone grid
6. `ColonyStats` — CPU readback of ant texture, computes aggregate stats (foragerRatio), feeds back as uniforms
7. `DrawScene` — user painting (food, home, obstacles, erase)
8. `ScreenScene` — final composited output with camera controls
### GPU textures
**ant state** — 2 RGBA Float32 textures per ping-pong target (MRT, `count: 2`):
- texture 0: `[pos.x, pos.y, angle, packed(storage << 1 | isCarrying)]`
- texture 1: `[personality, cargoQuality, pathIntDx, pathIntDy]`
**world state** — RGBA Float32 (worldSize x worldSize):
- R: packed cell metadata (bits 0-2: food/home/obstacle, bits 3-5: terrain type, bits 6-13: food quality)
- G: scentToHome
- B: scentToFood
- A: repellent pheromone
**discrete ants** — RGBA UnsignedByte (worldSize x worldSize):
- R: carrying ant scent deposit, G: non-carrying ant scent deposit, B: cell cleared flag, A: 1
**ant presence** — RGBA Float32 (worldSize x worldSize), cleared each frame. stub for future ant-ant spatial interaction.
### bit layout (world.R)
defined in `src/constants.ts`, shared between TS and GLSL via defines:
- bits 0-2: cell flags (food, home, obstacle)
- bits 3-5: terrain type (0-7, reserved for substrate-dependent decay)
- bits 6-13: food quality (0-255, reserved for quality-dependent pheromone modulation)
### key files
- `src/Renderer.ts` — render target creation, pass orchestration, MRT setup, colony stats readback
- `src/Config.ts` — simulation parameters (per-channel pheromone configs)
- `src/constants.ts` — cell metadata bit layout (single source of truth for TS + GLSL)
- `src/ColonyStats.ts` — CPU readback of ant texture for colony-level aggregate stats
- `src/shaders/antsCompute.frag` — ant behavior + MRT output (2 render targets via layout qualifiers)
- `src/shaders/worldBlur.frag` — per-channel pheromone diffusion/decay
- `src/shaders/world.frag` — cell metadata bit preservation + pheromone merging
## planning docs
- `REALISM-IDEAS.md` — research-backed features for more realistic ant behavior
- `INFRASTRUCTURE.md` — data structure analysis mapping features to GPU infrastructure layers
## shader files
in `src/shaders/`. each scene has a matched .vert/.frag pair. loaded as raw strings by the vite glsl plugin in `vite.config.ts`. all shaders use GLSL3 (`#version 300 es` via three.js `glslVersion: THREE.GLSL3`).
## textures
in `public/textures/` — ant.png and food.png sprites.