PROCITY/README.md
m3ultra e4a49b5bc8 Lane F R17 (v3.2): real towns boot in the engine + the town-matrix scout gate (ledger #7)
F wired the last mile of the real-map scout and gated the whole matrix.

- index.js barrel re-exports registerTownCache/validateTownCache; the shell fetches + registers
  assets/towns/<key>.json before generatePlanFor when the town isn't a checked-in fixture — so
  ?plansrc=osm&town=bendigo_real boots a REAL AU town in the engine (the gap: E's caches were on disk +
  in the node selfcheck, but the shell never loaded them → silent Melbourne fallback). Fail-soft
  (404 / invalid / ?noassets -> fixture fallback); opt-in, never on the default or ?classic path.
- tools/qa/town_matrix.py (opt-in qa.sh --matrix): boot / determinism / budget / district / ?noassets
  across 10 towns (2 synthetic hero seeds + 3 osm fixtures + E's 5 real AU caches). ALL 5x10 GREEN —
  Castlemaine at the 6-shop floor still lands a 3-venue district. The existing CityPlan contract eats real
  Australian geography: the evidence John charters v4 = THE REAL MAP on.
- docs: LANE_F_NOTES §17 (the town x gate table), README real-town row, F-progress R17.

qa.sh --strict --soak GREEN 7/7. Verified: ?plansrc=osm&town=bendigo_real -> Bendigo, 9 shops, 3 venues, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 15:23:15 +10:00

84 lines
5.4 KiB
Markdown
Raw Permalink 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
A standalone, procedurally generated, fully walkable 90s-Australian shopping town — every
building enterable (the Vuntra City trick), every interior seeded and themed: record stores,
op shops, toy shops, book barns, video rental, pawnbrokers, milk bars, market stalls. Built on
the proven house stack (three.js r175 vendored, plain JS, no build step) and the asset DNA of
90sDJsim + thriftgod. v1 is the *system*; the GODVERSE/BaseGod real-item content plugs in later.
## Run
```
cd web && python3 -m http.server 8130
# http://localhost:8130 (game shell — Lane B)
# http://localhost:8130/map.html (2D plan debugger — Lane A)
```
## Read first
- **`docs/CITY_SPEC.md`** — the treaty: schema, units, seeds, budgets, file ownership.
- **`docs/RESEARCH.md`** — what the parent repos already solved, with exact paths to port from.
## The lanes (parallel Opus 4.8 sessions)
Each lane is a self-contained prompt. To run one, start an Opus session in this repo and say:
**"Read docs/LANES/LANE_X_….md and execute it."** AE are parallel-safe (disjoint files,
standalone test pages); F integrates after they land.
| lane | mission | owns |
|---|---|---|
| [A — CITYGEN](docs/LANES/LANE_A_CITYGEN.md) | seed → CityPlan data (streets, blocks, lots, shops) + 2D map | `js/citygen`, `js/core/registry.js`, `map.html` |
| [B — STREETSCAPE](docs/LANES/LANE_B_STREETSCAPE.md) | chunk-streamed instanced 3D town + game shell | `index.html`, `js/world` |
| [C — INTERIORS](docs/LANES/LANE_C_INTERIORS.md) | every door opens: seeded themed shop interiors | `js/interiors`, `interior_test.html` |
| [D — CITIZENS](docs/LANES/LANE_D_CITIZENS.md) | rigged-near / impostor-far NPCs + shopkeepers | `js/citizens`, `citizens_test.html`, `models/` |
| [E — ASSETS](docs/LANES/LANE_E_ASSETS.md) | audit ultra's library, normalize GLBs, skins, manifest | `pipeline/`, `assets/` |
| [F — INTEGRATION](docs/LANES/LANE_F_INTEGRATION.md) | wire AE into one seed-to-town game + QA gates | (after AE) |
## Already in the repo
- `web/vendor/` — three.js r175 + addons (vendored from 90sDJsim; no CDN at runtime).
- `web/assets/gen/` — 69 generated texture skins (25 shopfront facades, 10 skies, 10 grounds,
8 wallpapers, 16 interior surfaces) inherited from thriftgod + 90sDJsim, style-locked.
- `web/js/core/` — frozen shared modules: `prng.js` (seeded-everything law), `loaders.js`
(fail-soft promise-cached GLB/texture + 3GOD depot), `canvas.js` (text planes).
## House laws (short form — CITY_SPEC has the fine print)
Seeded everything, `Math.random` banned in gen code · the game must run with zero assets ·
instancing from day one · canvas text, no font files · characters = shared base rigs + one
clip bank, canonical sources live outside this repo · 🟢 web-ok licensing only.
## v3.1 — THE FLIP: the town shows its best by default
The Friday-night layer soaked through alpha, beta, and the v3.0 release — so **v3.1 flips it on by
default**, and the mature v2 flags flip with it. Boot the plain URL and each town seeds **24 venues**
(pub, band room, RSL) with a **full seeded week of gigs**, town-wide **posters**, and a Friday night that
reads: a **4-piece band** (trio + a **seated drummer**) with real instruments, a mixed **crowd**, an
outdoor **queue**, a per-venue **cover charge**, muffled **gig spill** + **walla and applause**,
town-wide **streetlamp pools**, and **identity continuity** — the ped you followed in is in the crowd.
Plus **weather**, the **tram**, and the parallax interior-**window shader**, all live by default.
**The covenant moved, it didn't disappear.** `?classic=1` boots the **exact v2 town** — byte-identical
forever (synthetic golden `0x3fa36874`, zero gig layer, zero fetch delta). That is the new frozen
regression target; the default boot is deterministic to the gig golden `0xb1d48ea1`. Asset-free
(`?noassets=1`) composes with the default boot and stays silent-and-fine.
**Flags** — the four headliners are **ON by default**, each with a `=0` opt-out; `?classic=1` is the
master off:
| flag | default | what |
|---|---|---|
| `?classic=1` | off | **the exact v2 boot** — all four below off, byte-identical to the frozen baseline |
| `?gigs=0` | **on** | the gig district — venues, week schedule, band/crowd/queue, cover, posters, night pass |
| `?weather=0` · `?tram=0` · `?winmap=0` | **on** | seeded weather · the tram loop · the parallax interior-window shader |
| `?roster=v1` · `?pop=N` | stream | chunk-streamed citizen density is the baseline; `?roster=v1` restores the fixed roster |
| `?dig=0` · `?stock=real` | dig on | crate-riffle on record bins · real GODVERSE sleeves in the stock |
| `?noassets=1` · `?plansrc=osm` · `?mute=1` · `?dbg=1` | off | asset-free (zero network) · OSM plan source · silence · the `window.DBG` capture/soak harness |
| `?plansrc=osm&town=<key>` | — | boot a **real Australian town** (v3.2 scout): fixtures `melbourne`/`katoomba`/`silverton`, or a real OSM cache `bendigo_real`/`castlemaine_real`/`fremantle_real`/`katoomba_real`/`newtown_real` (ODbL, `docs`/`web/assets/towns/SOURCES.md`) |
| `?seed=N` | `20261990` | town seed |
**Release tour:** [`docs/shots/release_v3_1/contact.html`](docs/shots/release_v3_1/) — the money shots on
the default boot, plus a `?classic=1` before/after. **QA:** `tools/qa.sh --strict` (classic regression +
default-boot gate + smokes + no-giants) `--soak` (the full-week soak); the seated drummer passes the
no-giants gate at the seated stature band `[0.9,1.5] m`.