biota searches the parameter space of Flow-Lenia - a continuous cellular automaton where matter is conserved by construction. Rather than finding a single best creature, it fills a behavioral grid where each cell holds the most compact creature with a particular phenotypic fingerprint. The result is a structured catalog of qualitatively distinct life-forms.
Each creature is a soliton: a stable, self-maintaining pattern that persists indefinitely given the right parameters. Mass conservation is what makes them viable across a wide parameter range - without it, most settings produce explosion or collapse within a few steps.
MAP-Elites runs a loop: sample parameters, simulate a creature, measure its behavior, insert it into the matching archive cell if it beats whatever is already there. After thousands of rollouts the archive fills with creatures covering the behavioral space as broadly as possible - not optimizing toward one solution, but toward diversity.
Simulations run in parallel across a 3-node GPU cluster. One batch task evaluates B creatures as a single vectorized forward pass on one RTX 5060 Ti. The driver owns the archive and orchestrates the search; workers are stateless.
Three scalars measured from each rollout index the archive's three axes. The active set is chosen per run — any three from the built-in library of nine. All are normalized to [0, 1] and empirically calibrated against real cluster runs.
biota is a self-contained CLI tool. You can run it on a laptop for quick iteration or across a Ray cluster for full-scale searches. The only hard dependencies are Python 3.12, PyTorch, and Ray.
# Clone and install git clone https://github.com/rkv0id/biota cd biota uv sync
uv run biota search --preset dev --budget 200
python scripts/build_index.py open runs/index.html
On Apple Silicon pass --device mps --batch-size 32 for a meaningful speedup. On a CUDA cluster, use --batch-size 64 --workers N where N is the number of nodes. The standard preset (192×192, 300 steps) at B=64 on an RTX 5060 Ti cluster runs 500 rollouts in about 97 seconds.
# Apple Silicon uv run biota search --preset standard --budget 500 \ --device mps --batch-size 32 # Single CUDA GPU, no Ray uv run biota search --preset standard --budget 500 \ --device cuda --batch-size 64 # Multi-node Ray cluster, custom descriptor axes uv run biota search --ray-address head:6379 \ --preset standard --budget 2000 \ --device cuda --batch-size 64 --workers 3 \ --descriptors oscillation,compactness,png_compressibility
Pass --descriptors with three comma-separated names to control which behavioral axes the archive uses. With 9 built-ins there are 84 possible configurations. You can also supply your own via --descriptor-module path/to/file.py — the file must define a list named DESCRIPTORS containing Descriptor objects.
# Default axes uv run biota search --descriptors velocity,gyradius,spectral_entropy # Shape and complexity axes uv run biota search --descriptors oscillation,compactness,png_compressibility
Coming in v2.0.0. Spawn creatures from selected archive cells together on a large shared grid and observe what happens: do they interact, ignore each other, or destabilize? The behavioral descriptor space lets you make deliberate choices about which creatures to seed together.
Homogeneous first (v2.0.0): one archive cell, multiple copies, global parameters. Then heterogeneous (v2.1.0): creatures from descriptor-space-distant cells, parameter localization.