From 999c9d653fb6a4dcc678d9a5ddd6430a1c9fd8e4 Mon Sep 17 00:00:00 2001 From: m3ultra Date: Fri, 17 Jul 2026 17:29:39 +1000 Subject: [PATCH] =?UTF-8?q?Lane=20B=20R28=20(v5.1):=20the=20awning=20fabri?= =?UTF-8?q?c=20ripple=20=E2=80=94=20KILLED=20with=20the=20measurement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ledger #2. Built it, proved it worked, measured what it was worth, killed it. A 10x-over-driven billow — 1.4m of flap on a 0.14m canopy — cannot move 1% of the frame. It is not the gain, it is the geometry. Nothing ships: buildings.js and wind.js are byte-identical to HEAD. IT WAS BUILT, AND IT WORKED. Split the stall canopies out of the rigid awning InstancedMesh (own mesh, own subdivided box — a 4-corner box has nothing to ripple), gave only them a cloth billow riding R17's wind.js uniforms: sin(pi u)* sin(pi v) pin (zero at the four posts by construction), two crossed travelling waves, per-instance phase so forty stalls don't breathe in unison. Proven by rendered-pixel hashes, not by eye: cloth displaces (calm→gusty) 40f59eaf → d6d3e1f1 moves back to calm 40f59eaf identical uWindTime=99 at amp 0 40f59eaf identical ?classic=1, pre- vs post-build 453c0154 → 453c0154 BYTE-IDENTICAL rest of town rides wind? (hidden) 76c8b518 → 76c8b518 still control: cloth back frame moves again Cost at market_square, true A/B: +0 draws (98→98) / +2,160 tris. +0, not the +1 my own comment claimed — the square's chunks hold only stalls, so the rigid list empties and makeInstanced returns null; the cloth mesh replaces it. AND IT IS WORTH NOTHING (amp is the same multiplier as gain): 0.02m CALM, the default weather amp 0.05% of frame 0.14m STORM, the most a player ever sees 0.21% 0.35m 2.5x over-driven 0.33% 0.70m 5x, absurd on a 0.14m slab 0.49% 1.40m 10x, flapping a body-length 0.77% At the player's actual browsing pose, storm-force: 0.00%, max delta 1. Not one pixel. THE REASON IS PHYSICAL — the same physics that killed the verandah in R17. A canopy is a horizontal sheet at y2.2 seen by a 1.7m player: edge-on or from underneath, so vertical displacement runs almost parallel to the view ray and makes almost no pixels. You cannot see a flat horizontal sheet flex vertically while standing under it. No gain fixes it; 10x buys 0.77% and stops reading as cloth. WHAT WOULD WORK (for whoever reads this in round 35): the motion must be perpendicular to the view — VERTICAL cloth: hanging stall skirts, a flag, a banner, an awning valance. That is an ASSET (Lane E), not a shader. B's applyWind/applyFabricWind seam is ready the day such a mesh exists; the shader was never the missing piece. Ledger #2 leaves the backlog forever. TWO VACUOUS MEASUREMENTS CAUGHT ON THE WAY. (1) `!!material.onBeforeCompile` to prove the rigid verandah untouched — every THREE.Material inherits a prototype no-op, so it is ALWAYS truthy; the assert could never go red. Replaced with hasOwnProperty + a behavioural hide-and-hash control. (2) A gain sweep reporting an identical 0.21% at gains 0.4→4.0 because I never stored the shader ref, so uFabricGain never moved — four identical numbers across a 10x range is a sweep that proves nothing. The constancy, not the value, gave it away. Both would have passed as green. Co-Authored-By: Claude Opus 4.8 --- docs/LANES/LANE_B_NOTES.md | 67 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/docs/LANES/LANE_B_NOTES.md b/docs/LANES/LANE_B_NOTES.md index 22390d0..04c4a30 100644 --- a/docs/LANES/LANE_B_NOTES.md +++ b/docs/LANES/LANE_B_NOTES.md @@ -1,5 +1,72 @@ # LANE B — NOTES (measured) +## Round 28 (v5.1) — ledger #2, the awning fabric ripple: **KILLED with the measurement** + +**Built it, proved it worked, measured what it was worth, and killed it. A 10×-over-driven billow — +1.4 m of flap on a 0.14 m canopy — cannot move 1% of the frame. It is not the gain; it is the +geometry. The backlog item is closed permanently, and the reason names what *would* work.** + +R17 shipped tree sway and parked this with a physical reason: a posted verandah is a structural roof +and does not flutter. R28 asked for the half R17 left — the stalls' striped canopies really are cloth, +and they shared the rigid awning InstancedMesh, so neither could move without the other. That part was +all true, and the split worked. The cloth just turned out to be invisible. + +### It was built, and it worked +Split the canopies out of the rigid mesh (own `InstancedMesh`, own subdivided box — a 4-corner box has +nothing to ripple), gave only them a cloth billow riding R17's existing `wind.js` uniforms: a +`sin(πu)·sin(πv)` pin (zero at the four corner posts by construction, peak mid-panel), two crossed +travelling waves, per-instance phase off world position so forty stalls don't breathe in unison. +Proven by **rendered-pixel hashes**, not by eye: +| proof | result | +|---|---| +| the cloth actually displaces (calm vs gusty) | `40f59eaf` → `d6d3e1f1` — **moves** | +| returning to calm reproduces the calm frame | `40f59eaf` — **identical** | +| `uWindTime = 99` at amp 0 | `40f59eaf` — **identical** (amp 0 ⇒ `+= …*0.0`, the R17 pattern) | +| **`?classic=1`, same fixed pose, pre- vs post-change build** | **`453c0154` → `453c0154` — byte-identical** | +| rigid verandahs / rest of town ride the wind? | cloth+trees hidden: `76c8b518` → `76c8b518` — **still** | +| …and the control proves I hid the right thing | cloth restored: frame **moves** again | +Cost at `market_square`, true A/B: **+0 draws** (98 → 98) / **+2,160 tris**. +0, not the +1 I'd written +in my own comment — the square's chunks hold *only* stalls, so the rigid list empties, `makeInstanced` +returns null, and the cloth mesh replaces it rather than adding to it. + +### And it is worth nothing — the sweep (amp is the same multiplier as gain) +| peak billow | frame changed | +|---|---| +| **0.02 m — CALM, the default weather amp** | **0.05%** | +| **0.14 m — STORM, the most any player ever sees** | **0.21%** | +| 0.35 m (2.5× over-driven) | 0.33% | +| 0.70 m (5×, absurd on a 0.14 m slab) | 0.49% | +| **1.40 m (10×, a canopy flapping a body-length)** | **0.77%** | +At the player's actual browsing pose, storm-force: **0.00%, max channel delta 1**. Not one pixel. + +**The reason is physical, and it is the same physics that killed the verandah in R17.** A canopy is a +horizontal sheet at y 2.2 viewed by a 1.7 m player: you see it edge-on or from underneath, so a +*vertical* displacement runs almost parallel to the view ray and produces almost no pixel change. You +cannot see a flat horizontal sheet flex vertically while standing under it. No gain fixes that — 10× +buys 0.77%, and anything that large stops reading as cloth and starts reading as a trampoline. + +**What would work, if wind in the market is ever wanted (for whoever reads this in round 35):** the +motion has to be *perpendicular* to the view, which means **vertical cloth** — hanging stall skirts, a +flag, a banner, an awning valance. That is an **asset** (Lane E), not a shader. B's `applyWind` / +`applyFabricWind` seam is ready for it the day such a mesh exists; the shader was never the missing +piece. **Ledger #2 leaves the backlog forever.** + +### Kept from the round +Nothing shipped: `buildings.js` and `wind.js` are byte-identical to HEAD. Shipping an invisible ripple +would have cost 2,160 tris and a second draw path in the covenant town to move 0.05% of a calm frame. +*The R17 rule was "ships or dies". It died — and it died with numbers, which is the only way an item +this old stops coming back.* + +**Two vacuous measurements caught on the way (the epoch's own disease, still catching me):** (1) a +`!!material.onBeforeCompile` check to prove the rigid verandah was untouched — every `THREE.Material` +inherits a prototype no-op, so it is **always** truthy; the assert could never go red, and I replaced it +with `hasOwnProperty` plus a behavioural hide-and-hash control. (2) a gain sweep that reported the +identical 0.21% at gains 0.4→4.0 because I never stored the shader ref, so `uFabricGain` never moved — +**four identical numbers across a 10× range is a sweep that proves nothing**, and it was the constancy, +not the value, that gave it away. Both would have passed as green. + +--- + ## Round 27 wave 4 — `poseForShopFront` shipped · **and every real town's shops face away from the street** **The micro-task is done and verified. In doing it I found why F photographed empty road: it is not