1@README.md 2 3- `run_frame` loops `tick()` until the core reports `FrameRendered`. One call 4 is one video frame, never one CPU step; callers count frames with it. 5- Player-one input is `inputs.p1.set_field(button, pressed)`. The method is 6 generated by upstream's `define_controller_inputs!` macro, so it does not 7 appear in a grep for `fn set_`. 8- `wram()` and `wram_mut()` depend on two patches this repo carries on the 9 vendored core (`third-party/rust/jgenesis`, commits "jgenesis: expose work 10 RAM from snes-core" and "jgenesis: let a host write work RAM"). Upstream 11 keeps `Memory` private. Re-apply them after any subtree pull. 12- Index work RAM by offset from `$7E0000`. The RAM map in `../../research/` 13 writes addresses as `$7Exxxx`; subtract `0x7E0000`. 14- The core is deterministic: same ROM, same inputs, same frame count gives a 15 byte-identical picture, optimised or not (checked 2026-09-20 at 1500 16 frames). A test that compares frames is therefore sound. 17- **`snapshot` and `snapshot_fixed` are different formats on purpose.** Every 18 state on disk (`resume`, `home`, the MCP tools' named states) is 19 `snapshot`; only `packages/replay`'s keyframes are `snapshot_fixed`. 20 Switching either one breaks every file already written in it.