Coupled-subsystems planetary simulator
  • Rust 72.7%
  • JavaScript 24.5%
  • HTML 1.7%
  • CSS 1.1%
Find a file
Valis 09fc0a8c82 phase F visual fixes: live mesh updates + bigger displacement
The mountain rendering was broken in two places:

1. Vertex positions never updated after scenario load. buildMesh()
   read planet.positions() once (which baked in elevation displacement
   from initial terrain), then never refreshed. Plate tectonics could
   raise mountains in the data, but the mesh stayed flat — colours
   updated each frame but vertices didn't move.

2. Vertex normals never recomputed. Even if positions had updated,
   computeVertexNormals() only fired at mesh build, so lighting
   wouldn't reflect the new shape.

Fixes:

  - WASM: write_positions(buf: &mut [f32]) — zero-allocation positions
    writer paired with the existing colour writers.
  - Frontend: pullColors() became pullState() — refreshes colours every
    frame, refreshes positions and recomputes normals only when geology
    has changed (planet.time_myr() advanced) or sea level was just
    dragged. Position refresh is the expensive part (~5ms at depth 5
    including normal recomputation), so we skip it on frames where
    nothing geological happened.

Also:

  - Displacement scale changed from 30,000 m → 12,000 m per unit of
    sphere radius. At 30K, an 8 km mountain showed as 27% of radius —
    technically there but visually understated. At 12K, the same
    mountain shows as 67% — clearly mountainous. Earth's actual ratio
    is ~0.14% (mountains are essentially invisible from orbit), so
    we're exaggerating by ~10×, which is the right move for a planet
    you're meant to read at a glance.

  - Ocean cells now sit on the reference sphere regardless of their
    underwater bathymetry — the rendered ocean surface looks flat,
    matching real-water visual conventions. Sub-sea-level land
    (continental basins below sea level) sinks correctly.

  - Sea-level slider now flushes lastGeoTime so position refresh
    happens on the next frame — drag the slider and watch the ocean
    surface rise/fall in real time.

Out of scope for this fix:

  - The mesh still renders the icosahedron triangulation, not the
    Goldberg dual hex tiles. Cells *are* triangle vertices, so
    mountains spike at vertex points and the triangles between cells
    create "tent" geometry. Rendering the dual mesh would be cleaner
    but is its own substantial change.

Tests: 54, all green (no test surface changes).

Authored by Rowan Valle; Executed by Claude Code
By Symbiont Systems LLC
2026-04-27 21:58:48 -04:00
metabolic-core phase F: true-runtime plate tectonics 2026-04-26 21:20:34 -04:00
metabolic-wasm phase F visual fixes: live mesh updates + bigger displacement 2026-04-27 21:58:48 -04:00
research research: Phase F plan — true-runtime plate tectonics 2026-04-26 20:36:37 -04:00
web phase F visual fixes: live mesh updates + bigger displacement 2026-04-27 21:58:48 -04:00
.gitignore metabolic-core: spatial Daisyworld + geodesic grid 2026-04-25 21:55:58 -04:00
ARCHITECTURE.md audit chunk 6: ARCHITECTURE.md 2026-04-26 20:25:37 -04:00
Cargo.toml metabolic-wasm + web: browser visualisation of the hex-sphere planet 2026-04-25 21:56:44 -04:00
CLAUDE.md Metabolic: initial commit — Daisyworld engine, the SimEarth successor 2026-04-25 20:01:19 -04:00
README.md Metabolic: initial commit — Daisyworld engine, the SimEarth successor 2026-04-25 20:01:19 -04:00

Metabolic

A coupled-subsystems planetary simulator. The biological-systems sibling to Forms (mathematics) and Elemental (chemistry).

The successor question to Lovelock's SimEarth (1990): given thirty-six years of compute, biogeochemistry, microbial ecology, and Earth-systems modelling, what does a planetary simulator look like today?

Approach

Forms is a generative engine because mathematics is generative. Elemental is an atlas because the periodic table is finite. Biology is neither — it is process: coupled, multi-scale, historical, relational. Metabolic is therefore a simulator you inhabit, not a catalog you browse or an expression you evaluate.

The engine is a pure Rust library; visualisation and interaction layers attach later via WASM, the same pattern Forms uses for math-coremath-wasm → browser.

The Hello World

metabolic-core ships with one scenario: Daisyworld (Watson & Lovelock 1983). Two daisies, six equations, one feedback loop. As solar luminosity ramps from 0.6 to 1.6 over geological time, the planet's effective temperature is held inside the daisy growth window — without intent, without coordination, by selection alone.

If Daisyworld self-regulates here, the engine philosophy is right.

Author

Authored by Rowan Valle. By Symbiont Systems LLC.