BLOBBO/lanes/LANE-G-zones.md
type-two fedb43817c Lane docs F (audio), G (colour zones/puddles/MEGA-MINI), H (ghost/title)
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>
2026-07-18 11:31:41 +10:00

3.9 KiB
Raw Blame History

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

  1. src/paint/puddles.tsPaintPuddle: 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 via skin.splatAtPoint at the contact point on a cadence (~6 stamps/s, small radius) — rolling through paint coats your belly. Registered via an installPuddles(world, blob, skin, configs) entry point (integration calls it). Emit paint:splatted {color, target:'blob'} per stamp (audio hooks it).
  2. src/paint/buffs.ts — extend the coverage→modifier mapping (GDD §6):
    • purple MEGA: size 1.0→1.45 + extra massMul (heavy). Strength scales 20%→70% like the others.
    • pink MINI: size 1.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.ts for the new mappings.
  3. src/course/zones.tsinstallZones(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).
  4. 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.25 plate; 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.