# biosim4: a C++ evolution simulator you build and run from the command line

> biosim4 evolves 2D creatures through natural selection using a genome, a neural net brain and a config file. It is a research toy with no GUI, and the README says it is moving to maintenance-only.

**davidrmiller/biosim4** — Biological evolution simulator

- Repository: https://github.com/davidrmiller/biosim4
- Stars: 3,366 · Forks: 478
- Language: C++
- License: NOASSERTION
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/davidrmiller-biosim4

## The problem biosim4 solves, and who it is actually for

biosim4 simulates biological creatures that evolve through natural selection. The README describes it as a pile of code used to run those experiments, with results summarized in a YouTube video titled "I programmed some creatures. They evolved." That framing matters: this is a simulator for people who want to watch selection act on a population of agents they can inspect, not a general purpose game engine or an agent framework.

The intended user is someone willing to compile a C++ console program. The README states plainly that the program lacks a friendly interface and that compiling and executing it may require attention to details. Anyone who wants a UI is pointed to a fork hosted by @ilyabrilev. Within the repository, the code lives in the BS namespace, short for biosim, and the src directory compiles to a single console program named biosim4.

What you get out of a run is not a score or a leaderboard. It is a population whose genomes and neural nets you can print, a log of generations, movies of selected generations, and summaries of which sensory inputs connect to which action outputs. The value is in observing the trajectory of a lineage under a selection criterion you configured.

## Grid, Peeps and Indiv: how the simulation is wired

Three classes carry the world. Class Grid holds a 2D array of 16-bit indexes, where each nonzero index refers to a specific individual and zero marks an empty location. Grid stores nothing else about the world; it only records who lives where. Class Peeps holds every individual in a std::vector of struct Indiv, and the indexes in Grid are indexes into that vector. Class Peeps does not know how individuals work internally.

Struct Indiv is where an individual lives: its genome, its neural net brain, a redundant copy of its X,Y location, plus parameters such as responsiveness level, oscillator period and age. At the start of a simulation, Indiv converts its genome into a neural net brain. During a run it can print the genome and brain in text form to stdout, and Indiv::getSensor() computes the individual's input neurons on each simulator step.

Execution follows three nested loops in simulator(): the outer loop per generation, an inner loop per simulator step within the generation, and an innermost loop per individual. The README notes the innermost loop is thread-safe so OpenMP can parallelize it. At the end of each simulator step, endOfSimStep() runs single-threaded to build a video frame of all individual positions and push it onto a stack for later conversion to a movie, plus housekeeping for certain selection scenarios. At the end of each generation, endOfGeneration() turns the saved frames into a video and may generate a progress graph.

## biosim4.ini is the experiment, and it can be edited mid-run

Every tunable parameter for a run sits in a config file named biosim4.ini by default. The executable reads it at startup and then keeps monitoring it for changes during the simulation. The README says many parameters can be modified during a run, while admitting the mechanism is not foolproof. Class ParamManager manages those parameters and exposes them through a read-only pointer from ParamManager::getParamRef(). Most config entries map to members of struct Params in params.h, and params.h documents how to add new ones.

This is the most interesting design decision in the project. Live tuning turns a run into a conversation: you can watch a population respond to a changed selection pressure without restarting from generation zero. It also means a run is not reproducible unless you record what the config file looked like at each point, because the file on disk is not necessarily the configuration that produced the current generation. The README's own caveat about the mechanism not being foolproof is the honest framing here.

Output is split by purpose. logs/epoch.txt gets one appended line per completed generation with the generation number, survivors under the selection criterion, an estimate of genetic diversity, average genome length and deaths attributed to the kill gene. Sample genomes appear on stdout in hex and in a mnemonic format that tools/graph-nnet.py can turn into a network diagram, and tools/graphlog.gp plots the epoch log.

## Building biosim4 on Linux and running a first generation

The repository ships a Makefile and a CMakeLists.txt. The Makefile defaults to a release build and requires a C++17 compiler, OpenMP and OpenCV 4, which it locates through pkg-config --cflags opencv4. The Dockerfile installs build-essential, cmake, libopencv-dev, cimg-dev, gnuplot and python3-igraph on an Ubuntu base, which tells you the expected dependency set even if you build outside a container.

To build with make, run the release target. It creates bin/Release/ and obj/Release/src and links against the OpenCV core, video and videoio libraries plus libgomp and libpthread:

```bash
make release
```

If that succeeds you get the executable at bin/Release/biosim4. If pkg-config cannot find opencv4, the compile flags will be empty and the build will fail at the OpenCV headers, which is a dependency problem rather than a source problem.

