Files
Drew T 1431b523a4 feat(phase-17): T4+T5 — actor struct recovered (comprehension) but byte-neutral for matching
- recovered the engine actor/player struct cold via PCSX-Redux (R10/R11): base 0x80078E00,
  ~154 fields over 0x24C bytes, 32 pointer fields; HP/BP/gold/day/hour/position/BP-drain all
  live-verified and anchored to the Phase-3 player state + the walk diff. -> docs/actor-struct.md
- tools/ram_probe.py: PCSX-Redux RAM capture/diff/read/ptr-scan workhorse for field-typing
- FINDING (the matching verdict): feeding the struct to m2c as --context is BYTE-NEUTRAL.
  m2c adopts it (arg0->f_X) but structural-miss sample scores 0 better / 10 same / 2 worse vs
  m2c-alone (full code+RAM pointer set). The misses are 50-98% mismatched = m2c decompiler
  limits, not missing types. T4 fn-ptr context unblocks compilation but functions stay structural.
- conclusion: rich context (struct/type recovery) is a comprehension / decomp.me win, NOT a
  byte-match lever -> Phase-16 wall re-confirmed from the type angle. struct-core-pivot.md updated.
- emulator field-naming pass deferred (comprehension, off the matching path); NEXT: T6 permuter
  validation on the 146 genuine near-misses, then T7 go/no-go.
2026-06-19 13:03:14 -06:00

47 lines
3.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Actor / Player struct — recovered layout + the byte-neutral finding (Phase 17 / T4-T5)
> **Base: `0x80078E00`** (the player instance). ~154 fields over **0x24C bytes**. This is the engine's
> central entity record — `arg0` to 550/941 of the struct-heavy residual functions. Recovered by (a) static
> inference from the union of m2c `M2C_FIELD(arg0, T, off)` accesses across all drafts, (b) a live PCSX-Redux
> RAM pass (R10/R11), anchored to the Phase-3 player-state fields.
## ⚠ Key finding (the matching verdict)
**Feeding this struct to m2c as `--context` is BYTE-NEUTRAL for the structural-miss bucket.** Measured: on a
12-function structural-miss sample, m2c-with-struct vs m2c-alone → **0 better / 10 same / 2 worse** (even with
the full code-inferred + RAM pointer set, 32 pointers). `arg0->f_X` and `M2C_FIELD(arg0, T*, X)` emit identical
bytes; the structural misses (50–98% instruction mismatch) are m2c *decompiler* limits, not missing types — so
the struct does not crack them, and neither will the permuter at that mismatch magnitude. This confirms the
Phase-17 deep-research caveat: type recovery is **comprehension**, not a blanket match-% lever. The struct is
kept as a Gen2 quality artifact + decomp.me enabler, **not** a build input.
## Confirmed fields (live-verified, R10)
| offset | type | meaning | evidence |
|---|---|---|---|
| +0x08C | s32 | gold | =126 (Phase-3 anchor) |
| +0x0AC | u8 | day | =2 |
| +0x0B1 | u8 | hour | =22 |
| +0x0B2 | u16 | hp_max | =150 |
| +0x0B4 | u16 | **hp_cur** | =150 (the plan's "+0xB4"; Phase-3 0x80078EB4) |
| +0x0B6 | u16 | bp_max | =150 |
| +0x0B8 | u16 | bp_cur (stamina) | 74→50 as the player walked (BP-drain) |
| +0x108 | s16 | position X | +6 on a walk north |
| +0x10C | s16 | position Z | +10 on a walk north |
| +0xF0 | s16 | step/heading counter | +1 per walk tick |
## Pointer fields (the m2c-can't-infer set; idle RAM scan + code-inferred)
RAM-observed: `+0x54 → 0x8017E75C`, `+0x58 → 0x8017E720`, `+0x68 → 0x8017E91C` (overlay code — likely
behavior/handler function pointers), `+0x6C/+0x70 → 0x800D1E20` (resident), `+0x5C → 0x8010F5C8`. Plus ~26 more
offsets m2c dereferences as pointers in code (e.g. `+0x08`, `+0x4C`, `+0x50`). Full set in `.run/actor_fields.json`.
## Reproduce
- Static layout: aggregate `M2C_FIELD(arg0, T*, off)` over `.run/wt_drafts/*.c` (regen via the harvest).
- Live typing: `tools/ram_probe.py` against PCSX-Redux (host in `.run/ram/HOST.txt`); snapshot/diff across
controlled actions (walk/jump/swing/charge/damage) to type + name fields (R10 multi-datapoint).
- The validation (struct byte-neutral): m2c-with-`.run/actor_ctx2.c` → `match_one` vs m2c-alone.
## Deferred (comprehension, not the matching critical path)
Full field-naming via the emulator scenario list (jump=air-state/y-vel; swing=action-state+weapon-id;
charge=charge-level; damage=hp/hurt-state; the +0x14/+0x15 dispatch-state per memory-map; the flashing-HUD
"interactable nearby" Bincho flag). Resume when comprehension/decomp.me work is prioritized — it does **not**
move the byte-match needle (proven above).