Emergence lab

Status: Proof of Concept Phase: Hone Stack: TypeScript + Vite Renderer: WebGL2 Agents: Claude + Codex Licence: MIT

Many agents following simple local rules exhibit emergent behaviour, seen in everything from ecosystems to economies.

A test project for multi-agent orchestration across Claude and Codex using the Autometta repo. The higher tier models plan and orchestrate while lower tiers code and verify with clear boundaries. Cross-family orchestration improves outcomes and catches failure modes that a single model misses, at more than twice the cost...

Run the app in a browser

View the research: Emergent behaviour from nature to management theory.

Julia set, escape-time render from the lab

The twenty

Twenty deterministic kernels behind one renderer. Each is a different discipline's way of pointing at the same thing: local rules, global form.

  • Gray-Scott reaction diffusion. Chemistry's version of the question.
  • Abelian sandpile. Self-organised criticality in one toy.
  • 2D Ising model. A magnetic lattice assembling order at a phase transition.
  • Kuramoto oscillators. Different rhythms crossing into collective synchrony.
  • Conway's Game of Life. The original, and still the cleanest.
  • Belousov-Zhabotinsky waves. The reaction that taught chemistry about excitable media.
  • Boids. Flocking from three local rules.
  • Particle life. A handful of attraction rules, and cells assemble themselves.
  • Physarum. Slime-mould agents laying pheromone trails into networks.
  • Strange attractors (Lorenz, Rössler, Thomas, Aizawa, Halvorsen — five separate cards). Where deterministic equations stop being predictable.
  • Diffusion-limited aggregation. How dendrites and lightning agree.
  • Elementary cellular automata. Wolfram's one-dimensional zoo.
  • Brian's Brain. Three states. Somehow it breathes.
  • Cyclic cellular automata. Rock-paper-scissors that spirals into itself.
  • Lenia. Continuous cellular automata, and life gets smooth gliders.
  • Mandelbrot, Julia, Burning Ship. Iterated maps as the geometry of feedback.
  • Logistic Mandelbrot. The bifurcation cascade hung off the Mandelbrot set as a curtain.
  • Clifford-DeJong. Clifford, De Jong, and Svensson point-map attractors, with live coefficient drift.

Gray-Scott is the priority kernel. The others are calibrated and held.

Run it

npm install
npm run dev

Open the URL Vite prints, normally http://localhost:5173/.

Checks:

npm run verify   # types, kernel tests, production build
npm test
npm run build

Publish into the site

The lab's own standalone deploy serves from the root path (/) and is unaffected by the steps below. To vendor a build into a host site instead, at /labs/app/:

npm run publish:site

This publishes four artifacts (scripts/publish-site.sh), each rsynced with -a --delete so stale files from a previous build are removed:

  • dist/public/labs/app/ — the static app (Vite base /labs/app/), standalone and fullscreen target
  • dist-lib/public/labs/lib/ — the library build (vite.lib.config.ts, entry src/app/lib.ts): the <emergence-lab-sim> web component plus mountLab, which the site's /labs/run shell imports by URL and mounts inline
  • KaTeX css + fonts → public/labs/app/katex/ — stable unhashed path the web component links into its shadow root (class rules) and the host document (font faces)
  • registry manifest → src/vendor/emergence-lab/registry.json — lets the site's build fail on slug drift instead of shipping dead deep links

The promo-flow path defaults to a sibling checkout; override it with PROMO_FLOW_DIR if promo-flow lives elsewhere:

PROMO_FLOW_DIR=/path/to/promo-flow npm run publish:site

Nothing is committed or pushed on the promo-flow side; that repository commits its own copy of the vendored build.

Baking a local point cloud

The logistic-Mandelbrot orbit3d view builds its point cloud in the browser, time-sliced and capped so it stays responsive on whatever device it lands on. That ceiling is the honest one for the web: the deployed app cannot assume a desktop GPU, and a cloud dense enough to resolve the cascade tail runs to hundreds of megabytes — the current machine-local bakes are 10 MB to 650 MB. Nobody should be asked to download that over a network, so it never ships.

