diff --git a/docs/re/captures/entities-loadgame-slot01-s01.png b/docs/re/captures/entities-loadgame-slot01-s01.png new file mode 100644 index 00000000..19532af3 Binary files /dev/null and b/docs/re/captures/entities-loadgame-slot01-s01.png differ diff --git a/docs/re/entities-live-roster.md b/docs/re/entities-live-roster.md new file mode 100644 index 00000000..a6401b50 --- /dev/null +++ b/docs/re/entities-live-roster.md @@ -0,0 +1,86 @@ +# ✅ Entity objects ARE spawned — the vtables were never stale, the ROUTE was wrong + +**Confidence: ✅ CONFIRMED.** Measured 2026-08-26 in the sylph-re container, +Canary on the retail disc, save slot 01, Stage 01 "Glasner Training Area". + +## The result + +`gworld.py`'s two constants resolve exactly as written: + +| vtable | address | hits | +|---|---|---| +| `DEF_VTABLE` (parsed `.tbl` definition, one per unit type) | `0x820AF844` | **13** | +| `INST_VTABLE` (spawned entity instance, one per thing in the scene) | `0x820AF030` | **42** | + +`name_of()` resolves every one of them: + +``` +# 13 definitions # 42 live instances +UN_f001_TCAF_DeltaSaber_T_Player 20 UN_e007_ADAN_Turret +UN_f001_TCAF_DeltaSaber_T 6 UN_f001_TCAF_DeltaSaber_T +UN_e007_ADAN_Turret 5 UN_e010_ADAN_Attacker_S +UN_e106_ADAN_Destroyer 2 UN_e106_ADAN_Destroyer +UN_e010_ADAN_Attacker_S 8 UN_S01_Asteroid_cmesh_0{1..4}{a,b} +UN_S01_Asteroid_cmesh_0{1..4}{a,b} 1 UN_f001_TCAF_DeltaSaber_T_Player +``` + +`entities2.py` reports **52 moving triples**, so these are live objects with +changing positions, not inert table images. + +## Why this is not a false positive + +A bit pattern can occur by chance; a *coherent roster* cannot. The evidence is +the content, not the count: + +* The asteroid definitions are `UN_S01_…` and the stage actually loaded was + **S01** — the scan recovered the right stage's props without being told which + stage was running. +* The composition is internally sensible: **2** `e106` destroyers and **20** + `e007` turrets, i.e. ~10 turrets per destroyer, which matches the e106 part + breakdown in [ship placement](../../MEMORY.md) (8 hull parts + 2 turrets per + side). Six `DeltaSaber_T` = the player plus a wing. +* Exactly one object is the `_Player` variant, and exactly one definition is. + +❌ Control still owed, stated rather than glossed: the title-screen arm of this +comparison was measured in *earlier processes* (0 hits at every menu state), not +in this one. The stage-specific roster is strong evidence, but a same-process +title control has not been run. + +## What was actually wrong — the route, not the constants + +Every run in the preceding dozen iterations navigated through **MISSION SELECT** +(which needs the cleared-stage-mask poke to offer a stage at all). Both scans +returned 0/0 there, and the constants were marked 🔴 stale. + +They were not stale. [`structures/unit-struct-runtime.md`](structures/unit-struct-runtime.md) +records its own provenance — captures came from *"all six tutorials and Stage 02 +loaded from **save slot 01**"* — and `launch_mission.sh` already encoded that +route: **title → LOAD GAME → slot 01 → YES → READY ROOM → TAKE OFF**. + +`LOAD GAME` is the menu's **second** item. The previous iteration pressed the +**first** (NEW GAME) and read the 0/0 that followed as evidence about the +constants. One `step down` separated a dozen iterations of "stale vtable" from +this roster. + +🔑 **Method note.** Two iterations in a row were spent re-deriving something the +corpus already recorded — first the provenance line, then the working script. +Read `tools/re-capture/` and the doc's own provenance *before* deriving. + +## Reproduction + +`launch_mission.sh fly` does the whole thing. On a slow lavapipe boot the +attract movie can outlast `SKIP_INTRO_TIMEOUT`; the emulator is `nohup`ed and +survives, so re-run the post-boot half against the live process. + +⚠️ `wait_screen.sh readyroom` reports **failure on a successful run**: the cyan +mission-briefing map classifies as `menu` (see +[screen-id-briefing-misclass](screen-id-briefing-misclass.md)), so the route +looks stuck on the main menu while it is in fact three screens further on. + +## Still open + +* The **world-unit measurement** ([collisionset](collisionset.md)) — positions + in world units against the HUD's own distance readout. This run reached the + mission but the flight HUD was not yet up (green 0.03 %, vs 1.3–1.5 % in + flight), so no distance readout was available to compare against. +* A same-process title-screen control for the scan above.