PROCITY/docs/LANES/ROUND39_INSTRUCTIONS.md

8.9 KiB
Raw Blame History

PROCITY — Round 39 instructions (from Fable, integrator)

Date: 2026-07-26 · R38 closed green — v8 wave 1 shipped and the town is inhabited (21 palettes, 36 backyards, the magpie, six panning ambient layers; budget held at 292/300, eight draws of margin, because the worst frame is a night frame and both new layers are zero at night).

JOHN HAS RULED: do the street names. "yes do street names for sure and what else can we get on with? just keep it going." Round 39 opens v9 — THE CITY IS THE GAME with its two zero-draw keystones, and keeps every other lane busy on work that needs no ruling.

Charters: V9_THE_CITY_IS_THE_GAME.md (the hunt; read Fable's verification header first) · SALE_RED_TICKET_DAY.md (the round and the Band Floor Law) · V8_SOMEONE_LIVES_HERE.md (in flight; wave 2 later).

THE BINDING FACTS (verified by Fable — do not re-derive, do not contradict without numbers)

  1. 17,835 of 19,132 road ways in the shipped caches carry a name — 93.2%. Counted independently. plan_osm.js:363 builds each way as rawWays.push({ kind: roadEdgeKind(rd.kind), pl }) — it keeps the kind and the geometry and discards rd.name. Every real street in 23 Australian towns is in this repo and the game has never said one out loud.
  2. The names are recoverable without touching citygen's output. Plan nodes ARE snapped projected way points (plan_osm.js:361-372, SNAP=3), so plan edges lie ON the named ways: median distance from a plan-edge midpoint to its nearest named way is 0.030.90 m (worst town katoomba), and 97.8% of corpus shops (1,192/1,219) resolve to a street name.
  3. THE INTERIOR MARGIN IS SIX DRAWS, NOT 191. index.html:349 ships useGLB: !NOASSETS, so the default boot is the GLB path, and C-progress.md:841 records that sweep at GLB-on 344 against the ≤350 cap. Any interior work in any epoch spends against six.
  4. Vertical movement is fiction. player.js:64 and interior_mode.js:485 both write y = EYE unconditionally every frame on every path — no gravity, no floor query, no storey state, no floor height in any data structure. Nothing this round proposes stairs.
  5. Only record shops and market stalls have a diggable cratekind:'bin' is minted at fittings.js:60/:75 (recordBin, crate) and used by exactly two recipes (theme.js:38-39 record, :196 stall). The op shop's crateStack is labelled "back-room dressing" in its own comment. You cannot dig in an op shop, in a game built on op-shop DNA.

The ledger

39.1 — THE ADDRESS LAYER (Lane A — the approved thing, and the prerequisite for everything else)

Recover the names and publish the vocabulary. A new pure module (no THREE, no fetch, no plan mutation): createAddresses(plan, cache|null)streetOf(edgeId) · localityOf(shopId){street, district, block, side, label} · cohort(predicate)shopId[].

  • Real towns: street name by nearest named way to the edge midpoint (≤8 m tolerance).
  • Synthetic: no roads cache and only 22 edges → the label comes from district.kind + block: "the market end", "the arcade", "the backstreets". Same field, different supplier, one consumer contract — this matters, because consumers must not branch on town type.
  • The synthesis proposes a one-line upgrade: write norm.shift = {shx, shz} at plan_osm.js:510 into the caller-supplied opts.report sink, never onto the plan object, so it moves no golden and breaks no classic byte. Take it if it is genuinely that clean; measure and report if it is not.
  • Goldens must not move. State it plainly with your selfcheck numbers. If one moves, stop.
  • Publish the contract in LANE_A_NOTES §39 in your FIRST commit — B and C both consume it.

39.2 — THE FOG (Lane B — the keystone, zero draws)

minimap.js:52-63 draws every lot in the plan from the first frame, ungated: one M keypress hands over all 493 synthetic shops. Measured cost of earning that yourself: 5,330 m synthetic / 9,622 m fitzroy / 5,797 m northbridge of walking — 4.8 / 8.7 / 5.3 game-days at WALK 4.6 m/s against the 240-second day.

  • Gate the map to shops the player has walked past; discovery is player state, saved under the delta law (size it: 24 towns × N shops, bounded, and prove export/import + corrupt-reject).
  • Frame the map to what you know. The payoff is the reason to do it: a shop rectangle goes from 0.8×1.1 px to 29×39 px on bowral — a 35× legibility gain (21× katoomba, 17× adelaide, 11× fitzroy). The map is currently useless on the 21 towns that are supposed to be 21 mental maps.
  • BINDING corrections from the judges: discovery is a proximity probe, not chunks.onChunkBuilt (real towns are all BIG_CITY ⇒ R=2, so the outermost live chunk centre is 128 m out and its far corner 181 m — chunk-built discovery would hand you shops you never saw). And classic-gate it by construction: createMinimap(plan) becomes createMinimap(plan, game ? knownProvider : null), where a null provider is today's exact behaviour — the same pattern ground.js already uses, so minimap.js needs no flag test at all.
  • Consume A's localityOf for street labels on the map once A publishes.

39.3 — THE OP SHOP CAN'T BE DUG (Lane C — the game's namesake activity)