Run it from the repository root so the default config file and output directories resolve. The README states the program reads biosim4.ini by default and that a different config file can be specified on the command line:

```bash
./bin/Release/biosim4
./bin/Release/biosim4 myconfig.ini
```

During the run you should see sample genomes on stdout at the interval set in the config, a summary of neural connections from each sensory input neuron and to each action output neuron, and new files appearing in images/ and logs/ according to the parameters you set. To clear the generated artifacts between experiments, the Makefile provides a distclean target that removes logs/* and images/* in addition to the build output:

```bash
make distclean
```

## Where biosim4 will disappoint you

The README opens with a status section saying the project is transitioning to maintenance-only. Bug fixes that let the program compile and execute are welcome, and discussion is welcome in Issues, but feature work is not the offer. The last push to the repository was on 2026-06-13. If your plan depends on new selection scenarios, new sensory inputs or an improved interface arriving upstream, that plan is not supported by the project's own statement.

The interface is the second limitation, and it is stated as a fact rather than a complaint: this command line program lacks a friendly interface, and compiling and executing it may require attention to details. There is no GUI to fall back on, and the README directs users who want one to a fork. Output is also file-based. Movies land in images/, logs land in logs/, and genome dumps go to stdout, so any pipeline around the simulator is something you write.

Configuration is the third. Live editing of biosim4.ini is convenient and explicitly described as not foolproof. It is the wrong tool if you need bit-exact reproducibility from a single config snapshot, because the running configuration is not frozen at startup. It is also the wrong tool if you want to simulate something other than a 2D grid of agents with genomes, neural nets and pheromones; the architecture is built around that model.

## The ilyabrilev fork and what it changes

The README points to a fork of this project hosted by @ilyabrilev as the place to go for a nicer user interface. That is the alternative the project itself recommends, and the difference is interface rather than simulation model: the fork is presented as the same project with a friendlier front end, while davidrmiller/biosim4 stays a console program whose output is text, images and logs.

If your reason for evaluating biosim4 is that you want to run evolution experiments without writing your own viewer, the fork addresses that reason directly. If your reason is that you want to read, modify and extend the C++ internals in the BS namespace, the fork is not the relevant comparison, because the interface is not the part you were going to touch.

The honest way to frame the choice: pick the fork when the interface is the blocker, and pick this repository when you intend to work in src/ and want the reference implementation the README documents class by class. The README does not describe the fork's internals or how far it has diverged, so treat the fork as a separate codebase to evaluate on its own terms.

## Conclusion

Adopt biosim4 if you want to read and modify C++ source that evolves agents in a 2D grid and you are comfortable building with make or CMake against OpenCV and OpenMP. Do not adopt it if you need a friendly interface, packaged binaries or a project that still adds features, since the README states it is transitioning to maintenance-only and only bug fixes that keep it compiling and executing are welcomed. Before relying on it, verify that your toolchain satisfies the Makefile's pkg-config opencv4 lookup, that the biosim4.ini parameters you intend to change are among those the README says can be modified mid-run, and whether the fork by @ilyabrilev covers the interface gap you are trying to close.

## FAQ

### How do I install and build biosim4?

There is no package or installer. You clone the repository and build it with the provided Makefile or CMakeLists.txt, which require a C++17 compiler, OpenMP and OpenCV 4 found through pkg-config. The Makefile's release target produces bin/Release/biosim4.

### Does biosim4 have a graphical interface?

No. The README states the program lacks a friendly interface and that compiling and executing it may require attention to details. It directs users who want a nicer interface to a fork hosted by @ilyabrilev.

### Can I change biosim4 parameters while a simulation is running?

Yes. The executable reads biosim4.ini at startup and then keeps monitoring it for changes, and the README says many parameters can be modified during a run. The same README notes the mechanism is not foolproof.

### What files does a biosim4 run produce?

It appends one line per completed generation to logs/epoch.txt with the generation number, survivors, a genetic diversity estimate, average genome length and kill gene deaths. It writes movies of selected generations to images/ and prints sample genomes and neural connection summaries to stdout.

### Is biosim4 still being developed?

The README says the project is transitioning to maintenance-only and that bug fixes enabling the program to compile and execute are welcome. The last push to the repository was on 2026-06-13.

## Sources

- [davidrmiller/biosim4 on GitHub](https://github.com/davidrmiller/biosim4)
- [Issues](https://github.com/davidrmiller/biosim4/issues)
- [README](https://github.com/davidrmiller/biosim4/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/davidrmiller-biosim4
