The teaser and the tag were one claim, so it waited until there was a tag to stand on.
v5.0-alpha is now live at e7d58ea: walk into Monster Robot Party on Musgrave Road and riffle
its own real crate — 120 real records off its real POS, real covers, titles and prices.
Documents the tier ladder as the epoch's load-bearing idea (0 parody / 1 static real / 2 live
GODVERSE, each degrading softly to the one below), the offline law (?noassets fetches zero
bytes; a missing atlas falls to parody, never another shop's crate), and the covenant that
outlived four epochs (?classic=1 → 0x3fa36874, byte-identical forever).
States the licence position where a reader will actually meet it: item photos are each shop's
own product shots, in-house green, FLAGGED before any public or commercial release; real
titles/artists ride the same amendment; and no in-game purchase touches real inventory —
sell-sandboxed by ruling, with the reservation tier chartered for v5.x, not assumed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
137 lines
9.5 KiB
Markdown
137 lines
9.5 KiB
Markdown
# 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."** A–E 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 A–E into one seed-to-town game + QA gates | (after A–E) |
|
||
|
||
## 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 **2–4 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**: fixtures `melbourne`/`katoomba`/`silverton`, or a real OSM cache `bendigo_real`/`castlemaine_real`/`fremantle_real`/`katoomba_real`/`newtown_real` (ODbL, `web/assets/towns/SOURCES.md`). **REAL ROADS:** a cache with `roads[]` (schema v2) builds the CityPlan street graph from the town's **actual OSM streets**; without `roads[]` a cache marches onto synthetic avenues. Or just **pick a town from the HUD selector** — no URL needed |
|
||
|
||
## v4.0 — THE REAL MAP: the towns *are* the product
|
||
|
||
**23 real Australian towns — 1,210 real shops, every state and territory — on their actual streets.** Not
|
||
"inspired by": Fitzroy's shops sit on Fitzroy's roads, at their real positions, because the pipeline eats
|
||
OpenStreetMap and marches it through the same CityPlan contract the procedural town uses. **Pick one from
|
||
the in-HUD selector and walk it.** Everything built across v1–v3 comes along unchanged — the venues and their
|
||
seeded week of gigs, the 4-piece band with the seated drummer, the crowd that follows you into the pub, the
|
||
interiors behind every door, weather, the tram — because they all hang off the plan contract and never had
|
||
to know the geography got real.
|
||
|
||
The towns run from **meccas** (Fitzroy, 160 shops) to the **thin tail** (12), at real retail density: the
|
||
secondhand heroes keep their footfall while the street around them gets ~4× busier — texture, never a
|
||
takeover. Venues bias to the retail heart. The tram only runs where it fronts a real high street (elsewhere
|
||
it was honestly "a highway bus", so it's fenced). Everything stays **deterministic from the seed**, silent
|
||
under `?noassets=1`, and **`?classic=1` still boots the exact v2 town, byte-identical forever** (`0x3fa36874`).
|
||
|
||
**The tour:** [`docs/shots/release_v4/contact.html`](docs/shots/release_v4/) — the Fremantle hero, the
|
||
Fitzroy mecca, the thin tail (labelled honestly: the floor is shops-per-street-metre, and Toowoomba is
|
||
below it), the synthetic control, and the `?classic=1` covenant made visible. Charter:
|
||
[`docs/V4_REAL_MAP.md`](docs/V4_REAL_MAP.md) · data + licences (ODbL):
|
||
[`web/assets/towns/SOURCES.md`](web/assets/towns/SOURCES.md).
|
||
|
||
## v5.0-alpha — THE FIRST REAL CRATE: the shops get real too
|
||
|
||
**v4 made the towns real. v5 makes the shops real** — and the first one is standing.
|
||
|
||
Boot `?plansrc=osm&town=redhill_godverse&stock=real`, walk down **Musgrave Road** into **Monster Robot
|
||
Party** (147 Musgrave Rd, Red Hill, Brisbane — a real record shop), and riffle its crate. The records in
|
||
it are **that shop's real stock**: 120 real records off its real point-of-sale, real covers, real titles,
|
||
real prices. Buy one and the wallet debits what the sticker says. It's gone for the session and back next
|
||
boot — because until the live tier lands, the crate is a **file**, not a shop's ledger.
|
||
|
||
**Stock is a data tier now**, exactly like assets — each rung fully playable, each degrading softly to
|
||
the one below, so the game never depends on a server to be a game:
|
||
|
||
| tier | what | deterministic? |
|
||
|---|---|---|
|
||
| **0 · parody** | seeded canvas sleeves (v1) — any boot, always works | yes — the QA baseline |
|
||
| **1 · static real** | per-shop atlases baked from the shop's own POS | yes — atlases are files |
|
||
| 2 · live GODVERSE | live stock, sold-means-gone *(design ratified, not built)* | no — by design |
|
||
|
||
**The offline law:** the server enriches, never gates. `?noassets=1` still fetches **zero bytes** and plays
|
||
silent-and-fine; a shop whose atlas is missing falls soft to parody rather than borrowing someone else's
|
||
crate; and **`?classic=1` still boots the exact v2 town, byte-identical forever** (`0x3fa36874`). The
|
||
world stays seeded and golden-gated — only the *stock inside it* is data.
|
||
|
||
**Provenance:** item photos are each shop's own product shots, 🟢 in-house — **flagged before any public
|
||
or commercial release**, and every atlas carries that flag where the QA gate must print it. Real titles
|
||
and artists are an in-house amendment to the no-real-trademarks law, on the same footing. **Nothing an
|
||
in-game purchase does touches real inventory** — v5.0 ships sell-sandboxed by ruling; a real reservation
|
||
tier is chartered for v5.x, not assumed. Charter: [`docs/V5_REAL_SHOP.md`](docs/V5_REAL_SHOP.md) ·
|
||
economy design: [`docs/G3_ECONOMY_DESIGN.md`](docs/G3_ECONOMY_DESIGN.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`.
|