193 lines
13 KiB
Markdown
193 lines
13 KiB
Markdown
# PROCITY v8 — SOMEONE LIVES HERE (epoch charter — DRAFT, John's rulings recorded)
|
||
|
||
*Fable (m3), 2026-07-26. Built on [REVIEW_CITY_PATTERNS.md](REVIEW_CITY_PATTERNS.md) — a
|
||
16-agent top-down audit (5 lane cartographers · asset-capability probe · design research ·
|
||
4 design themes × adversarial verify · synthesis). That review is the evidence; this is the
|
||
plan. Read it first — it corrects three numbers this project had been repeating for epochs.*
|
||
|
||
## The vision
|
||
|
||
**v7 made the town a game. v8 makes it a place someone lives.** Not more systems — more
|
||
*inhabitation*: the sound of a life happening off-screen, twenty-three towns that finally look
|
||
like different towns, a magpie that won't let you walk past it in September, a back yard with
|
||
washing on the Hills Hoist, and a bloke actually standing at the pie cart that has been
|
||
sitting unmanned on the street for five epochs.
|
||
|
||
## JOHN'S RULINGS (2026-07-26, recorded verbatim in effect)
|
||
|
||
### RULING 1 — THE KERB: **FOOTPATH.** ✅
|
||
*"footpath for sure."*
|
||
|
||
The 9 m band between kerb and shopfront is **footpath**, not road. Lane A's published corridor
|
||
law (`roadWidth` / `vergeBand` / `poleOffset`, `registry.js`) is hereby the single source of
|
||
truth, and Lane B's ground adopts it: extend the **existing merged `footGeos` class** inward
|
||
from `e.width/2` to `roadWidth(e)/2`. **+0 draws** (same merged mesh), ~2k tris, fill-rate
|
||
improves because 18 m of every main street stops being painted as road.
|
||
|
||
Consequences, binding:
|
||
- The 14 gig posters currently standing in the road land where A already thinks they are.
|
||
- `registry.js`'s own comment calls that band "verandah'd footpath" and `buildings.js` already
|
||
builds an awning over it on every shop lot — so this ruling makes the geometry agree with the
|
||
code's own documentation. **Grass verges survive on residential edges only**, where they are
|
||
period-correct.
|
||
- Special cases that must be handled or the ruling breaks: `arcade` (`roadWidth` 0 → zero-area
|
||
road quad + coincident kerbs) and `lane` (`vergeBand` = [2,2]).
|
||
- **The gate ships with a falsifiability control**: run the poster-clearance leg against
|
||
`?verge=0` and assert it **FAILS there** — the pre-change failure is already known and
|
||
counted at exactly 14. Keep `?verge=0` permanently as a gate flag; it costs nothing and it is
|
||
the best gate design in the review packet.
|
||
|
||
### RULING 2 — REAL TOWNS GET THE CONTENT: **FUND THE CIVIC FETCH.** ✅
|
||
*"real towns where possible spread it out."*
|
||
|
||
The review's biggest strategic finding: **all 21 real towns are 100% `use:'shop'` lots with a
|
||
single district (`mainstreet`)** — no houses, no yards, no stalls, no market block. Every
|
||
residential/market/vendor idea was therefore synthetic-town-only. John has ruled that the
|
||
content goes to the **real** towns wherever possible, which means the fix is funded and moves
|
||
**into v8** rather than waiting for v9:
|
||
|
||
- **Lane A + Lane E: the third fetch class.** `build_towns.py` currently asks Overpass for
|
||
shops and roads. It gains a bounded third class — `landuse=residential`, `building=house`,
|
||
`leisure=park/pitch`, `amenity=marketplace/memorial/fuel/school/bus_stop/telephone/post_box`
|
||
— and `plan_osm.js` emits **more than one district** and **more than one lot `use`**.
|
||
- **The data is already half here**: the caches in-repo already contain, unused, 30,959
|
||
footway ways · 12,351 service ways · 6,421 crossings · 2,714 sidewalk tags · 13,199 oneway
|
||
tags. Some of the districting can be derived without any new fetch at all — A measures which
|
||
before E re-fetches.
|
||
- **Hazard, named now**: `build_towns.py` rewrites the *whole* cache and its own docstring
|
||
records the Newcastle incident (shops refetched, old roads silently reused). **46 pinned
|
||
goldens ride on byte-identity nobody has proven.** The re-fetch is therefore its own
|
||
carefully-gated round with per-town before/after diffs — not a step folded into a content
|
||
round.
|
||
- Standing Overpass authorisation applies (one bounded query per town, 4 s courtesy, ODbL
|
||
attribution into every cache and `SOURCES.md`).
|
||
|
||
### RULING 3 — ANIMALS: **answered by spike. Generate, don't download.** ✅
|
||
*"idk about rigged animal models... they have different rigging too right? diff skeleton?"*
|
||
|
||
Full answer + intake checklist + vetted sources: **[ANIMALS_ANSWER.md](ANIMALS_ANSWER.md)**
|
||
(5-agent spike: foreign-skeleton loader proof · CC0 source vetting · tiering · adversarial
|
||
review · Fable's adjudication header, which corrects one over-claimed verdict).
|
||
|
||
**John's instinct was right and it stops mattering.** There is no `mixamorig` for quadrupeds;
|
||
every animal ships a bespoke skeleton. But retargeting only exists because our 24 human bodies
|
||
share 8 clips — an animal carrying *its own* baked clips needs none of it. **Proven, not
|
||
argued:** a 10-bone quadruped GLB (`leg_fl`, `tail_01`, Blender-style clip names) was authored
|
||
byte-by-byte, loaded through **our own vendored three.js and our own `loaders.js`**, and played
|
||
its own clips through a bare `AnimationMixer` — 27 assertions green, including *pixels changing
|
||
on a real `WebGLRenderer`* (1,804 lit px, 704–1,015 changed between frames) and
|
||
`SkeletonUtils.clone` sharing geometry+material across N animals. Also proven in the mirror:
|
||
fed to the human stack, `buildFigure` would measure that dog's "feet-to-crown" at 0.36 m and
|
||
**scale it 4.9×** — silently. Hence the law: **animals get a sibling module
|
||
`web/js/citizens/animal_rig.js` importing nothing from `rigs.js`.** ~40 lines. The
|
||
classic-covenanted human fleet is never touched.
|
||
|
||
**The ruling is economic, not technical.** Measured on a real renderer: **1.00 draw per skinned
|
||
animal, 1:1, to N=80** — three.js cannot instance animated skinned meshes and our impostor bake
|
||
crops long low animals. Against that, **sixty birds on a wire cost ONE draw between them**
|
||
(one InstancedMesh, one 4-tri billboard, one 1024 WebP species atlas — every future bird
|
||
species then free). That asymmetry is the whole design:
|
||
|
||
- **Tier 0− — the heard animal. +0 draws, +0 tris. SHIPS.** A dog behind a paling fence, a
|
||
cockatoo at dusk, at a *seeded anchor* so it is the same dog on the same street every time.
|
||
~30 lines of numpy each in `gen_audio.py`. Highest charm-per-minute in the epoch; a town with
|
||
zero visible animals reads as a town with animals in it.
|
||
- **Tier 0a — the flock. +1 draw town-wide. SHIPS (wave 1).** Cockatoo, galah, corella,
|
||
lorikeet, perched magpie, ibis as cells in one atlas. Verified free when empty *to the
|
||
vendored line* (`three.module.js:2193-2199` returns before the GL call; `render.calls++` at
|
||
`:4094` lives downstream) — a bird-free town costs **exactly zero**, not "almost zero".
|
||
- **Tier 0b — near props. +1 draw per species. Wave 1.5, ONE species:** the ibis head-down in
|
||
a council bin.
|
||
- **Tier 1 — the magpie.** As already approved. **Binding correction carried:** 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.
|
||
- **Tier 2 — genuinely skinned: CUT this epoch**, and killed by our own spec rather than by
|
||
cost: the dog was anchored at `shopFront` — *tied outside the shops* — and a tied dog never
|
||
trots, so the walk clip that is the tier's entire justification would never play. It returns
|
||
only with a path, footpath alignment, a collision story and a sim hook the design explicitly
|
||
disclaims.
|
||
|
||
**So: generate ours, don't go shopping.** Nothing on the animal list needs a download. The one
|
||
thing genuinely worth grabbing online is *not an animal* — Quaternius's **Universal Animation
|
||
Library** (CC0, 130+ clips, Mixamo-compatible) is fuel for the **human** fleet's thin 8-clip
|
||
bank; it touches classic-covenanted `rigs.js`, so it is its own round with its own gates and
|
||
must not be folded into animal work.
|
||
|
||
**Two corrections binding on v8 from this spike** (both adjudicated in the answer's header):
|
||
`classic_regression` has **no network assertion at all** and grows an allow-list (never a
|
||
deny-list); and `furniture.js`'s module-scope loader is a **trap for new assets** — `fauna.js`
|
||
is dynamically imported behind its construction guard or carries a CLASSIC-derived module
|
||
guard stated in its header. *(The spike called the existing four furniture fetches a live
|
||
breach; they are not — git-verified as v2-era, `24cef5a`, tagged v2.0-alpha→v2.0, i.e. part of
|
||
the baseline the covenant preserves. The hazard is real; the breach is not.)*
|
||
|
||
## The shape
|
||
|
||
**WAVE 0 — THE FLOOR** *(one round, three lanes, all micro, must precede content)*
|
||
0.1 the kerb ruling landed as code + the `?verge=0` control · 0.2 repair `smoke_tram` (it
|
||
asserts one thing, prints a SKIP when absent, and **passes on the fenced path** — a live
|
||
vacuous-gate violation inside our own suite) · **0.3 SETTLE THE BUDGET OF RECORD — DONE (R37)**: the 280-vs-191 split was the CAMERA
|
||
BEARING (110 draws of spread; the audit took `DBG.teleport`'s default yaw 0 = the worst
|
||
bearing, the spike supplied a travel-facing yaw = mid-range — both correct, different
|
||
quantities). **PINNED: 292 draws / 124,793 tris**, worst-draw and worst-tri on DIFFERENT
|
||
frames, 8 draws of margin. Shared instance cap **256**, with ≤24 tris/instance and
|
||
proximity-first spending · 0.4 wire
|
||
`ctx.onChunkBuilt`/`onChunkDisposed` (producer and consumer both shipped since R3, never
|
||
connected) · **0.5 give `classic_regression` a network allow-list** (the four v2-era depot
|
||
GLBs + same-origin) — it currently makes no network assertion at all, which is why the R36
|
||
fetch-surface widening needed a brand-new smoke to catch it.
|
||
|
||
**WAVE 1 — INHABITATION** *(four parallel one-round items; no clips, no rigs, no mocap
|
||
footage — this epoch deliberately does not wait on John's camera)*
|
||
1.1 **the audio inhabitation layer** — the review's only unqualified SHIP: a dog going off
|
||
behind a paling fence, a mower two streets over, a radio through a window, sprinklers, a roller
|
||
door. Zero draws, zero tris, ~30 lines of numpy each. · 1.2 **the per-town character vector** —
|
||
23 towns get a ground palette, ambience mix and sky bias; `ground.js` merges each surface class
|
||
into ONE town-wide mesh, so a palette swap is **+0 draws / +0 tris**. · 1.3 **the magpie** —
|
||
one bird, six weeks, +1 draw. · 1.4 **backyard Australia** — Hills Hoists, paling fences,
|
||
aerials, tanks, built inside `buildings.js`'s existing `boxMats` instanced mesh (+0 draws for
|
||
the box props). *Per ruling 2, 1.4's reach now depends on the civic fetch — it ships on
|
||
synthetic immediately and extends to real towns as districts land.*
|
||
|
||
**WAVE 2 — THE STREET GETS A VERB** *(sequential, behind 2.0)*
|
||
2.0 the street interaction surface (a `KeyE` verb, an `interactRects` registry, hit priority,
|
||
a click fence) · 2.1 **the manned cart** — consumes the flagship dead seam (44 cart sites on
|
||
the golden seed, 511 across real towns; `furniture.js:252` already holds the shop record and
|
||
throws it away). **Blocker, not cosmetic**: the cheap `doorRect` ride would make every milk bar
|
||
and stall un-enterable from the front — the cart must raycast its own InstancedMesh. · 2.2 the
|
||
fauna substrate + field guide · 2.3 dogs, tier B first.
|
||
|
||
## Laws (inherited, plus this epoch's)
|
||
|
||
Everything standing. New for v8: **spend triangles, not draws** (the walked worst frame is
|
||
280/300; tris sit at 99–124k of 200k — every proposal states its draw cost against 280, and a
|
||
town-wide `InstancedMesh` costing 1 draw beats a per-chunk type costing +1 × up to 31 live
|
||
chunks) · **one instance cap per shared layer, settled once, before three implementations
|
||
invent three** · **the depot is a read-only archive** (971 live assets, 53 recorded, known
|
||
trademarked items inside) — generate fresh, never pool from it · every new gate copies the
|
||
shape of 1.1's control: point one table entry at a non-existent key and assert the leg FAILS.
|
||
|
||
## The cut list stands
|
||
|
||
Recorded in the review, killed with measurements, not re-opened without new evidence: the
|
||
town-loop bus (its own gate refuted it — what survives is one file: let the *tram* run on
|
||
main+side edges, retiring the same dead seam for +0 draws) · the ute that sells · the charity
|
||
bin (its filter accepts nothing) · the dusk flush (the day is 240 seconds long) · the magpie
|
||
hat (no street verb exists) · the OSM level crossing (the rescoped synthetic version survives) ·
|
||
the mail run · parked cars this epoch (deferred, not rejected — and when they land, 45° angle
|
||
parking is a charter requirement).
|
||
|
||
## Standing — what still needs John
|
||
|
||
1. **The market plaza amendment** — `ground.js` paints a 46×46 m plaza at the origin, on top of
|
||
the spine road, touching none of the 40 stall lots. Fixing it changes the covenanted town's
|
||
visual output. *Recommend: fix under the amendment law (the R27 precedent — the covenant is
|
||
anti-drift machinery, not a defect preservative), as its own small ruling.*
|
||
2. **hardyards provenance** — 39 GLBs that are exactly the vernacular kit's shopping list, with
|
||
provenance documented for one file. Only John knows where they came from. 🟠 until cleared.
|
||
3. **Where is MOCAPGOD?** The fleet docs say lanes 0/A/B are done; on m3ultra the directory is
|
||
0 bytes and not a git repo (it lives on gitea and, presumably, ultra). Not blocking — v8
|
||
needs no clips — but the fleet docs are wrong somewhere.
|
||
4. **The animal ruling**, once the spike reports.
|