116 lines
6.3 KiB
Markdown
116 lines
6.3 KiB
Markdown
# 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)
|
||
|
||
7. **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.
|
||
8. **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).
|
||
9. **`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 18–45 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.
|