HardYards/SPRINT3.md
m3ultra 624a72e458 Add Sprint 3 plan and lane prompts: close the game loop
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 01:11:16 +10:00

6.3 KiB
Raw Permalink Blame History

SPRINT 3 — THE GAME LOOP (instructions for Opus 4.8 lanes)

Sprint 2 verdict: the storm is real. Merged main boots into a yard with live weather, a walking ped, a rendered sail that cascades believably, debris that dents both cloth and player, rain that stops at the cloth, and 169/0/0 green. What's missing is the GAME around it: you can't rig with the mouse in the shell, can't pick up a spare, can't see loads without the console, and nothing scores the aftermath. Sprint 3 closes the loop so a stranger could play it.

Read THREADS.md from the last [I] entry down before starting. Two integrator facts you must absorb: (1) main.js now passes debris as rig.step's 4th arg; (2) the downdraft data is back at C's 0.3/0.18 and B's decision-3 assert self-skips below 0.5 — item 1 below is why.

Decisions (made)

  1. Garden HP is driven by skyfx.rainShadowOver(bed) during storms. B and C both recommended it and they're right — at night the sun shadow is a number about nothing. rig.coverageOver(bed, sunDir) stays as the daytime shade readout (and becomes the heatwave scorer later). Lane A wires it.
  2. Downdraft semantics change to fraction-of-TOTAL wind speed (B's preference, C's code). Gust-only semantics measurably cannot satisfy both the no-free-lunch bar and §7 survival (numbers in THREADS [I] 2026-07-17).
  3. world.shedTable is Lane A's, this sprint, first. It gates D's §7 hand-play and it's ~15 lines of dressing.

Lane A — finish the shell (the sprint's spine)

In priority order:

  1. world.shedTable — place shed_01_v1.glb + shed_table_v1.glb, expose {pos} (use E's pickup_anchor empty if present). Unblocks D immediately.
  2. Decision 2 anchor rework (carried from Sprint 2): posts in to ~(4.5,5.5) and (4.0,6.0), add p3 near (0,7), register E's tree branch_anchor_* (they carry rating_hint). New a.test assert: ≥3 pickable quads in 1845 m² covering the bed. This also fixes B's "cascade at t=0.4 s from pre-tension alone" finding — the yard currently teaches the wrong lesson.
  3. Prep phase playable: wire B's picking adapter (it exists on their branch contract — coordinate in THREADS) to anchor markers + hardware cycling + tension dial + spare purchase, with budget $80. Take B up on their offer of a preview rig for live force arrows during prep — DESIGN.md calls this the core teaching tool.
  4. HUD: per-corner load bars in kN vs rating (world-anchored), wind meter + gust telegraph banner, garden HP (decision 7) driving E's plants_full/tattered/dead swaps, phase banner.
  5. Forecast card (storm JSON summary: peak wind, gust character, change time — sell the dread) and aftermath screen (garden %, corners lost, hardware bill, verdict line). Enter-to-advance is fine.
  6. Yard dressing completion: swap graybox house for house_yardside_v1.glb (decision 6 — read fascia_anchor_* from the GLB), fence set, washing line (head spins in gusts — E gave you sway_amp handles too, use them for the canopy telegraph), wheelie bin into the debris pool, gnome placed in sail range (collateral_value 25 — score it in aftermath).
  7. Retitle the page — it still says M0.

Lane B + Lane C — the downdraft semantic (JOINT, do it first, pair in THREADS)

  1. C: weather.core.js — downdraft becomes a fraction of TOTAL wind speed (sustained + gust), keeping the own-RNG-stream determinism guarantee and the storm-JSON validator (rename the field if semantics change enough to warrant it — e.g. downdraftOfTotal — a silently re-meaning field is worse than a rename). Keep speedAt() horizontal.
  2. B: re-run the 8-direction sweep at C's proposed values, re-enable the decision-3 assert (delete the <0.5 self-skip — it documents gust-only semantics and dies with them), confirm §7 all three legs (cheap cascades / twisted survives / twisted+repair survives) against the SAME data. Log the final constants in THREADS. Both asserts green on the same storm JSON is this item's definition of done.
  3. B: sail UVs + E's sail_weave.png per their recipe (uv attribute, repeat 6×6, sRGB) — the membrane should read as fabric, and the tear decal strip is waiting for M3 tearing.
  4. C: storm_03 — author a third storm between gentle and wildnight so the campaign has a ramp (and the forecast card has range to sell).

Lane D — close the §7 loop by hand (gate 3)

  1. The moment A posts world.shedTable: verify the full loop live — pick up spare (PickUp → Carry/CarryIdle), run it through gusts (shelter on C when needed), hold-E repair at the blown corner (Crank/repair, spare consumed), rig finishes ≥3/4. Record the run (SHADES.step + screenshots, or a screen capture) — this artifact is the sprint's definition of done.
  2. Wire StumbleBack vs full knockdown thresholds against real storm_02 gusts with C's downdraft — the brace mechanic (hold C) changes the tuning you did pre-merge.
  3. Ladder: E shipped ladder_01_v1.glb with base/top nodes and you have ClimbLadder — if fascia repairs are meant to need it (DESIGN.md says yes), land carry-ladder + place + climb as the stretch goal; flag early if it's bigger than this sprint.

Lane E — juice pass (small)

  1. Sail tear decals hookup notes for B (you shipped the atlas; write the two-line recipe like you did for the weave).
  2. Aftermath props: broken-gnome variant (garden_gnome_01_broken), snapped fence panel — the aftermath screen wants wreckage to point at.
  3. Assembled-yard contact sheet refresh once A's dressing lands (your Sprint 2 item 4, still open — the yard finally looks like the game this week).

Gates

gate 1: A-1 lands → D starts closing the loop
gate 2: B+C downdraft semantic → both physics gates green on one storm JSON
gate 3: prep→storm→aftermath playable start to finish with the mouse,
        §7 scenario ON RECORD, selftest green

Definition of done = gate 3. That is also the moment SHADES stops being a tech demo — get there and the next conversation is about content (storms, sites, the landscaper campaign), not systems.

For John

  • Nothing blocks on you this sprint. The M1 stays an asset-build box.
  • When gate 3 lands you'll want to actually play it: python3 server.py in the repo, http://localhost:8801/ (or --port anything), WASD/shift/E/C/Enter.