Hyperdot
Helps AI agents prove that a Godot game still works, in GDScript or C#.
Build, test, export and launch checks that answer in JSON an agent can read.
Runs on your Windows machine and, as a GitHub workflow, on Linux runners.
Self-test Godot Evals Licence: Apache-2.0 Godot 4.7.2 .NET 8 PowerShell 7.6+
Choose your path · Quick start · Features · Skills · Reference · Roadmap
An AI agent can write GDScript and C# and then say "done". Whether the game still builds, passes its tests, plays through its menus and starts after export is a different question, and an agent that answers it from memory is guessing.
Hyperdot makes it show evidence. One script detects the project, installs the right Godot, builds, runs every test
framework the project uses, plays UI flows, exports and launches the build, and answers in JSON an agent can read.
The agent is done when test -Json says ok: true, not when it says so. With the Claude Code plugin, a Stop hook pushes
toward that: once for each set of changes it stops Claude from ending its turn while Godot files changed since the last full
passing test run, and tells it to run the tests. If the tests ran and failed, or Claude stops again, it lets the turn end,
so Claude must report the result. It checks only that; it does not judge the design or the code.
What the agent reads back when a test fails:
{ "schema": "hyperdot/1", "command": "test", "ok": false,
"runnerResults": [
{ "runner": "gut", "ok": false, "total": 3, "passed": 2, "failed": 1,
"failures": [ { "name": "test/test_score.gd.test_x", "message": "[20] expected to equal [25]:",
"file": "test/test_score.gd", "line": 7 } ] } ] }
Choose your path
| I want... | Start here |
|---|---|
| Automated Godot testing, locally, with GUT, gdUnit4Net, GoDotTest or xUnit/NUnit/MSTest | Quick start, then Test and verify and docs/usage.md |
| Which command to run when, by moment and by phase | docs/workflow.md, or status for what is due in your game now |
| CI for my game: tests on every push, a results comment on pull requests, exports and releases | GitHub and docs/usage.md |
| To use Claude Code: skills, two subagents and the Stop hook loaded from one clone | Quick start step 3 below, then Skills and docs/help.md |
| The complete AI development workflow: plan, author through the editor, verify, measure, ship | Advanced, How the pieces fit, The plan and docs/plan.md |
Quick start
You need PowerShell 7.6+ and Git (Prerequisites); Godot is downloaded by the kit on the first run, and C# projects need the .NET 8 SDK.
Try it on the examples in this repository (a GDScript game with GUT, and a C# game with every framework):
git clone https://github.com/nick-vas/hyperdot
cd hyperdot
pwsh ci/godot/hyperdot.ps1 test -Project examples/gdscript -Json -Quiet
pwsh ci/godot/hyperdot.ps1 test -Project examples/csharp/game -Json -Quiet
Each prints one JSON result with "ok": true and a runnerResults entry per runner. detect -Project <game> shows what the kit
found and changes nothing; doctor -Project <game> checks the machine and the project and gives a fix for each problem.
Use it on your game.
- Clone the kit once, outside your game, and point it at the game with
-Project. None of the kit's own code goes into your game's repository (initadds only the files listed below) or its exported builds:git clone https://github.com/nick-vas/hyperdot C:\Tools\hyperdot $kit = 'C:\Tools\hyperdot\ci\godot\hyperdot.ps1' $game = 'C:\path\to\your\game' pwsh $kit doctor -Project $game pwsh $kit init -Agents -Mcp godot-mcp -Project $game # once: tests, CI, AGENTS.md, the plugin (skills, subagents, hooks), editor bridge pwsh $kit test -Json -Quiet -Project $game # every time: build + every test, one JSON resultci/godot/tools/Initialize-HyperdotGame.ps1 -Game $gamedoes these steps, finds a local Godot of your game's version before downloading anything, and makes a second working copy for a parallel Claude chat (docs/usage.md).initadds a starter test, a GitHub workflow,.gitignorelines, test exclusions in the export presets,AGENTS.md,CLAUDE.md,docs/kit-notes.md, the Claude Code plugin in.claude/settings.json(the skills, both subagents and the hooks come from it; nothing is copied into the game) and.mcp.json. It never overwrites a file and prints each change. The full list, and how to keep the kit in the game as a submodule instead: docs/usage.md. - If you only want the tests, you are done: use
-Mcpand the steps below only with an agent. - With Claude Code the skills, subagents and hooks come from the plugin that
init -Agentsenabled in the game's.claude/settings.json; no skill is copied into the game (-CopySkillsdoes that for a host without plugins). The plugin comes from this GitHub repository (-PluginSource github, the default; works in cloud sessions too;claude plugin update hyperdot@hyperdotfetches the newest commit onmain) or from your clone (-PluginSource local: agit pullthere updates every game). Skills are named/hyperdot:game,/hyperdot:kitand so on. Or by hand:/plugin marketplace add nick-vas/hyperdot, then/plugin install hyperdot@hyperdot. - If you chose
-Mcp, run the addon commandinitprints and enable the plugin in Godot. - Open Claude Code in the game's folder and start every session with
/game: it reads where the game stands (GDD, plan, tests, git), writesplan/STATUS.mdand ends with the three best next tasks to pick from. Then ask the agent to work; it readsAGENTS.mdand runstest -Jsonto check itself./kit(orhyperdot.ps1 help) lists every command, skill and subagent in one line each;/kit <name>shows one page (docs/help.md).
Prerequisites
- PowerShell 7.6+ (
winget install Microsoft.PowerShell) and Git. - Godot: the kit downloads the version your project needs into
~/.hyperdoton the first run. SetGODOT_BINto use your own. - For C# projects, the .NET 8 SDK.
Only for some commands
| Need | For |
|---|---|
| A display (Xvfb on Linux) | bench, shot, audio -Mix |
| ffmpeg | audio; also the localized-voice and trailer checks, which are skipped without it |
| Export templates | export; the kit downloads them with Godot |
| Node.js and a Playwright browser | export -Run of a Web preset; the kit installs the playwright package, npx playwright install chromium adds the browser |
Node.js 20+ (22+ for -McpDiagnostics) |
the default editor bridge, godot-mcp |
| uv | the godot-ai editor bridge and -McpAseprite |
doctor checks a machine and a project and says what is missing.
What Hyperdot adds on top of your test framework
GUT, gdUnit4Net, GoDotTest and xUnit, NUnit or MSTest (through dotnet test) are the runners Hyperdot runs, not
rivals: you keep writing your tests in them. They are test frameworks; the rows below are what Hyperdot puts around them.
| The test framework alone | With Hyperdot | |
|---|---|---|
| Write and run tests | yes | yes: it runs them for you |
| Find the project, the solution and the Godot version | you set them up | detect; the right Godot is downloaded on the first run |
| Every framework in one call | one at a time | test picks its runners from the project and returns one result |
| Failures an agent can read | the framework's own report | JSON with each failure's message, file and line; fails on zero tests and on engine ERROR: lines |
| Load every script, scene and resource | not what it is for | validate and smoke runners |
| Play the UI | not what it is for | flows runner: *.flow.json files in the real engine, headless |
| Export, then launch the build | not what it is for | export -Run (Web presets open in real browsers) |
| Misconfiguration that breaks CI or ships broken builds | not what it is for | doctor, a fix with each finding |
| CI with a comment on the pull request | you write the workflow | the reusable workflow godot.yml (GitHub) |
What it gives an agent
Core is test, build and export, with detect and doctor to see what the kit found. That is all most games need,
and it works with no editor bridge, no plan and no GitHub Project. Everything under Advanced is optional.
Understand the project
| Capability | Command | Result |
|---|---|---|
| Find the right tool | help [name], /kit [name] |
one line per command, skill and subagent, or the page of one |
| Know the project | detect -Json |
project, Godot version, solution, test runners, export presets |
| Find misconfiguration | doctor -Json |
checks with a fix each: missing solution_directory, tests in release builds, dead GUT files, add-ons, store art |
| See where the game is | status -Json, /game |
GDD features with their tagged tests, plan, runs, git activity and subagent handoffs; /game adds a short design and architecture review |
| Drive the live editor | init -Mcp godot-mcp |
registers an editor-bridge MCP server; -McpDiagnostics adds GDScript checks and the game console |
Test and verify
| Capability | Command | Result |
|---|---|---|
| Test first | test -Json -Quiet [-Runners x -Filter y] |
per-runner pass/fail with the failure's message, file, line; fails on zero tests and on any engine ERROR:; Godot's output stays in a log file |
| Play the UI | flows runner |
*.flow.json files: press buttons, send input, wait, assert on node properties, headless in the real engine |
| Catch what tests miss | validate and smoke runners |
loads every script, scene and resource; plays the main scene |
| Keep the structure sound | architecture runner, godot-architect subagent |
warns on fragile node paths, per-frame lookups, events never unsubscribed and more; design reviews recorded in docs/decisions/ |
| Build errors as data | build -Json |
diagnostics[] with file, line and C# error code |
| Coverage floor | -MinCoverage 60 |
merged report, fails below the floor |
| Drive the game | -GameArgs '--autoplay','--seed=3' |
your game's own flags, passed to smoke runs, export -Run, bench and shot |
| Keep "done" honest | the plugin's Stop hook | once for each set of changes, stops Claude from ending its turn while Godot files changed since the last full passing test run (no -Filter, a real test framework), and tells it to run the tests; if the tests ran and failed, or Claude stops again, the turn ends and Claude must report the result. It only checks that the tests passed after the last edit: it is not a design or code review |
Ship
| Capability | Command | Result |
|---|---|---|
| Have sounds on day one | sfx -Sound jump,coin,hit -Count 3 |
placeholder WAVs from a seed (bfxr2's synth) and .bfxr files bfxr2 opens |
| Credit everyone | credits |
CREDITS.md, credits.json and THIRD-PARTY-NOTICES.txt from assets.json; fails when a credit or notice is missing |
| Ship | export -Preset X -Run |
exported and launched; Web presets open in real browsers (-Browser chromium,firefox). The workflow's release input zips the exports into a GitHub Release |
test picks its runners from the project: validate and architecture always; dotnet, godottest, gut, flows and
smoke when their tests or a main scene exist; l10n when there are translations. The optional runners switch on when their
file is in the project folder: juice.json, playthrough.json, data.json, textsize.json, layout.json, placement.json. -Runners picks
them by hand. Every parameter: docs/reference.md.
Frameworks: GUT, gdUnit4Net, GoDotTest, xUnit/NUnit/MSTest via dotnet test, and UI flows. Verified on Godot 4.7.2 and .NET 8.
Advanced
Optional, and none of it is needed to run test, build or export: checks of the game itself, measurements, the plan and
its GitHub Project mirror (experimental), the editor bridge, the skills, the two subagents and the Stop hook, and the
benchmark and evals that measure the kit. The sections after the tables are
How the pieces fit, Skills and The plan.
Check the game itself
| Capability | Command | Result |
|---|---|---|
| Check game data | data runner, data.json |
ids, types, ranges and references in the game's JSON and CSV tables; soft-locks in levels written as data, currencies without a sink, lines missing a translation |
| Check translations | l10n runner |
duplicate, untranslated, missing and too long keys, translation remaps, missing glyphs |
| Read on small screens | textsize runner, textsize.json |
text and subtitle sizes at 1280x800 (Steam Deck) and other resolutions |
| Fit every screen | layout runner, layout.json |
phones, a tablet and an ultrawide: controls off screen, under a notch or too small to touch fail |
| Check placed objects | placement runner, placement.json |
every level's AI points, torches, zip lines and landmarks against limits read from the gameplay code's constants |
| Feel the game | juice runner, juice.json |
every gameplay event must get its feedback (flash, sound, shake) within 100 ms |
| Finish the game | playthrough runner, playthrough.json |
the game's bot plays at fixed game time and must log every milestone, the ending last |
Measure
| Capability | Command | Result |
|---|---|---|
| Measure frame pacing | bench -Scene X -BudgetMs 16.7 |
1% and 0.1% lows, p50/p99/max, a frame-time histogram, a hitch log, draw calls, load time, GC; -MaxDrawCalls and -MaxLoadMs budgets |
| Check for the Steam Deck | deck -Scene X,Y |
text size, layout, a screenshot and a 30 fps budget at 1280x800, one verdict |
| Validate the GPU calls | shot -GpuValidation (also bench, export -Run) |
Vulkan's validation layer on; fails on its errors, each with its VUID |
| See the screens | shot -Scene X,Y -Resolution 1920x1080 [-Baseline before] |
real PNG frames; with a baseline, the share changed and a diff image; -Locale for translations |
| Hear the mix | audio [-Mix] |
each sound file's loudness and true peak by category; with -Mix, the game's own mix against -24 LUFS and -1 dBTP |
| Hold up online | soak -Clients 8 -Seconds 600 -MaxGrowthMbPerHour 50 |
one server and headless clients: crashes, engine errors, memory growth, a clean stop on SIGTERM |
| Read the run history | telemetry [test] |
per command: runs, pass rate, mean, median and p95 duration, the trend; for test the slowest runners, failure hot spots, flaky tests and recurring errors, from .godot/hyperdot-history.jsonl |
| Read a playtest | playtest -Sessions playtests/sessions |
per level: time, deaths, stalls, items found, and PNG heat maps from testers' telemetry |
Plan
| Capability | Command | Result |
|---|---|---|
| Plan A to Z | plan -Json |
current phase, open gates, warnings |
| Track tasks | plan -Do add|move|remove, plan -Do sync |
tasks with a work-in-progress limit; optional GitHub Project mirror (experimental) |
Improve the agent and the kit
| Capability | Command | Result |
|---|---|---|
| Improve the kit | /retro, /kit-review, evals/, docs/kit-notes.md |
lessons with evidence, and the game's one-line notes each time the kit got in the way, become kit pull requests you approve, each measured with and without the plugin; /kit-review files its findings as issues in the kit's repository |
| Measure agent cost | benchmark/Invoke-TokenBenchmark.ps1 |
tokens, cost and time per task, as medians over repeated runs |
How the pieces fit
plan -Json what phase am I in, what is next
|
editor MCP author and inspect: scenes, nodes, running game, live state (needs the editor)
|
hyperdot.ps1 -Json verify: build, test, flows, export, launch (headless, CI-safe)
bench / shot measure frame pacing, look at screens (with a display)
audio [-Mix] loudness of the sound files and of the game's own mix (ffmpeg; -Mix needs a display)
|
plan -Do move/done record progress; the GitHub Project mirrors the board
The editor is what you see; the files on disk are what CI and the export see. So the agent authors through the bridge, saves, and
is done only when test -Json says ok: true. Neither editor MCP server builds C#, which is why the verification gate is a
separate, headless tool.
Skills
53 skills in .agents/skills/. Each SKILL.md description says when to use it.
- Test and verify:
godot-test-loop,verify-before-done,ui-flows,godot-diagnose,godot-pitfalls,automation-hooks,godot-editor-bridge,debug-tools - Design and plan:
game-plan,game-design,game-playtest,progression,narrative - Code and systems:
patterns,math,algorithms,procgen,game-ai,game-data,saves,input,xr,determinism,godot-addons,llm - Look, sound and feel:
game-juice,camera,animation,godot-shaders-vfx,asset-pipeline,game-audio,ui-accessibility,typography,localization,performance - Online:
multiplayer,servers,anti-cheat,game-telemetry,modding - Ship:
godot-export-release,release-readiness,mobile-web,steam,store-page,legal,console-cert - Run by hand:
game(where the game stands, what next),kit(every command, skill and subagent, one line each),look(style guide and screenshot critique),retro,kit-review,weekly-review
The godot-verifier subagent runs screenshots, benchmarks and export launches and returns a short verdict, so their logs and
images stay out of the main conversation. The godot-architect subagent compares designs for a new system before code is
written, records the decision in docs/decisions/ for you to accept, and keeps docs/ARCHITECTURE.md, the code's shape on
one page (autoloads, scene tree, signals, authored and runtime data, save version, minimum spec, open questions).
The skills are checked like code: ci/godot/tools/Test-Skills.ps1 enforces structure and a 16 KB budget, and verifies that
every command, flag, error code and package version a skill quotes exists. See docs/skills-quality.md.
The plan
Seven phases, each with gates: concept, prototype, vertical slice, production, alpha and beta, launch, post-launch.
| Gate type | Example | Who closes it |
|---|---|---|
| Automatic | a test runner is detected, an export preset exists, docs/GDD.md exists |
the project, by being true |
| Manual | a stranger played the prototype for 15 minutes; the PROCEED/PIVOT/KILL verdict | you, with plan -Do done -Id <gate> |
A phase past its timebox warns you to cut scope, never testing. Tasks live in plan/plan.json and move through
Backlog, Design, To Do, Doing, Verify and Done; move refuses to put a task in Doing past the work-in-progress limit.
plan -Do sync -Board @me makes a private GitHub Project for the game and mirrors the tasks to it (experimental: tested against
a stand-in gh only; needs the GitHub CLI signed in with the project scope). Where the plan comes
from, and the project rules: docs/plan.md.
GitHub
on: [push, pull_request]
jobs:
godot:
permissions: { contents: read, pull-requests: write }
uses: nick-vas/hyperdot/.github/workflows/godot.yml@v1
Tests on every push, a results comment on pull requests, optional coverage, exports and tagged releases. @v1 is a
moving tag that follows the kit's releases, so a kit change reaches a game only when a release moves the tag, and a game
moves up on purpose
(docs/usage.md). In this repository, a weekly canary tries new Godot, test-framework and GUT
releases on both examples and opens a pull request for those that pass. Free on public repositories; Linux runners are the
cheapest on private ones. More: docs/usage.md and docs/reference.md.
Status
What has been run, and what has not.
| Verified | Both examples (C# with every framework, GDScript with GUT) pass on Godot 4.7.2, locally and in GitHub Actions on Linux and Windows; -Json output for each command; init file handling; the self-tests in tests/; bench and shot under a virtual display (software OpenGL) |
| Exports | Windows, Linux and Android builds; Web builds run in Chromium, Edge and Firefox through export -Run (the self-test) (docs/mobile-web.md). Not run: macOS and iOS exports, an Android build on a phone |
| Tested against a stand-in only | GitHub Project sync; the live test (Test-ProjectSync.ps1 -Live) waits for a repository token with the project scope |
| Not run | The editor MCP servers themselves (they need the editor); bench and shot on a real GPU and on Windows |
| Known | Godot 4.7.2 occasionally aborts during import on some machines. The kit retries the import up to twice and reports importRetried; the cause is not found |
| Evals | With and without the plugin (docs/research.md): lost-in-level 1.00 against 0.00 (runs 4 and 5; 0.33 against 0.00 in run 6), review-publishing-deal 1.00 against 0.78 (run 6, 3 runs per arm). The cases that run commands measured a broken sandbox until run 7, where explain-failure scored 1.00 in both arms (1 run per arm) |
FAQ
Do I need GitHub?
No. Everything runs locally; the workflow is the same script on a Linux runner.
GDScript or C#?
Both. GDScript projects use GUT and need no .NET; C# projects can use all frameworks.
Which test framework should I pick?
godot-test-loop has the table.
Why does it fail when Godot exited 0?
Godot exits 0 after printing script errors, so the kit scans the log and fails.
Do I need the editor MCP server, or a GitHub Project?
No. The CLI, flows, plan and skills work without them. See docs/mcp.md and docs/plan.md.
Does it edit my files?
It never changes your scripts or scenes. These commands write into the project:
init: the additions above (it never overwrites a file;.mcp.jsonis backed up first);plan:plan/plan.jsonandplan/PLAN.md;test,buildand the other commands that build: GUT intoaddons/gutwhen the project has GUT tests and no GUT of its own;sfx: WAV and.bfxrfiles insounds/sfxand, when the project has anassets.json, an entry in it;credits:CREDITS.md,credits.jsonandTHIRD-PARTY-NOTICES.txt.
Results, logs and exports go to folders in the current directory (test-results, build, screenshots...), and the run
history to the project's .godot/ folder. Run detect or
doctor first to see before anything is written.
Can I call it from a script?
Yes: run it as a process (pwsh -NoProfile -File ci/godot/hyperdot.ps1 test -Json) and read stdout.
Logs go to stderr. See docs/json.md.
Documentation
Also as a website: nick-vas.github.io/hyperdot, the repository's default github.io address, built from these files on every change (docs/site.md).
Using the kit
- docs/usage.md: usage scenarios, from adding the kit to a game to several games in one repository
- docs/reference.md: parameters, config files, workflow inputs and secrets, cost
- docs/json.md: the
-Jsoncontract and error codes - docs/coverage.md: which self-test covers each command, error code, kit file, tool, skill, subagent and workflow job, and the gaps
- docs/ci.md: what the kit's own CI runs when, what it costs, and which tests ever caught anything
- docs/ci-cache.md: a design for a CI cache keyed by the inputs of a job: stage 0 (hashes and markers, nothing skipped) is built; the rest awaits decisions
- docs/godot-pipelines.md: test frameworks, versions, release-safe packaging
- docs/self-hosted-runners.md: the workflow on your own machines
- docs/plan.md: the A-to-Z plan, tasks and GitHub Project sync
- docs/mcp.md: editor-bridge MCP servers and how they fit
- docs/roadmap.md: the plan to 0.1.0 and 1.0, decisions and the open to-do list
- docs/retro.md: a look back at the 0.1.0 effort: what went well, what cost time, numbers, lessons
Making the game
- docs/art.md: textures, pixel art, Blender to glTF, shaders, particles, animation
- docs/audio.md: buses, adaptive music, 3D sound, ducking, loudness targets
- docs/wcag-ui.md: WCAG 2.2 read as rules for game menus and UI
- docs/input.md: rebinding, controllers, button prompts, Steam Input
- docs/xr.md: OpenXR in Godot: the player's body, comfort, hands, throwing; what ran without a headset
- docs/localization.md: translations, plurals, fonts, the
l10nrunner - docs/data.md: game data as Resources, JSON and CSV, the
datarunner - docs/saves.md: save files that survive crashes, new versions and cloud conflicts
- docs/algorithms.md: textbook algorithms measured against Godot's built-ins
- docs/game-ai.md: state machines, behaviour trees, utility, steering, navigation
- docs/determinism.md: what .NET and Godot repeat, for replays and rollback
- docs/multiplayer.md: netcode, dedicated servers and
soak - docs/anti-cheat.md: server authority, trusted scores, client anti-cheat
- docs/telemetry.md: crash reports and analytics with consent
- docs/modding.md: PCK and ZIP mods, C# mods, Steam Workshop, mod.io
- docs/debug-tools.md: cheats, consoles and overlays that stay out of release builds
- docs/addons.md: popular add-ons and GDExtensions, and C# access to them
- docs/dialogue-tools.md: Dialogue Manager, Yarn Spinner, godot-ink, Dialogic and inkgd compared from their repositories
- docs/awesome-lists.md: what the kit took from awesome-godot and the awesome project, and what it left
Shipping
- docs/profiling-and-builds.md: C# profiling, GC, versions, signing, store uploads
- docs/mobile-web.md: Android and Web exports, touch, safe areas
- docs/steam.md: Steamworks bindings, Steam Deck, Cloud, achievements
- docs/console-cert.md: Xbox, PlayStation, Switch and Steam Deck certification
- docs/store-and-legal.md: store pages, ratings, privacy, licences and credits
- docs/publisher-contracts.md: two public publishing agreements, clause by clause
Research
- docs/research.md: output sizes, evals and the studies behind the plugin
- docs/token-benchmark.md: the token benchmark and how to read it
- docs/skills-quality.md: how the skills are checked, compared with other skill sets
- docs/case-study-breakout-roguelike.md: lessons from a real Godot 4.7 C# game
- docs/studio-lessons.md: what studios say worked and failed
- docs/valve.md: how Valve makes games, from its own public material
- docs/gdc/README.md: GDC talks and what the kit took from each
- docs/googleforgames.md: Google for Games' open source and what the kit took
This repository: AGENTS.md (working on it), docs/powershell.md (writing PowerShell here, with sources), CONTRIBUTING.md, SECURITY.md, CHANGELOG.md.
Licence
Hyperdot is licensed under the Apache License 2.0. Copies and modified versions must keep the NOTICE
file, which credits Hyperdot and its author. The files Hyperdot copies into a game (ci/godot/templates/ and the starter
tests init writes) are under MIT-0: a game owes nothing for them. Third-party parts keep
their own licences, listed in NOTICE.
Innovating without patents Patent-free
The two banners above link to the End Software Patents campaign and are loaded from the campaign's host.
Hyperdot is not affiliated with or endorsed by the Godot Foundation. Godot and the Godot logo are trademarks of the Godot Foundation.