# 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). side-view ant farm with sand/powder physics and material-based world. ## 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. `SandPhysicsScene` — Margolus block CA for sand/powder physics 2. `WorldBlurScene` — diffuse + decay pheromones (3 channels: toHome, toFood, repellent, blocked by solid cells) 3. clear `antsPresenceRenderTarget` (ant-ant spatial queries, stub) 4. `AntsComputeScene` — per-ant state via MRT (writes 2 textures simultaneously), material-aware digging 5. `AntsDiscretizeScene` — maps continuous ant positions to discrete world grid cells 6. `WorldComputeScene` — merges ant deposits into world pheromone grid 7. `ColonyStats` — CPU readback of ant texture, computes aggregate stats (foragerRatio), feeds back as uniforms 8. `DrawScene` — user painting with material palette 9. `ScreenScene` — final composited output with side/top camera views (V to toggle) ### 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, cargoMaterialId, pathIntDx, pathIntDy]` **world state** — RGBA Float32 (worldSize x worldSize): - R: material ID (0-255), maps to MaterialRegistry entry - 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. ### material system `src/materials/` defines a data-driven material registry. adding a new material requires only a registry entry — no shader changes needed. - `MaterialRegistry` — 6 built-in materials (ids 0-5): air, sand, dirt, rock, food, home - behavior types: `BEHAVIOR_POWDER` (0), `BEHAVIOR_LIQUID` (1), `BEHAVIOR_GAS` (2), `BEHAVIOR_SOLID` (3) - each material has: id, name, behavior, density, hardness, angleOfRepose, color - lookup textures (256x1 Float RGBA) uploaded as uniforms to shaders: - properties texture: `[behavior, density, hardness, angleOfRepose]` per row - colors texture: `[r, g, b, a]` per row - material IDs defined in `src/constants.ts` (MAT_AIR through MAT_HOME) ### sand physics Margolus neighborhood cellular automata runs as the first render pass each frame. - world is divided into 2x2 blocks; block offset alternates each frame between (0,0) and (1,1) - within each block, cells with `BEHAVIOR_POWDER` fall downward and slide diagonally, swapping with lighter materials - physics pass writes back to world ping-pong target before pheromone diffusion runs - `src/sand/margolus.ts` computes the per-frame block offset (JS side, passed as uniform) ### 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` — material IDs (single source of truth for TS + GLSL) - `src/ColonyStats.ts` — CPU readback of ant texture for colony-level aggregate stats - `src/StatsOverlay.ts` — on-screen stats display (cursor position, TPS, colony info) - `src/materials/types.ts` — Material interface and BehaviorType constants - `src/materials/registry.ts` — MaterialRegistry with 6 built-in materials - `src/materials/lookupTexture.ts` — builds GPU lookup textures from registry - `src/sand/margolus.ts` — Margolus block offset calculation - `src/scenes/SandPhysicsScene.ts` — sand physics render pass - `src/shaders/antsCompute.frag` — ant behavior + MRT output (2 render targets via layout qualifiers) - `src/shaders/worldBlur.frag` — per-channel pheromone diffusion/decay (solid cells block diffusion) - `src/shaders/world.frag` — material ID preservation + pheromone merging - `src/shaders/sandPhysics.frag` — Margolus block CA for powder/sand movement ## planning docs - `REALISM-IDEAS.md` — research-backed features for more realistic ant behavior - `INFRASTRUCTURE.md` — data structure analysis mapping features to GPU infrastructure layers - `docs/plans/2026-03-11-ant-farm-sand-physics-design.md` — sand physics design - `docs/plans/2026-03-11-ant-farm-implementation.md` — ant farm implementation plan ## 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.