Lane D R36 w2.5 (Fable ruling): CLASSIC KEEPS ITS PEOPLE — the 5 DJ bodies gate out of ?classic's pool
b339402 appended the 5 trellis'd DJ bodies to PED_NAMES.normal unconditionally, so
?classic=1 fetched them and its seeded crowd pool widened 17->22 (F's held §36.4 warn).
Ruled option (b): the five gate OUT of classic, mirroring the sit/look/dance !CLASSIC
clip gates. classic is the v2 town INCLUDING ITS PEOPLE; the DJs walk every other boot.
MECHANISM (rigs.js only — zero shell edits): PED_NAMES.normal restored to the covenanted
base 17 (exact pre-July-20 list); the five move to PED_NAMES.djs; loadPedFleet gains
djs = dance (default tracks the existing dance flag, which the shell already passes as
!CLASSIC). Roster = djs ? [...normal, ...djs] : normal — the five APPEND, so no base
slot renumbers: default boot's 22-list is byte-identical to the pre-ruling list and
classic's 17-list is byte-identical to pre-b339402. pickRig maps through pool.length,
so 17 restores the exact pre-July-20 crowd mapping, not merely the width.
MEASURED (fresh contexts, port-isolated no-store servers, seed 20261990):
- ?classic=1: ZERO of the 5 DJ GLBs fetched (21 ped-GLB fetches = 17+2 bodies +
walk+idle) · pool 17 normal / 19 all · 129-citizen census all base-17 u comical,
zero DJ · 0 console errors.
- default: all 5 fetched · pool 22/24 · 37 DJ-bodied street peds · F's organic gig
proof preserved (pinned seed's venue crowd includes dj_phrtt_01 + woman_dj_02) ·
0 console errors.
- IDENTITY vs pre-July-20: classic booted on a shadow tree with b339402^ rigs.js —
full 129-citizen (id, pedRoll, pedIndex, pedName) census BYTE-IDENTICAL to the
gated tree's classic boot. Same crowd, ped for ped, as before July 20.
Known side effect (noted §36): citizens_test.html passes no opts -> its dev harness
shows 17+2; not a covenanted surface, {djs:true} restores it if wanted.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
622a5e0d82
commit
2fd4c1cf79
@ -6,6 +6,48 @@ _rotOnly/head-bone normalize/upgradeStreetPeople). Measurements on the M3 Ultra
|
||||
|
||||
---
|
||||
|
||||
## ROUND 36 (wave 2.5) — CLASSIC KEEPS ITS PEOPLE: the DJ bodies gated out of `?classic`
|
||||
|
||||
**The ruling (Fable, on F's §36.4 held warn):** `b339402` (July 20) appended the 5 trellis'd DJ
|
||||
bodies (`woman_dj_01/02/03`, `dj_techno_01`, `dj_phrtt_01`) to `PED_NAMES.normal` UNCONDITIONALLY —
|
||||
so `?classic=1` fetched them and its seeded crowd pool widened 17→22, six epochs after the covenant
|
||||
froze. Ruled option (b): the five gate OUT of classic's pool, mirroring the sit/look/dance `!CLASSIC`
|
||||
clip gates. Classic is the v2 town INCLUDING ITS PEOPLE; the DJs walk every other boot.
|
||||
|
||||
**Mechanism (D's call — one file, `rigs.js`, per the wave-2.5 pathspec law):**
|
||||
- `PED_NAMES.normal` is restored to the covenanted **base 17** (exact pre-July-20 list, order
|
||||
preserved). The five move to a new `PED_NAMES.djs` extension list.
|
||||
- `loadPedFleet` gains **`djs = dance`** — a new opt whose DEFAULT tracks the existing `dance` flag.
|
||||
The shell already passes `dance: !CLASSIC` (index.html:194), so the classic-ness signal arrives
|
||||
with ZERO shell edits: classic ⇒ `dance:false` ⇒ `djs:false` ⇒ no DJ fetch, 17-pool; default ⇒
|
||||
`djs:true` ⇒ all 22. Separable for callers wanting clips without bodies (or vice versa).
|
||||
- The roster is built `djs ? [...normal, ...djs] : normal` — the five APPEND, so no base slot is
|
||||
renumbered in either mode: the default-boot 22-list is byte-identical to the pre-ruling list, and
|
||||
classic's 17-list is byte-identical to pre-b339402. `pickRig` maps `r01 * 997 % pool.length`, so
|
||||
pool LENGTH is crowd identity — 17 restores the exact pre-July-20 mapping, not merely the width.
|
||||
- Known side effect (accepted, noted): `citizens_test.html` calls `loadPedFleet` with no opts ⇒
|
||||
`dance:false` ⇒ its dev-harness roster shows 17+2, not 22+2. It is not a covenanted surface; a
|
||||
future D round can pass `{djs:true}` there if the harness wants the five back.
|
||||
|
||||
**Measured (fresh contexts each, port-isolated no-store servers :8971 current / :8972 pre-b339402
|
||||
shadow tree, seed 20261990):**
|
||||
|
||||
| check | `?classic=1` (gated) | default boot (gated) |
|
||||
|---|---|---|
|
||||
| DJ-GLB fetches | **0 of 5** (21 ped-GLB fetches total = 17+2 bodies + walk+idle) | **5 of 5** |
|
||||
| pool | **17 normal** / 2 comical / 19 all | **22 normal** / 24 all |
|
||||
| crowd census | 129 active, 129 named, **19 distinct — all base-17 ∪ comical, zero DJ** | 153 named street peds incl. **37 DJ-bodied** (techno 13 / w01 8 / phrtt 7 / w03 6 / w02 3) |
|
||||
| gig crowd (F's organic proof) | n/a (gig layer absent) | **preserved** — pinned seed's venue crew (12) includes `dj_phrtt_01` + `woman_dj_02` in the crowd |
|
||||
| console errors | **0** | **0** |
|
||||
|
||||
**The pre-July-20 identity check (the R29 lesson: measure, don't assume):** booted `?classic=1` on a
|
||||
shadow tree whose `rigs.js` is `b339402^` (everything else current), same seed, same server law.
|
||||
Roster arrays identical; the full 129-citizen census — every `(id, pedRoll, pedIndex, pedName)`
|
||||
tuple — is **byte-identical** to the gated tree's classic boot. Classic's crowd is not just 17-wide;
|
||||
it is the SAME crowd, ped for ped, as before July 20. (This held by construction — the five were
|
||||
appended, so gating them off restores both list content and length — but it is now held by
|
||||
measurement too.)
|
||||
|
||||
## ROUND 29 — v6 SPIKE 1: `look.glb` bound and wired — peds glance (wave 0)
|
||||
|
||||
*PROCITY-D, 2026-07-17. The spike finally reaches the game: E's `look.glb` (mesh-free, 65 joints, 6.5 s
|
||||
|
||||
@ -14,12 +14,17 @@ import { clone as skeletonClone } from 'three/addons/utils/SkeletonUtils.js';
|
||||
import { loadGLB } from '../core/loaders.js';
|
||||
|
||||
// The 19 rigged peds (17 normal + 2 comical) copied byte-identical from 90sDJsim into web/models/peds/.
|
||||
// [R36 wave 2.5 — Fable ruling on F's §36.4 hold] `normal` is the CLASSIC-COVENANTED base 17 (the exact
|
||||
// pre-July-20 list, order preserved — pickRig maps r01 through pool.length, so the length IS the identity).
|
||||
// The 5 trellis'd DJ bodies (b339402, fbx_to_ped, 4k tris) live in `djs` and join the roster only when
|
||||
// loadPedFleet's `djs` opt is on — they are APPENDED, so the default-boot pool is byte-identical to the
|
||||
// pre-ruling 22-list and `?classic=1` is byte-identical to pre-July-20 (fetch surface AND crowd identity).
|
||||
export const PED_NAMES = {
|
||||
normal: ['man_worker_hivis_01', 'man_suit_01', 'man_casual_01', 'man_casual_02', 'man_casual_03',
|
||||
'man_grunge_01', 'man_elder_01', 'man_athletic_01', 'man_bouncer_01', 'man_soldier_ww2_01',
|
||||
'man_dj_streetwear_01', 'woman_casual_01', 'woman_casual_02', 'woman_business_01',
|
||||
'woman_athleisure_01', 'woman_smart_01', 'woman_chef_01',
|
||||
'woman_dj_01', 'woman_dj_02', 'woman_dj_03', 'dj_techno_01', 'dj_phrtt_01'], // trellis'd DJ bodies (fbx_to_ped, 4k tris)
|
||||
'woman_athleisure_01', 'woman_smart_01', 'woman_chef_01'],
|
||||
djs: ['woman_dj_01', 'woman_dj_02', 'woman_dj_03', 'dj_techno_01', 'dj_phrtt_01'], // gated: dance-scene bodies, NOT in classic's pool
|
||||
comical: ['comical_luchador_01', 'comical_boy_01'],
|
||||
};
|
||||
|
||||
@ -56,7 +61,12 @@ function loadRig(ref) {
|
||||
// sit.glb fetch would break the ?classic=1 zero-fetch-delta covenant — F passes sit:true on the gig/default
|
||||
// boot, sit:false (default) under ?classic. Absent/off → fleet.sitClip stays null and the drummer falls
|
||||
// back to the standing-sunk hack, so this never breaks a boot. Does NOT touch fleet.ready / determinism.
|
||||
export function loadPedFleet(base = 'models/peds/', { sit = false, look = false, dance = false } = {}) {
|
||||
// `opts.djs` (R36 w2.5): admit the 5 trellis'd DJ bodies into the normal roster. DEFAULTS TO `dance` —
|
||||
// the shell already passes `dance: !CLASSIC`, so the classic-ness signal arrives without a shell edit and
|
||||
// the bodies ride the same `!CLASSIC` gate as the sit/look/dance clips: `?classic=1` fetches none of the
|
||||
// five and keeps the covenanted 17-pool; every other boot gets all 22. Separable for callers that want
|
||||
// dance clips without the bodies (or vice versa).
|
||||
export function loadPedFleet(base = 'models/peds/', { sit = false, look = false, dance = false, djs = dance } = {}) {
|
||||
const fleet = {
|
||||
normal: [], comical: [], all: [], // all = normal ++ comical, stable index for the impostor atlas
|
||||
walkClip: null, idleClip: null, sitClip: null, lookClip: null, danceClips: [],
|
||||
@ -66,10 +76,13 @@ export function loadPedFleet(base = 'models/peds/', { sit = false, look = false,
|
||||
// order (and thus every pickRig index + identity signature) depends on GLB load-completion timing,
|
||||
// which varies per run/machine and silently breaks "same seed → same crowd". Compact after all
|
||||
// settle (filter(Boolean) preserves the fixed relative order, so a missing file is deterministic too).
|
||||
const nSlots = new Array(PED_NAMES.normal.length).fill(null);
|
||||
// R36 w2.5: the DJ bodies extend the roster AFTER the base 17, so gating them off shortens the pool
|
||||
// without renumbering a single base slot — classic's pickRig mapping is the pre-July-20 one exactly.
|
||||
const normalNames = djs ? [...PED_NAMES.normal, ...PED_NAMES.djs] : PED_NAMES.normal;
|
||||
const nSlots = new Array(normalNames.length).fill(null);
|
||||
const cSlots = new Array(PED_NAMES.comical.length).fill(null);
|
||||
const jobs = [];
|
||||
PED_NAMES.normal.forEach((n, i) => jobs.push(loadRig(`${base}${n}.glb`).then(r => {
|
||||
normalNames.forEach((n, i) => jobs.push(loadRig(`${base}${n}.glb`).then(r => {
|
||||
if (r) { r.pedName = n; nSlots[i] = canonRig(r); } })));
|
||||
PED_NAMES.comical.forEach((n, i) => jobs.push(loadRig(`${base}${n}.glb`).then(r => {
|
||||
if (r) { r.pedName = n; cSlots[i] = canonRig(r); } })));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user