Skip to content

Introduction

BrainlessLab is an extensible Julia lab for “brainless” cognition — behaviour that emerges from collectives of simple neuron-like nodes, with no homunculus and no hand-wired control. It is a Diverse Intelligences Summer Institute 2026 project, built as infrastructure for others to run experiments around a settled Falandays baseline.

What the lab studies

The two angles share a single object of study: a class of entity — self-organising collectives of minimal, neuron-like units, the same object whether the units are nodes in a reservoir or agents in an ensemble. The work is to characterise that class, and it has two halves.

One half asks what the class can do: each task is not a problem to be solved but a test of a capacity for behavioural complexity — responsiveness, coordination, and, at the frontier, adaptation and memory. The capacities are an open, evolving set, carved by the tasks that probe them, closer to construct-validation than to a benchmark. A score is only a calibrated indicator that a capacity is present, never the capacity itself: a collective self-organises toward its own viability, not toward our task, so that it can be made to do the task is the thing worth measuring — and measuring it honestly means saying what the number is measured against.

The other half asks what makes that possible: the collective dynamics — the qualities (criticality, timescale separation, coupling) a collective must have for a capacity to appear. These are the real payoff, and the two halves meet where the same neurons-as-nodes-within-a-collective signatures are measured at the node scale and the agent scale.

These are the two angles by their proper names: cellular cognition (test and evolve node designs; read a capacity off a calibrated score) and collective intelligence (profile and sweep the dynamics that underwrite it). See Concepts for the ontology and Scoring for what a score means.

Prerequisites

  • Julia 1.10 or newer (the package [compat] pins julia = "1.10").
  • Git, to clone the repository.
Terminal window
git clone https://github.com/…/brainless-lab.git
cd brainless-lab

Everything below runs from the brainless-lab/ root you just entered.

The one environment story

BrainlessLab ships a checked-in Manifest.toml, so you don’t resolve dependency versions — you reproduce the pinned set. Launch Julia with the project active and instantiate:

julia --project=. # from brainless-lab/ — activates BrainlessLab's own project
pkg> instantiate # materialise the pinned Manifest.toml (one-time)
pkg> add CairoMakie # a Makie backend, for plotting

The compute core is Makie-freesimulate runs headless with no plotting dependency. Plot methods live in a package extension (BrainlessLabMakieExt) that loads automatically once a Makie backend is present, which is why CairoMakie is a separate add rather than a baked-in dependency.

The separate tooling projects (bench/, profile/) have their own environments and are instantiated in their own directories — see the onboarding notes for that split.

Your first run

using BrainlessLab, CairoMakie
sim = simulate(:wall; node=:falandays_base, ticks=300) # stable baseline, 1 agent
visualize(sim) # spike raster + rate + trajectory

simulate runs the rollout and returns a result you can render; visualize assembles a static figure from it. The first Julia/Makie call spends noticeable time compiling — that is normal, and repeat calls are much faster.

CairoMakie vs GLMakie — pick by whether you have a display:

  • CairoMakie draws static figures and GIFs (visualize, animate). It is the headless-friendly path — use it over SSH, in CI, or with tooling --save / output-path flags.

  • GLMakie backs the interactive explore(...) window (Play / Step / speed slider), which needs a live display:

    explore(:torus; node=:falandays_base, n_agents=6) # interactive swarm (needs GLMakie)

    On a headless machine, save static outputs with CairoMakie instead of opening a window.

The recording model

A run is only as observable as what it recorded. simulate returns a SimResult (often bound to sim) — the recorded trace of a rollout, which the visualisation layer reads off the hot path. What gets kept is gated by record channels: pass record=[…] to select them, e.g. record=[:effectors] to keep the motor-output vector each tick. The engine’s only coupling to visualisation is a small channel-gated, downsampling Recorder; visualize, animate, and replay(sim) all read the resulting SimResult, and a saved run directory can be loaded back with replay(rundir).

Where to next

Concepts

The ladder of collectives — nodes, reservoirs, bodies, agents, ensembles — and the sensorimotor contract. Read the ontology →

Tooling

The command-line verbs (bench, profile, sweep, ablate), their run directories, and the per-project environment split. Set up the tools →