ppsspp_replay
Records, executes, saves, and loads PPSSPP input replays (.ppr) to reproduce gameplay sequences. Use boot-aligned timing to inject recorded inputs accurately.
Instructions
PURPOSE: Aggregate PPSSPP replay subsystem — record input sequences, execute them, and save/load .ppr recordings.
USAGE: action + session_id; actions: begin/abort/flush/execute/status/time_get/time_set/save/load/wait_complete; execute needs version + base64_input; time_set needs value; save/load take a bare file name (always under output/replays/).
BEHAVIOR: STATE-CHANGE. Recording requires the CPU RUNNING (real input timing); screenshots are rejected while recording. Replay timelines use ABSOLUTE game-clock timestamps anchored at the RECORDING session's boot — a replay only injects correctly when a fresh boot's clock is aligned to them: execute/load ONLY loads the event table and returns t0_s / estimated_end_s + the boot-aligned sequence (reset -> wait_ready -> wait boot+estimated_end_s -> abort); it does NOT play by itself. executing/saving NEVER clear on their own — only abort clears them — so wait_complete times out on any un-aborted replay; completion = the timeline estimate + explicit abort. execute/load auto-abort a live executing/saving state first (R4). restore_rtc defaults to False: setting it rewinds the game-visible wall clock of the RUNNING session and pollutes every in-game timer (R2); when needed, set it before the boot-aligned reset.
RETURNS: {action, executing, saving, version, size, base64, base_rtc, data} — execute/load data carries t0_s, estimated_end_s, event_count and boot_aligned_sequence; fields depend on the action.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| value | No | Base RTC value in seconds (uint32). Required for action='time_set'; ignored for all other actions. | |
| action | Yes | Replay operation. Valid values: - 'begin': begin/resume recording. - 'abort': abort any recording or execution. - 'flush': flush recorded data (returns version + base64). - 'execute': execute a replay (requires version + base64_input). ONLY loads the event table — follow the boot-aligned sequence in the response (reset + wait + abort) or input never injects (U7 root cause). - 'status': query {executing, saving}. - 'time_get': get base RTC. - 'time_set': set base RTC (requires value). WARNING: rewinds the game-visible wall clock on the RUNNING session — pollutes every in-game timer (R2). - 'save': flush + time_get + write .ppr file (requires file_path: bare file name under output/replays/). - 'load': read .ppr + execute (requires file_path; same containment). Returns t0_s / estimated_end_s and the boot-aligned sequence. - 'wait_complete': poll replay.status until executing=False — NOTE: executing never clears on its own (only abort clears it), so this always times out on an un-aborted replay; kept for recording-completion checks and backwards compatibility. | |
| version | No | Replay format version (from a prior replay.flush). Required for action='execute'; ignored for all other actions. | |
| file_path | No | Bare .ppr file NAME (no directory parts) for action='save' / action='load'. The file is always placed under the server-managed directory .ppsspp-dfx/output/replays/ — absolute paths and path separators are rejected. Required for save / load; ignored for all other actions. | |
| session_id | Yes | Active session ID. | |
| timeout_ms | No | Total timeout in milliseconds for action='wait_complete' (default 10000 = 10s). Ignored for all other actions. | |
| interval_ms | No | Polling interval in milliseconds for action='wait_complete' (default 100ms). Ignored for all other actions. | |
| restore_rtc | No | Whether to restore base_rtc via replay.time_set before execute when action='load' (default False; R2). true sets the game-visible wall clock back to the recording moment — pollutes EVERY timer of the running session (attract timeouts, clocks, cooldowns) because game time = rtcBaseTime + elapsed. Only use for deterministic replays, and prefer setting it BEFORE the reset of the boot-aligned sequence so the game boots on the shifted base. Ignored for all other actions. | |
| base64_input | No | Base64-encoded replay data (from a prior replay.flush). Required for action='execute'; ignored for all other actions. | |
| session_note | No | Optional human-readable note embedded in the .ppr file when action='save'. Ignored for all other actions. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | Raw PPSSPP response dict (echoed for diagnostic / future field extraction). Empty dict when no additional fields. | |
| size | Yes | Recording size in bytes from `replay.flush`. 0 when the action does not return a size. | |
| action | Yes | Replay action executed: 'begin' / 'abort' / 'flush' / 'execute' / 'status' / 'time_get' / 'time_set' / 'save' / 'load' / 'wait_complete'. | |
| base64 | Yes | Base64-encoded recording payload from `replay.flush`, or the input payload passed to `replay.execute`. Empty string when the action does not carry a payload. | |
| saving | Yes | True if a replay recording is in progress. After `begin` → True; after `flush` or `abort` → False. | |
| version | Yes | Recording format version from `replay.flush` (currently 1). 0 when the action does not return a version. | |
| base_rtc | Yes | Base RTC timestamp (seconds) from `replay.time.get` / `replay.time.set`. 0 when the action does not return it. | |
| executing | Yes | True if a replay is currently executing. Drives `wait_complete`'s exit condition (polls until False). | |
| wait_iterations | Yes | Number of `replay.status` polls performed by `wait_complete` before exiting. 0 for non-wait actions. |