From c0ad587321fc00f618fac8966ff6eb55d9cbdb77 Mon Sep 17 00:00:00 2001 From: type-two Date: Fri, 17 Jul 2026 17:25:09 +1000 Subject: [PATCH] =?UTF-8?q?Lane=20D:=20play=20site=5F02=20cold=20=E2=80=94?= =?UTF-8?q?=20night=203=20soft-locks,=20carport=20trap=20is=20inert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gate 1.3, four sprints owed. Played the real path (nights 1-2-3, mouse). The corner block is a good yard; two gate-1 blockers stand in front of it, both measured rather than reasoned: - Night 3 is unplayable. rigging.setWorld is undefined, so main.js:450's optional call is a no-op and createRiggingUI's markers (rigging.js:254) stay bound to the boot-time backyard. On night 3 the world/session/rig re-point correctly but the only clickable markers are the backyard's, at backyard coordinates. Clicks are silent no-ops, commit() returns false, Enter refuses: you cannot rig, cannot start, cannot leave night 3. The selftest never opens that door, which is why 296/0/0 and unplayable are both true. - The carport trap has no teeth. anchor.ratingHint and anchor.collateral are written by world.js:556-557 and read by nothing; sail.js:871 fails corners on hardware rating alone, and scoreRun() only ever bills the gnome. 46 m2 hung off the carport through the funnel pays +$82 at garden 83%. Also: boot({site}) is overwritten by showTonight() (inverse desync), the 'post' enum makes the carport unreadable pre-rig, the venturi measures 1.5-1.8x at the throat after the change (works as shipped, don't drop the gain), and the site is winnable off honest anchors at 98%. THREADS-only; no code touched on lane/d this sprint. --- THREADS.md | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/THREADS.md b/THREADS.md index 3de2be4..9c27888 100644 --- a/THREADS.md +++ b/THREADS.md @@ -3228,3 +3228,112 @@ anchors are your GLB), but the tooling is now waiting, not TODO. · D's cold playthrough of site_02 — unblocked at last; · A decides the carport collateral number and the Anchor.type enum widening D flagged; · gate 3 (John plays the week) — FOUR sprints standing. + +[D] 2026-07-19 — 🎮 **I PLAYED site_02 COLD (§gate 1.3, four sprints owed). The yard is good. Night 3 is + NOT PLAYABLE, and the carport trap is inert data.** Two of those are gate-1 blockers, both with + receipts. Played the real path — nights 1→2→3 on `index.html`, mouse, no shortcuts. + + **1. BLOCKER — night 3 SOFT-LOCKS. Lane B, your `setWorld` ask IS the sprint.** Reaching the corner + block the way a player does, prep opens with **last night's sail still hanging in the new yard** + (tension labels P4/H2/H3 live over the carport, a `T2B BLOWN` marker) while the HUD says "pick 4 + more corner(s)". The anchor panel lists `h1 h2 h3 t1..t2b p1..p4` — the BACKYARD's twelve — in a + yard that has none of them. The data layer is fine: `world`/`rigging.session`/`rig.anchors` all + re-point to `tr1,tr1b,q1..q4,cb1,cb2,cp1,cp2` correctly. It's the UI that doesn't: + **`typeof rigging.setWorld === 'undefined'`**, so main.js:450's `rigging.setWorld?.(world)` is a + silent no-op, and `createRiggingUI` snapshots `world.anchors` into markers at line 254 — at BOOT, + off backyard_01, once. Measured, not inferred: scene-traversing every `userData.anchorId` on night + 3 returns exactly the backyard's twelve, at backyard coordinates (h2 at z=−9.95, the old house + line); site_02's ten have **no markers at all**. So: + ``` + click a ring dead-centre → no error, no ticker, no corner. summary.corners === [] + rigging.commit() → false → the Enter handler (main.js:788) returns early + ⇒ you cannot rig, cannot start the storm, cannot leave night 3. The week ends there. + ``` + Nothing is thrown and nothing is logged — it is the quietest possible failure. **This is why the + selftest can say 296/0/0 while the game is unplayable: no test drives a site change through the + rigging UI.** An assert that cannot fail is decoration; so is a green suite that never opens the + door it shipped. `setWorld(world)` — rebuild markers + pickTargets, dispose the old — unblocks it. + + **2. Lane A — `boot({site})` is dead, and it fails INVERSELY.** main.js:456 promises "opts.site lets + a debug boot jump straight to a site". It doesn't: :458 loads opts.site, then `showTonight()` at + :691 immediately re-runs `loadSiteInto(week.site)` = backyard_01 and overwrites it — but the + markers were built in between, off site_02. Result is bug 1 mirrored: **markers site_02, world + backyard**, from the first frame. Verified both directions. Either honour opts.site in the week or + delete the hook — right now it's a documented lie, and it's the hook anyone debugging a site + reaches for first. + + **3. THE CARPORT TRAP DOES NOT EXIST YET — its data is read by nothing.** This is the one I'd want + ruled on before gate 2 eats the sprint. Two dead fields: + ``` + anchor.ratingHint world.js:556 writes it → NOTHING reads it. sail.js:871 fails a corner on + `c.load > c.hw.rating` — HARDWARE only. + anchor.collateral world.js:557 writes it → NOTHING reads it. scoreRun() main.js:610-613 only + ever pushes the gnome, on a blanket lost>=2. + ``` + So beam 0.22 / post 0.30 / fascia 0.35 / tree 1.0 are **inert**: every anchor in the game is exactly + as strong as the carabiner you hang off it. I played the exact line DESIGN warns about — 46 m² + across `cb1+cb2` in the early buster, straight through the funnel: + ``` + carport line cb1 cb2 q2 q3 → garden 83% 3/4 collateral NONE +$82 "THE GARDEN MADE IT" + honest line q1 q2 q3 q4 → garden 98% 3/4 collateral NONE + ``` + DESIGN promises "tie 25 m² to it in a southerly and you take the carport, and it lands on whatever's + under it." I tied 46 m² to it and **got paid**. The carport held; `q3` blew — cb1 was carrying 948 N + next to q3's 952 N and the sim has no reason to prefer one. The trap is currently a ~15 HP geometry + penalty (the carport is in the west corner, the bed is centre, so it drags coverage off the bed) — + directionally right, but not a trap. It reads *fine*, not buggy; it just doesn't bite. + **Lane A: the $180 ruling is bigger than SPRINT11 thinks — "change the constant, not the asset" + assumes a constant and a consumer, and there is neither.** It needs wiring: which anchor blew → + that anchor's collateral. **One landmine when you do:** `q1..q4` are built from site JSON, not GLB + nodes, so world.js:556 never runs for them and their `ratingHint` is **undefined** — the honest + posts carry no strength data at all. Wire anchor strength naively and the anchors that should be + the *strongest* read `undefined`. Default before you multiply. + + **4. And the enum is why the trap can't even tempt (my SPRINT10 flag, now with a play consequence).** + Pre-rig the panel shows only `type`. The site JSON types all four carport anchors `'post'`, so a + cold player reads **eight identical "post" rows** — `q1..q4` and `cb1/cb2/cp1/cp2` are + indistinguishable, and the carport's rating never surfaces at any point before or after rigging. + "Four free anchors that look free" isn't temptation if it looks *identical to the honest steel* — + it's a coin flip, and a coin flip you can't lose (see 3). Widening to `'carport'` gives the trap its + only pre-rig read. This is the same bug shape as the ladder one I landed: a rule keyed on a type + string a new site doesn't fit. + + **5. Lane C — good news, the venturi WORKS at the shipped numbers, and I measured it in the storm.** + axis 2.1 / gain 1.5, throat (−6,0), sampling `wind.speedAt` through the change: + ``` + t=4..17.5 (before) throat/east 0.95 – 1.08 ← calm, indistinguishable from the rest of the yard + t=19..40 (after) throat/east 1.08 → 1.79 ← throat peaks 19.7 m/s vs 11.0 east + ``` + That is exactly the personality the site asks for: **calm until the southerly comes through, then it + screams**, and the throat sits on the carport (x=−7) — the funnel howls precisely where the bad + steel is. That's a lovely piece of design and it's already live. Your −1.08 measurement and this + aren't in conflict — the ratio is throat-vs-east, not the bare venturi factor. **Don't drop the gain + on my account**: B, the site is winnable off honest anchors (q1..q4 → **98%**), so the funnel isn't + killing the $80 line, and E doesn't need to move the tree. + + **6. The ladder trip — the site's stated thesis — did not fire in either run, and can't reliably.** + `needsLadder` is live and correct (cb1/cb2 y=2.29 > the 2.20 reach, `work: 'bracket'` → ladder; + q-posts are `work: 'cloth'` at y≈4.0 → you pull the cloth corner down, no ladder, which is the rule + doing its job). But the trip only happens when a **cb** corner blows, and nothing makes cb likelier + to blow than q — that's bug 3. Fix the collateral/rating wiring and the thesis fires by itself. + + **7. Small one, Lane B:** `<- weak link` is arbitrary when the hardware is uniform. rigging.js:205 + reduces with a strict `<`, so ties keep the first pick — it flagged `cb1` only because I clicked cb1 + first. It happened to point at the genuinely worst anchor, by luck. + + **Method, so anyone can re-run it:** the shipped code cannot give you a coherent cold boot on + site_02 (bug 1 breaks the night-3 path, bug 2 breaks `opts.site`), so I rewrote `NIGHTS[0]` to + `{storm:'storm_03b_earlybuster', site:'site_02_corner_block'}` before `boot()` in a scratch copy of + index.html — then :458, `createRiggingUI` and :691 all agree and :691's rebuild no-ops, which is the + same path the four backyard nights already take. Harness deleted; **nothing of mine is on lane/d + this sprint but this entry.** Also note for anyone playtesting from a headless/hidden tab: rAF is + throttled dead, so `SHADES.step(dt)`/`.render()` are the only honest drive — and the phase change + into prep needs one frame before the markers accept clicks (that's the harness, not the game). + + **Verdict as the playtester: the corner block is a GOOD yard and I want it in the game.** It reads + instantly — two streets, the carport squatting in the west corner, the bed exposed in the middle, + the gum tree as the one honest high anchor. The blurb does real work. The 18s change (vs night 2's + 30s) genuinely lands as "looks like night 2 and isn't". None of that is the problem. The problem is + that **the yard's whole argument — that the free anchors cost you — is currently unenforced**, and + that you can't reach the yard at all without B's `setWorld`. Both are small, sharp fixes. Neither is + a design question.