Chessistics/tools/automation
Samuel Bouchet 480c783bd6 Add bidirectional arrows and idle pulsation on piece trajectories
TrajectView now draws an arrow at each endpoint (since pieces oscillate
between start and end, both directions are relevant) and runs a looped
width/alpha tween that breathes between 0.3 and 0.75 over ~2.2s. The
pulse makes stationary relays visually distinct from static board art
without competing with active cargo/particle animations.
2026-04-17 22:31:56 +02:00
..
harness.py Add drag & drop to relocate placed pieces 2026-04-17 22:18:50 +02:00
README.md Add file-IPC automation harness for autonomous game testing 2026-04-16 22:34:56 +02:00
run_game.py Add file-IPC automation harness for autonomous game testing 2026-04-16 22:34:56 +02:00
smoke.py Add file-IPC automation harness for autonomous game testing 2026-04-16 22:34:56 +02:00
test_collision.py Add collision camera pan/zoom and toast notification 2026-04-17 22:21:36 +02:00
test_delete_key.py Add Delete/Backspace shortcut to remove the selected piece 2026-04-17 22:23:38 +02:00
test_quicksave.py Add QuickSave/QuickLoad with full state restore and visual rebuild 2026-04-17 22:10:06 +02:00
test_relocate.py Add drag & drop to relocate placed pieces 2026-04-17 22:18:50 +02:00
test_trajectory.py Add bidirectional arrows and idle pulsation on piece trajectories 2026-04-17 22:31:56 +02:00
test_undo.py Add Undo (Ctrl+Z) backed by the WorldSave checkpoint mechanism 2026-04-17 22:14:06 +02:00

Chessistics automation harness

Drive a running Chessistics build via file-based IPC, so an AI agent (or a scripted test) can take screenshots, inject inputs, and read game state without a human in the loop.

How it works

  • Launch Godot with --automation=<dir>. The game activates an AutomationHarness node that polls <dir>/inbox/ each frame.
  • Send commands as JSON files; the game writes results to <dir>/outbox/ and screenshots to <dir>/screens/.
  • A handshake file <dir>/ready.json is written on startup.

Without the flag, the harness is not instantiated — zero runtime overhead and zero behavior change for normal play.

Quick start

# From repo root
python tools/automation/smoke.py     # end-to-end smoke test
python tools/automation/run_game.py  # interactive REPL

Requirements:

  • Python 3.10+ (stdlib only)
  • Godot 4.6 mono build at C:\Apps\godot\Godot_v4.6.2-stable_mono_win64_console.exe (override with Harness(godot_exe=...) or edit the default in harness.py).
  • A compiled build: run dotnet build Chessistics.csproj first.

Python API

from tools.automation.harness import Harness

with Harness.launch() as h:
    h.load_mission("campaign_01", 0)
    state = h.state()                       # full snapshot as dict
    h.screenshot("before")                  # → .automation_runs/<ts>/screens/before.png
    h.place("Rook", (0, 0), (0, 3))         # place a piece
    h.step()                                # one simulation tick (auto-waits for animation)
    h.screenshot("after")
    h.set_speed(0.1); h.play()              # auto-run fast

Methods on Harness:

  • screenshot(name) -> Path
  • state() -> dict — full snapshot + animating flag
  • select(kind) — e.g. "Rook", "Knight"
  • place(kind, start, end, level=1) — returns {placed, pieceId, reason}
  • click_cell(col, row, button="left"|"right")
  • key(name)"Space" (play/pause), "Escape" (cancel)
  • play() / pause() / step() / wait_idle()
  • set_speed(interval_seconds) — auto-step interval
  • load_mission(campaign, missionIndex=0)
  • back_to_menu() / quit()

Every non-query command auto-waits for EventAnimator.IsAnimating == false before returning, so consecutive calls see a fully-settled state.

JSON protocol

Inbox: { "id": "<uuid>", "cmd": "...", "args": {...} } Outbox: { "id": "<uuid>", "ok": true, "result": {...} } or { "id": "<uuid>", "ok": false, "error": "..." }

See the cmd table in Scripts/Automation/CommandDispatcher.cs for the complete list.

Output locations

  • .automation_runs/<name>/ready.json — handshake
  • .automation_runs/<name>/inbox/, outbox/ — command queue
  • .automation_runs/<name>/screens/*.png — 1280x720 PNGs

.automation_runs/ is a good candidate for .gitignore (not added here automatically — add it manually if needed).

Troubleshooting

  • Godot exits before ready.json — build probably didn't compile, or the --path arg is wrong. Run dotnet build Chessistics.csproj and check stderr from the harness.
  • Screenshot is all black--headless was passed; the harness needs a real rendering context. Don't use --headless with automation.
  • Command times out — an animation may be stuck; check the Godot console log for errors.

Architecture notes

The harness sits behind a thin facade (AutomationFacade) that the dispatcher uses. It never reaches into engine internals — only calls existing public surfaces on GameSim, InputMapper, EventAnimator, ControlBar, PieceStockPanel. The black-box simulation separation stays intact.