PROCITY/docs/RESEARCH.md
2026-07-14 10:46:40 +10:00

96 lines
7.2 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.

# RESEARCH — what the parent repos already solved (port, don't reinvent)
*Condensed technical briefs from full sweeps of both repos (2026-07-14). Exact paths verified.
Read the section for your lane before writing code; open the referenced files and lift patterns.*
## 90sDJsim (`/Users/jing/Documents/90sDJsim`)
- three.js r175 **vendored** at `web/world/vendor/` (copied into PROCITY `web/vendor/`), importmap
in `web/world/index.html`. No build, no npm. Backend = single stdlib-Python `server.py` :8123.
- Docs: `CLAUDE.md`, `DEVMANUAL.md` (single source of truth), `TOWNMAP.md`, `ECONOMY_SPEC.md`.
- **World**: `web/world/index.html` (~3400 lines, all inline). One scene, one `room` Group
swapped per mode. `AREAS` data table (~line 711) declares streets as shop rows; `buildStrip()`
(~740) realizes them: `BoxGeometry(4.8,h,4)` shell + facade JPEG on a `PlaneGeometry(4.7,2.4)`
+ awning box + `textPlane()` canvas signs, seeded per building with `mulberry32(i*77+5)`.
`buildHome()` ~963, `buildVenue()` ~1094. Day/night = 6-segment `applyLighting(segIdx)`.
- **Facade skins**: `web/world/tex/facade_{record,opshop,pawn,pub,video,dept,milkbar}.jpg`
Cloudflare Flux, committed 2026-07-10 (commit `e31e605`), cropped below the sign band. Mapped
by `FACADE` table (~line 276). Copied into PROCITY as `facade-djsim-*.jpg`.
- **NPC stack (the crown jewel — port for Lane D)**, `web/world/index.html` ~258393:
- `models/peds/` = 17 normal + 2 comical rigged GLBs (~2MB each) + clip-only `walk.glb`/`idle.glb`.
- `spawnRig(rig,target,x,z,ry,clipName,height,extClip)`: SkeletonUtils.clone → height-normalize
off the **head bone** → plant feet by min bone Y → mixer.clipAction().play() with random
start offset to desync.
- `_canon = s => s.replace(/mixamorig\d+/g,'mixamorig')` — one clip binds to any character.
- `_rotOnly` strips position tracks + Hips.quaternion from shared clips (prevents scale blowups).
- `upgradeStreetPeople()` — world builds instantly with primitive figures, rigs hot-swap in
when ~40MB of GLBs arrive. Venue crowd: rigged front rows, bobbing box-figures behind.
- **`web/world/fittings.js`** — standalone parametric shop-fitting kit (racks, bins, shelves,
counters, pegboards, canvas-texture garments). Takes THREE as arg, returns placeable Groups.
Written to theme "any shop, any count". Port for Lane C.
- **`web/world/dig.js`** — self-contained crate-riffle minigame (own scene/camera, callback API
`onBuy/getCash/spawnClerk/spawnFittings`). Already ported across 3 games. Content phase.
- Loaders: `loadGLB`/`loadRig`/`loadProp`/`loadTex` promise-cached, fail→null→placeholder stays.
- Perf: **zero instancing/LOD/atlases** (small scenes got away with it — we can't). Tricks worth
keeping: `GFX_TIERS` era-tiered graphics (~line 167), bloom threshold 0.9, single 2048 shadow
map on street only, additive light-cones, `tools/shots.py` screenshot regression harness.
- Gear/prop gen: MeshGod manifests (`MESHGOD/manifests/djsim_home.json` pattern), webp-optimized
~1MB GLBs, **no Draco**. Gotcha: thin wires/flat discs reconstruct badly — do those as
in-engine primitives.
## thriftgod (`/Users/jing/Documents/thriftgod`)
- three.js 0.175 from unpkg importmap in `web/index.html` (2,061 lines = whole game). Backend
`server.py` (1,616 lines, stdlib + psycopg2) :8777; reads `dealgod` DB (1.77M real listings).
- **Real-world city**: `build_city()` (`server.py:433`) — Overpass query for all named AU
secondhand/charity/music/antiques/books/toys shops → `city_source.json` cache → dedupe →
nearest-capital assignment → suburb inference → parody names → seeded hours. ~2,918 shops.
The recipe for later swapping PROCITY's synthetic plan for real geography.
- **Seed + override architecture (the big idea)**: every shop interior is deterministic from
`shop.seed` via mulberry32 (`web/index.html:1063`); Postgres `layout_shop`/`layout_area`/
`layout_asset` tables hold optional hand-authored overrides; NULL = procedural fallback.
In-game editor (E1E4) writes overrides. See `EDITOR_PLAN.md`.
- **Street**: `buildStreet()` (`index.html:1441-1515`) — 4.4×3.4×0.4 box per shop, facade skin
on front face, canvas name sign, OPEN/CLOSED plate, `SphereGeometry(70)` BackSide sky dome
(seasonal `pickSky`), landmark billboard, textured ground planes.
- **Interior**: `buildShop()` (`index.html:1109+`) — 5 archetypes `SHOP_SHAPES`
(cosy/gallery/wide/hall/pokey), seeded wallpaper/carpet/art, shuffled wall-slot system so
decor never overlaps, record bins, shelves with product thumbnails, floor piles, counter+till,
glass case. Port for Lane C.
- **Generated assets**: 557 JPGs in `web/assets/gen/` from `gen_assets.py` (OpenRouter
`google/gemini-3.1-flash-image`, ~$0.004/img, resumable `.genraw/`, style-bible prefix
*"1990s Australian op-shop aesthetic, slightly faded and worn…"*). Facade prompts generate
**blank signboards** (template at `gen_assets.py:69-86`). 69 relevant skins copied into
PROCITY. CORS enabled on live `/assets/*`.
- **3GOD depot loading** (`index.html:1072-1249`): `DEPOT='https://digalot.fyi/3god'`,
`GLB_CACHE[file] ||= loadAsync`, SkeletonUtils.clone, bbox floor-plant, auto-play `/idle/i`
clip. Editor palette from `/api/list`.
- Movement: PointerLockControls + AABB clamps + rotated-rect divider collision (`hitsDivider`,
`index.html:1994`). `/img` caching proxy with SSRF guard (`server.py:1362`) for CORS-free
WebGL textures.
- Item economy (content phase): `mint()` `server.py:792-858` — per-shop-type profiles, gem
bands, curation axis (CBD distance), isolation multiplier, `TABLESAMPLE` over real listings,
rarity from live supply. `dig.js` riffle with real physical sleeve thicknesses.
## Everything else
- **character_kit** (`~/Documents/character_kit/`, also on ultra): female + male canonical rigs,
props (hats/boombox/camera/thermos), `scripts/finish_rig.py`, `export_for_mixamo.py`.
House law: edit here, copy into games, never edit game-local.
- **mixamo-fetch** (`~/Documents/mixamo-fetch/`): `fetch.cjs` drives Mixamo's REST API (token
from logged-in Brave via CDP :9222). 34 clips in `out/`. Search first; never re-download.
Bespoke clips (crate-riffle, DJ) don't exist there — hand-author.
- **ultra 3D=models library** (`johnking@100.91.239.7:~/Documents/3D=models/`):
`shop-fittings/` (record_crate_plastic_01, clothes_rack_01, shelf_metal_wire_01,
garage_shelves_metal_v2, bookshelves, cube_bookcase, wardrobes, many tables, balcao counter…),
`street-furniture/` (bench, longbench, park_bench_01, market_stall_01, food_cart_bakso_01,
**building_shell_01.glb**), `furniture/`, `props-scenes/` (dj_room, turntable), `characters/`,
`animations/`. `MANIFEST.md` + `CH_MAPPING.md` + `_thumbnails/` exist — read them on ultra.
- **GODVERSE brain** (`~/Documents/dealgod/GODVERSE.md`, `docs/GODVERSE_3D_BRIEF.md`): recordgod/
toygod/bookgod/mediagod data feeds, 44k solid-object 3D candidates, 185k vinyl w/ images —
this is the content firehose for later. Not v1.
- **Vuntra City reference** (YouTube devlogs): 20×20km UE5 city, every building enterable,
interiors generated at runtime, million-NPC layered simulation (detailed near / abstract far),
faked GI. We steal the *ideas* at hamlet scale: on-demand interiors, LOD'd simulation,
cheap lighting.