Add ant farm sand physics design doc
Covers GPU Margolus block CA for particle sand, hybrid material system (shader behaviors + data-driven registry), ant digging/carrying mechanics, dual camera (side view primary, top-down secondary), and tiered gravity model (basic -> angle of repose -> pressure propagation).
This commit is contained in:
parent
1c74aabd53
commit
de010adf44
1 changed files with 245 additions and 0 deletions
245
docs/plans/2026-03-11-ant-farm-sand-physics-design.md
Normal file
245
docs/plans/2026-03-11-ant-farm-sand-physics-design.md
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
# Ant Farm with Sand Physics
|
||||
|
||||
Design for transforming the ant colony simulation into a side-view ant farm with GPU-accelerated particle sand physics, a data-driven material system, and dual camera support.
|
||||
|
||||
## Vision
|
||||
|
||||
A 2D cross-section ant farm — sand below, sky above, ants on the surface. Ants dig tunnels by picking up sand grains in their mandibles and carrying them to the surface. Sand falls under gravity, tunnels can collapse, and different materials behave differently. Side view is the primary experience. The world is a sandbox — eventually any element (including ants) can be dropped in by the user.
|
||||
|
||||
## World Model
|
||||
|
||||
- 2D grid, same as current. Y-axis is vertical, gravity pulls -Y
|
||||
- Side view is primary camera. Top-down is secondary (surface projection, like a minimap)
|
||||
- Default scene: horizontal split — solid sand below, empty air above, ants placed on sand surface
|
||||
- World stays 2D — no 3D volume. An ant farm is inherently a thin cross-section
|
||||
|
||||
### Why Not 3D
|
||||
|
||||
A 512^3 Float32 volume = ~2GB VRAM per buffer (need 2 for ping-pong = 4GB). Fragment shaders operate on 2D surfaces — updating a 3D volume requires compute shaders (WebGPU, not WebGL2). The ant farm metaphor is naturally 2D, so this is both the simpler and architecturally correct choice.
|
||||
|
||||
## Sand Physics — Margolus Block Cellular Automata
|
||||
|
||||
### The GPU Read-Write Problem
|
||||
|
||||
Naive falling sand on GPU: two grains try to fall into the same empty cell simultaneously, both read "empty", both write themselves there. Data race.
|
||||
|
||||
### Solution: Margolus Neighborhood
|
||||
|
||||
Divide the grid into non-overlapping 2x2 blocks. Each block updates independently — the 4 cells within a block can swap/rearrange without conflicting with other blocks. Alternate the block offset each frame (even frames: blocks at 0,0 / 2,0 / 0,2...; odd frames: blocks at 1,1 / 3,1 / 1,3...). Over two frames, every cell interacts with all its neighbors.
|
||||
|
||||
References:
|
||||
- GPU-Falling-Sand-CA: https://github.com/GelamiSalami/GPU-Falling-Sand-CA
|
||||
- Writeup: https://meatbatgames.com/blog/falling-sand-gpu/
|
||||
- falling-sand-shader: https://github.com/m4ym4y/falling-sand-shader
|
||||
|
||||
### Gravity Tiers
|
||||
|
||||
#### Tier 1: Basic Falling Sand (starting point)
|
||||
- Grains fall down if cell below is empty (or lower density)
|
||||
- If blocked below, try diagonal-down (randomize left/right to prevent bias)
|
||||
- Density-based displacement: heavier materials sink through lighter ones probabilistically
|
||||
|
||||
#### Tier 2: Angle of Repose
|
||||
- Grains only slide diagonally if local slope exceeds material-specific angle
|
||||
- Sand: ~34 degrees, dirt: ~40 degrees, gravel: steeper
|
||||
- Creates realistic pile shapes and mound formation
|
||||
- Implementation: probability tweak on the diagonal check based on neighbor occupancy in a wider radius
|
||||
|
||||
#### Tier 3: Pressure and Weight Propagation (dream goal)
|
||||
- Cells feel weight of material above
|
||||
- Unsupported overhangs collapse under load
|
||||
- Granular arching: force chains form naturally around voids, stabilizing tunnels
|
||||
- Matches real ant tunnel physics (Caltech PNAS 2021 research)
|
||||
- Requires additional simulation pass for pressure propagation
|
||||
|
||||
## Material System — Hybrid Architecture
|
||||
|
||||
### Core Behaviors (shader-native)
|
||||
Four physics behavior types baked into GLSL:
|
||||
- **POWDER** — falls under gravity, piles up (sand, dirt, gravel)
|
||||
- **LIQUID** — falls + spreads horizontally, viscosity parameter (water, mud)
|
||||
- **GAS** — expands omnidirectionally, rises (air, smoke)
|
||||
- **SOLID** — immovable, no physics (rock, bedrock, obstacles)
|
||||
|
||||
### Material Properties (data-driven)
|
||||
Defined in a TypeScript registry, uploaded to GPU as a lookup texture:
|
||||
- density (determines displacement order and fall speed)
|
||||
- color / color variation range
|
||||
- behavior type (powder / liquid / gas / solid)
|
||||
- hardness (resistance to ant digging, resistance to degradation)
|
||||
- angle of repose (tier 2)
|
||||
- reactions (material A + material B -> material C, with probability)
|
||||
|
||||
Adding a new material = adding a registry entry. No shader changes unless it needs a new behavior type.
|
||||
|
||||
### Material Lookup on GPU
|
||||
Material ID stored per cell. Shader samples a 1D lookup texture (or small 2D atlas) indexed by material ID to get density, behavior type, color, etc. Keeps the fragment shader branching minimal — switch on behavior type (4 branches), read properties from texture.
|
||||
|
||||
### Starting Materials
|
||||
- air (empty)
|
||||
- sand (powder, density 1.5, color tan with variation)
|
||||
- dirt (powder, density 1.3, color brown)
|
||||
- rock (solid, density 2.5, color gray — immovable)
|
||||
- food (solid-ish, density 1.0, color green — pickup target)
|
||||
- home marker (solid, density 0, color blue — nest entrance)
|
||||
|
||||
### Future Materials (post-launch, Sandboxels-inspired)
|
||||
- water (liquid), wet sand (powder, higher cohesion), mud (liquid, high viscosity)
|
||||
- gravel (powder, high density, large angle of repose)
|
||||
- clay (powder, very cohesive), packed sand (solid until disturbed)
|
||||
- rock wall, bedrock (indestructible solid)
|
||||
|
||||
## Ant-Material Interaction
|
||||
|
||||
### Carrying Mechanic
|
||||
- Ants pick up material grains with mandibles (same gesture as food carrying)
|
||||
- Each ant has a carry strength value
|
||||
- Each material has a weight value
|
||||
- Ant can pick up and carry any material where weight < ant strength
|
||||
- When carrying, ant moves the grain from source cell to wherever it drops it
|
||||
|
||||
### Multi-Ant Cooperation
|
||||
- Multiple ants adjacent to the same heavy grain combine their strength
|
||||
- If combined strength > material weight, one ant picks it up
|
||||
- Emergent behavior — ants don't coordinate intentionally, but spatial clustering near obstacles creates natural cooperation events
|
||||
|
||||
### What Ants Do With Carried Material
|
||||
- Excavated grains carried to surface and deposited near tunnel entrance (forms anthill mound)
|
||||
- Drop location follows pheromone-like heuristic: away from entrance, near existing mound
|
||||
- If tunnel dead-ends or ant is confused, may deposit grain in-tunnel (creates natural backfill)
|
||||
|
||||
### Material Degradation (later enhancement)
|
||||
- Persistent ant activity at a material face slowly degrades it
|
||||
- rock -> gravel -> sand (over many ant-ticks of contact)
|
||||
- Multiple ants at same face speeds up degradation
|
||||
- Enables ants to eventually get through anything given enough time and workers
|
||||
|
||||
## Digging Behavior
|
||||
|
||||
### How Ants Decide Where to Dig
|
||||
Based on real ant research — digging is NOT pheromone-guided:
|
||||
- Ants probe for loose/low-stress grains (prefer cells with fewer occupied neighbors)
|
||||
- Negative feedback on tunnel length: less digging in already-long tunnels
|
||||
- Colony size drives branching complexity
|
||||
- Individual ants have no blueprint — structure emerges from local rules
|
||||
|
||||
### Tunnel Properties
|
||||
- Tunnels follow angle of repose for current material
|
||||
- Branching increases with colony size
|
||||
- Chambers form at tunnel intersections or where ants cluster
|
||||
- Specialized chambers emerge from ant behavior patterns (food storage near food sources, etc.)
|
||||
|
||||
## Camera System
|
||||
|
||||
### Side View (primary, new default)
|
||||
- Orthographic camera, Y-up, gravity is -Y
|
||||
- Full view of the cross-section: sky, surface, underground
|
||||
- Zoom and pan preserved from current controls
|
||||
- This IS the ant farm experience
|
||||
|
||||
### Top-Down View (secondary)
|
||||
- Shows just the surface layer (top row of occupied cells + some depth)
|
||||
- Like looking down at the ground above the ant farm
|
||||
- Useful for seeing surface foraging patterns, anthill mound shape
|
||||
- Implementation: either a camera rotation or a separate render pass sampling the top-N rows
|
||||
|
||||
### Stats Overlay
|
||||
- Cursor position (x, y grid coords)
|
||||
- Active particle count
|
||||
- TPS (ticks per second, simulation steps)
|
||||
- Material under cursor
|
||||
- Ant count, carrying count
|
||||
|
||||
## Render Pipeline Changes
|
||||
|
||||
Current pipeline is pheromone-focused. New pipeline adds sand physics pass:
|
||||
|
||||
1. **SandPhysicsScene** (NEW) — Margolus block CA pass, updates material grid
|
||||
2. **WorldBlurScene** — pheromone diffusion/decay (unchanged conceptually, operates on pheromone channels only)
|
||||
3. **AntsComputeScene** — ant behavior, now includes dig/carry logic and material awareness
|
||||
4. **AntsDiscretizeScene** — maps ant state to grid (now includes material deposits from carrying ants)
|
||||
5. **WorldComputeScene** — merges ant changes into world (pheromone deposits + material modifications)
|
||||
6. **ColonyStats** — CPU readback for aggregate stats
|
||||
7. **DrawScene** — user painting, now supports material palette (not just food/home/obstacle)
|
||||
8. **ScreenScene** — final composite, side-view camera, material coloring
|
||||
|
||||
### Texture Layout Changes
|
||||
|
||||
The world texture needs to encode material ID per cell instead of just bit flags:
|
||||
|
||||
**Current world R channel:** bit-packed flags (food, home, obstacle, terrain type, food quality)
|
||||
|
||||
**New world encoding (proposal):**
|
||||
- R: material ID (0-255, indexes into material lookup texture)
|
||||
- G: scentToHome (pheromone, unchanged)
|
||||
- B: scentToFood (pheromone, unchanged)
|
||||
- A: repellent pheromone (unchanged)
|
||||
|
||||
Material ID replaces the bit-packed flags. Food, home, obstacle become materials in the registry instead of bit flags. This is cleaner and scales to unlimited material types.
|
||||
|
||||
The material lookup texture (1D, 256 entries) stores per-material: behavior type, density, color RGBA, hardness, angle of repose, flags.
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
Reasonable, targeted tests — not exhaustive coverage of every edge case.
|
||||
|
||||
### Unit Tests
|
||||
- Material registry: adding materials, looking up properties, validation
|
||||
- Margolus block offset calculation (even/odd frame alternation)
|
||||
- Ant strength vs material weight threshold logic
|
||||
- Coordinate transforms between side view and world grid
|
||||
|
||||
### Integration Tests
|
||||
- Sand grain falls through empty space and stops on solid ground
|
||||
- Ant picks up sand, carries it, deposits it (full carry cycle)
|
||||
- Material lookup texture generation matches registry data
|
||||
- Camera switching between side and top-down views
|
||||
|
||||
### Visual / Manual Tests
|
||||
- Sand piling behavior looks natural (no directional bias)
|
||||
- Ants visibly dig tunnels that persist
|
||||
- Tunnel collapse when support removed
|
||||
- Draw tool places correct materials
|
||||
|
||||
### What We Don't Test
|
||||
- Individual shader math (tested visually, not worth the harness)
|
||||
- Every material combination reaction
|
||||
- Performance benchmarks (profile manually when needed)
|
||||
- UI layout/styling
|
||||
|
||||
## Migration Path
|
||||
|
||||
The existing simulation keeps working throughout. Changes are additive:
|
||||
|
||||
1. Add material system + lookup texture alongside existing world encoding
|
||||
2. Add sand physics pass (new, doesn't touch existing passes)
|
||||
3. Modify ant compute to understand materials (extend, don't rewrite)
|
||||
4. Modify screen rendering for side view + material colors
|
||||
5. Add camera toggle for top-down
|
||||
6. Swap default init from top-down food/home to ant-farm sand/sky scene
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Pheromone behavior in side view: do pheromones diffuse through sand or only through air/tunnels? (probably only air — sand blocks diffusion)
|
||||
- Should food sources appear on the surface (above ground) or embedded in sand (underground deposits)?
|
||||
- Ant spawning: do ants emerge from a queen chamber underground, or appear at the surface home marker?
|
||||
- How wide vs tall should the default world aspect ratio be? Currently square (1024x1024). Wider for more horizontal foraging space?
|
||||
|
||||
## References
|
||||
|
||||
### GPU Falling Sand
|
||||
- GPU-Falling-Sand-CA: https://github.com/GelamiSalami/GPU-Falling-Sand-CA
|
||||
- Blog writeup: https://meatbatgames.com/blog/falling-sand-gpu/
|
||||
- falling-sand-shader: https://github.com/m4ym4y/falling-sand-shader
|
||||
- Sandspiel (Rust+WebGL): https://maxbittker.com/making-sandspiel/
|
||||
|
||||
### Real Ant Digging Research
|
||||
- Caltech: The Science of Underground Kingdoms (granular arching)
|
||||
- PNAS 2021: Unearthing real-time 3D ant tunneling mechanics
|
||||
- PLOS ONE: The Role of Colony Size on Tunnel Branching Morphogenesis
|
||||
- Key finding: ants sense grain stress like Jenga — remove loose grains, arches self-stabilize
|
||||
|
||||
### Sandboxels (neal.fun)
|
||||
- Source: R74nCom/sandboxels on GitHub
|
||||
- Key patterns: sparse pixel storage, random tick order, density-based displacement, behavior type system (POWDER/LIQUID/GAS), reaction registry
|
||||
- All CPU — our GPU approach is architecturally different but the material/behavior model is directly applicable
|
||||
Loading…
Reference in a new issue