re: unit_state reads rec+4 and rec+104, never rec+16

Disassembling built-in 69's handler at 0x8226ADF0 instead of trusting the
summary: it loads rec = base[idx], tests rec+4 against zero (early exit =
absent), passes rec+4 to sub_82301240 for the lifecycle lookup, and compares the
byte at rec+104. rec+16 is never touched on that path.

That explains the null poke result exactly -- I wrote into a field the condition
does not consult. +16 remains a faithful OBSERVABLE (the arrival and death
transitions were real) but it is a readout, not the input. It also explains why
rec+4 holds small consecutive integers: it is a handle that sub_82301240
resolves, not a pointer.

The corrected simulation of 'this squadron is gone' is rec+4 = 0, taking the
documented early exit.

Flags a general caution: this built-in table came from a subagent's reading of
handler behaviour, and this is the second per-offset field description that did
not survive the disassembly. The identifications of which built-in does what
have held up; the offset meanings are leads to verify.
This commit is contained in:
Sylpheed RE agent
2026-08-25 16:58:49 +00:00
parent 852cdc1e54
commit e342d5f454

View File

@@ -184,6 +184,44 @@ unconditional jump. **Not confirmed** — the handlers (`0x82271598` for op10,
`0x82271830` for op13) have not been read, and I am not going to name them from
a pattern alone.
## 🔴 Correction: `unit_state` does NOT read `+16` — it reads `+4` and `+104`
Disassembling built-in 69's handler (`0x8226ADF0`) rather than trusting the
one-line summary:
```
lwz r10, 324(r30) ; the unit array
lwz r11, 4(r31) ; arg blob +4 = the symbol-table-2 index
lwz r10, 4(r10) ; records base
lwzx r9, r11, r10 ; rec = base[idx]
lwz r9, 4(r9) ; <-- rec+4
cmplwi r9, 0
beq 0x8226AF44 ; rec+4 == 0 -> early exit, "absent"
lwz r4, 4(r11) ; rec+4 again
bl 0x82301240 ; lifecycle lookup ON rec+4
...
lbz r11, 104(r11) ; rec+104, a BYTE, compared against 1
li r11, 2 ; -> result 2
```
**`rec+16` is never touched on this path.** The predicate reads the **handle at
`rec+4`** — which is why it holds small consecutive integers (26/27/28) rather
than pointers; `sub_82301240` resolves it — plus the byte at `rec+104`.
That is exactly why poking `+16` to 4 changed nothing
([script-runtime-probe](../script-runtime-probe.md)): the value was written into
a field the condition does not consult. `+16` still tracks
deployed/active/destroyed faithfully as an *observable* — the arrival and death
transitions were real — but it is a **readout, not the input**.
**The corrected way to simulate "this squadron is gone" is `rec+4 = 0`**, which
takes the documented early exit. That is the next experiment.
⚠️ General lesson for this table: it was assembled by a subagent from handler
behaviour, and this is the second field description that did not survive contact
with the disassembly. Treat the per-offset meanings as leads to verify, not as
facts — the *identifications* (which built-in does what) have held up well.
## 🟡 Not settled
* **Three handlers resisted**: id 55 (`vt35`, 411 instructions, returns a float),