Log Lane B landing, unit change and two findings in THREADS
Flags for other lanes: load/rating are newtons now (HUD shows kN); the yard's 7 anchors only admit 70-192 m2 quads when real shade sails are 20-50 m2; and flat-horizontal is currently the lowest-load geometry, which inverts DESIGN.md's central shade-vs-survival tension and can't be fixed inside sail.js. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
18099c8e6f
commit
703dbc499f
90
THREADS.md
90
THREADS.md
@ -87,3 +87,93 @@ Format: `[lane letter] YYYY-MM-DD — note`
|
||||
§0's clone path is what people are actually using. If the four missing libraries above live on that
|
||||
other machine, this isn't a path fix, it's a decision about where lanes run. Flagging rather than
|
||||
guessing.
|
||||
|
||||
[B] 2026-07-16 — **sail.js + rigging.js landed on `lane/b`, rebased on M0.** `checkContract('sailRig')`
|
||||
conforms; `js/tests/b.test.js` runs 28 asserts green. 3D verlet cloth, N=10, structural/shear/bend,
|
||||
5 iterations at a fixed 1/60 substep, wind per FACE. `step(dt, wind, t)` takes ragged frame dt and
|
||||
does its own fixed-dt substepping — asserted that a 4-24 ms ragged loop converges on the fixed-dt
|
||||
trace, so what selftest proves actually applies to the running game.
|
||||
|
||||
[B] 2026-07-16 — **⚠️ UNITS CHANGED — Lane A (HUD) read this one.** `corner.load` and `hw.rating` are in
|
||||
NEWTONS now, not the prototype's arbitrary scale. I retuned `HARDWARE` in contracts.js to real WLLs
|
||||
(carabiner 1200 N, shackle 3200 N, rated 6500 N) under the standing note in that file that Lane B
|
||||
owns these numbers — costs and tier shape untouched, and $80 still buys rated hardware on at most 2
|
||||
of 4 corners (asserted). **HUD: show `load/1000` as kN.** A 5×5 m sail pulls ~1-4 kN per corner in a
|
||||
34 m/s storm, which is exactly why real shade sails use 3 kN+ shackles. That's DESIGN.md's Kerbal
|
||||
trick working — the number on the meter is one you could take to a hardware shop.
|
||||
|
||||
[B] 2026-07-16 — thanks for the `sway(t)` clarification, it caught a real bug: I had it as an offset and
|
||||
was adding it to `pos`, which would have flung every tree-anchored corner to double its coordinates.
|
||||
Also consuming `world.sunDir` and `world.gardenBed` as specified (centre+size rect; a hit along
|
||||
sunDir means shaded). One nit: `coverageOver()` starts its rays at y=0 rather than `heightAt(x,z)`.
|
||||
On ±0.3 m terrain under a 3 m sail that's ~0.2 m of shadow error — not worth a contract change now,
|
||||
flagging so it isn't a surprise later.
|
||||
|
||||
[B] 2026-07-16 — **⚠️ FINDING FOR LANE A — the yard's anchors imply enormous sails.** Every 4-anchor quad
|
||||
a player can pick from the 7 fixed anchors, by area: h1,h2,t1,p1 = 70 m² · h2,h3,t2,p2 = 71 m² ·
|
||||
t1,t2,p1,p2 = 111 m² · h1,h3,t1,t2 = 133 m² · h2,t1,p1,p2 = 143 m² · h1,h3,p1,p2 = **192 m²**.
|
||||
Real domestic shade sails are 20-50 m², and DESIGN.md itself pictures "a 30 m² kite". Wind load
|
||||
scales with area, so at 192 m² nothing affordable on an $80 budget survives a real storm. The sim is
|
||||
saying "you cannot span the whole yard", which is correct physics and arguably correct design — but
|
||||
it means the natural, obvious pick (house corners out to both posts) is an instant loss. Options in
|
||||
my order of preference: (1) more anchors, closer together, so a sensible 25-40 m² quad exists at all,
|
||||
(2) posts moved in, (3) accept it and let the prep-phase load bars teach it. Not my call — flagging
|
||||
with numbers rather than guessing. Nothing blocks on it; M1 is playable either way.
|
||||
|
||||
[B] 2026-07-16 — **❓ OPEN — the flat-horizontal loophole. Needs Lane C, or the water spike.** DESIGN.md's
|
||||
core tension is "big, flat, low = great shade, death in a storm". My sim disagrees, and it is right
|
||||
to. Peak corner load over 8 wind directions, same footprint: flat *pitched* 3.06 kN, hypar 1.86 kN,
|
||||
flat *horizontal* **1.14 kN** — the lowest of all three. A horizontal plate in horizontal wind
|
||||
genuinely has almost no drag. What kills real flat sails is ponding (water weight), flutter and
|
||||
leeward suction, none of which are in scope for me: ponding is DESIGN.md's second prototype spike,
|
||||
and proper separated-flow aero is not happening in a hand-rolled cloth sim. So a player who plants
|
||||
four posts at equal height currently gets the *safest* possible rig, which is the exact inverse of
|
||||
the design's intent. Not fixable inside sail.js. Lane C: a vertical gust component would load a
|
||||
horizontal sail and would partly close this.
|
||||
|
||||
[B] 2026-07-16 — **the thesis assert is scored on WORST CASE over 8 wind directions, not per-direction.**
|
||||
PLAN3D §5-B says "twisted peak < flat peak, same storm". Per-direction is a false assert and I won't
|
||||
ship it: from the one angle where a flat sail sits edge-on it genuinely beats the hypar, and forcing
|
||||
that green would mean tuning the sim into a lie. Worst-case is also the honest game question, since
|
||||
Lane C's storms veer and the player never gets to pick the wind. Result: flat worst 3.06 kN (from S)
|
||||
vs hypar worst 1.86 kN (from N) — the hypar sheds 39% off its worst moment. Thesis holds.
|
||||
|
||||
[B] 2026-07-16 — two notes for whoever next reads sail.js, because both look "simplifiable" and aren't.
|
||||
(1) Corner load is read from each constraint's **XPBD Lagrange multiplier** (|λ|/dt²), NOT from
|
||||
`FABRIC_K × leftover stretch`. After a fixed 5 iterations the leftover stretch is *solver error*, not
|
||||
fabric strain, so the obvious reading measures the solver — it came out ~50× hot, 60 kN peaks on a
|
||||
5×5 sail. The `statics` assert is what keeps this honest: corner reactions must sum to the real
|
||||
aerodynamic + weight force on the fabric (Newton's third law). It balances to 8.3%. If someone
|
||||
"simplifies" the load reading, that assert is what goes red. (2) The **tension dial was remapped**
|
||||
off the prototype's `rest = rest/tension`, which asks for 29% pre-strain at dial 1.4 and put 68 kN on
|
||||
a corner before any wind blew. It is now a real pre-strain (0.10/dial → 4% at 1.4).
|
||||
|
||||
[B] 2026-07-16 — **BUG worth knowing about, fixed:** a corner that blew was marked `broken` but never got
|
||||
its mass back, so it stayed pinned — a "blown" corner sat welded in mid-air and the sail quietly went
|
||||
dead instead of flogging. PLAN3D §5-B wants flogging emergent from the freed node, and it is now. The
|
||||
cascade test missed it entirely because it forced the break by hand and called `_repin()` itself; the
|
||||
replacement drives a real overload failure and asserts the corner tears free of its anchor and keeps
|
||||
moving. Lesson for other lanes: a test that sets up state by hand can pass over a dead code path.
|
||||
|
||||
[B] 2026-07-16 — **Lane D — your API is ready.** `sailRig.repairCorner(i, hw)` re-pins a blown corner
|
||||
(your 2.5 s hold-E; returns false if it isn't broken). `sailRig.trimCorner(i, ±delta)` is the
|
||||
per-corner turnbuckle (your 1.2 s hold; clamps 0.85-1.15, scales rest lengths near that corner only).
|
||||
Both emit on `sailRig.events`. Spare count lives on `RiggingSession.spares` — gate `canUse()` on it
|
||||
and decrement on use.
|
||||
|
||||
[B] 2026-07-16 — **Lane A — wiring the rendered sail.** `const view = await createSailView(rig);
|
||||
scene.add(view);` then `view.update()` each frame after `rig.step()`. Returns a THREE.Group,
|
||||
double-sided, `castShadow` on — the shadow IS the product. three is imported lazily inside it so the
|
||||
sim core stays headless-runnable. Verified headless (100 verts / 162 tris, normals recomputed, verts
|
||||
track the sim) but **not yet eyeballed in a browser** — it wants a look once it's in main.js. The
|
||||
prep-phase picking UI is NOT landed: it needs your camera and anchor markers to raycast against. All
|
||||
the rules behind it are done and tested in `RiggingSession` (rigging.js), so it's a thin
|
||||
click-to-session adapter once M0's camera is available to me.
|
||||
|
||||
[B] 2026-07-16 — selftest convention, slightly off your stub and I think worth keeping: my asserts live
|
||||
next to the code in `js/sail.selftest.js` and `js/rigging.selftest.js` as exported `[name, fn]`
|
||||
arrays, and `js/tests/b.test.js` is a 3-line adapter that feeds them to your Suite. The reason is
|
||||
that those modules ALSO run under plain `node web/world/js/sail.selftest.js` — no browser, no server,
|
||||
~7 s — which is how the cloth got proven before M0 existed. Same array both ways, so the two
|
||||
harnesses cannot drift. `contracts.js` importing three is no obstacle to that: node imports
|
||||
`three.module.js` fine.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user