Metabolism: add README
Project pitch, invariants, quick-start commands, layout, reference songs, status, and how to read the coupling × residual report.
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# metabolism
|
||||
|
||||
Songs as **substrate**. A music video generator whose outcome is grown, not
|
||||
mixed: the track is not a parameter set the renderer modulates — it is the
|
||||
world an agent ecology grows on. Same song + same seed ⇒ the same world,
|
||||
bit for bit, frame for frame, preview identical to export.
|
||||
|
||||
```
|
||||
song (PCM) ──► analyse ──► score · field · graph · laws ──► species ──► world ──► camera ──► frames
|
||||
```
|
||||
|
||||
The full concept and rationale live in **[DESIGN.md](DESIGN.md)** — read it
|
||||
before touching the code.
|
||||
|
||||
---
|
||||
|
||||
## The idea in one paragraph
|
||||
|
||||
Most visualisers *modulate* one fixed stage: the song turns knobs, and every
|
||||
track ends up presenting the same toy in different clothes. Here the song
|
||||
places the **food** (events land where the track's harmonies point), the **laws**
|
||||
(each section changes the rules at its boundary), and the **species** (the
|
||||
seed picks a rule set — built from tempo, noise, brightness and band
|
||||
correlations — not a parameter vector). Two songs differ like two habitats
|
||||
differ, not like two skins. `drone` grows a slow tonal weaver with heavy,
|
||||
lasting ground markings; `runner` grows a fast noisy swarm with jittered
|
||||
motion and thin ephemeral trails; `dusk` grows a crystalline, slow,
|
||||
over-clustered world where the sparks reject the builders.
|
||||
|
||||
## Invariants
|
||||
|
||||
Everything is load-bearing to keep these true:
|
||||
|
||||
- **Persistence** — agents and their trails last seconds to tens of seconds.
|
||||
- **Causality** — every visible event has an audible cause (hits are rings on
|
||||
the ground) and a visible one.
|
||||
- **Consequence** — the field is eaten, the trails accumulate; state at `t` is
|
||||
made of state at `t−1`, never re-rolled.
|
||||
- **Determinism** — no `Math.random`, no wall clock; tools and browser share
|
||||
the same `Run`, so preview provably equals export.
|
||||
|
||||
---
|
||||
|
||||
## Quick start
|
||||
|
||||
Requires Node 20+ (for `node --test`) and your usual package manager.
|
||||
|
||||
```bash
|
||||
npm install
|
||||
|
||||
# tests: analysis, determinism, world invariants, metrics sanity
|
||||
npm test
|
||||
|
||||
# filmstrips: 12 frames per song, tiled
|
||||
# (needs the flow-state test bank WAVs at ../flow-state/test/songs)
|
||||
npm run strip # drone, runner, dusk
|
||||
npm run strip -- --songs drone --cols 6 --rows 2 --out out
|
||||
npm run strip -- --songs drone,runner,dusk --combined 1 # comparison sheet
|
||||
|
||||
# report: coupling × residual fitness + fingerprint divergence across songs/seeds
|
||||
npm run report # prints a table, writes out/report.md + report.json
|
||||
npm run report -- --songs drone,runner,dusk --seeds 999,12345,777777
|
||||
```
|
||||
|
||||
Outputs land in `out/` (gitignored). `npm run dev` serves a Vite root once a
|
||||
browser demo exists.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
DESIGN.md concept, invariants, build order
|
||||
src/
|
||||
audio/ WAV decode, radix-2 FFT, feature table, sectioning, onset score
|
||||
song/ events (onsets → geometry), species (genome), palette, song assembly
|
||||
sim/ wells (harmony→food) and world.js (the typed-array ecology)
|
||||
render/ software framebuffer, trail composer, PNG encoder
|
||||
camera.js event-reactive cutting, shot-size rhythm, drift-and-push
|
||||
film.js Run: the single wire-up of sim → camera → framebuffer
|
||||
metrics.js coupling, residual, fitness, fingerprint, divergence
|
||||
rng.js seeded PRNGs (the only randomness in the repo)
|
||||
tools/
|
||||
load.js WAV → analysis → song (node-only)
|
||||
strip.js filmstrip renderer
|
||||
report.js system-level evaluation → markdown table
|
||||
test/ node:test suites
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
`tools/*` load the synthetic reference tracks from
|
||||
`../flow-state/test/songs` (`drone`, `runner`, `dusk`) — three 120 s test
|
||||
signals chosen to cover the axes the species reads: dark/tonal/beatless,
|
||||
bright/noisy/fast, darkest/all-tonal/mid-tempo. Drop any WAV there and point
|
||||
`--songs` at it; the species will derive from whatever the track actually says.
|
||||
|
||||
## Status
|
||||
|
||||
Currently a proof: the simulation is alive, the three songs are measurably
|
||||
distinct (fingerprint divergence between songs ≫ divergence between seeds),
|
||||
and the tools verify it. It is **not yet a film** — nothing is muxed to
|
||||
audio/video, the renderer is a 480 p proof, and the demo page isn't built.
|
||||
Next milestones: a browser demo, event-reactive cutting tuned to a full real
|
||||
track, and video export. See DESIGN.md's *Build order & status*.
|
||||
|
||||
## Auditing what it grew
|
||||
|
||||
The report's **coupling × residual** fitness is the honest score: coupling is
|
||||
how much the ecology answers the track; residual is the internal dynamics the
|
||||
track does not explain. A pure visualiser scores ~0 (no residual); a random
|
||||
walk scores ~0 (no coupling). The fingerprint (occupancy, clustering, trail
|
||||
fill, class mix) tells you whether two songs grew *different* worlds without
|
||||
anyone having to opine about it.
|
||||
|
||||
<!--- _Note: this README documents the design intent; the full argument for
|
||||
every mechanism is in DESIGN.md._ -->
|
||||
Reference in New Issue
Block a user