PROCITY/docs/LANES/ROUND38_INSTRUCTIONS.md

181 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PROCITY — Round 38 instructions (from Fable, integrator)
Date: 2026-07-26 · **R37 closed green: the floor is level.** The kerb is footpath at +0 draws,
14 posters are out of the road, two vacuous gates are dead, the budget is pinned at
**292 draws / 124,793 tris (8 draws of margin)**, the shared instance cap is **256**, and
`ctx.onChunkBuilt` is finally subscribable. Round 38 is **WAVE 1 — INHABITATION**: four items
that make the town feel lived in. **Three of the four are +0 or +1 draws.** None needs a rig, a
clip, or John's mocap footage.
Charter: [V8_SOMEONE_LIVES_HERE.md](../V8_SOMEONE_LIVES_HERE.md) · evidence:
[REVIEW_CITY_PATTERNS.md](../REVIEW_CITY_PATTERNS.md) · animals:
[ANIMALS_ANSWER.md](../ANIMALS_ANSWER.md) · R37's rulings and debt ledger:
[ROUND37_INSTRUCTIONS.md](ROUND37_INSTRUCTIONS.md).
## THE CORRECTIONS THAT ARE BINDING (adversarial review already killed the naive version)
Do not re-derive these. They cost a review pass each.
1. **1.1 is SIX NEW MIXER LAYERS, not "generalise `audio.js:300-311`"** — audio.js has
hardcoded bed layers per source class, not a generic point-source system. **There is no
panning**: `playSfx` is mono with a gain multiplier, so *distance* works and *direction* does
not. Say so in the notes or budget a `StereoPannerNode`. Derive day-of-week **locally**.
2. **1.2's `state` field is NOT populated on all 23 towns**`newtown_godverse` and
`redhill_godverse` carry `state: ''`. The vacuous arm must be **per-town**, not per-corpus,
or those two silently take a default branch with no SKIP printed.
3. **1.2's `skyBias` must NOT go through `lighting.setSky`**`externalSky` (`lighting.js:53`)
is a **one-way latch with no un-set path**. Feed the base `skyName` selection instead.
`townCharacter(null)` returning the frozen literals makes classic byte-identical **by
construction rather than by flag** — that is the right mechanism, use it.
4. **1.3: the ice-cream-container hat is CUT** (no street verb exists; `index.html` binds only
`] [ P M T` plus a click that enters a shop). And **the magpie's territory must scale with
the road graph**: 370 pole anchors on synthetic vs **10,014 poles / 13,730 tree anchors
across 2,593 edges on `bendigo_real`** — a capacity-4 magpie there is a swooping town where
you never meet the magpie. R37's own anchor-supply measurement says the same: synthetic
**246 poles / 6.8 km** vs bendigo **7,325 / 188 km**. **Spend the cap proximity-first**
through `ctx.onChunkBuilt`, which B wired last round precisely for this.
5. **1.4 is built INSIDE `buildings.js`'s existing `boxMats` InstancedMesh** (it already carries
shells, parapets and verandah posts, and `buildHouse` already pushes into it) → hoist, fence
run, aerial and tank are **+0 draws**. A separate `world/yards.js` cannot reach `boxMats` and
would pay a draw the proposal then presented as its honest cost. **Only the alpha washing
quads need a new mesh → +1 draw/chunk total, not +2.**
6. **1.4's washing needs an INVERTED wind weight.** `wind.js:38-45` computes
`wH = clamp(y/4.4,0,1); wH *= wH` — top-weighted, base planted. Correct for a gum, exactly
wrong for a sheet pegged at the top. At 1.6 m the amplitude is **0.74.5 cm, i.e. visually
inert**. Either write an inverted-weight sway mode or **drop the washing this round** and say
which.
7. **1.4 is synthetic-only until the civic fetch lands** (all 21 real towns are 100%
`use:'shop'`, one district). It ships on the default boot — which is still the boot every
player gets — and extends to real towns in a later round. Scope it honestly; do not fake it.
8. **REJECT the hardyards GLBs on provenance** (39 GLBs, provenance documented for one file).
Generate ours. This was the best licence judgement in the review packet.
9. **The budget line every item must answer:** margin is **8 draws**, and triangles are the
cheap resource (~75k spare). A town-wide `InstancedMesh` is **1 draw at any N**; a per-chunk
type is **+1 × up to 31 live chunks**. Prefer town-wide. Cap 256, ≤24 tris/instance.
## The ledger
### 1.1 — SOMEONE ELSE'S LIFE: the audio inhabitation layer *(E + B, F gates)*
**The review's only unqualified SHIP.** The manifest ships 7 ambience / 9 sfx / 7 music and not
one animal, domestic or seasonal sound. A dog going off behind a paling fence, a mower two
streets over, a radio through a window, sprinklers, a roller door, a distant magpie carol —
the sound of a life happening off-screen, at a **seeded anchor** so it is the same dog on the
same street every time you walk it.
**E:** ~30-line numpy generators in `gen_audio.py`'s PACK registry, deterministic via
`crc32(name)`, 🟢 original by construction. **B:** the six mixer layers + seeded anchor
placement + distance falloff. **Budget: zero draws, zero tris — the only item in the epoch that
cannot touch the budget under any circumstance.** Audio pack ~10 MB → ~11 MB against a 25 MB cap.
**Gate (F):** keep the falsifiability control verbatim — point one table entry at a
non-existent key and assert the leg **FAILS**. Every other gate this round copies its shape.
### 1.2 — TWENTY-THREE TOWNS: the per-town character vector *(B + E, F gates)*
Twenty-three real towns currently differ only in street layout and shop names. Give each a
ground palette, an ambience mix and a sky bias. `ground.js`'s `add()` merges each surface class
into ONE mesh for the whole town regardless of size (verified: exactly 5 meshes) — **a palette
swap is +0 draws / +0 tris**, the strongest cost claim in the packet. `gravel` (verge) and
`reddust` (outback) already ship in the manifest and are selected by **nothing**.
**E:** 34 new `gen_skins.py --local` grounds (dry summer grass, cool-temperate grass,
red-dusted bitumen, coastal sand) so "Darwin is red dust, Hobart is cold light" is real.
### 1.3 — THE MAGPIE *(B + E, F gates)*
Swooping season: for ~six weeks of the game's year, one bird on one street will not let you
walk past it. Real behaviour — a 6-week window AugOct, and ~90% of males never swoop, so
**one bird, not a plague**. A static mesh on a scripted parabola (the tram's verified
position-is-a-function-of-(seed,time) contract), wing wave through `wind.js`'s amplitude
uniform, byte-identical at amp 0. **+1 draw / ≤900 tris.**
**Gate (F):** keep "the day-roll clears the latch and localStorage gained no new key" verbatim
— the best single arm in the packet and a genuine delta-law falsifier.
### 1.4 — BACKYARD AUSTRALIA *(B + E, F gates)*
Hills Hoists, paling fences, TV aerials, water tanks. **181 house and yard lots on the default
boot with nothing in them.** Per correction 5, inside `boxMats`: **+0 draws** for the box props,
+1 draw/chunk only if the washing ships.
*Measured headroom:* the residential district walks at **157 draws / 31,651 tris** worst
(edge 16, 20 live chunks) against a main-spine control of 263/123,602 on the same build —
~143 spare draws where these props land.
## Laws
Everything standing, plus: **every item states its draw cost against the pinned 292/300 and its
tri cost against ~75k spare** · every new gate ships its falsifiability control demonstrated ·
classic stays byte-identical **by construction where possible** (1.2's `townCharacter(null)` is
the model) · `?noassets` fallback for every asset · pathspec-atomic commits · **no tag** — wave 1
is content, the epoch tags when it is whole.
⚠️ **Tree hazard:** a separate background session is editing **`web/js/world/venue.js`** (capping
town-wide pool instances on real towns). **No lane touches `venue.js` this round.** Expect it
dirty; commit around it by pathspec.
## Order
1. **Parallel: E (the asset wave) + B (all four runtime items, procedural-first so nothing
blocks on E).**
2. **Then F:** the four gates, full `qa.sh --strict --matrix`, round close. No tag.
## ROUND CLOSED (Fable) — **THE TOWN IS INHABITED. All four items, all green, no tag.**
`qa.sh --strict --matrix`: **7 passed · 0 failed · 0 warn · 0 skipped** · flags_check **0/0** with
all four new gates inside it · **MATRIX GREEN 10 towns × 7 gates**, 0 fetches under `?noassets`.
**THE BUDGET: 292/300 STANDS — margin is still EIGHT, not six.** My naive sum (292 + 2 = 294) was
wrong, and wrong in our favour: **the pinned worst frame is a NIGHT frame, and both of wave 1's
draw-spending layers are structurally zero at night** (the washing comes in, the magpie roosts).
Wave 1's one draw is spent in daylight, where the walked peak sits ten draws lower. F reproduced
the R37 pin **to the byte, twice** (292 / 120,145 / 31 live chunks) on a control tree, then
isolated every delta by flag revert: `?yards=0` at night returns all three control numbers;
`?yards=0` at noon isolates the noon +1 to the washing alone.
**B's control-346 is adjudicated, not merely cited.** As a *delta* it was the wall-clock ped-spawn
trap and B was right to hide the sim — but ">300" is a claim about the world, and neither existing
method could adjudicate it (one photographs a half-dressed street, the other arrives clean at 27
chunks). F built `budget_walk.py --method stepsettle` — fixed-yaw stations, each drained *then held
N real rAF frames*, so R+1 residue and a full crowd land in one frame. The sign flip is the finding:
the settle is **+3 draws at noon, 9 at night**, because at night the settled street retires near
rigs to impostors and a sampler that never waits never sees the crowd go home. **Highest number
anywhere — 4 methods × 2 trees × 2 segments × 5 towns — is 292. Nothing read over 300.**
**F corrected its own R37 pin:** corpus tri worst is **130,727** (fitzroy), not 124,793 — and it
reads 130,727 on the *control*, so it is R37's 8 m station spacing vs this round's 2 m, not a wave-1
cost. *Station spacing is a bigger lever on a walked worst frame than settle policy.*
**What shipped:** 21 distinct palettes across 23 towns at +0/+0 (classic byte-identical **by
construction** — `townCharacter(null)` returns the v1 literals with the same material cache key) ·
36 `yard` lots that had rendered as blank shopfront sheds since v1 are now fenced backyards, and
the box props are **2 draws** because those lots used to fall through to `buildShopfront` · the
magpie at +1 draw / 182 tris, season now **23 distinct positions across 24 towns** · six audio
layers at zero draws **that pan** (B refused the no-panning limitation and added a
`StereoPannerNode`; F proved the pan is a bearing: yaw 0/90/180/270 → +0.00 / +0.85 / 0.00 / 0.85).
**Three self-caught errors, one per lane — the round's real signature.** B's own season mechanism
was **vacuous**: keyed on `citySeed` alone it made **24 of 24 towns a constant 214 days** from
swooping season, and it would have gated green because `?magpie=1` forces the state. F's own pan
arm used two bearings, read ±0.00, and **would have called a working panner inconclusive** — four
bearings now. E generated a perfectly good 1,121-tri `paling_fence` that B rejected on measurement
(905 instances = **1.01 M triangles** against ~75k spare), producing the sizing law this round paid
for: **an asset's budget is `tris × the instance count the placement rule implies`** — get the
instance count from the consuming lane *before* generating anything that tiles or repeats per-lot.
**Assets:** `trellis2_mlx` swap verified **1.92×** (and it hid a trap — `sorted(rglob)[0]` was
picking the *untextured* candidate); six sounds; four grounds; three GLBs published and
**sha1-verified in both directions off the public depot**; and two **decisive failures**
`hills_hoist` and `tv_aerial` cannot be generated (TRELLIS returns thin wire as thousands of
fragments; no voxel size keeps a 30 mm pole and a 2 mm wire at 600 tris), deleted so nothing could
catalogue them, permanently primitive at +0 draws. The magpie shipped reading as a **crow**; E
tinted it by projecting anatomical windows through the UVs in the mesh's own frame (a 100-island
smart unwrap has no island that announces itself as "nape"), and **Fable verified the render by
eye**: pied and unmistakable at 64/48/32 px.
**Carried:** two magpies now exist (B's 182-tri procedural bird ships; E's 894-tri tinted GLB is a
named upgrade at `birdGeometry()`/`birdMaterial()`) — **filed for a side-by-side screenshot, not
forced** · `magpie.js` carries two stale tri comments (154 vs measured 182) · §1.4 is synthetic-only
until the civic fetch, and its gate **skips loudly** on real towns rather than passing vacuously ·
audible output is unverifiable headlessly and every run prints so — *nobody in this loop has ears* ·
A's D1D4 · the matrix budget column is bookmark numbers · `?r=3` breaches at 307 · the
`?classic=1` selector question.
## Standing
Nothing needs John. Carried debt (R37's ledger, unchanged): A's D1D4 · the matrix's budget
column is bookmark numbers · `?r=3` breaches at 307 · should `?classic=1` show the town
selector at all.