Files
goldeneye-pc-port/docs/BRIEF-C3-C6-prop-model.md
T
James Dansereau 9d118e0b13 M-13: 21-level sweep matrix + D123 (C1 fix) + D124 (C2 Jungle fix)
WS4 level sweep driven to completion: 12/21 solo levels PASS
(load + render + no-crash). Full matrix in docs/LEVEL-STATUS.md,
reusable runner tools_pc/level_sweep.sh, WS6 checklist docs/LEVEL-PLAYTEST.md.

Fixes:
- D123 (tools_pc/d88_propdefs.py): crash class C1 on 6 levels
  (Dam/Runway/Frigate/Statue/Streets/Cradle). D122 fallout - the widened
  Vehichle/AircraftRecord.ailist slot was zeroed instead of carrying its
  read-before-write integer AI-list id, so prop.c -> ailistFindById(0) ->
  GAILIST_AIM_AT_BOND -> ai() ran a CHR aim list with a NULL chr ->
  chrIsNotDeadOrShot(NULL). New OBJ_ID_WORDS arm. 4 levels -> PASS,
  Runway falls through to C2. BUNKER1/Silo unregressed.
- D124 (port/src/gimgfixup.c): crash class C2 on Jungle. Compiled
  explosion-DL pointer-sync keyed on an IMAGESEG marker that texLoad()
  had already erased -> compiled globalDL_0xNNN arrays kept link-time
  IMAGESEG words -> 0xABCDxxxx into fast3d on first explosion draw.
  Latent on every level. Detect the slot from the compiled array instead.

Diagnosed, NOT fixed (write-ups in PCPortResearch.md SF):
- C2-GDL (D124-Facility addendum): Facility/Runway - model texture-pool
  path yields a garbage tex->data; every model file loads at an odd
  bank base (mempAllocBytesInBank does no alignment). Suspect
  d43_emit.py/pcmodels sidecar texture-blob offsets (N64 8B vs PC 16B Gfx).
- C3/C6 (D125): Aztec/Bunker2/Surface2 - converted propDefs blob in RAM
  doesn't match d88_propdefs.py offline output (garbage after record 0);
  runtime sizepropdef() walk drifts ~100 records -> wrong door/modelid.
  d88_propdefs.py convert_stream + sizepropdef() PORT strides verified
  correct; suspect a dest-offset/pd_end bug in d88_emit.py propdefs emit.

Remaining: 9 crashes / 6 classes (C2-GDL, C3/C6, C2m Jungle G_MTX,
C5 Control BG portal, C4 Depot BG tile/room, C7 Surface1 sndSetupSound).
Priority order in docs/LEVEL-STATUS.md.

Also folds in the in-progress docs restructure (HANDOFF/AGENTS/CLAUDE,
PCPortResearch D121/D122 SF/SH entries, PLAN-linear-level-sweep,
HANDOFF-ARCHIVE, BACKLOG).
2026-08-29 16:36:18 -04:00

3.0 KiB

BRIEF C3+C6 — prop/door/item model-load crashes (Aztec, Bunker2, Surface2)

Dispatch AFTER C1 lands (shares tools_pc/d88_propdefs.py + src/game/prop*.c with C1 — do not run concurrently with C1).

Repo: REPO_ROOT (git master, Windows).

READ FIRST

  • docs/HANDOFF.md top, docs/PORT-LEARNINGS.md §A + §C (esp. the D122 "polymorphic-record converter with a forgotten type" note).
  • docs/PCPortResearch.md §F D122, D120, D112, D53.2, D57, D67 (jump via index).
  • docs/BRIEF-D122-per-level-modelload.md — direct predecessor, same class.
  • AGENTS.md non-negotiables.

SYMPTOM (WS4 sweep — docs/LEVEL-STATUS.md)

Level # Site Note
Aztec 28 propobj.c:13601 door->model->obj->RootNode->Child->Child fault 0x10
Bunker2 27 propobj.c:13523 door displacement linkedDoor list walk fault 0x8
Surface2 43 loadobjectmodel.c:393 PitemZ_entries[modelid].header->RootNode fault 0x0 — direct D122 continuation

All three: a prop/door/item model pointer or model-id from a Usetup*Z propDef record is wrong. D122 fixed the [s16 obj][s16 pad] half-swap for 6 inherits ObjectRecord types; these levels emit a door subtype or another record type whose model / linkedDoor / modelid field is still converted wrong (or a placeholder-sized type: VEHICLE/AIRCRAFT/TANK/AMMO/DEPOSIT_IN_ROOM per d88_propdefs.py). Run tools_pc/d88_propdef_scan.py for the per-level type histogram; diff Aztec/Bunker2/Surface2 against the 7 passing levels.

TASK

Root-cause all three (likely one converter gap), extend tools_pc/d88_propdefs.py (+ sizepropdef() #ifdef PORT stride in src/game/prop.c to match, per the D122 pattern). Resolve any placeholder PROPDEF_PC_BYTES via tools_pc/d88_layoutprobe.c.

FILES YOU MAY TOUCH

tools_pc/d88_propdefs.py, d88_emit.py, d88_layoutprobe.c, d88_propdef_scan.py; src/game/prop.c, src/game/propobj.c, src/game/loadobjectmodel.c (narrow #ifdef PORT); new tools_pc/c3_* probes; docs/PORT-LEARNINGS.md, docs/PCPortResearch.md §F, docs/LEVEL-STATUS.md.

KNOWN-GOOD / RULED OUT

D121, D122 (committed f2beae4b), the 7 passing levels' prop/model load, C1's chr fix (landed first — rebase on it).

PRE-FLIGHT / ENV / BUDGET / CONSTRAINTS / REPORT

Same as docs/BRIEF-C1-chr-airecord.md (repro -level_28 / -level_27 / -level_43; taskkill //F //IM ge007.x86_64.exe; regen all 3 sidecars after converter change; #ifdef PORT with N64 line under #else; verify the 3 levels boot to a frame + -level_09/-level_20 unregressed). Budget: ~12 cycles / ~90 min.

STILL OPEN AFTER THIS (singletons, own briefs later)

  • C4 Depot 30 — prop.c:902 sp4C->room after walkTilesBetweenPoints_NoCallback (BG tile/room table).
  • C5 Control 23 — bg.c:5723 portal_pts->numPoints (g_BgPortals[].offset_portal unresolved/BE), via chrprop.c:62.
  • C7 Surface1 36 — snd.c:653 sndSetupSound (audio subsystem is parked; may just need a narrow load-time guard until Phase 3).