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:
BIN
docs/re/captures/entities-loadgame-slot01-s01.png
Normal file
BIN
docs/re/captures/entities-loadgame-slot01-s01.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 242 KiB |
86
docs/re/entities-live-roster.md
Normal file
86
docs/re/entities-live-roster.md
Normal 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.3–1.5 % in
|
||||
flight), so no distance readout was available to compare against.
|
||||
* A same-process title-screen control for the scan above.
|
||||
Reference in New Issue
Block a user