ppsspp_diff_memory
Snapshot a PPSSPP memory range, then compare it after game actions to list changed addresses and bytes, helping locate dynamic variables.
Instructions
PURPOSE: Snapshot a memory range and diff it against current memory — the classic "what changed?" variable-locator.
USAGE: diff_memory(action="snapshot", start=..., end=...) → handle; act in game; diff_memory(action="compare", handle=...) → changed-byte list; action="drop"/"list" manage handles.
BEHAVIOR: READ-ONLY. Memory is never written — only the per-server snapshot registry mutates. Large ranges are read across multiple reads; per-snapshot cap 8 MiB; registry cap 4 with FIFO eviction. The registry is process-global: parallel sessions share one cap and FIFO order, so another session's snapshots can evict yours under load. compare requires the handle's exact range.
RETURNS: snapshot → {handle, start, size_bytes, checksum}; compare → {handle, start, size_bytes, changed_count, truncated, changes: [{address, old, new}]}; drop → {handle, dropped}; list → {handles: [...], count, max_snapshots}.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Range end (exclusive), same format — required for snapshot unless 'address'+'size' are given. | |
| size | No | Range length in bytes. Provided for naming consistency with read_memory/write_memory/scan, which all take 'size'. Use either address+size or start+end. | |
| start | No | Range start, hex ('0x08804000') or decimal — required for snapshot unless 'address'+'size' are given. | |
| action | Yes | Diff operation. Valid values: - 'snapshot': read [start, start+size) and store it under a new handle (registry cap 4, FIFO eviction). - 'compare': read the same range now and diff against the handle's snapshot; returns a changed-byte list (inline cap 256, truncated flag keeps the true count). - 'drop': release a handle. - 'list': live handles. | |
| handle | No | Snapshot handle — required for compare/drop. | |
| address | No | Range start, same format as 'start'. Provided for naming consistency with read_memory/write_memory/scan, which all take 'address'. Use either address+size or start+end. | |
| session_id | No | Active session ID; auto-resolved when exactly one session is active (required for snapshot/compare, ignored for drop/list). |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of live snapshots. | |
| start | No | Start address (hex). | |
| handle | No | Dropped handle. | |
| changes | No | First N changed bytes (address + old/new). | |
| dropped | No | True when the handle existed and was removed. | |
| handles | No | Live snapshot handles (oldest first). | |
| checksum | No | sha256 of the snapshot bytes (first 16 hex). | |
| truncated | No | True when changes exceed the inline cap (see changes list). | |
| size_bytes | No | Compared range size in bytes. | |
| changed_count | No | Total changed bytes. | |
| max_snapshots | No | Registry capacity (FIFO eviction). |