Fixed-step world runtime, event bus wire protocol between lanes, integration seam (game.ts) with placeholder ball. Lanes A/B/C own disjoint dirs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3.0 KiB
3.0 KiB
Lane C — Machine (Rube Goldberg toolkit)
Owns: src/machine/, demos/lane-c.html, src/demo/lane-c.ts.
Never touches: src/contracts.ts, src/world.ts, src/game.ts, src/main.ts,
package.json, other lanes' dirs. No new deps — three + rapier only.
Mission
Player-triggered contraptions with mandatory telegraphs (GDD §5.4). Contraptions are data-placeable parts that chain via signals — the course is a machine.
Deliverables (src/machine/)
telegraph.ts— helper: given a mesh + duration (default 0.5s), play an unmissable windup (flash + shake/scale pulse + optional emissive) then resolve. EVERY contraption that applies force or dumps paint MUST telegraph first. This is a design pillar, not decoration.parts.ts— each part takes a config{id, position, ..., onSignal?, emits?}, registers physics + visuals, listens/emits onworld.events:- PressurePlate
{massThreshold}— depresses under weight; uses blob effective mass (body.mass()); emits itsemitssignal on trip. - SeeSaw — plank on Rapier revolute joint; purely physical (heavy blob dominates it).
- SpringBoot
{impulse, direction}— on signal: telegraph → kick anything in its strike volume. - BucketDump
{color, radius}— on signal: telegraph (teeter!) → tips; emitspaint:request-splat {point, color, radius}for everything under it (paint lane renders the splat; you also spawn a brief visual slosh mesh). - ConveyorBelt
{velocity}— surface that adds velocity to bodies on it. - BubbleArch
{fraction}— sensor volume; on blob overlap emitspaint:request-cleanse {fraction}+ bubble particle burst. - Fan
{force, direction}— constant force volume (pushes light blobs hard, heavy blobs barely — mass does the work).
- PressurePlate
surfaces.ts—SurfaceMaterialregistry per contracts (normal,ice,oil,honey,mud,water): friction/restitution + tags; helperapplySurface(collider, name)+ a way for the blob controller to query the surface under a body (surfaceAt(point)).- Chain demo
demos/lane-c.html+src/demo/lane-c.ts: heavy test ball (your own stub — do NOT import Lane A) rolls onto PressurePlate → SpringBoot → ball lands on SeeSaw → tips into BucketDump trigger → bucket teeters and dumps (log the paint event), plus a ConveyorBelt and a BubbleArch on the side, and an ice + honey patch to feel surfaces. Debug key T re-runs the ball.
Acceptance
npm run buildpasses; the full chain runs end-to-end on one ball with a visible telegraph before every kick/dump.- PressurePlate does NOT trip below its mass threshold (test with a light ball).
- Surfaces measurably change rolling behavior.
- No edits outside owned paths.
Contracts (frozen — read src/contracts.ts first)
Emit: machine:signal {id}, paint:request-splat, paint:request-cleanse.
Nothing in this lane imports from src/paint/ or src/blob/ — events only.