Why this entry exists

The 24-byte-stride "navmesh" reading was structural inference from a single pair of mednafen save-state diffs (comparing emulator RAM snapshots before and after an area load). Broader inspection across three separate save states (mc1 / mc2 / mc3) falsifies it - and negative findings are worth writing down, because the same diff evidence would suggest the same wrong conclusion to the next person.

What the data actually looks like

Three shapes appear across the captures, none matching a navmesh table:

  • Repeating constant runs. In mc1 (map01), the same 1700-byte window holds 0c 00 0c 00 0c 00 ... 0d 00 0d 00 ... 0e 00 ... - a uniform u16 sequence with no record structure.
  • GPU-packet shapes. In mc2 and mc3, 12-byte runs that mirror the GP0 packet header + RGB-color + delta-position layout the PSX renderer emits (GP0 packets are the raw draw commands sent to the PlayStation GPU). Bytes like 80 80 80 7E / 80 80 80 76 are the canonical TMD primitive flag/mode/code/ilen quartet; bytes like c1 c1 c1 / cc cc cc / f7 f7 f7 are RGB color triplets; signed 0xff deltas appear at the i16 positions.
  • Cross-save residency. mc1, mc2, and mc3 all show different shapes at the same offset. A real navmesh would carry stable per-scene records that other code reads through a known base pointer; this region is overwritten wholesale on scene entry.

The smoking gun: nothing points at it

A mednafen-state pointer-hunt over the full 2 MiB main-RAM window for any u32 value pointing into 0x80108EA4..0x80109550 returns zero hits in mc1, mc2, or mc3. There is no RAM cell anywhere - overlay slot, SCUS data segment, kernel stack, or runtime heap - that holds the table base. A real navmesh table would be consulted through a stable base-pointer cell; this buffer is consumed by code that knows its address as a compiled-in constant (a MIPS LUI+ADDIU immediate pair inside the renderer), not via indirection.

The wider window 0x80108000..0x8010A000 does have 6 external pointers (in mc1), but they target neighbouring offsets (0x80108398, 0x80108BC8, 0x80108C2C, 0x80108C38) - that's the pre-fill / sprite-batcher reading from data structures adjacent to this scratch region, not the scratch region itself.

So where IS the pathing data?

Real per-scene region / event-trigger data for actor pathing is not in this RAM window. The actual systems:

  • General town/field free-movement locomotion + collision is FUN_801d01b0 (player controller) + FUN_801cfe4c (collision), which sample a per-scene walkability tile map through the base pointer _DAT_1f8003ec (grid at +0x4000, 4 sub-cell wall bits per byte, one byte per 128-unit tile). See field locomotion. This is the resolved answer to "where is the collision data" - a nibble grid keyed on the player tile, not a RAM table in this window.
  • A tile-board grid (cell 2 = wall) is installed inline in the field-VM event script by op 0x49, but that drives the puzzle / board minigame mode, not general locomotion.
  • Per-scene region / zone boxes are 18-byte records at the MAN control block _DAT_801c6ea4 + 0x4, queried by player tile via FUN_801dba20 (bbox in bytes[1..4]; bytes[5..17] is the region's camera preset, not pathing data).
  • The encounter-record pointer lives in actor records at actor[+0x94] - see encounter record format and the world-map subsystem for that flow.

Reproducing the negative finding

./target/release/mednafen-state extract <mc1.mc1> --start 0x80000000 --end 0x80200000 --out /tmp/ram_mc1.bin
./target/release/mednafen-state extract <mc3.mc3> --start 0x80000000 --end 0x80200000 --out /tmp/ram_mc3.bin

python3 scripts/mednafen/pointer-hunt.py into-window /tmp/ram_mc1.bin \
    --target-lo 0x80108EA4 --target-hi 0x80109550 --exclude-self
python3 scripts/mednafen/pointer-hunt.py into-window /tmp/ram_mc3.bin \
    --target-lo 0x80108EA4 --target-hi 0x80109550 --exclude-self

Both invocations return zero hits. The narrow --target-lo/--target-hi bounds match the original reading; widen to 0x80108000..0x8010A000 to surface the adjacent sprite-batcher pointers.

See also