Driven by the live fresh-eyes finding: a naive racer finishes with 0% paint — the core mechanic is currently skippable. G makes paint route-guaranteed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3.9 KiB
Lane G — Colour zones, paint puddles, MEGA/MINI
Owns: src/paint/puddles.ts, src/paint/buffs.ts (extend — you inherit
Lane B's file), src/course/zones.ts, demos/lane-g.html, src/demo/lane-g.ts.
Never touches: contracts, world, game, main, package.json, src/blob/,
src/machine/ (USE machine parts via import — just don't edit them), other
lane dirs. No new deps.
Why this lane exists (live-play finding, 2026-07-18)
A naive racer currently finishes the course with 0% paint — ballistic cannons miss fast movers and nothing on the ground paints you. The core mechanic is skippable. Fix: paint must be guaranteed by ROUTE, not by aim, and colours must come in ZONES so buffs actually activate (20% threshold is unreachable when three colours dilute each other — also observed live).
Deliverables
src/paint/puddles.ts—PaintPuddle: a flat coloured strip on the track (mesh + config{position, size, color}). While the blob's ground contact is inside the strip, stamp its UNDERSIDE viaskin.splatAtPointat the contact point on a cadence (~6 stamps/s, small radius) — rolling through paint coats your belly. Registered via aninstallPuddles(world, blob, skin, configs)entry point (integration calls it). Emitpaint:splatted {color, target:'blob'}per stamp (audio hooks it).src/paint/buffs.ts— extend the coverage→modifier mapping (GDD §6):- purple MEGA:
size1.0→1.45 + extramassMul(heavy). Strength scales 20%→70% like the others. - pink MINI:
size1.0→0.62, LESS mass (lighter than clean at high %). - purple and pink fight: net size uses (purple − pink) strength.
- Existing red/green/blue unchanged. Keep the pure-function style +
UPDATE
src/paint/coverage-math.test.tsfor the new mappings.
- purple MEGA:
src/course/zones.ts—installZones(world, blob, skin): builds the colour zones ON the existing greybox (import nothing from game.ts; use absolute course coordinates — the course spans z 30 → -70, see src/course/greybox.ts):- RED zone (ramp approach, z≈20..8): red puddle strip + the existing red cannon position gets a second red cannon (crossfire). BURN speed helps the climb.
- GREEN zone (shelves + slope, z≈8..-24): green puddles on both shelves; GRIP helps the slope and gravity-flip future.
- BLUE zone (milk river, z≈-24..-37): blue puddle lines the riverbanks; waterproof = your paint survives the water.
- PURPLE/PINK fork (machine district, z≈-37..-58): LEFT lane (x<0): purple puddle → MEGA → heavy enough to trip the pressure plate → boot yeet (the course TEACHES paint=weight). RIGHT lane (x>3): pink puddle → MINI → a low tunnel (build it: a slab roof over the track at y≈0.9, only a MINI blob fits under) that shortcuts toward the finish. Normal-size blobs bonk and must take another lane.
- Cannons: relocate/add so each zone's cannons fire ITS colour (configs returned so integration can place them; or place them yourself in installZones — your call, document it).
- Demo
demos/lane-g.html+src/demo/lane-g.ts: a test ball rolling through each zone in sequence with live coverage/modifier logging; prove: puddles coat reliably, purple grows + trips a test plate, pink shrinks + fits the tunnel while a clean ball bonks.
Acceptance
npm run build+ updated coverage-math tests pass.- A straight-line hold-forward run through the zones ends with ≥40% total coverage and at least one active buff (puddles guarantee it — verify in demo).
- Purple demo ball trips a
massThreshold: baseMass*1.25plate; clean ball doesn't. - Pink demo ball (≥35% pink) passes under the tunnel; clean ball cannot.
- No edits outside owned paths.
Contracts
Emit paint:splatted per puddle stamp. Existing events unchanged. blob.modifiers.size
is already honored by the controller (collider + visual scale) — do not touch the blob.