microbe-life
v0.5.0
Published
Particle life as small microbial creatures: one typed-array core for a web background and an Aether node.
Maintainers
Readme
Microbe Life
Particle life as small microbial creatures, for the night.earth background and an Aether node whose sliders are musical parameters. Plan: https://night.earth/view/microbe-life-plan
One core, no DOM, no dependencies (src/core.js): typed arrays and a uniform
grid, so it runs in a page, a worker or an AudioWorklet.
classicmode is Hunar Ahmad's rule. Withprecision: 64andneighbours: 'brute'it reproduces his particle_life.html bit for bit from the same seed (tested against a reference copy of his code).cellmode is a short-range push plus a smooth pull on a torus, which forms colonies, chains and swimmers. Itscorestiffness (default 3) caps how densely cells pack.- Rules are attraction: positive pulls together.
- One seed (a number, or a word such as
moss_ember) sets the rules and the starting layout.
import { Life, worldSize } from './src/core.js'
const life = new Life({ mode: 'cell', kinds: 4, count: 250, ...worldSize(1000), seed: 'moss_ember' })
life.step()
life.stats() // per kind: energy, centre, spread; meetings; clustersGenomes (src/genome.js) hold a creature: kinds, seed, and optionally
designed rules, per-pair radii and a mix of counts. encode() turns one into
a short share code (g1…, 24–50 characters) and lifeFromGenome() grows it.
Twelve curated genomes live in src/genomes.js: amoeba, budding, hyphae,
mycelium, diatoms, ciliates, segmented, swimmers, flagellates, volvox,
crescents, colonies. life.colonies() finds colonies by union-find and
measures their elongation (chains) and layering (membranes);
toCytoscape() (src/cyjs.js) exports a creature as cytoscape graph data.
A page background is one script tag (dist/microbe-bg.min.js, 11.9 KB,
5.2 KB gzipped):
<script defer src="microbe-bg.min.js" data-genome="amoeba"></script>It draws on a transparent fixed canvas behind the page, takes no clicks, runs
at 30 fps at most, halves its particles when frames run over 8 ms, stops while
the tab is hidden and shows one still frame to readers who ask for reduced
motion. data-count, data-opacity, data-fps and data-scale tune it;
window.microbeBackground has show(), level(), pause() and resume().
On the night.earth Sound Site it gives each page its own creature, crossfades
with the scene and breathes with the music.
The Aether node (dist/microbe-life.aethernode, 13 KB) is a manifest, an
AudioWorklet (wrappers/node/dsp.js) and a panel (wrappers/node/ui.js).
The worklet runs its own small copy of the creature: each kind is a voice,
new contacts between kinds ring grains, a dividing colony rings a bell. The
nine sliders (src/map.js) are musical and change the creature too; the
panel draws a larger copy that follows them. On the Sound Site a
Microbe Life voice steers the page background (dist/microbe-steer.js,
loaded on demand).
Classic mode (src/classic.js) and colonies/stats (src/colonies.js) add
themselves to Life when imported, so the background carries neither.
Cost follows density, not count. Keep the world growing with the particle
count (worldSize) and 1,000 particles step in well under 2 ms.
npm test # conformance, grid = brute force, seeds, stats
npm run bench # step cost per mode and size
npm run build # dist/microbe-life-demo.html, one file
npm run scan 400 # score random seeds for membranes, chains, division (JSON)
npm run thumbs # looping MP4 + JPG poster per curated genome (ffmpeg)
npm run cyjs # cytoscape graph data per curated genome
node bench/render.js out.wav 20 't=0 genome=3' 't=10 harmony=1' # render the node offlineMIT. See LICENSE for credits to Hunar Ahmad and Chevy Ray Johnston.
