feat(automation): drive the game by script from an [auto:ui] log

Merged
G-
3d ago
+2230-4

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, buy and shot.
  • Routes from launch: route shop|map|pool|items|hotel [--vacation N], and route 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 stop if the run changed them.
  • Screenshots: RECOMP_SCREENSHOT_TRIGGER saves 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.py runs the driver against a fake game thread: lost presses, the shared mark, goto direction, 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-tree passes.

  • Public runtime build and ctest: 41/41 with GCC. (Host clang passed 39/39 on the earlier base 3243911; not rerun.)

    • ui_log_test covers every line kind on synthetic memory.
    • screenshot_test covers 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-ci on the fork (custody, runtime-tests, runtime-tests-clang, runtime-tests-macos).
    • public-ci on this PR covers the rebased commits.
  • Full-program build from a user-owned disc, on the earlier base 3243911:

    • lifter 7adaf210a89814c5ca4444e4876fccb51b938878;
    • generation parity exact-local-match;
    • executable SHA-256 053d44e885fa33c1d15d909a533f39dfbd976e97eeaf67e4fdef8438ea7e5c54.
  • Observed in the game on the earlier base 3243911 (not rerun since), each route from a fresh launch to its natural end:

    RouteEnds atTime
    route shopSports Shop list, cursor line16 s
    route itemsitems screen18 s
    route hotelrests until night, through the gift dialogs, to the hotel menu53 s
    route new --girl Tinaopening, character select, welcome, Accessory Shop71 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.

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.md and CONTRIBUTING.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