Lane B R39 (Fable's ruling): THE SIGN — +sin lands; the fourth instance of the -Z/+Z confusion
index.html:428 (Lane D's patronage door points, since R8) and :500 (doorOf, the R32 cluster-pose
spawn) computed the shop front as (-sin ry, -cos ry) — the BACK of the building. buildings.js:410,
:583-597 put the facade, the door and the doorRect at local +Z; dbg.js:53 says so in words;
minimap.js has always drawn its front tick there. Two characters, both sites.
THE PATRONAGE DOOR POINT, on the footpath (registry.js's own roadWidth/vergeBand split, outside the
carriageway, outside every lot):
synthetic 0/493 -> 427/493 median 26.22 m -> 9.40 m from the centreline
katoomba_real 0/72 -> 67/72 19.10 -> 3.90
fitzroy_real 0/139 -> 139/139 19.10 -> 3.90
bowral_real 0/30 -> 28/30 21.10 -> 5.90
Not one door point in the corpus was on a footpath. Lane D's peds ducked into the back fence.
THE SPAWN, booted code both sides (:8702 the fog commit, :8701 the fix, nothing monkey-patched):
synthetic (25.5,-17.9) 3 shops within 25 m, 0 in front, 0 discovered
-> (6.1,-19.8) 4 within 25 m, 4 in front, 4 discovered
katoomba (-219.0,-471.3) 3/0/0 -> (-200.0,-474.4) 4/4/4
And in the picture (docs/shots/laneB_r39/sign-*): katoomba's shipped boot opens STANDING IN A
PADDOCK FACING THE BLANK BACK WALL OF A BUILDING — the R31 playtest's own complaint, the one R32 was
written to fix and, because of the sign, never did.
NO GOLDEN MOVES: SPAWN and the patronage points are runtime pose, computed in the shell from a plan
it never writes. Lane A selfcheck either side: fingerprint 0x5f76e76 -> 0x5f76e76, 157,647/157,647.
?classic=1 never enters the branch and keeps the frozen (-96, 9) pose.
-> LANE F: the R32 cluster-pose spawn gate and the R35 first-five-minutes smoke both photograph this
pose and need re-baselining. The falsifiable arm that needs no picture: at spawn, the count of shops
within 25 m that are IN FRONT of the player must be > 0 (0 on 4/4 towns before, 4 on 4/4 after).
THE LINEAGE, written down as Fable asked — this is the FOURTH instance of the same confusion:
R13 RY_FLIP (the band 180 deg off) · R15 the venue poster on the back wall (15.9 m from the facade,
0.07 m from the back) · R27 every real-town shopfront facing the paddock (dot = -1.000 on 35/35 and
72/72 lots; CITY_SPEC:71 says -Z, :335 says +Z) · R39 these two. Every time the rig/pose convention
is local -Z and the visible front is local +Z, and every time it was caught by a PICTURE or by a
consumer with a different convention — never by a metric. A heading has no falsifiable arm inside
the file that computes it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ -77,10 +77,20 @@ Measured live, both towns, fresh boot then a 900 m walk through the real rAF loo
|
||||
|
||||
| | synthetic | katoomba_real |
|
||||
|---|---|---|
|
||||
| fresh boot | 0/493 shops · 1/22 segs · frame **240 m** · lot **20.97×41.16 px** | 0/72 shops · 0/993 segs · frame **240 m** · lot **29.4×39.2 px** |
|
||||
| fresh boot | 4/493 shops · 1/22 segs · frame **240 m** · lot **20.97×41.16 px** | 4/72 shops · 1/993 segs · frame **240 m** · lot **29.4×39.2 px** |
|
||||
| after 900 m | 113/493 shops · 7 segs · frame 515 m · **9.77×19.18 px** | 34/72 shops · 18 segs · frame 965 m · **7.31×9.75 px** |
|
||||
| the shipped map | — · frame 965 m · 5.22×10.24 px | — · frame **4,984 m** · **1.42×1.89 px** |
|
||||
|
||||
*(Fresh boot reads 4 shops rather than 0 because the `+sin` fix below landed: you now start standing in
|
||||
front of four shopfronts instead of behind them. **On katoomba that fresh-boot map draws 3,478 pixels
|
||||
of shop colour — against HEAD's ZERO for the entire town.** Four shops you can read beat seventy-two
|
||||
you cannot see.)*
|
||||
|
||||
**One harness assertion of mine is wrong and F should not inherit it:** `r39_verify.py`'s fog arm
|
||||
asserts *more shop-colour pixels after the walk*, which only holds at a fixed zoom — after 900 m on
|
||||
katoomba the frame has grown to 965 m, so 34 shops draw 1,902 px where 4 drew 3,478. The honest
|
||||
assertion is the **shop count** (4 → 34, already checked separately), or px-per-known-shop.
|
||||
|
||||
**The frame is the shops you have stood in front of, plus where you are standing — NOT the streets you
|
||||
have walked**, and that was a real correction to my own first cut. An edge is drawn as the whole
|
||||
node-to-node line, and the synthetic's main street is one ~400 m edge, so stepping onto it at spawn
|
||||
@ -115,7 +125,25 @@ synthetic, 40.3% katoomba, 43.4% bowral, 43.5% fitzroy** — and on a shopper's
|
||||
refuses **0–2**, which is exactly the shape you want: free where a shopper stands, decisive behind the
|
||||
buildings.
|
||||
|
||||
### THE SIGN WAS WRONG AND IT IS THE SHELL'S, NOT MINE — a finding, held, not fixed
|
||||
### THE SIGN WAS WRONG — the FOURTH instance of the −Z/+Z confusion *(Fable ruled: landed, `1b7fa5f`)*
|
||||
|
||||
**The lineage, because the next lane to touch a heading should find it.** Every time, the rule is the
|
||||
same: **the rig/pose convention is local −Z, the visible front is local +Z**, and every time it
|
||||
survived because *the thing checking it shared a convention with the thing that was wrong.*
|
||||
|
||||
| round | where | what it did | how it was caught |
|
||||
|---|---|---|---|
|
||||
| **R13** | Lane C's pose `ry` vs Lane D's rig | the band played 180° off; settled with `RY_FLIP = π` (`ROUND13_INSTRUCTIONS:26-28`) | another lane's mesh looked wrong |
|
||||
| **R15** | `buildPosters` item 1, `lot + (−sin, −cos)·d/2` | the venue's own frontage poster on the **back wall** — measured **15.9 m from the street facade, 0.07 m from the back** | a screenshot of the pub |
|
||||
| **R27** | real-town shopfronts | **dot = −1.000 exactly** on 35/35 redhill and 72/72 katoomba lots — every real shop had faced the paddock since v1. `CITY_SPEC:71` says the facade is −Z, `CITY_SPEC:335` says +Z; the two generators each implemented one half (`ROUND27_INSTRUCTIONS:169` already named it *"the same −Z/+Z species as R13's RY_FLIP and R15's posters"*) | standing on Musgrave Road and looking |
|
||||
| **R39** | `index.html:428` patronage door points · `:500` the R32 spawn | Lane D's peds ducked into the back fence and **every non-classic boot since R32 opened behind the shop row** | the fog: my probe copied the shell's sign and read 4 shops known / 1,231 in-radius rejections |
|
||||
|
||||
Four instances, four rounds apart, and each one was found by a *picture* or by a consumer with a
|
||||
different convention — never by a metric. That is the entry worth keeping: **a heading has no
|
||||
falsifiable arm inside the file that computes it.** If you write one, check it against
|
||||
`buildings.js`'s `toWorld` and take the screenshot.
|
||||
|
||||
### The R39 instance, measured
|
||||
My first cut copied `index.html`'s own front-normal and the walk read **4 shops known and 1,231
|
||||
in-radius rejections** on the synthetic — the fog hiding the town from a player standing in front of it.
|
||||
The geometry says the shell is wrong:
|
||||
@ -123,25 +151,50 @@ The geometry says the shell is wrong:
|
||||
- `buildings.js:410-416, :583-597` build the facade, the door and the `doorRect` at local **+Z** —
|
||||
`lot + (sin ry, cos ry)·d/2`. `minimap.js`'s front-edge tick has always been drawn at local +Z.
|
||||
`dbg.js:53` says it in words: *"Front normal = local +Z rotated by lot.ry"*, `fx = Math.sin(ry)`.
|
||||
- `index.html:384` (Lane D's patronage door points) and `index.html:450` (`doorOf`, the R32 cluster-pose
|
||||
spawn) use **`(−sin ry, −cos ry)`** — the back of the building.
|
||||
- `index.html:428` (Lane D's patronage door points, since R8) and `index.html:500` (`doorOf`, the R32
|
||||
cluster-pose spawn) used **`(−sin ry, −cos ry)`** — the back of the building. **Both now `+sin/+cos`.**
|
||||
- Measured against each lot's **own `frontEdge`**: the +sin point is **0.00 m** from the kerb on the
|
||||
synthetic and −1.50 m on katoomba (i.e. on the kerb line, where a facade belongs); the −sin point is
|
||||
**15.25 m / 12.50 m** the wrong side of it. **493 of 493 and 72 of 72 shops agree.**
|
||||
- The consequence, measured at the shipped spawn on four towns: **0 of the 1–3 shops within 25 m are in
|
||||
front of you.** At the corrected spawn: **all of them are** (synthetic 4/4, katoomba 4/4, bowral 4/4,
|
||||
fitzroy 1/1). R32's own comment says the spawn stands *"ON the footpath door-line"*; the code stands
|
||||
in the back lane, and the fresh-boot fog map is the picture of it — one street, its yards, no shops.
|
||||
- **And in a picture, live, both towns** (`spawn-*-SHIPPED.png` vs `spawn-*-FRONT-NORMAL.png`): the
|
||||
shipped spawn stands on a footpath facing an empty plaza and a retaining wall with **not one shopfront
|
||||
in frame**, and the fog reports **0 shops known after 2.5 s of standing there**; recompute the same
|
||||
pose with `+sin` and the player is **under a shop awning with the sign at their shoulder**, **4 shops
|
||||
known**. Same on katoomba_real: 0 → 4.
|
||||
|
||||
**I did not fix it.** It is a two-character change in my own file, but it moves the default boot's
|
||||
opening pose for every gate and screenshot in the project, mid-round, with three lanes in the tree and
|
||||
Lane F gating at the close. The patch is `+Math.sin` / `+Math.cos` at `index.html:384-385` and `:450`.
|
||||
**Fable's call.**
|
||||
**THE PATRONAGE DOOR POINT — is it on the footpath?** (in the verge band per `registry.js`'s own
|
||||
`roadWidth`/`vergeBand` split, outside the carriageway, outside every lot):
|
||||
|
||||
| town | shipped | **fixed** | median distance from the street centreline |
|
||||
|---|---|---|---|
|
||||
| synthetic | **0 / 493** | **427 / 493** | 26.22 m → **9.40 m** (carriageway edge 5 m, facade 14 m) |
|
||||
| katoomba_real | **0 / 72** | **67 / 72** | 19.10 m → **3.90 m** |
|
||||
| fitzroy_real | **0 / 139** | **139 / 139** | 19.10 m → **3.90 m** |
|
||||
| bowral_real | **0 / 30** | **28 / 30** | 21.10 m → **5.90 m** |
|
||||
|
||||
Not one door point in the corpus was on a footpath. Lane D's peds have been ducking into the back
|
||||
fence since R8. (The residue — 31 synthetic / 5 katoomba / 2 bowral — are corner lots whose front
|
||||
point lands inside a *neighbouring* lot; that class is pre-existing and **14 fewer** than before.)
|
||||
|
||||
**THE SPAWN — booted code on both sides**, `:8702` serving the fog commit, `:8701` the fix, nothing
|
||||
monkey-patched:
|
||||
|
||||
| | shipped | fixed |
|
||||
|---|---|---|
|
||||
| synthetic | (25.5, −17.9) · 3 shops within 25 m, **0 in front**, **0 discovered** | (6.1, −19.8) · 4 within 25 m, **4 in front**, **4 discovered** |
|
||||
| katoomba_real | (−219.0, −471.3) · 3 within 25 m, **0 in front**, **0 discovered** | (−200.0, −474.4) · 4 within 25 m, **4 in front**, **4 discovered** |
|
||||
|
||||
**And the picture, which is the whole argument** (`docs/shots/laneB_r39/sign-*`): the shipped katoomba
|
||||
boot opens **standing in a paddock facing the blank back wall of a building** — which is the R31
|
||||
playtest's own complaint, *"faced dirt and building-backs"*, the complaint R32 was written to fix and,
|
||||
because of the sign, never did. The fixed boot opens on the footpath under the awnings with the
|
||||
shopfronts and their signage running away down Katoomba Street.
|
||||
|
||||
**NO GOLDEN MOVES, plainly: `SPAWN` and the patronage points are RUNTIME POSE, computed in the shell
|
||||
from a plan it never writes to.** Lane A's selfcheck run either side of the change:
|
||||
**fingerprint `0x5f76e76` → `0x5f76e76`**, 157,647/157,647 checks. `?classic=1` is untouched by
|
||||
construction — it never enters the branch and keeps the frozen (−96, 9, looking east) pose forever.
|
||||
|
||||
**→ LANE F, two gates photograph this pose and need re-baselining:** the **R32 cluster-pose spawn**
|
||||
gate and the **R35 first-five-minutes** smoke. Both are correct to move — the pose they baselined is
|
||||
the defect. The falsifiable arm to gate on instead, which needs no picture: at the spawn, **the count
|
||||
of shops within 25 m that are in front of the player must be > 0** (it was 0 on 4 of 4 towns before,
|
||||
4 of 4 after), and it goes red the moment the sign flips back.
|
||||
|
||||
### The save shape, and its bound
|
||||
`known` — OPTIONAL, absent until something is learned, so a save that predates R39 stays valid forever
|
||||
|
||||
@ -13,5 +13,11 @@ both sides. Every number behind these pictures is in `docs/LANES/LANE_B_NOTES.md
|
||||
| `fog-01-before-katoomba_real.png` | **R39, fresh boot** — the 240 m frame, a shop lot at 29.4×39.2 px |
|
||||
| `fog-02-after-katoomba_real.png` | **R39, after 900 m** — 34 shops on **Katoomba Street**, with **Edwards Street** running off it (Lane A's address layer) |
|
||||
| `map-classic.png` | `?classic=1` — the pre-R39 map, hash-identical to HEAD's |
|
||||
| `spawn-*-SHIPPED.png` | the default boot's spawn pose today: a footpath facing a plaza, **not one shopfront in frame**, 0 shops discovered |
|
||||
| `spawn-*-FRONT-NORMAL.png` | the same pose recomputed with the front normal `buildings.js`/`dbg.js`/`minimap.js` all use: **under the awning, sign at your shoulder**, 4 shops discovered |
|
||||
| `sign-*-BEFORE.png` | the default boot's spawn **as shipped since R32**: synthetic — a footpath facing a plaza with not one shopfront in frame; katoomba — **standing in a paddock facing the blank back wall of a building**. 3 shops within 25 m, **0 of them in front of you**, 0 discovered |
|
||||
| `sign-*-AFTER.png` | the same code with the front normal corrected (`+sin`): **on the footpath under the awnings, signage down the strip**, 4 shops within 25 m, **4 in front**, 4 discovered |
|
||||
|
||||
The `sign-*` pair is **booted code on both sides** — two port-isolated no-store servers, `:8702`
|
||||
serving the fog commit (old sign) and `:8701` the fix. Nothing is monkey-patched.
|
||||
|
||||
Katoomba's BEFORE is the R31 playtest's own complaint, verbatim — *"faced dirt and building-backs"* —
|
||||
which R32 was written to fix and, because of the sign, never did.
|
||||
|
||||
BIN
docs/shots/laneB_r39/sign-katoomba-AFTER.png
Normal file
|
After Width: | Height: | Size: 690 KiB |
BIN
docs/shots/laneB_r39/sign-katoomba-BEFORE.png
Normal file
|
After Width: | Height: | Size: 746 KiB |
BIN
docs/shots/laneB_r39/sign-synthetic-AFTER.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/shots/laneB_r39/sign-synthetic-BEFORE.png
Normal file
|
After Width: | Height: | Size: 912 KiB |
|
Before Width: | Height: | Size: 691 KiB |
|
Before Width: | Height: | Size: 746 KiB |
|
Before Width: | Height: | Size: 844 KiB |
|
Before Width: | Height: | Size: 918 KiB |
@ -422,10 +422,16 @@ if (!rosterV1) {
|
||||
}
|
||||
// [Lane F R8 — Lane D patronage] shop door points per chunk (facade normal → the street), fed once to the
|
||||
// sim so streamed peds can duck into open shops they pass. Computed from the plan (sim stays graph-only).
|
||||
// [Lane B R39 — THE SIGN, fixed] This read `(-sin ry, -cos ry)` since R8 and that is the BACK of the
|
||||
// building. `buildShopfront` puts the facade, the door and the doorRect at local +Z (buildings.js:410-416,
|
||||
// :583-597 — `toWorld(lot,0,0,d/2)` = `lot + (sin ry, cos ry)·d/2`); dbg.js:53 says it in words; minimap.js
|
||||
// has always drawn its front-edge tick there. Measured against each lot's OWN frontEdge: the +sin point is
|
||||
// 0.00 m from the kerb on the synthetic and −1.50 m on katoomba_real, the −sin point is 15.25 m / 12.50 m
|
||||
// the wrong side, and the front wins on 493/493 and 72/72 shops. Peds were ducking into the back fence.
|
||||
const shopsByChunk = new Map();
|
||||
for (const s of plan.shops) {
|
||||
const l = plan.lots.find((x) => x.id === s.lot); if (!l) continue;
|
||||
const ry = l.ry || 0, fx = -Math.sin(ry), fz = -Math.cos(ry);
|
||||
const ry = l.ry || 0, fx = Math.sin(ry), fz = Math.cos(ry);
|
||||
const x = l.x + fx * (l.d / 2 + 0.6), z = l.z + fz * (l.d / 2 + 0.6);
|
||||
const k = citizens.chunkKeyAt(x, z);
|
||||
if (!shopsByChunk.has(k)) shopsByChunk.set(k, []);
|
||||
@ -484,6 +490,12 @@ const queueCountOf = (id) => { const q = venueQueues && venueQueues.get(id); ret
|
||||
// (a point every shop already computes for patronage — known walkable), looking down the strip toward
|
||||
// the cluster's heart. Deterministic (pure plan math, no draws — no stream moves), and ?classic=1
|
||||
// keeps the frozen pose forever (the covenant is a POSE here, not just a plan).
|
||||
// [Lane B R39 — THE SIGN, fixed] R32's comment above is exactly right and the code below contradicted
|
||||
// it: `-Math.sin(ry)` put the "footpath door-line" 15 m THROUGH the building, so every non-classic boot
|
||||
// since R32 has opened standing behind the shop row. Measured at the shipped pose on four towns, **0 of
|
||||
// the 1–3 shops within 25 m were in front of the player**; with the sign the geometry actually uses, all
|
||||
// of them are (synthetic 4/4, katoomba 4/4, bowral 4/4, fitzroy 1/1). Runtime pose only — SPAWN never
|
||||
// touches the plan, so no golden moves and `?classic=1` keeps the frozen (-96, 9) pose regardless.
|
||||
let SPAWN = { x: -96, z: 9, yaw: -Math.PI / 2 };
|
||||
if (!CLASSIC && plan.shops && plan.shops.length >= 2) {
|
||||
// main-street shop doors only (block kind — both generators stamp it); every-door fallback
|
||||
@ -491,7 +503,7 @@ if (!CLASSIC && plan.shops && plan.shops.length >= 2) {
|
||||
const doorOf = (s) => {
|
||||
const l = plan.lots.find((x) => x.id === s.lot); if (!l) return null;
|
||||
const ry = l.ry || 0;
|
||||
return { x: l.x - Math.sin(ry) * (l.d / 2 + 2.6), z: l.z - Math.cos(ry) * (l.d / 2 + 2.6), block: l.block };
|
||||
return { x: l.x + Math.sin(ry) * (l.d / 2 + 2.6), z: l.z + Math.cos(ry) * (l.d / 2 + 2.6), block: l.block };
|
||||
};
|
||||
let doors = plan.shops.map(doorOf).filter(Boolean);
|
||||
const ms = doors.filter((d) => msBlocks.has(d.block));
|
||||
|
||||