From godot-ai-builder
Internal development skill for working on the AI Game Builder plugin itself. NOT for game generation — this is for modifying the builder's skills, MCP server, Godot plugin, hooks, docs, and tooling. Load this when continuing builder development. Triggers on: "improve the builder", "add a new skill", "fix the MCP server", "update the plugin", or any request about developing the AI Game Builder itself.
npx claudepluginhub hubdev-ai/godot-ai-builderThis skill uses the workspace's default tool permissions.
This skill is for **developing the builder itself**, not for generating games.
Guides developers on finding, invoking, and mandating GodotPrompter skills across Claude Code, Copilot CLI, Gemini CLI, and Cursor for Godot 4.x GDScript/C# projects.
Provides persistent godot-mcp and AI Bridge workflows for Godot 4.x projects, handling .tscn/.gd/.gdshader/.tres files and live editor tasks like scene inspection, node edits, refresh/run/test loops, runtime diagnostics, hybrid validation.
Provides specialized guidance for Godot Engine projects: .gd, .tscn, .tres file formats, component-based patterns, signals, resources, debugging, validation tools, templates, and CLI workflows.
Share bugs, ideas, or general feedback.
This skill is for developing the builder itself, not for generating games. Use it when modifying skills, the MCP server, the Godot editor plugin, hooks, or docs.
User prompt → Claude Code + plugin (skills + MCP + hooks)
│ │
Writes .gd/.tscn MCP Server (Node.js)
directly to disk │
│ HTTP on port 6100
│ │
Godot auto-reloads Godot Editor Plugin (GDScript)
(bridge + dock + errors + scanner)
Three layers:
.mcp.json, .claude-plugin/mcp-server/) bridging Claude ↔ Godot via stdio (MCP protocol) + HTTP (to Godot)godot-plugin/) running inside the Godot editor, HTTP server on port 6100Claude Code starts the MCP server automatically via .mcp.json. The MCP server talks to the Godot editor plugin over HTTP. Users don't start anything manually except enabling the Godot plugin.
godot-ai-builder/
├── .claude-plugin/
│ ├── plugin.json # Plugin manifest (name, version, author, keywords)
│ └── marketplace.json # Marketplace registry entry
│
├── skills/ # 14 game-generation skills + this dev skill
│ ├── godot-builder/SKILL.md # Master router — entry point for all game requests
│ ├── godot-director/SKILL.md # 6-phase build protocol (PRD → Foundation → ... → QA)
│ ├── godot-init/SKILL.md # Project bootstrapping, folder structure
│ ├── godot-gdscript/SKILL.md # GDScript syntax and patterns reference
│ ├── godot-scene-arch/SKILL.md # Scene building (programmatic vs .tscn)
│ ├── godot-physics/SKILL.md # Collision layers, physics bodies
│ ├── godot-player/SKILL.md # Player controllers (top-down, platformer, twin-stick, etc.)
│ ├── godot-enemies/SKILL.md # Enemy AI, spawn systems, boss patterns
│ ├── godot-ui/SKILL.md # UI screens, HUD, menus, transitions
│ ├── godot-effects/SKILL.md # Audio, particles, tweens, visual effects
│ ├── godot-assets/SKILL.md # Visual quality system, shaders, procedural art
│ ├── godot-polish/SKILL.md # Game feel — screen shake, dissolve, hit flash, juice
│ ├── godot-ops/SKILL.md # MCP tool operations (run, stop, errors, reload)
│ ├── godot-templates/SKILL.md # Genre-specific file manifests
│ └── godot-dev/SKILL.md # THIS FILE — builder development guide
│
├── hooks/
│ ├── hooks.json # Hook registration (Stop hook only)
│ └── stop-guard.sh # Prevents Claude from quitting mid-build
│
├── .mcp.json # MCP server config (auto-launched by Claude Code)
│
├── mcp-server/
│ ├── index.js # MCP server entry — Server + StdioServerTransport
│ ├── package.json # Dependencies: @modelcontextprotocol/sdk, sharp
│ └── src/
│ ├── tools.js # TOOL_DEFINITIONS array (21 tools) + handleToolCall dispatcher + handlers
│ ├── godot-bridge.js # HTTP client → Godot editor (port 6100)
│ ├── scene-parser.js # .tscn text format parser
│ └── asset-generator.js # SVG/PNG sprite generator (layered gradients, shadows, glow)
│
├── godot-plugin/
│ └── addons/ai_game_builder/
│ ├── plugin.cfg # Godot plugin metadata
│ ├── plugin.gd # EditorPlugin — starts bridge + dock
│ ├── http_bridge.gd # HTTP server (port 6100) — route handlers
│ ├── dock.gd # Bottom dock panel — status + log display
│ ├── dock.tscn # Dock scene file
│ ├── error_collector.gd # Two-strategy error detection (script validation + log scan)
│ └── project_scanner.gd # File discovery for /state endpoint
│
├── knowledge/ # Reference docs (copied into user projects by setup.sh)
│ ├── godot4-reference.md # GDScript syntax, nodes, signals
│ ├── scene-format.md # .tscn format spec
│ ├── game-patterns.md # Architecture templates per genre
│ └── asset-pipeline.md # Asset creation and import
│
├── setup.sh # Installs Godot plugin + knowledge into a project
├── README.md # Public README
├── GETTING-STARTED.md # Full user walkthrough (6 steps)
└── GETTING-STARTED.pdf # PDF version (generated via pandoc + typst)
Each skill is a directory under skills/ containing a single SKILL.md file.
The file has YAML frontmatter (name, description) and markdown body.
Skills are namespaced as /godot-ai-builder:godot-* when the plugin is loaded.
---
name: godot-skillname
description: |
One-paragraph description of what this skill does.
Include trigger phrases so Claude knows when to load it.
---
# Skill Title
Content: patterns, code examples, checklists, rules.
Skill content IS the instruction set. There's no separate config — the markdown text directly controls what Claude does when it loads the skill. Write it as if you're briefing a senior developer on exactly how to do the job.
godot-builder is the master router. It reads the user's prompt and loads
specialized skills based on intent. When adding a new skill:
skills/godot-newskill/SKILL.mdgodot-builder/SKILL.md (Section "Route to Skills")mcp-server/index.js — creates an MCP Server, registers ListToolsRequestSchema and CallToolRequestSchemasrc/tools.js — exports TOOL_DEFINITIONS (array of MCP schemas) and handleToolCall(name, args) dispatchersrc/godot-bridge.js — HTTP client that calls the Godot editor on port 6100GODOT_BRIDGE_PORT (default 6100), GODOT_PROJECT_PATH (default .)plugin.gd is the EditorPlugin entry — creates the HTTP bridge and dock on _enter_tree()http_bridge.gd runs a TCPServer on port 6100, routing requests:
GET /status → editor stateGET /errors → error_collector resultsPOST /run → run scene in editorPOST /stop → stop running scenePOST /reload → rescan filesystemPOST /log → send message to dock panelPOST /phase → update phase state, emit phase_updated signalGET /phase → return current phase stateGET /scene_tree?max_depth=N → live scene tree hierarchyGET /class_info?class_name=X&inherited=bool → ClassDB lookupPOST /add_node → add node to edited scenePOST /update_node → modify node propertiesPOST /delete_node → remove node from sceneGET /screenshot?viewport=2d|3d → editor viewport capture (base64 PNG)GET /open_scripts → list open scripts in script editordock.gd displays phase progress bar, control buttons (Run/Stop/Reload), error badges, filtered log, and quality gates checklist. Connected to bridge via signals bridge_log(msg) and phase_updated(data)error_collector.gd uses two strategies: active script validation + Godot log scanningproject_scanner.gd walks the filesystem for /state responsesOnly one hook: the Stop guard.
hooks/hooks.json registers a Stop event hook running stop-guard.sh.claude/.build_in_progress file{"decision": "block", ...})mcp-server/src/tools.js — add to TOOL_DEFINITIONS array:{
name: "godot_new_tool",
description: "What this tool does — be specific so Claude knows when to use it.",
inputSchema: {
type: "object",
properties: {
param_name: { type: "string", description: "..." },
},
required: ["param_name"],
},
},
handleToolCall():case "godot_new_tool":
return await toolNewTool(args.param_name);
async function toolNewTool(paramName) {
await bridge.sendLog(`[MCP] Doing something with ${paramName}...`);
// Implementation...
const result = { /* response data */ };
await bridge.sendLog(`[MCP] Done: ${paramName}`);
return result;
}
http_bridge.gd:# In _route_request():
"/new_endpoint":
_handle_new_endpoint(client, body)
And add the corresponding bridge function in godot-bridge.js:
export async function newEndpoint(data) {
return bridgeRequest("POST", "/new_endpoint", data);
}
Add logging — every tool handler should call bridge.sendLog() before and after.
Document it — add the tool to:
skills/godot-builder/SKILL.md (MCP tools list)skills/godot-ops/SKILL.md (operations reference)README.md (MCP Tools table)skills/godot-newname/SKILL.md with YAML frontmattergodot-builder/SKILL.md:
godot-director/SKILL.md phase descriptionsFiles live in godot-plugin/addons/ai_game_builder/. Changes here require:
setup.sh again on any test project to copy updated filesKey GDScript patterns in the plugin:
@tool scripts (run in editor, not game)http_bridge.gd uses TCPServer + StreamPeerTCP for HTTPbridge.log_message.emit(msg) → dock picks it uperror_collector.gd caches results, refreshed on /errors requesteditor_interface reference for editor API accessmcp-server/src/asset-generator.js exports:
generatePlaceholder(args) → SVG string + writes filegeneratePng(args) → uses sharp to convert SVG → PNGEntity type builders (each returns an SVG inner content string):
buildCharacter, buildEnemy, buildBoss, buildProjectile, buildTile,
buildIcon, buildBackground, buildNpc, buildItem, buildPickup, buildUi
Helpers: hexToRgb(), darken(), lighten(), withAlpha(), uid(), simplePrng()
When adding a new entity type:
DEFAULT_COLORS mapbuildNewType(w, h, color, style) functionswitch in the buildEntity() routerTOOL_DEFINITIONS enum in tools.jsgodot_generate_asset with the new typeVisual quality rules for SVGs:
<radialGradient> or <linearGradient> — never flat fills<filter id="shadow"> with <feDropShadow>darken(color) for shadows, lighten(color) for highlightsFiles to update (keep them in sync):
README.md — public-facing, architecture diagram, install steps, skill table, tool tableGETTING-STARTED.md — user walkthrough (6 steps), troubleshooting, project structureGETTING-STARTED.pdf — regenerate after editing the markdownRegenerating the PDF:
cd /path/to/godot-ai-builder
pandoc GETTING-STARTED.md -o GETTING-STARTED.pdf --pdf-engine=typst
GitHub URL: https://github.com/HubDev-AI/godot-ai-builder
Always use this URL in all docs and scripts. Check setup.sh too — it has inline URLs.
hooks/hooks.json:{
"hooks": {
"EventName": [
{
"hooks": [
{
"type": "command",
"command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/new-hook.sh\"",
"timeout": 10
}
]
}
]
}
}
Create the shell script in hooks/. It receives JSON on stdin and can return JSON to influence behavior.
Available hook events: Stop, PreToolUse, PostToolUse, Notification
The Director (skills/godot-director/SKILL.md) controls the 6-phase build:
Each phase has quality gates — conditions that must pass before moving on. To modify a phase: edit the phase section in the Director skill and update its gates.
The Director also manages:
.claude/.build_in_progress file (build lock)Structured build state saved to .claude/build_state.json after each phase completion.
MCP Tools:
godot_save_build_state — writes JSON checkpoint (direct filesystem, no bridge)godot_get_build_state — reads JSON checkpoint, handles missing file gracefullygodot_update_phase — sends phase progress to Godot dock via bridge POST /phaseData Model (.claude/build_state.json):
{
"version": "1.0",
"build_id": "unique-id",
"timestamp": "ISO-8601",
"game_name": "...",
"genre": "...",
"visual_tier": "procedural",
"current_phase": { "number": 0, "name": "...", "status": "...", "started_at": "..." },
"completed_phases": [{ "number": 0, "name": "...", "completed_at": "...", "quality_gates": {} }],
"files_written": ["scripts/player.gd"],
"error_history": [{ "file": "...", "message": "...", "resolution": "...", "resolved": true }],
"test_runs": [{ "phase": 0, "errors": 0, "success": true }],
"prd_path": "docs/PRD.md",
"next_steps": ["..."]
}
Resume Flow:
godot_get_build_state() at session start.claude/build_state.json and .claude/.build_in_progressThe dock (dock.gd + dock.tscn) provides:
error_collector every 2s, show red/green error count + yellow warning countphase_updated signal dataSignal flow: Director → godot_update_phase tool → bridge POST /phase → http_bridge.phase_updated signal → dock._on_phase_updated()
Skills enforce visual quality through documentation rules:
godot-assets — defines the 4-tier visual system, shader library, entity drawing patternsgodot-player — visual standard for player entities (layered _draw(), sprite fallback)godot-enemies — visual standard for enemy entities (type-specific shapes, hit flash)godot-effects — shader effects (hit flash, dissolve, glow), particles, trailsgodot-polish — game feel checklist, shader-based polish, styled UI, transitionsasset-generator.js — SVG generation with gradients, shadows, highlightsAll these must stay consistent. When you change visual patterns in one skill, check the others.
Skills reference each other. Key dependencies:
godot-builder → routes to ALL skillsgodot-director → invokes skills per phase (player in P1, enemies in P3, UI in P4, polish in P5)godot-polish → references shaders from godot-assets, effects from godot-effectsgodot-player / godot-enemies → reference visual patterns from godot-assetsgodot-ops → documents all MCP tools that other skills callEvery MCP tool logs to the Godot dock via bridge.sendLog():
[MCP] for tool operations[Agent: name] for sub-agent workAdditionally, every tool response includes a _dock_reminder field that reminds the AI to call godot_log() after the tool completes. This ensures the AI keeps the Godot dock updated constantly. The godot_log and godot_update_phase tool descriptions are marked ⚠️ MANDATORY to further reinforce this requirement.
The MCP server enforces error checking at the tool level — the AI cannot bypass these:
index.js: Every tool response (except lightweight tools) includes _error_count from a live bridge check. If > 0, _action_required tells the AI to stop and fix.
toolReloadFilesystem: After reloading, automatically calls bridge.getErrors() and includes _error_count and _error_files in the response. Logs a warning to the dock if errors exist.
toolUpdatePhase with status="completed": Calls bridge.getErrors() first. If any errors exist, the completion is REJECTED — returns {ok: false, rejected: true} with error details. The phase is kept at "in_progress". This is the hardest gate: the AI literally cannot mark a phase complete while errors exist.
getErrorCount(): Exported helper used by index.js to get a quick error count from the bridge's cached validation. Does NOT run headless Godot (that would be too slow for every call).
These gates ensure that even if the AI ignores skill instructions about error checking, the tools themselves force compliance.
isConnected() checks by calling getStatus() — swallows errorssendLog() wraps in try/catch — never throwsindex.js catches and returns isError: trueproject.godot parser is lenient — returns {} on missing file# Install dependencies
cd mcp-server && npm install
# Test the server starts
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node index.js
# Test with a running Godot instance (plugin enabled)
# The MCP server needs GODOT_PROJECT_PATH set to a real project
GODOT_PROJECT_PATH=/path/to/test/project node index.js
./setup.sh /path/to/test/projectcurl http://localhost:6100/statusSkills are just markdown — test by loading the plugin and using the skill:
cd /path/to/test/project
claude --plugin-dir /path/to/godot-ai-builder
# Then: /godot-ai-builder:godot-skillname
# Quick test: generate assets and inspect the SVGs
cd /path/to/test/project
claude --plugin-dir /path/to/godot-ai-builder
# Then ask: "Generate a character sprite" or "Generate an enemy sprite"
# Check the output SVG in assets/sprites/
When editing files, ALWAYS re-read the file first to get exact strings. Old strings from memory or previous sessions may not match the current file contents. Failed edits cascade — if one Edit fails in a parallel batch, siblings may fail too.
There is no runtime config for skills. The SKILL.md content IS the instruction set. If Claude doesn't do something, the skill text needs to be more explicit. If Claude does something wrong, the skill needs a rule against it.
Early SVGs were flat colored shapes (triangles, rectangles). Users found them ugly. The asset generator was rewritten with layered gradients, shadows, highlights, and entity-specific builders. When modifying SVGs, always maintain:
All visual skills must agree on patterns. A change to how player visuals work
(godot-player) must be reflected in the effects that apply to players
(godot-effects, godot-polish). The visual checklist in godot-assets is
the authoritative source.
Claude has a tendency to overwrite project.godot sections. The builder skill
explicitly warns against this: "ALWAYS read before modifying, NEVER overwrite,
MUST preserve [autoload]". If you see game-breaking bugs after builds, check
if project.godot sections were stripped.
After updating GETTING-STARTED.md, always regenerate the PDF:
pandoc GETTING-STARTED.md -o GETTING-STARTED.pdf --pdf-engine=typst
Both pandoc and typst must be installed. On macOS: brew install pandoc typst.
The setup.sh file contains inline URLs for marketplace instructions. Keep these
in sync with the real GitHub URL (https://github.com/HubDev-AI/godot-ai-builder).
The MCP server is launched automatically by Claude Code via .mcp.json. Users
don't need to start it manually. The config uses ${CLAUDE_PLUGIN_ROOT} to
resolve paths relative to the plugin directory.
error_collector.gd uses two strategies:
/errors request. The active strategy catches errors that Godot's
log doesn't always surface (e.g., scripts that fail to parse).Follow the existing commit style:
type: short description
Longer explanation if needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Types used: feat, fix, docs, refactor
Recent examples:
feat: visual quality overhaul — layered procedural visuals, shaders, polished SVGsfix: rewrite error collector to actively validate scriptsdocs: update guides with scope choice, godot_log tool, and dock loggingfeat: add godot_log MCP tool + dock console logging for all operations