PROCITY/docs/LANES/ROUND38_INSTRUCTIONS.md

120 lines
8.0 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.
## 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.