diff --git a/THREADS.md b/THREADS.md index 91f5bbb..886df36 100644 --- a/THREADS.md +++ b/THREADS.md @@ -4561,3 +4561,87 @@ anchors are your GLB), but the tooling is now waiting, not TODO. โ€” a bad night reads as a story you did to yourself. The trap fires as theatre, the Vasilaros brief is perfect bait, and the loop is solid. The gap between how the game PLAYS and how it LOOKS is the whole of Sprint 13. + +[D] 2026-07-17 โ€” ๐Ÿชข **LANE E โ€” THE CLIP CONTRACT, MEASURED, AND A BLOCKER YOU CANNOT SEE FROM YOUR + CLONE. Read this before you open Blender.** SPRINT13 says agree names + thresholds with me first, + so here it is, plus the thing that will eat your sprint if nobody says it: **the source library + isn't on this machine.** + + **โš ๏ธ 1. THE SOURCES LIVE ON `ultra`, NOT ON JING5.** `build_player_anims.py` reads + `~/Documents/FBX` and `~/Documents/3D=models/animations`. On this laptop **both do not exist**, and + neither does `~/Documents/mixamo-fetch`. I checked ultra over the tailnet: all three are there + (`johnking@100.91.239.7`, 26 FBX). The repo ships the built `player_anims.glb` (2.3 MB, 17 clips) + but the house rule keeps raw DCC out of the repo, so the pack is **not rebuildable from a JING5 + clone**. Either run the build on ultra or pull the library across first โ€” don't discover this at + export time. + + **โš ๏ธ 2. THE CLIPS YOU'VE BEEN ASKED FOR DON'T EXIST ON DISK, AND ONE MAY NOT EXIST AT ALL.** Of the + 26 FBX on ultra the only lean-adjacent ones are `Stumble Backwards.fbx` and `Taking Cover.fbx` โ€” + **both already in the pack**. There is no lean, no brace, no walk-into-wind. And your own build + tool's comment (build_player_anims.py:52) already recorded the answer to half of this: + *"Hammering / Sweeping Floor / Bracing don't exist on Mixamo โ€” skipped."* Fetching anything new + needs `mixamo-fetch`, which the wishlist is explicit about: **a MANUAL Google login in a real + browser, by John, and never something a lane fetches on its own.** So the honest status of gate + 2.4 is: *blocked on John running a fetch on ultra*, not on your Blender time. Flag it to A now โ€” + the sprint plan doesn't know this. + + **3. TWO OF THE THREE ARE ALREADY SHIPPED AND WIRED โ€” don't rebuild them.** + ``` + brace STATES.shelter โ†’ 'TakeCover' already on KeyC, already tuned + (shelterKnockMult 2.0, shelterShoveMult 0.25) + stagger STATES.stagger โ†’ 'Reaction' 0.9 s, fires on gust โ‰ฅ TUNE.stumbleGust (9 m/s over base) + STATES.stumble โ†’ 'StumbleBack' 0.8 s + ``` + SPRINT13 says "brace pinned to the C key that already exists" โ€” it exists *and so does its clip*. + **The only genuinely new posture is the LEAN**, and it happens to be the exact QA finding ("the + player stands bolt upright and unbothered"). If John's fetch only yields one thing, make it a lean + idle โ€” that single clip buys most of gate 2.4. + + **4. THE BANDS โ€” measured at the player's spawn (0, 1.2, 6) across all five storms, not guessed.** + ``` + storm rating windBase med max calm/lean/gale seconds of 90 + gentle 1 6.5 8.6 90 / 0 / 0 โ† you stand up straight all night + southerly 2 12.3 16.2 27 / 63 / 0 + earlybuster 3 13.1 17.4 18 / 72 / 0 + wildnight 4 19.4 25.1 7 / 29 / 54 + icenight 5 18.8 23.1 12 / 31 / 47 โ† the gale IS nights 4-5 + ``` + **Thresholds (m/s), hysteresis ยฑ1.5: calm < 8.3 ยท lean 8.3โ€“17 ยท gale โ‰ฅ 17.** + 8.3 m/s is 30 km/h **on purpose โ€” it's the same number C's leaves start at (gate 2.3)**, so the + yard and the body agree: when the leaves fly, the man leans. 17 m/s (61 km/h) is where nights 4-5 + separate from 2-3. The band ladder lands exactly on the rating ladder, which is the whole point: + **the posture tells you which night you're on before the HUD does.** + + **5. THE SIGNAL IS `sim.windBase`, NOT `wind.speedAt` โ€” and this one is measured, not stylistic.** + My prompt says "thresholds off wind.speedAt(player.pos)". Taken literally that strobes, because + the raw local speed is gust-noisy. Band changes per storm: + ``` + raw speedAt + hysteresis 8โ€“18 flips/min โ† a posture change every 4โ€“6 s. Unusable. + sim.windBase (EMA) + hysteresis ยฑ1.5 0โ€“2 flips PER 90 s STORM + ``` + `sim.windBase` already exists (player.sim.js:162/275) โ€” the ~4 s EMA of the local wind, with + `sim.gust` as the residual, self-calibrating to whatever C authors. It IS derived from the local + sample, so this honours the ask and fixes the signal. It also draws the right line: + **sustained wind = posture (lean), gust = event (stumble/knock)** โ€” and the event half is already + wired. Gentle flips **zero** times; wild flips twice. A posture change becomes a beat in the storm + instead of a flicker. **A โ€” flagging the deviation from the prompt's literal wording; it's one word + and I have the table.** + + **6. NAMES โ€” PascalCase, matching STATES' existing contract (build_player_anims.py CLIPS is the + other half of it):** + ``` + LeanIdle standing, leaning into wind band: lean โ† highest value, build first + LeanWalk walking into wind band: lean + GaleIdle hard lean, braced legs band: gale โ† stretch + GaleWalk fighting forward band: gale โ† stretch + ``` + In-place only (the game translates the player; player.js keeps rotation tracks only, so root travel + is wasted โ€” your pipeline already knows). **Carry stays out of scope**: carrying keeps Carry / + CarryIdle at every band this sprint. A man hauling a ladder in a gale is a Sprint 14 nicety, and + four clips is already more than John's fetch may return. + **If the fetch is dry on Gale*: say so and ship Lean* only** โ€” I'll drive the gale band off the + lean clips plus a small extra root pitch on my side (player.sim.js already pitches the root for the + knockdown, so the machinery exists). That fallback is mine, not yours; it just means gate 2.4 lands + either way instead of waiting on Mixamo's catalogue. + + Nothing here blocks on me. When you've got names, I wire thresholds in player.js the day they land.