clone

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

main
marbles / docs / physics.md
physics.md 4.4K rendered
1# Marble physics research + design (M11)23## Research findings45**Box3D meshes** (docs/collision.md, sample_mesh.cpp, pinned commit):67- Trimesh via b3MeshDef → b3CreateMesh → b3CreateMeshShape (static only).8- `identifyEdges=true` suppresses internal-edge (ghost) collisions — the modern9 equivalent of Marble Blast's smooth convex-brush interiors.10- Docs recommend `weldVertices=true` (tolerance ~1mm). Samples pass a11 degenerate-triangle capacity; b3CreateMesh can fail → NEVER ignore a null12 return (our first ribbon dropped whole strips silently = holes).13- Per-triangle `materialIndices` + b3ShapeDef materials = native per-surface14 friction/restitution → the future icy/boost surface hook.15- Character mover doc: roundness beats soup — capsules/spheres slide because16 they're convex; keep the marble a dynamic sphere.1718**Marble Blast recipe** (MBHaxe src/Marble.hx — "99% identical physics"):1920- gravity 20 (marble r≈0.2 → ~our world scale): gravity-DOMINANT feel.21- Restitution 0.5 with minBounceVel 0.1 / minBounceSpeed 3 (thresholded — no22 micro-bounce); shock absorber 0.01, super bounce 0.9 (timed override).23- Rolling: accelerate HARD toward a target velocity (maxRoll 15, angular accel24 75 ≈ linear 15) — responsiveness comes from authority, not speed.25- Friction: kinetic 0.7, static 1.1, bounce-kinetic 0.2. Air control 5.26- Powerups are cheap parameter/impulse mutations with timers (helicopter =27 gravity ×0.25). Gravity pads rotate the gravity vector.2829## Our design mapping3031- Geometry: ONE welded ribbon trimesh per strip (identifyEdges), cups for drop32 shafts, boxes for islands. Mesh creation failures are LOUD.33- Feel: gravity −20; assist = strong acceleration (≈8) toward target cruise,34 climb carry sized by rail lookahead, soft brake above max; restitution ~0.3535 on the marble.36- Per-tile modifiers (next): rail stations inherit def-family tags →37 speed/gravity multipliers; per-triangle materials for icy later.38- Powerup pattern (later): timed overrides {gravityScale, restitution, impulse}39 — Marble Blast's proven cheap trick. Island gravity rotation = rotating the40 world gravity vector while anchored.4142## Ribbon debug state (next session)4344- Shim mesh path WORKS: 2-triangle repro (scratchpad mesh-repro.mjs) collides45 with winding [0,2,1] (one-sided; CW in (x,z) viewed from +y = up-facing46 collision). ph_add_mesh is loud on failure now.47- The FULL ribbon holds the marble in NEITHER winding — the discrepancy is48 unexplained. NEXT: isolated repro — build ribbonOf() output for a synthetic49 straight 10-unit path, drop a marble in node, inspect. Suspects: vertex50 ordering per ring vs winding assumption, weld collapsing rings, triangle51 indices crossing ring boundaries wrongly, or scale (verts are fine floats).52- USE_RIBBON=false gates it in proxies.ts; slab law is live and proven (65/65).53 Adopt Marble Blast constants (g=20, accel 8, restitution 0.35 thresholded)54 TOGETHER WITH the ribbon once it holds — recorded values in the section above.55- Then: per-tile modifiers via rail-station def tags (speed/gravity) and56 per-triangle materials (icy); Marble Blast powerup pattern; island gravity57 rotation.5859## Ribbon session 2 findings (isolated repro chain — major progress)6061- FIXED: upV cross-product order (right×t hung gutters/walls BELOW the floor;62 straights masked it — flat middle sits at up=0 either way).63- FIXED: winding is layout-handed (profile runs along right = up×t = −z for +x64 travel → original winding was correct; the square repro misled because its65 layout mirrored).66- FIXED: strips now extrapolate to true boundary ports (stations are67 mid-samples; the half-step gap at every segment boundary dropped marbles at68 speed). Shaft-adjacent ends never extend.69- Isolated straight AND arc ribbons now hold a rolling marble perfectly.70- REMAINING: full-stream falls at chute VALLEYS — the pitch crease where a steep71 chute cubic meets flat acts as a kicker (marble arrives vy≈−11, reflects off72 the sharp V, launches over the 0.66 wall laterally; slabs' overlapping73 geometry incidentally rounded this). NEXT: round the valley — insert74 interpolated rings across part-boundary pitch jumps (bound Δpitch per ring75 like MAX_TURN bounds Δyaw), and/or raise walls through high-|dv| creases.76 Repro: phys-deep cua-seed-1 → FELL at s=27.3.77- Ribbon stays gated (default slabs) until the valley fix lands green.