Physarum-inspired particle simulation that recreates the classic Unity compute-shader slime using pure Python. It supports a NumPy CPU path and an accelerated Taichi GPU path while keeping visualization lightweight via pygame. The repo stays minimal: one Python file and one requirements file.
| Pure Green Slime | Red + Green Trails | RGB Trails |
|---|---|---|
![]() |
![]() |
![]() |
| Single-species, monochrome trails | Two-species interaction | Three-species emergent braids |
Inspired by and with thanks to Sebastian Lague’s slime/ant simulation video.
- Overview
- Features
- Installation
- Usage
- Project Structure
- How It Works
- Configuration
- Implementation Notes
- Troubleshooting
- License
- Acknowledgments
This project simulates slime-mold-like agents that follow simple local rules—sense nearby trails, steer toward stronger signals, and deposit their own trails. Diffusion and decay on the shared trail map create striking emergent patterns (lanes, braids, and flowing rivers of color). The code mirrors the Unity compute-shader logic in a single Python file.
Key points:
- Two interchangeable backends: NumPy CPU and Taichi GPU.
- Supports 1–3 species out of the box, each with distinct color and steering parameters.
- Minimal dependencies for quick experimentation.
- Agent system: 20k+ agents by default; GPU mode can push higher.
- Trail field: Per-pixel RGBA trail map with diffusion + decay every step.
- Directional sensing: Three forward-facing sensors per agent with tunable angle/offset/size.
- Spawn modes:
random,point,inward_circle,random_circle. - Headless-friendly: Core sim decoupled from rendering; pygame only wraps display.
- Deterministic rules: No ML—patterns emerge from local interactions.
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
pip install -r requirements.txt- Taichi is optional but recommended for speed; the code falls back to NumPy when unavailable.
Run the interactive window (auto-selects Taichi if installed):
python slime_sim.pyRuntime options are defined in run_pygame (near the bottom of slime_sim.py):
display_scale: Downscale for smaller windows.target_fps: Display frame cap.use_taichi: Force CPU (False) or GPU (Truewhen Taichi available).num_species: 1–3 preset species.board_scale: Scales world size and agent count together.
Controls in the window:
ESCor window close: quit.- FPS is shown in the title bar.
Headless stepping (import and run without pygame):
from slime_sim import SlimeSettings, Simulation
sim = Simulation(SlimeSettings(num_agents=5000, steps_per_frame=5))
for _ in range(600):
sim.step()
frame = sim.build_colour_map() # numpy array (H, W, 3) in [0, 1]slime_sim.py # Simulation (NumPy) and Taichi backend + pygame runner
requirements.txt # Minimal dependencies (Taichi optional but listed)
docs/ # Place your GIFs here (see Demo table)
- Initialization
- Agents spawn using the chosen
SpawnMode, with random headings. - Species are assigned round-robin/randomly; each species has its own speed, turn rate, sensor angle, and display color.
- Trail map is a float32
(H, W, 4)array storing RGBA weights.
- Per-step update
- Each agent samples trail intensity at three sensor offsets (forward/left/right) weighted toward its own species mask.
- Steering follows the original shader logic: keep heading if forward is strongest; otherwise bias left/right or add jitter.
- Agents move; if they hit the boundary, they clamp position and randomize heading.
- When inside bounds, they deposit their species mask into the trail map (capped at 1.0).
- Diffuse and decay
- A 3×3 blur approximates diffusion without SciPy.
- Exponential-ish decay reduces the trail each step, preventing saturation.
- Color build
- For each pixel, species channels are combined using their RGB colors to produce a
(H, W, 3)display array.
- Rendering
- Pygame turns the NumPy color map into a surface; Taichi path transposes buffers for the same output.
Key knobs in SlimeSettings:
width,height: Render buffer resolution.num_agents: Population size (affects density and performance).steps_per_frame: Simulation steps per draw; higher = faster evolution, more GPU/CPU load.trail_weight,decay_rate,diffuse_rate: Balance how fast trails strengthen, fade, and spread.species_settings: Per-speciesmove_speed,turn_speed(rev/sec),sensor_angle_degrees,sensor_offset_dst,sensor_size, and RGBAcolour.
Species presets in run_pygame:
- Green-only demo: set
num_species=1and use a greenSpeciesSettings. - Red+green demo: set
num_species=2. - RGB demo: default
num_species=3.
- CPU path (
Simulation): Pure NumPy arrays; triple loops for sensing are acceptable at 20k agents but can be tuned by loweringnum_agentsorsteps_per_frame. - GPU path (
TaichiSimulation): Mirrors CPU logic with kernels_update_agents,_diffuse,_build_colour; initializes with CUDA, then generic GPU fallback. - Trail map: Stored as RGBA so multi-species trails coexist; deposition clamps to
[0, 1]. - Diffusion: Manual padding + slicing; avoids SciPy dependency.
- Sensing weights: Each species sees its own trails as attractive and others as repulsive (
species_mask * 2 - 1), yielding lane formation and braiding.
- Taichi not installed: The script prints a hint and uses NumPy; install with
pip install taichifor speed. - Slow FPS: Reduce
num_agents, lowerwidth/height, or setsteps_per_frame=5on CPU. - No window on headless servers: Skip
run_pygameand driveSimulationdirectly as shown above. - GIFs missing: Add your GIFs to
docs/with the filenames referenced in the demo table.
Apache-2.0 (same spirit as the original Unity-inspired demo).
- Thanks to Sebastian Lague for the inspiring slime/ant simulation breakdown.
- Taichi and pygame communities for approachable GPU kernels and 2D rendering.