The active route is exposed on the simulation canvas as data-orbit3d-sampler (the DOM form of canvas.dataset.orbit3dSampler):

Path When selected data-orbit3d-sampler data-orbit3d-boundary-detail
GPU sampled WebGL2 float targets and the orbit sampler both complete gpu-sampled active when Boundary detail is raised; otherwise off
CPU sampled GPU sampling is unavailable or fails; the time-sliced sweep completes cpu-sampled-gpu-failed degraded when requested; the normal Tail refinement plan is used
Prebaked ELPC A valid requested local bake finishes loading and supersedes the live build prebaked off; Boundary detail applies only to live builds
2D field orbit3d setup or both live cloud builders fail orbit3d-fallback-field degraded when requested; otherwise off

For a 3D cloud, data-orbit3d-build="complete" and a positive data-orbit3d-points confirm that the selected path produced a whole cloud. The 2D fallback intentionally has neither attribute. Boundary detail is an opt-in GPU-only live-build control: at maximum it raises the point budget from the unchanged 9.6M extreme ceiling to 16M and spends the additional capacity on a 5x5 boundary sub-grid warmed for 20,000 iterations. That depth is deliberate: stage 35 measured boundary-band period mismatch falling from 1.71% at 1,500 warmup iterations to 0.25% at 20,000.

Instead the cloud can be baked offline, on the machine that will view it, with no time-slicing, a much higher warmup, and a second refinement level the browser can't afford:

npm run build:test                  # the baker reuses the compiled kernel
node scripts/bake-orbit3d.mjs --points 50e6 --warmup 30000 --out public/baked/lm-50M.elpc

Flags: --points (target total), --samples (orbit window per cell, default 64), --warmup (default 20000), --refine-fraction (default 0.35), --out (default public/baked/logistic-mandelbrot.elpc).

Total points ≈ cells × samples, so at a fixed --points budget raising --samples buys vertical density in the attractor at the cost of resolution in the c plane. Periodic cells only have p distinct heights however many samples are taken; the chaotic bands are where extra samples show.

Each run writes the quantized .elpc binary and merges an entry into public/baked/index.json. The app fetches that manifest at mount and turns it into the Model source dropdown in the View controls — live plus one option per bake. With no manifest the control is not rendered at all, and the fetch is skipped outright unless the page is served from a local host, so the published site never asks for a file that cannot exist there.

public/baked/ is git-ignored and excluded from the publish rsync (scripts/publish-site.sh), so bakes stay on the machine that made them.

Stack

Vite and TypeScript throughout. Kernels are pure deterministic numerics with no runtime dependencies. The renderer uses a quality-first WebGL2/GPU path, including direct fragment-shader fractals, with Canvas 2D kept as a fallback and debug surface. Legacy browsers are not a target.

Adding a simulation

  1. Extend the SimKernel contract in docs/INTERFACE.md if the new sim needs it.
  2. Add the kernel under src/sims/<name>/ and wire the gallery in src/app/**.
  3. Write the essay in essays/<name>.md.

There is no fixed split of the codebase by model — any agent may work any
part of it. Multi-agent work runs through autometta (a worker/verifier loop)
when parallel work and cross-checking are wanted. The kernel contract in
docs/INTERFACE.md stays a reviewed boundary. See
MODELS.md.

Repository layout

emergence-lab/
  src/                    # kernels, renderer, controls, gallery
    sims/<name>/kernel.ts # deterministic kernel
    app/                  # renderer, gallery, controls, presets
  essays/                 # one .md per sim
  scripts/                # publish, deploy, thumbnail and point-cloud baking
  public/baked/           # machine-local .elpc bakes + index.json (git-ignored)
  docs/
    INTERFACE.md          # the SimKernel contract
    PUBLISH-WORKFLOW.md   # publish-safety hooks and remotes
  state/handoffs/         # autometta worker completion envelopes

Version history

Version Date Summary
v0.2.0 2026-07-20 Immersive fullscreen, web-component build + site publish pipeline
v0.1.0 2026-07-20 Initial public mirror: 19 kernels behind one renderer

We use analytics cookies to understand site usage and improve the service. We do not use marketing cookies.