Software & Sims · 2026
Sim Env: Open-Ended Evolution
An artificial-life world in C++20 where bodies, brains and behaviour evolve from nothing but survival and reproduction. A three-tier food chain, weather and climate events, deterministic multithreaded engine, and an always-on server whose world anyone can watch live in the browser.
- C++20
- Multithreading
- Neuroevolution
- raylib
- JavaScript / Canvas
- nginx
- systemd
- producers, grazers, predators — no fitness function
- 3 tiers
- evolvable cell types on an 11×11 body grid
- 14
- per creature per frame to each live viewer
- ~1 byte
- engine tests (energy, determinism, snapshots)
- 40

What it is
Sim Env is a 2D world in which creatures with growing bodies and recurrent, plastic neural brains evolve with no goal other than staying alive and reproducing. There is no fitness function and nothing is scripted after birth: whatever gathers energy and leaves offspring spreads.
Light is the only energy that enters the world. Producers live on it, grazers eat producers, and predators hunt grazers. Seasons move the sunny band across the map, clouds drift, lakes and moisture decide where plants can grow, and random climate events (drought, ice age, heat wave, volcanic winter, plague, bounty) reshuffle who survives. The point is to watch macro evolution happen: species rising, taking over, crashing and adapting after a catastrophe.
This is a rewrite of an earlier browser version, Sim Env v1.
What evolves
| Bodies | A growth program on an 11×11 grid. Creatures are born as a single core and grow (and regrow) cells as energy allows. 14 cell types — tissue, armour, fin, eye, mouth, spike, photosynthetic, fat, toxin gland, shield, jet, light sensor, gonad — and placement matters: eyes see where they face, spikes hurt what they touch, fat insulates. |
| Brains | 144 inputs → 32 leaky recurrent units → 14 outputs. Time constants and neuromodulated Hebbian plasticity are part of the genome, so how much a creature learns during its life evolves too. |
| Senses | 8 vision sectors, smell, pheromones, temperature, hydration, a compass and a clock, plus memory of where food and threats were last seen. |
| Physiology | Warm- or cold-blooded, preferred temperature, fat, a gut for gorging, torpor. Frostbite, heatstroke, thirst and disease are real causes of death. |
The engine
Energy is conserved
A cell’s build cost is its embodied energy, and eating can only take what the prey built or stored. A test fails if any energy appears from nowhere.
Deterministic in parallel
Sensing, thinking, moving and interacting run on all cores. Each creature writes only its own state; cross-creature effects are resolved afterwards in a fixed order. The result is identical for any thread count.
Saves that last
Snapshots round-trip exactly and migrate across format changes, so long-running worlds and the creature bank survive every update.
Background “training worlds” (islands, a duel league, a species school) run on the same engine and send adapted genomes back into the main world. A creature bank keeps the best organisms of every run and can found new worlds.

Watching it live
The desktop app is for experiments. For an always-on world, the engine runs headless in evo_serve on a small machine on the LAN, and browsers do all the drawing, like clients of an online game.
| Part | Role |
|---|---|
| Sim host (LAN) | Runs the world, saves on every stop or update, and sends the world state as compact binary frames over a tiny built-in HTTP server |
| nginx (web server) | Public, read-only reverse proxy with a shared cache; LAN-only controls are blocked |
| Browser | Decodes the frames, interpolates motion, and renders the map, population masses, cell bodies, charts and an inspector on a canvas |


Measurements
Measured on the live setup (medium world, 4 frames per second) and on a local nginx 1.24 test bench:
| Result | |
|---|---|
| Bandwidth per viewer, zoomed out | 0.24–0.3 Mbit/s (7–9 KiB per frame) |
| Bandwidth per viewer, zoomed in | 0.4–1.0 Mbit/s |
| 100 simulated viewers through nginx | all at 4.1 frames/s, 0 errors; 8,421 of 8,521 frame requests were cache hits, so the host saw the same load as for one viewer |
| Frame size, 5,178 creatures | 88 KB raw → ~20 KB as a gzipped delta |
| Decoding | every delta frame compared against a fresh keyframe: identical |
| Update | build, 40 tests and restart on the host in ~35 s; the world saves and resumes, open pages reload themselves |
The first host is a spare laptop. Running uncapped on four cores it sat at 92 °C, so it now runs at a fixed 60 ticks per second (58–66 °C). The same cap will matter on the Orange Pi.
Status
The engine, the desktop app and the live pipeline work, and the public page runs from a LAN host behind nginx. Still to do: move the host to an Orange Pi 4 Pro and measure it there (the brain step has no ARM NEON path yet), and bring more of the desktop inspector, such as the live brain, to the browser.