Make the game you designed, with AI doing the building and you staying the director.
A workflow for Godot projects, new or already in development. You decide the design, the balance and the priorities. The AI builds, tests and keeps the records. Designed to work with any AI coding assistant that reads AGENTS.md. Built and tested on Claude Code; other assistants are untested. Everything lives in your game's own git repository.
This is one of three frameworks built on Director-Driven Development, a way of working with AI coding agents: you direct the design, agents build in small, fresh contexts, and the build verifies every change. The same loop runs all three; only the rules the check enforces change.
- Godot-Director: games in Godot 4 (this one)
- App-Director: small web, mobile and desktop apps
- SaaSAllTheThings: B2B SaaS on Azure
AI writes game code fast. Without structure, that speed goes wrong in familiar ways:
- The design drifts. The AI quietly decides a mechanic or a number you never agreed to. With Godot Director, design calls come to you as 2-4 options with a recommendation. Only your choice is written down, and anything undecided goes on an open-questions list instead of being guessed.
- "Done" means "it compiled". One check defines "works": the whole project loads and the tests pass. It runs before every commit that touches code, and in Claude Code also before the AI ends its turn.
- Rules end up inside UI screens. Game rules live in testable classes and screens only display them. The check fails when a screen rolls dice or writes game state.
- Context gets lost between sessions. A few plain files hold everything: the design document, a decision log, the task queue, and an architecture table. Each fact has one home, so any session picks up where the last one stopped.
You've read this far, so Godot Director may be what you're looking for. It's free and open source, and if it helps you make your game, a tip on Ko-fi or GitHub Sponsors helps me keep building it. I greatly appreciate your support.
Before you install, write your game design document in your own words. The template shows what to cover; fill in what you know and leave the rest blank. Then install Godot Director below: onboarding reads your document and asks only about what you left open.
Your game needs git (git init if it has none) and no uncommitted changes. You also need Godot 4.5 or newer, and bash (on Windows it comes with Git for Windows). gitleaks is optional and recommended: with it installed, the check and the pre-commit hook scan for secrets (winget install gitleaks, brew install gitleaks); without it they print a note and go on (a prototype, below, needs it: its commits skip the check, so the scan is their only gate).
Option 1: the skill. In your game's folder, run:
npx skills add Freakling/Godot-Director
That installs the skill for the assistant you choose in the prompt. In Claude Code it becomes a /godot-director command. The skill fetches the latest Godot Director release outside your game and runs onboarding.
Option 2: the Claude Code plugin. In Claude Code:
/plugin marketplace add Freakling/Godot-Director
/plugin install godot-director@godot-director
The plugin installs the latest release. Then open a new Claude Code session in your game's folder (or run /reload-plugins), and run /godot-director:godot-director.
Option 3: manual install. Put the latest release in your game's root folder, next to project.godot, as a folder named Godot-Director. The release's tag is v followed by its version number, and the Releases page shows the latest one. Either run git clone --branch <tag> --depth 1 https://github.com/Freakling/Godot-Director.git Godot-Director there, replacing <tag> with it, or download that release's source zip from the Releases page and rename the extracted folder. Then ask your assistant:
Read Godot-Director/ONBOARDING.md and follow it to install Godot Director into this project.
Either way, onboarding works out whether this is a new game, an existing game, a Godot Director 1.x project to migrate, or an upgrade. It then:
- installs the files and finds your Godot;
- interviews you (new game) or reads the existing game, or reads the Game Design Document you wrote yourself in
design/director-gdd.md(an alternative or an addition; it adds context for everything that follows); - agrees with you who owns what, and whether the game uses user stories;
- ends with one commit for you to approve.
Afterwards, restart Claude Code so the new commands load. Each new clone of the game later needs one command: bash tools/setup-clone.sh.
With another AI assistant: tell onboarding, and it installs the tool-neutral core only (--tools none); you can also keep the Claude adapter alongside. Your assistant reads AGENTS.md, which points it to .godot-director/rules.md and the procedures. The core is tool-neutral: rules, procedures, the check and the git hooks work the same everywhere. Fresh-context builds, the reviewer, model sizing and the hooks that block risky commands depend on your assistant supporting subagents and hooks.
- Skill: run
npx skills add Freakling/Godot-Directoragain to get the skill of the latest release, then ask for it (/godot-directorin Claude Code). - Plugin: run
/plugin marketplace update godot-directorand then/plugin update godot-director@godot-director. Start a new session in the game, and run/godot-director:godot-directoragain. - Manual: put the new Godot Director folder in the game, and ask for ONBOARDING.md again.
Only Godot Director's own files are replaced, and your edits to them are kept. When a new version also changes a file you edited, the new version is written next to it as <file>.gdir-new for you to merge. Review the result with git diff.
| Say | What happens |
|---|---|
"Do the next task" (/next-task) |
Builds the next ready item (high-severity bugs first), proves it with the check, updates the records, and asks you to approve the commit. |
| "Do the next 3 tasks", "Work through the queue", "Grab tasks until you're blocked" | The same, item after item, committing each without pausing, until one needs you. |
"Which open questions block development?" (/design questions) |
Ranks the open design questions by what they unblock, with options and a recommendation for each. |
"Let's brainstorm {topic}" (/design {topic}) |
A design session. Your decisions become GDD text, decision-log lines, user stories (if the game uses them) and task items. |
"Validate the user stories" (/design validate the stories) |
In a game that uses user stories: you confirm, correct or drop each story the recently built items served, and each one still unconfirmed. /next-task proposes it every 10 built items (tools/check.cfg › [stories] every); you can decline. Each playtest and function check also asks whether the stories behind what it covers are still right. |
"Prototype {idea}", "Let me try {change} quickly" (/prototype {name}, then /prototype harvest {name}) |
Tries a change fast, before it's built against the design: a new git worktree beside your game on a proto/{name} branch, where you open a second session that is outside the loop (no items, records, reviews or check on its commits; the guard and the secrets scan stay on, and nothing is pushed or merged: a pre-push hook refuses a proto/ branch). The game runs there: play it yourself, or let autoplay play it, and keep notes on what you tried and how it felt in its PROTOTYPE.md; with screens, /ui-design captures before and after let you compare. The harvest, back in your main session, is a design session on the prototype's diff and your notes: you decide what becomes GDD changes, decisions, user stories (if the game uses them) and items, which are built from main with the check and reviews, and the prototype's code is never merged. Then it offers to remove the worktree; deleting the branch is yours to run (git branch -D). A prototype needs gitleaks installed, since the secrets scan is the only gate on its commits. /prototype list shows the prototypes. |
"Research how other games handle {topic}", "What licence does this plugin use?" (/research {question}) |
A read-only researcher looks into one question in a fresh context and saves a dated note in design/research/: the conclusion, the options, the sources with a confidence, and a recommendation. It informs; you decide. A design session asks it for facts it doesn't have, and you can queue a research item (R1, R2, ...) for later. |
"Export the game", "Make a Web build" (/export) |
Exports every export preset headless with the Godot your clone already knows, after checking the export templates are installed, into the gitignored builds/ folder, and reports what it produced. Onboarding asks which platforms you ship to and where exports run (this machine, a build container, or a hosted service such as GitHub Actions); skip it and the GDD gets an open question, so /design Q{n} sets it up later. |
"Release the game", "Push a build to UAT", "Promote to production" (/release) |
Exports the presets, then runs the upload command you supplied for each preset to its UAT branch or channel (release.cfg names the commands and the CI secrets they read; Godot Director knows no store). It goes to production only when you ask, with the check passing. .godot-director/templates/release-workflow.yml is a GitHub Actions workflow that exports on every change, uploads to UAT from main, and runs production behind a protected Environment you approve. Onboarding asks for the commands and secret names, or you skip it and the GDD gets an open question. |
"Playtest this", "Run the smoke test", "I just played, check the logs" (/autoplay) |
The game plays itself through its real main scene, clicking and pressing keys as you would, and the assistant reads the play log into findings, each with a step, a screenshot and a command that replays it. After your own session it reviews your log the same way. |
"New playtest", "Process my playtest" (/playtest) |
Creates a report from the template, or turns a filled-in one into bugs, score trends and design proposals. |
"Capture the screens", "Redesign the shop screen", "Process my drawing", "Verify the hero room" (/ui-design) |
Renders each screen at each size with a numbered map of its elements and a layout lint (squeezed text, off-screen or unreachable controls, no default focus), and writes a starter drawing per screen. You draw over it in Excalidraw (free, no account) and save it in director/ui/; process reads exactly what you drew, asks about what it can't tell, and records the layout once in design/ui/<screen>.md; the build follows that spec, and verify captures the built screen, lists its deviations from the spec and writes a compare image of your drawing's screenshot beside the result. A catalog entry's overlays put a HUD an autoload draws into the shot. The lint can also run in the check (tools/ui_capture.cfg › [lint]: on for new games, off after an upgrade, per screen in enforce). Drawing is optional; capture and lint work without it. |
"Prepare a function check", "Process the function check" (/function-check) |
A checklist of what's been built since the last round and needs a human eye; you tick Works or Broken. |
"Check the docs are aligned" (/align) |
A consistency pass. Drift gets fixed; gaps and conflicts come to you. |
"Reset the design drift" (/drift-reset, later /drift-reset postmortem) |
For when a pillar has been built two ways. Maps how the game really works, puts each conflict to you as a design call, and plans the rebuild as tasks. Align often, reset when you have to. |
"Prune the task list" (/prune) |
Moves done items to TASKS-archive.md. |
you play, or have an idea
│
▼
design session ── options + a recommendation ── you decide ──► GDD + decisions.md + TASKS.md items (+ user stories)
│
▼
next task ── builds the next ready item ── tests ── bash tools/check.sh ──► commit (you approve)
│
▼
playtest (how it feels) · function check (does each built rule work?)
│
▼
bugs and design proposals ── you decide ── repeat
| Responsible for | |
|---|---|
| You | Design, balance, art direction, priorities; playing and playtesting; approving commits. You have the final say on everything. |
| The AI assistant | GDScript, scenes, .tres schemas, placeholder art, tests, running Godot and git, keeping the records true. |
your-game/
│ yours: never overwritten
├── AGENTS.md for every assistant: project facts, layout, architecture, ownership, project rules
├── CLAUDE.md "@AGENTS.md", for Claude Code
├── TASKS.md milestones and the queue (tasks, bugs and research)
├── design/gdd.md the game's current design, and Open Questions
├── design/director-gdd.md a GDD template for you to fill in, in your own words (optional); onboarding reads it first and never edits it
├── design/decisions.md why: one line per design decision
├── design/user-stories.md if the game uses user stories: whom it's for and why each feature is built, confirmed by you; each feature item names the ones it serves
├── design/research/ dated research notes, one per topic; the decision line links to its note
├── playtesting/TEMPLATE.md playtest template, one section per core loop
├── tools/check.cfg check settings: screen folders, folders to skip, whether the check plays smoke, the stories validation cadence
├── .gitleaks.toml gitleaks settings for the check and the hook: the built-in rules, and the .godot/ cache allowlisted
├── tools/ui_screens.gd the screen catalog: every screen, how to open it in a state, the overlays it shows
├── tools/ui_capture.cfg capture sizes and seed, lint thresholds, which screens the check lints, verify tolerance
├── tools/play_log.gd the PlayLog autoload: what the play log's header, snapshots and progress line say for this game
├── tools/autoplay_adapter.gd how autoplay starts a run, which actions are legal and how each is performed
├── tools/autoplay_scenarios.gd the scenarios autoplay plays: smoke, scripted ones and strategies
├── tools/autoplay_invariants.gd the game's own always-true checks, run after every autoplay step
├── playtesting/signatures.tsv the problems log review has seen, each with a stable signature (changes only when one is new)
├── tools/dev_menu.gd the DevMenu autoload, if you want one: how it is enabled and which systems it shows
├── design/ui/ one spec per screen (and a gitignored captures/ folder); README.md says how to draw
├── director/ui/ your screen drawings (you create it; the agent only reads it)
│
│ Godot Director's, tool-neutral: updated on upgrade
├── .godot-director/rules.md the workflow rules, loaded through AGENTS.md
├── .godot-director/tasks.md the TASKS.md item format, read when items are written
├── .godot-director/procedures/ next-task · build · design · prototype · research · export · release · ui-design · autoplay · playtest · function-check · align · drift-reset · prune · review
├── .godot-director/research-domain.md what the researcher adds for Godot: the docs and engine version, plugin and asset licences, export and store requirements
├── tools/check.sh, check.gd the check; tools/test_case.gd: base for tests in tests/
├── tools/ui_capture.sh, ui_*.gd screen capture, element map, layout lint, drawing reader, compare and verify
├── tools/play_log_base.gd the play log: a .log and a .jsonl per run in user://logs/play/, engine errors, scrubbing
├── tools/autoplay.sh, autoplay*.gd autoplay: plays the real game through the adapter, checks invariants, writes repros
├── tools/log_review.sh, .gd log review: a play log into review.md and findings.json, with signatures
├── tools/dev_menu_base.gd the dev menu: a tab per system with its actions and hidden values, and the play log's tail
├── tools/setup-clone.sh per clone: finds Godot, installs the pre-commit and pre-push hooks
├── tools/prototype.sh a prototype's git steps: its worktree, branch and notes; list, harvest, remove
├── tools/release.sh runs the upload commands release.cfg names, per export preset
├── tools/stories.sh whether the user stories are due for validation (says so when the game doesn't use them)
├── .godot-director/templates/ the release workflow, and the user stories file a game gets when it turns them on
├── .githooks/pre-commit runs the check before commits that touch code, scenes or data (not in a prototype), and scans every commit for secrets (with gitleaks; a prototype's commits need it)
├── .githooks/pre-push refuses to push a prototype's proto/ branch, or its commits under another name
├── playtesting/README.md how playtests and function checks work
│
│ Godot Director's, Claude Code adapter: updated on upgrade
├── .claude/skills/ /next-task and the rest: each points to its procedure
├── .claude/agents/ builder (builds each item in a fresh context) · reviewer and researcher (read-only)
├── .claude/hooks/ runs the check before a turn ends; blocks risky git commands
└── .claude/settings.json permissions, hooks, timeouts
Machine-local and gitignored: tools/godot_bin.local (the path to your Godot) and .claude/settings.local.json.
The full rules are in .godot-director/rules.md, and the assistant reads them every session.
- You decide design. The assistant offers options and a recommendation. It never picks balance numbers (new values are marked
## PLACEHOLDER), and never answers an open question itself. - Areas you own are never generated. Onboarding asks who owns art, audio, scenes, tunables and text. Human-owned areas get a documented placeholder policy instead of generated content.
director/is an optional protected workspace; the AI reads it for context but never creates, modifies or deletes anything inside it. - Each fact lives in one place, and is updated in the same change that makes it untrue.
- Rules live in systems, not screens. They sit in plain classes that tests can build directly. Saves are JSON in
user://, never Resources, which can run scripts when loaded. - Everything is logged. Every player action, turn step, view change and blocked progress button writes a line to the play log, a
.logfor you and a.jsonlfor tools per run, and tests assert on those lines. The log ships in every build, never leaves the machine, and leaves out the user name, the home path and the install id. - Every action is drivable. Every player action is offered to autoplay while it's legal, through a key, a pad button or a uniquely named control, so the game can be played without a person.
- User stories, if you want them. Onboarding asks once, and recommends neither: they tell the AI why each thing is built and keep it aligned with your design, and some developers prefer the GDD alone. With them on,
design/user-stories.mdholds one line per thing a player does and why ("As a player I ..., so ..."), under the GDD's pillars and systems, every feature item names the stories it serves, and you confirm them in design sessions, playtests, function checks and every 10 built items. With them off, nothing about them appears or asks. - A dev menu, if you want one. Onboarding asks, and recommends F12 in debug builds. A tab per system shows its
debug_*actions and the values only code can see (debug_inspect()), plus the play log's tail, so an assistant can look inside the game. You choose how it is enabled: in game (the key, debug builds), a setting (debug/dev_menu), a command-line flag (-- --dev-menu), or none. - Done means the check passes, and the work is committed only with your approval.
- Guarded git: in Claude Code, force-push,
reset --hard,--no-verifyand other work-destroying commands are blocked by a hook that checks the whole command line. It's a strong safety net, not a guarantee.
The orchestrator and the builder are deliberately separate contexts. Each optimises differently.
The orchestrator
- Small at the start. A session starts with about 10 KB of instructions (AGENTS.md and the rules). Each procedure, and the task format, loads only when it's used.
- Stays small across items. The orchestrator picks items, records decisions, updates TASKS.md, and approves commits. It never reads the files being changed. After it hands an item to the builder and the report comes back, its context holds only that ~20-line report, not the source files, test output, or check logs the builder went through.
- Nothing to hand off between sessions. TASKS.md, the commits, AGENTS.md and the GDD hold everything. Once an item is committed, a new session (or
/clearin Claude Code) loses nothing. An item interrupted mid-build gets a one-lineNote:in TASKS.md; the next session reads it and resumes. - Design sessions: clear after each commit. Once a design session's commit lands, the conversation has no value left: every decision is in the GDD and decisions.md.
/clearbefore the next topic so you're not carrying a week of brainstorming into an unrelated question. The procedure reminds you at the end of each session.
The builder
- Fresh context per item. In Claude Code, each build runs as a separate
buildersubagent that starts with an empty context. It reads only what the item needs: the files inTouches, the relevant Architecture rows in AGENTS.md, and the GDD sections named in the item. It builds, runs the check, and returns a structured ~20-line report. - Isolation prevents accumulation. Because the builder is isolated, the orchestrator never carries the file contents, check logs, or edit history from the build. A session that works through ten tasks stays about as lean as one that worked through one.
- The report is the only channel. The builder's report fields (
Files,Done when,Systems,API/saves,Found,For the human) give the orchestrator exactly what it needs to update the records and decide what's next; no more.
Model sizing (recommended on): each item size maps to its own build model in AGENTS.md › Project rules. Claude Code defaults: XS and S to Haiku, M to Sonnet, L and XL to Opus. A size without an entry uses the session model, and a failed build retries once on the next size's model. Onboarding writes the mapping; /refresh-model-sizing updates it, or tells you if your assistant can't choose a model per subagent.
The game plays itself, so an assistant can playtest a change before you do, and read what your own session did.
- How it works.
bash tools/autoplay.sh smokelaunches the real game through its main scene and plays a scenario through the game's adapter. Buttons are clicked and keys pressed through real input, as you would; a few actions call the systems directly for speed. After every step it checks that there's no engine error, no softlock, an action to take, a view that isn't freed, a focused control (under the view, or under the nodes the adapter'sfocus_roots()names, for a shell that keeps a view's UI elsewhere), no growing orphan nodes and no slow step. The same seed plays the same run. It writes the play log, screenshots with their element maps, and a repro for anything it finds, inplaytesting/autoplay/(gitignored). - What's whose. Godot Director owns the driver, the play log base and the review tool, and replaces them on upgrade. The game owns three seeds,
tools/autoplay_adapter.gd(how a run starts, which actions are legal, how each is performed),tools/autoplay_scenarios.gd(smoke is required) andtools/autoplay_invariants.gd, plustools/play_log.gdandplaytesting/signatures.tsv. Until the adapter is filled in, a run says what to wire and is skipped. - Running it.
/autoplayplays smoke, reviews the run and reports./autoplay <scenario>,--all,--replay <run folder>and--playerdo what they say. The check plays smoke headless whentools/check.cfg›[autoplay]hascheck_in_check=true, and a finding fails it whenenforcenames the scenario. New projects start with both on, and an upgrade starts with both off until the adapter is wired. - Reading a review.
bash tools/log_review.shwritesreview.mdandfindings.jsonnext to the log: a timeline in turns and views, the findings by signature (the same problem keeps itssig-xxxxxxxxacross runs), the coverage of views and actions, and a delta against the previous run of the scenario. "I just played, check the logs" reviews your newest session the same way (--player). An assistant that can't view images reads the element map beside each screenshot: every element's name, text, position and focus order.
bash tools/check.sh runs six steps:
- scans the working tree for secrets with gitleaks, when it's installed (credentials are listed as
file:linewith the values redacted;.gitleaks.tomlholds the settings, and the check prints a note instead when gitleaks isn't installed); - Godot's import pass;
- loads every script, scene and resource (views that only load when opened too), checks screen scripts for game rules, and runs
tests/**/test_*.gd; - scans Godot's output for errors;
- plays the smoke scenario headless, when
tools/check.cfg›[autoplay]turns it on; - runs
tools/check.local.sh, if the game has one.
It exits 0 on pass, 1 on fail, and 3 when it can't run, including when a Godot run hits its timeout (tools/check.cfg › [tests] timeout, 600 seconds by default): the report then names the test file it was in, so a slow suite never reads as a failing one. An installed gitleaks that is too old ([gitleaks] min-version, 8.18.0 by default) or that can't scan, such as 8.19.0, also exits 3. It remembers the last passing state, so hooks don't run it again when nothing has changed. Game-specific settings go in tools/check.cfg, and extra steps (for example an existing GUT suite) go in tools/check.local.sh.
- One test file.
bash tools/check.sh --only tests/<file>.gd(repeat--onlyfor more) runs just those tests, after the import pass when one is needed, under the check's time limit. It skips the rest of the check and records nothing for--if-changed, so a builder uses it while working and the full check still decides done. It is the supported way to run one test file: the Bash guard refuses a direct Godot run without a shorttimeout, and the refusal points here. - Parallel tests. The tests run in several headless Godot processes at once, one per CPU core by default (
[tests] jobs, or--jobs Nfor one run;--jobs 1runs them in one process). Each process takes a contiguous group of the sorted test files, in file order, with its own log in.godot/godot-director/, and the check merges them into one report. So a test must not depend on autoload oruser://state that another test file left behind: it sets up what it reads. Test files also run at the same time and share oneuser://and one.godot/, so two of them must not write the sameuser://file: use a unique name per test (or per file, in ano-splitfile). - Balanced and split runs (opt-in).
[tests] balance = truedeals the test files longest first by their times in the last run instead (files with no time yet go first), each to the process with the least time so far. With it on,[tests] split_over = <seconds>splits a file whose whole time is over that into shards of its test methods, each in its own process, its tests counted once; a file whose tests share state across methods keeps a line# gdir: no-splitamong its first ten lines and runs whole. Every run records the times in.godot/godot-director/test-times.tsv(each file's whole time, which sizes the split; a split run that finishes all its shards lowers it to their sum but never raises it, and the shard count and longest shard of its last run), so turning it on works at once;bash tools/check.sh --jobs 1re-measures every file whole, which is how a file that got slower gets a larger split. Turn it on once no test depends on another having run first, when a few files hold up the run; where heavy files then compete for the CPU it may not help, so compare the slowest-files summary before and after. - Slowest files. Each test file's time is in the logs, and every run ends with the ten slowest files and their share of the test time, so you know which tests to make faster.
- Parallel sessions. Give each building session its own git worktree (
git worktree add ../game-b, thenbash tools/setup-clone.shthere), so sessions don't share.godot/, the check's lock or each other's half-written files.
| Path | |
|---|---|
ONBOARDING.md |
what the assistant follows to install, migrate or upgrade |
install.sh |
copies the files deterministically, keeps your edits, writes a manifest (--tools claude|none) |
framework/ |
installed into each game: the tool-neutral core, plus .claude/ for Claude Code |
project/ |
seeds for the game's own files, copied only when missing |
skills/godot-director/ |
the installer skill, for npx skills add and the plugin |
.claude-plugin/ |
the Claude Code plugin (/godot-director:godot-director) |
examples/market-day/ |
a tiny game that uses the workflow: a worked example, and the self-test's fixture |
examples/scenarios.md |
prompts to try after changing the framework, to check that behaviour still holds |
selftest.sh |
tests the installer, the check and the hooks (bash selftest.sh [path to Godot]) |
CHANGELOG.md |
what changed, and the upgrade steps for games |
CLAUDE.md |
instructions for an assistant working on Godot Director itself |
Privacy: Godot Director runs on your machine and sends nothing anywhere; see PRIVACY.md.
MIT © 2026 Vikingur Saemundsson: see LICENSE. You may use, fork and change Godot Director, including in commercial games, as long as the copyright notice and the license stay with it. Installed games carry a copy in .godot-director/LICENSE.