PROCITY is built on thriftgod's op-shop DNA and an op shop has no diggable bin. Its recipe is clothes racks, metal shelves, a bookshelf, a trestle table and a crateStack its own comment calls back-room dressing. Meanwhile the dig — the crown jewel, soaked since v2 — fires only in record shops and market stalls.

  • Measure first: what can a player actually DO in each of the 12 shop types today? Enumerate it honestly (dig / pull-and-buy / nothing) and put the table in your notes. That table is the deliverable even if nothing else lands.
  • Then the mechanism: give the op shop a diggable bin (a bric-a-brac tub, a $2 book crate, a rummage bin — you own the fitting and the recipe). The mechanism is uncontroversial and yours.
  • FLAG, do not decide: what is IN it. Records mixed in? Books and toys through the existing pull-and-buy pack? Its own item class? That is a John taste call and it is the difference between "op shops now dig" and "op shops now dig records", which changes the game's economy. Propose, measure the options, and hold.
  • Spend against SIX draws (fact 3). Say what your bin costs and prove it.

39.4 — TWO MAGPIES, AND THE ARCADE'S ASSETS (Lane E)

  • Settle the magpie (filed from R38): B ships a 182-tri procedural bird with vertex-colour white; E published an 894-tri tinted GLB that reads properly. Render them side by side at the size the bird is actually seen (64/48/32 px, the same sheet form as your tint render) and recommend. Fable rules on the picture, not the prose.
  • The arcade is a real 42 m covered lane with 17 shops and it is dressed as nothing — no props, no signage, no roof texture, no reverb. Generate its kit for a later round: a two-dollar- shop A-frame, a key-cutter sign, hanging shopfront signage, a tiled arcade floor skin. Same laws: $0, on-device, 🟢, provenance rows, and size every asset by tris × the instance count the consuming lane implies — the law your own paling_fence bought us.
  • Correct magpie.js's two stale tri comments (154 vs measured 182) — that is Lane B's file, so write the ask, do not edit it.

39.5 — THE GATES AND THE CLOSE (Lane F, last)

Gate 39.139.3 with falsifiability controls; full qa.sh --strict --matrix; round close. No tag. Specifically: prove the address layer resolves ≥97% of corpus shops and fails loudly on a town with no roads cache; prove the fog hides what has not been walked and reveals what has (both arms, or it is vacuous); prove classic and ?noassets untouched; and re-measure the interior budget against fact 3 if C's bin lands.

Laws

Everything standing. This round: zero draws is the requirement for 39.1 and 39.2 — they are information design and must cost nothing on the street · the interior margin is six · pathspec-atomic commits (four lanes share the tree) · no pushes, no tags — Fable pushes at close · every gate ships its control demonstrated.

⚠️ Tree note: a background session may still be editing web/js/world/venue.js. No lane touches it this round.

Order

  1. Parallel: A (39.1, contract in the first commit) · B (39.2) · C (39.3) · E (39.4).
  2. Then F (39.5).

Standing — for John, when he wants them

The op-shop bin's contents (39.3) · whether the fog is default-on or a mode · and the v9 shape itself: the address layer and the fog are its first two layers, and the third (the unmarked door / semi-hidden retail) waits on how these two feel.