ppsspp_scan
Scan PPSSPP emulator memory for byte patterns, tracked values with narrowing sessions, or charset-aware strings to locate game data and addresses.
Instructions
PURPOSE: Three-mode memory scanner — byte-pattern search, Cheat-Engine-style value scan with narrowing sessions, and charset-aware string harvesting.
USAGE: mode='pattern' + pattern + start_addr/end_addr (migrated from read_memory scan); mode='value' + phase='initial'/value/width → handle, then phase='narrow'/op/value to converge, 'list'/'drop' to manage; mode='strings' + charset + start_addr/end_addr → [{address, text}]. background=true submits a detached job instead (recommended for full-band scans) and returns {action:'submitted', batch_id, ...} — poll ppsspp_batch_status(batch_id=...).
BEHAVIOR: READ-ONLY. Large ranges are read across multiple reads; unreadable regions are skipped per-chunk (one WS round-trip each), but CONSECUTIVE read timeouts (10 s each, >5 in a row) abort the scan — a wedged PPSSPP fails the scan cleanly instead of pinning the session lock. pattern/strings ranges over 2 MiB are AUTO-BACKGROUNDED (returns {action:'submitted', batch_id, ...} even with background=false) — measured: 24 MB @ 4 KiB chunks takes 53-96 s depending on PPSSPP build, always past the ~30s client timeout, while @ 64 KiB chunks it is 3.4-40 s (build-dependent). Value sessions live in a bounded per-server registry (cap 4, FIFO), are bound to the creating session, and the initial-scan cap is 8 MiB foreground / 32 MiB background. Background scans carry a 600 s wall-clock budget; exceeding it fails the job and releases the session. The registry is process-global: parallel sessions share one cap and FIFO order, so another session's scans can evict your handle under load.
ROUTING: what-changed-between-two-points -> ppsspp_diff_memory (snapshots); who-accesses-this-address -> ppsspp_breakpoint(action='trace'); value candidates with known addresses -> read_memory directly.
RETURNS: pattern → {action, address, value: [matches], size}; value initial → {scan_handle, width, candidates, passes}; value narrow → {scan_handle, candidates, passes}; value list → {scan_handle, addresses: [...]}; value drop → {scan_handle, dropped}; strings → {charset, count, strings: [{address, text}]}; background submission (explicit background=true OR pattern/strings range > 2 MiB) → {action: 'submitted', batch_id, session_id, estimated_s}.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| op | No | Comparison for value scans (initial + narrow; default eq). | eq |
| mode | Yes | Scan mode: - 'pattern': byte-pattern search (hex/ascii) over a range — migrated from read_memory(action=scan). - 'value': Cheat-Engine-style value scan with narrowing sessions (phase: initial → narrow → list → drop; width u8/u16/u32, op eq/ne/lt/gt). - 'strings': charset-aware string harvesting (charset shift_jis/utf8/ascii, min_len, quality filter) — returns [{address, text}]. | |
| phase | No | Value-scan phase (value mode): 'initial' scans the range for `value`; 'narrow' re-reads candidates and filters by `op`+`value` (requires explicit session_id; auto-resolve not supported for this phase); 'list' returns current candidates; 'drop' releases the session. | |
| value | No | Value to scan/narrow for (value mode). | |
| width | No | Value width (value mode; default u16). | u16 |
| charset | No | String charset (strings mode; default shift_jis). | shift_jis |
| min_len | No | Minimum string length (strings mode; default 6). | |
| pattern | No | Pattern to scan for (pattern mode). Interpreted per pattern_type: 'hex' (default, e.g. 'AABBCCDD') or 'ascii'. | |
| quality | No | CJK-ratio quality floor for shift_jis (strings mode; 0..1, default 0.2; 0 disables). Random bytes can chance-decode to kana — the filter keeps signal. ascii/utf8 have no quality filter — expect noise in code regions. | |
| end_addr | No | Range end, exclusive, hex string (same format as `address`). | |
| background | No | Run as a detached background job: returns a batch_id immediately; poll ppsspp_batch_status(batch_id=...), cancel via ppsspp_batch_cancel. Value initial cap lifts 8 MiB → 32 MiB in background mode. NOTE: pattern/strings ranges over 2 MiB are auto-backgrounded even when this is false — a foreground scan that outlives the ~30s client timeout is the classic 'frozen session' trap. | |
| chunk_size | No | Bytes per read request during chunked scans (default 65536 — measured ~6x faster end-to-end than the old 4096 default; clamped to [64, 65536]). | |
| session_id | No | Active session ID; auto-resolved when exactly one session is active. Required for the pattern / value initial / strings phases, which start a new scan. The narrow / list / drop phases only re-read addresses already recorded by an earlier phase, so they do not need it passed -- but it must still resolve to the same session. | |
| start_addr | No | Range start, inclusive, hex string (same format as `address`). | |
| max_results | No | Maximum number of matches (pattern mode, default 100). | |
| scan_handle | No | Value-scan session handle (narrow/list/drop phases). | |
| pattern_type | No | How to interpret `pattern` (pattern mode). 'hex' (default) or 'ascii'. | hex |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| hint | No | ||
| mode | No | Scan mode: pattern / value / strings. | |
| size | No | Match count (pattern mode). | |
| count | No | Hit count (pattern & strings modes; matches the value/strings list in this response). | |
| value | No | Matches (pattern mode). | |
| width | No | Value width (u8/u16/u32). | |
| action | No | ||
| passes | No | Completed passes (value narrow). | |
| address | No | Scan start (pattern mode). | |
| charset | No | Charset used (strings mode). | |
| dropped | No | True when the session was dropped. | |
| strings | No | Harvested strings (strings mode). | |
| batch_id | No | ||
| addresses | No | Candidate addresses (value list). | |
| truncated | No | True when the strings hit cap was reached and remaining matches were dropped (narrow the range or raise min_len). | |
| candidates | No | Candidate count (value initial/narrow). | |
| session_id | No | ||
| estimated_s | No | ||
| scan_handle | No | Value-scan session handle. |