Metabolism: rule program, song-driven life, tribe VMs; M2.7 design (strains & allegiances, living wells)

This commit is contained in:
Dejvino
2026-10-28 10:07:05 +01:00
parent 16f4b4a805
commit f939351689
28 changed files with 3199 additions and 601 deletions
+72 -14
View File
@@ -60,29 +60,81 @@ 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
# prepare: analyse songs once, so the demo loads instantly instead of
# re-analysing the WAV in the browser (falls back to live analysis if absent)
npm run prepare # writes out/prepared/<song>-<seed>.json
```
Outputs land in `out/` (gitignored). `npm run dev` serves a Vite root once a
browser demo exists.
Outputs land in `out/` (gitignored).
## The demo
```bash
npm run dev # open http://localhost:5173 and pick a song
```
A browser demo that plays the songs off the actual pipeline. The page serves
the bank from `../flow-state/test/songs` (via `vite.config.js` — no copies),
lists **all 17 tracks** with the species each one grows, and plays the chosen
track while the world steps to it:
- **select a song** → it fetches the WAV, decodes it, and grows the world to
frame 0 before letting you in. Run `npm run prepare` once and the browser
loads the pre-computed analysis instead of re-analysing, so viewing is fast
(it falls back to live analysis when an artifact is missing);
- **play / pause** (or <kbd>space</kbd>), **seek** (or <kbd>←</kbd>/<kbd>→</kbd>
±5 s) — the audio clock only chooses *which* frame the world should have
reached, so seeking is fast forward; a backward seek re-grows from frame 0;
- **seed** (the exact world), **res** (640×360 realtime default, up to
1280×720) and **volume**; changes live without breaking playback;
- the seek bar shows **section ticks** (the laws), the status line shows the
current law, shot size/zoom and live world stats (population, field, trail);
- the page accent **wears the track's palette hue**, and the URL carries
`?song=&seed=&res=` so a film is a link.
Determinism is the point: the page renders through the same `Run` as the
tools — same song, same seed, same frame ⇒ the same pixels (tested bit-identical
against `strip` output, including the prepared-artifact path). `npm run build`
bundles it; `npm run preview` serves the built page from `dist/`. The world
behind the `Run` is the **macro ecology** of EVOLUTION.md M1 — population
fields, not entities; see `EVOLUTION.md`.
Files: `index.html`, `vite.config.js` (song-bank + prepared-artifact plugin),
`src/demo/*` (`main.js` page wiring, `player.js` Run→canvas, `audio.js`
WebAudio clock, `catalog.js` metadata, `style.css`).
## Layout
```
DESIGN.md concept, invariants, build order
DESIGN.md concept, invariants, build order (end-goal)
EVOLUTION.md course-corrected roadmap (M1 done, M2–M4 ahead)
index.html the demo page
vite.config.js song-bank + prepared-artifact plugin (dev + build)
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
song/ events (onsets → geometry), species (genome), rules.js (the
per-song rule program + section operator regimes),
tribe.js (the per-tribe behaviour VM: senses, memory,
actions, branching — compiled from the song), palette,
song assembly, serialize.js (prepare cache)
sim/ wells (harmony→food) and world.js (the macro field-world:
128² density, 5 substeps/frame, executes the rule program
and the tribe programs)
render/ software framebuffer: trail composer, density glow + speck
swarms (the "billions"), PNG encoder
camera.js wide event-reactive shots, 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)
demo/ player page: main.js wiring, player.js (Run→canvas),
audio.js (WebAudio clock), catalog.js, style.css
tools/
load.js WAV → analysis → song (node-only)
prepare.js pre-computes analysis → out/prepared/<song>-<seed>.json
strip.js filmstrip renderer
report.js system-level evaluation → markdown table
test/ node:test suites
test/ node:test suites (incl. prepared-artifact bit-identity)
```
## References
@@ -95,12 +147,18 @@ bright/noisy/fast, darkest/all-tonal/mid-tempo. Drop any WAV there and point
## 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*.
M1, M2 and M2.6 of **EVOLUTION.md** are done: the entity world is a **macro,
population-field ecology** (density, substeps, coarse-grid forces, speck
rendering); the rules that run it are a **declared, compiled rule program**
(per-caste rule entries, interaction rules, per-section operator regimes, the
event→response mapping); and the tribes are **small deterministic programs** —
sensing, memory, actions and branching, compiled by the song and executed on
the decision grid every substep. Songs grow balanced, *mixed* societies (block
mix 0.86–0.95) with structured geography, and the opening is a genesis-settled
world, not a blank plate. Everything is deterministic and bit-identical across
the demo, the tools and the prepared-artifact path (28 tests green). It is
**not yet a film** — the camera still cuts rather than travels (M3) and nothing
is muxed to a video file (M4).
## Auditing what it grew