re: entity objects ARE spawned -- the vtables were stale-labelled, the ROUTE was wrong

gworld.py's DEF_VTABLE 0x820AF844 and INST_VTABLE 0x820AF030 resolve exactly as
written: 13 unit definitions and 42 live instances, every one name-resolved, with
52 moving triples.  The roster is coherent and stage-specific -- UN_S01_Asteroid_*
in the S01 training area, 2 e106 destroyers against 20 e007 turrets, 6 DeltaSaber_T
and exactly one _Player -- which is far stronger evidence than a hit count.

The constants were never stale.  structures/unit-struct-runtime.md records its own
provenance ("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 resulting 0/0 as evidence
about the constants.  One `step down` separated a dozen iterations from this.

Control still owed and stated in the doc: the title-screen arm was measured in
earlier processes, not this one.
This commit is contained in:
Sylpheed RE agent
2026-08-26 20:46:21 +00:00
parent 1bada3ba4c
commit 779bdde390
2 changed files with 86 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

View File

@@ -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.31.5 % in
flight), so no distance readout was available to compare against.
* A same-process title-screen control for the scan above.