Skip to content

feat: add visual test harness for screenshotting running games#96

Open
SwiftEngineer wants to merge 1 commit into
Coding-Solo:mainfrom
SwiftEngineer:feat/visual-test-harness
Open

feat: add visual test harness for screenshotting running games#96
SwiftEngineer wants to merge 1 commit into
Coding-Solo:mainfrom
SwiftEngineer:feat/visual-test-harness

Conversation

@SwiftEngineer
Copy link
Copy Markdown

While working on a game, I found it annoying to have to take screenshots to show agents what I was seeing in the game. I asked Claude to cook this PR up as a simple solution. I've been using it for a while in my game and it seems to be working well, so I thought I'd open it as a PR here in case anyone else finds it useful.

The high-level idea of it is:

  • Adds a small GDScript autoload, which this server is capable of installing and uninstalling, which exposes a very basic loopback TCP endpoint.
  • The TCP endpoint can be used by the server to take screenshots of the game and share them with your agents.
  • In the future this TCP endpoint could be modified to allow agents to send inputs. I decided to stick with just screenshots though for now for the sake of keeping this PR small enough to be easily reviewed.

In case you're worried that this TCP server might end up getting shipped inside of someone's game, the autoload entry is written to override.cfg, not project.godot. Godot explicitly excludes override.cfg from exported projects. To be even more safe, I also directed Claude to make it so that the server is not started unless OS.is_debug_build() == true.

--- Note to maintainer:

I wrote this PR description, Opus 4.6 wrote literally everything else about this PR. I've given it a review, but I will be forthcoming and say that I am not super familiar with Godot or gdscript, so I apologize if I missed something.

Adds three MCP tools — install_test_harness, uninstall_test_harness,
and capture_screenshot — so agents can visually inspect what a Godot
project actually renders, not just whether its tests pass. Screenshots
are returned as MCP image content blocks so vision-capable clients
see the frame inline.

Mechanism: a small GDScript autoload, shipped by this server, runs
inside a debug Godot process and exposes a loopback TCP endpoint.
run_project picks a free port and passes it via `++ --mcp-port N`
(Godot's user-args separator); projects without the harness installed
simply ignore the extra argument. The Node side speaks a minimal
length-prefixed binary protocol over `net` — no new runtime deps.

Export safety — three independent guarantees that this cannot ship in
an exported game:

  1. The autoload entry is written to override.cfg, not project.godot.
     Godot explicitly excludes override.cfg from exported projects.
  2. mcp_harness.gd calls queue_free() and returns on the first frame
     if OS.is_debug_build() is false.
  3. The TCPServer binds 127.0.0.1 only, never 0.0.0.0.

No new dependencies: uses Node 18+ built-ins (net, fs.cpSync,
fs.rmSync). scripts/build.js copies the bundled addon into
build/scripts/addons/ alongside godot_operations.gd. README gains a
"Visual testing" section documenting the workflow and the export
safety story, and the Cline auto-approve list picks up the three new
tools.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant