feat(automation): drive the game by script from an [auto:ui] log
Summary
This lets a script play the game and check where it is, so features can be tested without someone at the pad. No linked issue.
RECOMP_AUTO_LOG=1 (recomp-runtime/ui_log.c) prints an [auto:ui] line when the game changes screen or moves a cursor. It never writes guest memory. It covers:
- the scene and the menu screen;
- the save select, and the game's list widgets as numbered lists with the game's own item text. List 0 holds the main, pool, hotel and Casino menus; list 2 holds the save prompt;
- the island place (map, shop, items, Collection, pool or hotel, rest, Casino), the part of the day and the map location;
- the shop's cursor and its Buy/Wrap prompts;
- the items and Collection screens' tabs and cursors;
- a new vacation's opening scene and character select;
- a conversation flag (
dialog open|closed).
Every line meant for scripts starts with [auto:<source>], so ^\[auto: picks them out.
tools/drive_game.py sends pad presses through the runner's existing --input-paused-analog-file. After each press it waits for the log line that shows the press landed, and presses again when the game ignored one. A session folder under private/ keeps the game running between commands.
- Steps:
press,wait,until,goto(map),select(list menu),rest,buyandshot. - Routes from launch:
route shop|map|pool|items|hotel [--vacation N], androute new [--vacation N] [--girl NAME], which starts a new vacation, skips the opening scene, picks the girl and gets through the welcome dialogs. - Saves: they are copied at start and put back on
stopif the run changed them. - Screenshots:
RECOMP_SCREENSHOT_TRIGGERsaves the next frame whenever a given file appears, so scripts need no window capture.
Addresses, the log's line grammar and how each address was found (RAM dumps diffed across screens and cursor positions, each checked against a screenshot) are in docs/ui-log.md. Usage, the game's day flow and its pitfalls are in docs/automation.md. The pitfalls include the pool menu hiding itself, an A on the hotel menu entering the Casino, and the welcome tour ending in the Accessory Shop.
Seven commits: the log and driver, the hotel's night, starting a new vacation, the CHANGELOG entry, then three fixes: waits look only after the newest press, the controller-mode preference is put back after a run, and start puts back the saves of a run that ended without stop.
Verification
Linux (CachyOS), on this branch rebased onto ab007e4:
-
python -m unittest discover -s tools -p "test_*.py"passes (1 skipped).test_drive_game.pyruns the driver against a fake game thread: lost presses, the shared mark,gotodirection, waking the pool menu,rest,buy,finish_dialogs, refusing a slot with a save, and restoring saves.
-
python tools/public_export.py verify --require-public-treepasses. -
Public runtime build and
ctest: 41/41 with GCC. (Host clang passed 39/39 on the earlier base3243911; not rerun.)ui_log_testcovers every line kind on synthetic memory.screenshot_testcovers the trigger file.
-
MSVC and llvm-mingw were not run locally; there is no Windows toolchain here.
- The same three commits before the rebase passed
public-cion the fork (custody, runtime-tests, runtime-tests-clang, runtime-tests-macos). public-cion this PR covers the rebased commits.
- The same three commits before the rebase passed
-
Full-program build from a user-owned disc, on the earlier base
3243911:- lifter
7adaf210a89814c5ca4444e4876fccb51b938878; - generation parity
exact-local-match; - executable SHA-256
053d44e885fa33c1d15d909a533f39dfbd976e97eeaf67e4fdef8438ea7e5c54.
- lifter
-
Observed in the game on the earlier base
3243911(not rerun since), each route from a fresh launch to its natural end:Route Ends at Time route shopSports Shop list, cursor line 16 s route itemsitems screen 18 s route hotelrests until night, through the gift dialogs, to the hotel menu 53 s route new --girl Tinaopening, character select, welcome, Accessory Shop 71 s - Earlier runs on the fork covered
buy(Buy and Wrap prompts) and the Collection and Casino screens. - Runs that wrote the save (night, new vacation) had it restored by
stop. The restored saves matched a snapshot taken before the runs.
- Earlier runs on the fork covered
Not verified: the tool's Windows process handling (taskkill, tasklist, process groups) was written but not run on Windows.
Contribution checklist
- The change follows
AGENTS.mdandCONTRIBUTING.md. - No XBE, generated game C, retail instruction bytes, extracted assets or
filenames, saves, BIOS data, private paths, or run evidence are included. - Third-party material and its license are identified, if applicable. (None.)
š¤ Generated with Claude Code