PRIMORDIA
Menu
Under the hood

How it works

One Rust workspace: a deterministic simulation, a server that speaks newline-delimited JSON, an MCP server for agents, and a browser viewer. Players never touch organisms directly. They design them, release them, and read what happened.

The world

A torus of cells holding two diffusing chemicals: sugar for energy and mineral for building children. Vents feed them. World presets change the feeding: calm, drift (vents move), seasons, patchy, desert, bloom, and random.

Every tick, each organism senses, thinks, turns, swims, eats and pays its upkeep. Bodies push apart on contact. When energy and material allow, an organism divides: the child gets half the energy and a slightly mutated brain. At zero energy it dies, and its body returns to the pool.

Deterministic, to the bit

The simulation is single-threaded, uses its own PCG32 random generator, and routes every floating-point function that is not bit-reproducible across platforms (sine, tanh, even min and max) through fixed implementations. A SHA-256 hash of the full world state at a fixed tick is pinned by a test: change one bit of behaviour and the test fails. So far the hash is confirmed across debug and release builds on one machine; the cross-machine check is still to do. A second test fails the build if anyone calls a banned float method.

The organism

A genome is a JSON document: a list of parts, a brain size, and mutation settings. The server derives the phenotype (capacity, upkeep, speed, cost of a child) and refuses invalid genomes with the rule they broke.

The brain is a small neural network (tanh). Inputs: each sensor's reading, the organism's own energy, and a bias. Outputs: thrust and turn. Weights can be given or left random; at every birth they mutate at the genome's own mutation rate, which can be zero.

PartWhat it does
membranethe body; radius 2–20. Bigger stores more and costs more, and swims slower.
flagellumforward thrust.
ciliaturning.
moutheats sugar (energy) and mineral (material for children) under the body.
chemo_sensorreads sugar, mineral, or the scent of other organisms, at an angle off the heading.
vacuoleextra energy storage; starts empty.
jawoffence: bites enemies smaller than you; you keep 35%. Shells block it.
stingeroffence: drains enemies of any size, through shells; you keep a fifth.
shelldefence: blocks up to 75% of a bite; slows you.
spikesdefence: anything that bites or stings you takes damage; at full power, more than a full jaw gains.
camouflagedefence: invisible to scent sensors.
toxindefence: attackers gain less; from power 0.5 up, they lose energy instead of gaining.

The API

Players connect over TCP (loopback only, for now) and send one JSON request per line. An MCP server wraps the same calls as tools for agent frameworks, and repairs the most common malformed genomes a model sends.

OpPurpose
hellojoin; get the limits, budget, and the match rules
catalogevery part, limit, cost formula and the combat setting
submit_genomea JSON genome in; a species and its derived phenotype out, or a refusal naming the broken rule
releasespend budget to drop founders of a species into the pool
observewhat you can see of the world
reportper lineage since your last report: births, deaths, kills, energy in and out, and plain-language notes
end_turnin an arena: done for this window; returns the scoreboard when the next window opens

Arenas

An arena is one world shared by several players. The server owns the clock. Time moves in windows (500 ticks by default): turn-based, where a window closes when everyone ends their turn or its time runs out, or real time, where the world runs continuously and a slow thinker simply misses the moment.

  • Score: the biomass (sum of radius²) of your organisms born in the pool, averaged over every tick of the match. Founders you release never score; only lineages that eat and reproduce do.
  • Budget: founders cost 5·(r/5)² each, from a budget that refills over time.
  • Combat: off, colony (each player is one colony; its organisms never fight each other) or individual (every organism for itself, sparing parent, children and siblings).
  • Body evolution: a per-birth chance that a child's body mutates into a new species. Off by default.

Watching

The viewer draws every organism from its genome: waving flagella, cilia, mouths, sensor antennae, shells, spikes and mandibles. Zoom to 32×, drag to pan, and click any organism to track it. A panel explains in words what it is doing, what it senses and what its brain decides. Fights, kills and newly evolved bodies are marked in the pool and logged in an event feed.

Organisms drawn from their genomes at 4x zoom
Bodies drawn from genomes, 4× zoom.
A whole pool with combat markers and the event feed
The whole pool, with fights and kills marked.