clone

an endless marble-race generator in the browser; the url is the seed, so every track can be shared

main
marbles / README.md
README.md 4.8K source

marbles

Seeded, emergent marble-track generator. A Deno webapp that assembles an endless marble race from Kenney's CC0 Marble Kit, with the Nature Kit as a scenery layer. The URL fragment is the seed — every generated track is a browser-history entry you can share, revisit, and step back/forward through.

Quickstart

deno task dev        # build (watch) + serve → http://localhost:8000

Open http://localhost:8000/#your-seed-here — any string is a valid seed.

  • New run button (or editing the hash) generates a new seed and history entry.
  • Follow cam / Orbit cam or C toggles the camera. Drag to rotate and scroll to zoom. Follow zoom persists; wide views use gentler camera movement.
  • Pause / Resume or K pauses the run while leaving orbit controls usable.
  • Your marble / Race leader or Space changes the camera subject when the run has other racers. Solo runs omit this control.
  • Full screen or F toggles full screen; Esc exits.
  • Share copies the complete world URL, including seed and settings.
  • Settings returns to the launch screen with the current seed and options.
  • Simulation options contains Classic loop, Modern/Legacy steering, physical simulation, diagnostics and Piece gallery.
  • ?debug=1 overlays the loop centerline; ?gallery=1 lays out every imported piece.

Tasks

task what
deno task dev bundle watch + dev server with live reload
deno task build one-shot browser bundle → static/dist/app.js
deno task build:physics rebuild Box3D shim → static/dist/box3d.mjs + .wasm
deno task build:site rebuild JS and physics, package static files and assets
deno task assets:import re-run the asset pipeline from the Kenney packs
deno task test full test suite (RNG, registry, topology fuzz, golden seeds)
deno task check type-check everything

assets/ ships committed (packed GLBs + manifests), so assets:import is only needed when re-importing from the source packs (path configurable via --source-root).

Physics shim changes require build:physics as well as the browser build. It uses Emscripten and CMake; include both native artifacts when distributing the site. See the stall fix notes for the current collision behavior and verification.

Deployment

The existing Cloudflare Pages project is marbles, at marbles-3a0.pages.dev. Build the complete site, including the native physics module and asset packs, before deploying:

deno task build:site
npx wrangler pages deploy --project-name marbles --branch main

The build output is output/site/; generated bundles stay out of Git.

How it works

seed (URL fragment)
 └─ rngFamily(seed, label)     one independent sfc32 stream per system;
     ├─ topology               closed rectilinear cycle (closure by construction)
     ├─ elevation              hill profile, Σ deltas = 0, support-grid heights
     ├─ style                  theme weights, palette a/b/c, solid policy
     ├─ setting                scenery pack + placement rule table (Nature Kit)
     ├─ decor                  rule-based scenery realization around the track
     └─ wfc                    realization: wave-function collapse over the ring
 └─ assemble                   placements + supports + closed centerline
 └─ validateTrack              invariants (tests/dev)

Systems emit constraints and weights, never placements; the WFC pass picks the actual pieces (windows over the ring, min-entropy collapse, occupancy vetoes, single-cell fallbacks make contradictions impossible). Streams are derived by label, not draw order, so adding systems later never perturbs existing seeds.

Piece semantics (ports, channel-floor heights, arc radii, ramp tier deltas) were measured from the GLB geometry; tests/registry_test.ts lints the registry's internal consistency, and tests/golden_tracks.json pins fixed-seed outputs — regenerating it breaks every seed URL in the wild, so do it knowingly.

Assets

All assets are Kenney's, CC0. The import pipeline packs each kit into a single deduped GLB (162 pieces / 2.0 MB for the Marble Kit) plus a classification manifest. Marble Kit coverage is staged: M1 realizes straights, corners, curves, ramps, slants, tunnels, supports, and decor; bends, s-curves, wide pieces, waves, bumps (M2), helixes, crossings (M3), and splits, funnels, fans-as-obstacles (M4) extend the same window/registry model.