THREADS: Sprint 13 gate 3 + 2.5 landed; M-mute ask to C; gate-1 rulings parked on C's diagnosis
This commit is contained in:
parent
701403ab1d
commit
6cf5b07f32
64
THREADS.md
64
THREADS.md
@ -4561,3 +4561,67 @@ 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.
|
||||
|
||||
[A] 2026-07-18 — 🚪 **SPRINT13 GATE 3 (front door) + GATE 2.5 (camera) LANDED. selftest 339/0/0** (was
|
||||
335; +4 asserts, all mutation-checked). `lane/a` pushed. main is shippable — the public URL is safe.
|
||||
|
||||
**GATE 3 — the front door, since strangers reach this now:**
|
||||
· **Enter pinned.** The exploit shipped because the rule lived in a keydown closure inside boot(),
|
||||
behind a canvas — nowhere a test could reach, which is WHY it went out. `enterCommits(phase,
|
||||
cardOpen)` is a value now, asserted exhaustively over PHASES (a 6th phase is covered the day it's
|
||||
added, and the default it gets is "may not advance"). Mutation-checked: reverting the guard
|
||||
reddens forecast/storm/aftermath.
|
||||
· **Splash card.** A cold visitor used to land on the job sheet — an invoice from a business they'd
|
||||
never heard of. Now: name, premise, controls, one START. One more `.card`, built on E's letterhead
|
||||
because the masthead IS the game's name. `boot({splash:false})` skips it for benches and D's
|
||||
harness.
|
||||
· **P pause / M mute.** P stops the accumulator (storm only — nothing else has a clock), drains it so
|
||||
resume gives back no free frame, and clears at every phase change so a pause can't survive into a
|
||||
night where P is inert. Veil sits under the card layer, over the scene.
|
||||
· **Touch notice.** `(any-pointer: fine)` not `(pointer: coarse)` — the naive check locks a
|
||||
touchscreen LAPTOP out of a game it can play, which is worse than the dead canvas. Errs toward
|
||||
letting people in.
|
||||
· **Dev fps line** out from under B's anchor panel (both were top-left), and hidden off localhost /
|
||||
`?dev=1` — a stranger was reading "60 fps · storm 12.3s · debris 4" on the front door.
|
||||
|
||||
⚠️ **C — M MUTE IS WIRED BUT NOT ADVERTISED, and it's waiting on ONE line from you.** `createAudio`
|
||||
holds `master` inside skyfx's closure and exposes only `unlockAudio()`, so main.js has nothing to
|
||||
turn down. **Please add `setMute(on)` to the skyfx public API** — one line against your master gain
|
||||
(`master.gain.value = on ? 0 : 1`, or a smoothing ramp if you'd rather). The moment it exists, M
|
||||
lights up by itself: main.js already asks `typeof sky.setMute === 'function'` at boot, the key is
|
||||
live, the state is real, and the HUD only advertises M once the tap is there. I deliberately did NOT
|
||||
ship `sky.setMute?.(on)` behind an advertised key — that's D's night-3 soft-lock with a keycap on it
|
||||
(`?.()` on a missing method is a silent no-op that looks like a call, on a public URL where the
|
||||
person pressing M just wants the noise to stop).
|
||||
|
||||
**GATE 2.5 — two camera fixes:**
|
||||
· **Spawn framing.** `spawnYawFor()` in camera.js — points the opening frame at the garden with no
|
||||
pole through the player, per YARD (off site data), because site_02 spawns elsewhere. Measured, and
|
||||
wrong twice before right: clearance 0.6 not 1.1 (1.1 is unreachable when a post is 1m from spawn,
|
||||
and the unbounded fallback swung 105° to a fence), maxOff caps the fallback to a 90° arc. Assert
|
||||
reproduces the real 105° and pins the cap brings it to 68°.
|
||||
· **Aftermath cloth-swallow.** The dead sail joins the camera's solid set (`refreshCameraSolids()`,
|
||||
called from both rebuilds). Verified live: camera solids 9→10 the instant a sail rigs. Added a
|
||||
`camera.solids` getter so that was checkable — anyone wanting to know what the camera collides with
|
||||
can now read it.
|
||||
|
||||
**For the other lanes, off my files:**
|
||||
· `camera.js` now exports `spawnYawFor(player, lookAt, obstacles, opts)` and a `cameraRig.solids`
|
||||
getter. D — if a playtest ever spawns facing wrong on a NEW site, the obstacle list I pass is
|
||||
`posts + trees + structures` from site JSON; a site with its bed boxed in on all sides gets the
|
||||
best-available frame, never a throw.
|
||||
· `main.js` exports `enterCommits`, `accumulate`, `canPlayHere`, `stormsToPreload` (pure, tested).
|
||||
|
||||
⏳ **GATE 1 — MY TWO RULINGS ARE PARKED, WAITING ON C.** SPRINT13 gate 1.4 routes two decisions to
|
||||
me and both need C's shadow-geometry diagnosis FIRST: (1) the garden separation target — C proposes,
|
||||
I rule; the plan's steer is "alive-vs-dead on the wild nights, not 88-vs-83", and I'll hold C to
|
||||
something a player can FEEL, not just measure. (2) whether `GARDEN_DRAIN` moves once the geometry is
|
||||
honest — my own main.js comment says the constant was compensating for the rain shadow decaying to
|
||||
nothing, so once C fixes the MODEL it likely wants lowering back; I'll rule on the number when C
|
||||
posts the before/after. **C: post the separation target in THREADS before you tune to it** (plan's
|
||||
instruction), and ping me. Nothing of mine blocks you.
|
||||
|
||||
🎮 Front door verified in the running game start to finish: splash → job sheet → prep → storm, P
|
||||
pauses to a clean veil, the spawn frame is player+bed with the poles beside not through. Screenshot
|
||||
path in the session. Not asserted, because 339 tests can't see a pole through a head — that's what
|
||||
gate 4 (John plays) is for, same as the two bugs looking caught last sprint.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user