re: refute my own position anchor, withdraw the entities2 "defect", find the trap

Three results, two of them against my own earlier claims:

 - REFUTED: position = instance - 0x12c.  The corpus anchors on position (def ptr
   at +0x130, orientation at -0x70, hull at +0x154) and name_of reads the def ptr
   at instance+4, which predicts -0x12c.  Measured over all 42 named instances:
   almost every read is (0,0,0), three are garbage, and 0/42 move.  The vtable
   object and the position block are different structures.

 - WITHDRAWN: last iteration's claim that entities2.py's ENT_VA window is aimed at
   the definitions rather than the instances.  entities2 does not look for vtable
   objects at all -- it hunts moving position triples and checks +0x130, the
   documented anchor -- and it had worked minutes earlier (6914 movers, +0x130
   voted 92x; then 6634/138x).  I built the defect report on the single sample in
   between that returned zero.  The +0x29d0 position candidate falls with it.

 - FOUND: sampling 64 spots across the 505 extents (357 MB) twice, 2.5s apart,
   with the mission visibly running, only 5 change.  The megabyte holding all 42
   instances is byte-identical over seconds, as is its primary-VA counterpart.
   The mapping IS live (5 regions prove it); what is undetermined is whether the
   entity records are simply static or whether writes land in a different alias.
   Either way: verify a region changes before measuring through it.
This commit is contained in:
Sylpheed RE agent
2026-08-26 21:36:47 +00:00
parent 9770eadad4
commit f59c4e595c

View File

@@ -0,0 +1,86 @@
# ❌ Two of my own claims, refuted — and a live-memory trap behind both
Measured 2026-08-26, Canary on the retail disc, save slot 01, Stage 01, **in
flight with a live HUD** (`TIME 00:28.42`, speed 350, target on radar, dialogue
mid-render — the game was unambiguously running throughout).
## ❌ Refuted: `position = instance 0x12c`
The corpus anchors the entity layout on **position**:
[`autopilot-memory-driven.md`](autopilot-memory-driven.md) gives the definition
pointer at `position + 0x130`, orientation at `position 0x70`, hull at
`position + 0x154`. `gworld.py`'s `name_of()` reads the definition pointer at
`instance + 4`. If those name the same field, `instance + 4 = position + 0x130`,
so `position = instance 0x12c`.
They do not. Read at `instance 0x12c` for all **42** named instances:
```
UN_f001_TCAF_DeltaSaber_T_Player ( 0.0, 0.9, 0.1) moved 0.00
UN_e106_ADAN_Destroyer ( -48.9, 0.0, 0.0) moved 0.00
UN_S01_Asteroid_cmesh_01a (2.07e11, 0.0, 0.0) moved 0.00
...
moved in 0.8 s : 0/42
```
Almost every read is `(0, 0, 0)`, three are garbage, and **nothing moves**. The
vtable-bearing object and the position block are two different structures that
merely name the same units. The prediction was clean and it was wrong.
## ❌ Withdrawn: "`entities2.py`'s VA window is aimed at the wrong region"
[Last iteration](world-unit-attempt-2026-08-26.md) I recorded `ENT_VA_LO/HI =
0xBD0000000xBE000000` as a defect, on the grounds that the live instances sit at
`0xBC384CE00xBC9BAC20` and the window "covers the definitions instead".
That reasoning was wrong. It assumed the thing the window *should* contain is the
vtable-bearing instance — but `entities2.py` does not look for those. It hunts
**moving position triples** and checks `+0x130` for a definition pointer, exactly
the documented anchor. And in the run where I called it broken it had *worked*
moments earlier: **6914 movers, `+0x130` voted 92×**, then 6634 and 138× on a
re-run. I built a defect report on the one sample in between that returned zero —
the same single-sample error this corpus keeps logging.
The window may still be imperfect (it is hardcoded, and the heap moves). But it
is not "aimed at the definitions", and nothing here shows it needs changing.
## 🟡→❌ The `+0x29d0` position candidate is not trustworthy either
It was read through the same region that is shown below not to be updating, so
what it captured is load-time data, not a live position. Withdrawn pending a
re-measurement through a region that demonstrably changes.
## ✅ The trap: most of guest memory is not changing while the game runs
Sampling **64 spots of 64 KB** spread across the mapping's **505 extents
(357 MB)**, twice, 2.5 s apart, with the mission visibly running:
```
CHANGING: 5 / 64
0x007006f000 0x00704db000 0x0070557b000 0x00705df000 0x0080240000
```
Everything else — including the megabyte containing all 42 live instances
(`0x11c37d780`), and that region's primary-VA counterpart at `0x00bc300000` — is
**byte-identical over seconds**. So:
* The mapping is live. Five regions prove it, so "the shm view is stale" as a
blanket claim is refuted.
* The entity-object region genuinely does not change on a seconds timescale.
***Not determined**: whether that is because those records are static
metadata and the moving state lives elsewhere, or because the guest physical
page is aliased at several file offsets and writes land in a different one.
Both fit the evidence. `gmem.primary_va(0x11c384ce0) = 0xbc384ce0` shows the
alias relationship exists; it does not show which copy the guest writes.
**Consequence for anyone reading guest memory here:** verify the specific region
you are sampling actually changes before drawing conclusions from it. A scan that
finds correct, name-resolving records can still be reading a snapshot.
## Still open
* Where the live position blocks are. The five changing offsets above are the
place to start, but `moving()` takes **VAs** and converts with
`gmem.va_to_off`, while those five are **file offsets** — they are not the same
number and must be converted before they can be scanned.
* Whether `entities2.py`'s window needs any change at all.