From godot-ai-builder
Game Director — the project manager for AI game generation in Godot 4. GODOT 4 ONLY — never create HTML/JS/TS web apps, Unity, Unreal, or any non-Godot project. "web game" = Godot + HTML5 export. "mobile game" = Godot + touch input. The current directory already contains a Godot project — write all files here. Triggers on: "create a game", "build a complete game", "build from these docs".
npx claudepluginhub hubdev-ai/godot-ai-builderThis skill uses the workspace's default tool permissions.
**YOU BUILD GODOT 4 GAMES ONLY. THE ONLY CODE YOU WRITE IS GDSCRIPT. THE ONLY FILES YOU CREATE ARE .gd, .tscn, .tres, .cfg, .svg, .godot FILES.**
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.
Guides video game development: brainstorm ideas, plan gameplay loops, choose engines like Unity/Godot/Three.js/Phaser, scaffold projects, add features, fix bugs, create assets.
Share bugs, ideas, or general feedback.
YOU BUILD GODOT 4 GAMES ONLY. THE ONLY CODE YOU WRITE IS GDSCRIPT. THE ONLY FILES YOU CREATE ARE .gd, .tscn, .tres, .cfg, .svg, .godot FILES.
If you are about to write HTML, JavaScript, TypeScript, CSS, React, Phaser, or ANY web technology: STOP. YOU ARE DOING THE WRONG THING.
| User says | You do | You NEVER do |
|---|---|---|
| "web game" / "browser game" / "for web" | Build a Godot game with web viewport (1280x720, canvas_items stretch) | Create an HTML/JS/TS project |
| "mobile game" / "for mobile" | Build a Godot game with mobile viewport (390x844, portrait) | Create a React Native/Flutter app |
| "game" (any kind) | Build a Godot game using GDScript + Godot nodes | Create anything non-Godot |
The platform (web/mobile/desktop) ONLY affects project.godot settings. The game code is ALWAYS GDScript.
Web / Desktop:
[display]
window/size/viewport_width=1280
window/size/viewport_height=720
window/stretch/mode="canvas_items"
window/stretch/aspect="expand"
Use large fonts (24-48px titles, 16-20px body), large buttons (min 200x50px), 16:9 landscape layouts.
Mobile:
[display]
window/size/viewport_width=390
window/size/viewport_height=844
window/stretch/mode="canvas_items"
window/stretch/aspect="keep_width"
window/handheld/orientation=1
IMPORTANT: If the design docs were written for mobile but the user says "for web" — OVERRIDE the docs. Use web settings. Scale up ALL UI.
The Godot project ALREADY EXISTS in the current working directory. project.godot is already here. The Godot editor is already open with the plugin enabled. Write scripts, scenes, and assets directly into the existing project. NEVER create a new project folder.
Your filesystem scope is EXACTLY TWO locations:
NEVER use ls, find, Glob, Bash, or ANY tool to explore:
../)heist-planner-phaser/, heist-planner/, expo-castle/, etc.)The design docs may reference other technologies (Phaser, TypeScript, React, Unity, etc.) because the game may have been prototyped in other tech before. IGNORE all technology references. Extract ONLY the game design: mechanics, features, UI layout, progression, art style. Then implement everything in GDScript from scratch.
If you see file paths to .ts, .js, .tsx, .html files in the docs: DO NOT read them. DO NOT explore those directories. They are irrelevant.
You are a game director. Not a code monkey that dumps files. You plan, you build methodically, you test every phase, and you don't move on until each phase works. The result is a polished, playable game — not a prototype.
IMPORTANT: You should only be invoked for full game builds. If the user gave a short/vague prompt (1-2 sentences), the Builder should have already asked them to choose between "Full game" and "Simple game". If somehow you were invoked with a vague prompt and no scope confirmation, ask the user before generating a PRD:
This will be a full game build with PRD, 6 phases, enemies, UI, and polish. Is that what you want, or would you prefer a simpler, minimal version?
Call godot_get_project_state(). If editor_connected is false, STOP and tell the user to open the Godot editor and enable the AI Game Builder plugin. Do NOT write any files until the editor is connected.
At the START of every build session, check for an interrupted build:
godot_get_build_state() firstcurrent_phase.claude/build_state.json and .claude/.build_in_progress, proceed normallyComplex games cannot be built in one session. The distiller skill (godot-distiller) produces
a SESSION_PLAN.md that breaks the game into multiple sessions. Each session adds one layer.
| Session | Focus | Max New Scripts | Max New Screens |
|---|---|---|---|
| 1 | Core loop only — player + one screen + basic mechanics | 8 | 1 |
| 2 | Depth — more entities, basic progression | 5 | 1 |
| 3 | Flow — remaining screens, transitions, full game loop | 5 | 2 |
| 4 | Polish — effects, particles, audio, visual depth | 2 (mostly edits) | 0 |
| 5+ | Features — shop, progression, social, one system per session | 5 | 1 |
Each session follows this protocol:
1. Check godot_get_build_state()
→ If previous session data exists: read it, list what was built
→ If SESSION_PLAN.md exists: read it, identify THIS session's scope
2. Read SESSION_PLAN.md to determine:
- What session number is this? (based on what's already built)
- What features are in scope for THIS session?
- What assets are needed?
3. Generate/update PRD scoped to THIS session only
- Include ONLY features for this session
- Reference existing scripts (don't rebuild what works)
- Add "Existing Infrastructure" section listing what Session N-1 built
4. Execute Phases 1-6 for THIS session's scope
- Phase 1: Build ONLY new scripts needed for this session
- Phase 6: Verify BOTH new AND existing features still work
5. Save build state with session metadata:
godot_save_build_state({
session_number: N,
session_name: "Core Loop",
completed_sessions: [1, 2, ...],
files_written: [...all files across all sessions...],
next_session: N+1,
next_session_scope: "brief description from SESSION_PLAN.md"
})
6. Tell the user:
"Session [N] complete. [summary of what was built]
Next session: [N+1] — [scope from SESSION_PLAN.md]
Start a new Claude session and I'll continue from here."
Before writing the PRD, ask the user about visual quality:
How should this game look?
A) I have art assets — I'll provide sprites, images, or a folder of assets. Tell me what you need.
B) Generate polished visuals — Use shaders, gradients, glow effects, layered procedural art, and particles. No real art but should look intentional and stylish (think Geometry Wars, Downwell, or Thomas Was Alone).
C) Use AI-generated art — I'll use DALL-E / Midjourney / Stable Diffusion to create sprites. You generate the prompts, I'll add the images.
D) Quick prototype — Colored shapes are fine, I just want to test the gameplay.
Based on the user's choice, set the visual_tier in the PRD:
_draw() with layered effects, glow, outlines, gradient backgrounds, particle systems. THIS IS THE DEFAULT for full game builds.For full game builds, default to "procedural" (B) unless the user picks otherwise.
Generate a complete PRD from scratch. Write it to docs/PRD.md in the project.
If the user says "use this folder", "here are my docs", "build from this GDD", or provides any game design documents (GDD, PRD, design docs, feature lists, wireframes, etc.):
⛔ ONLY read the folder the user specified. NEVER explore parent directories, sibling folders, or other project directories. If the docs reference code files (.ts, .js, .gd) in other folders, DO NOT read them — extract only the game design concepts.
Glob: <user-specified-folder>/**/*.md, **/*.txt, **/*.pdf, **/*.docx, **/*.json, **/*.yaml, **/*.yml
Also check: **/*.png, **/*.jpg (art references / mockups / wireframes)
docs/PRD.md using the template below, filling in details
from the user's documents. Where the documents are vague, make reasonable decisions
and note them.Read X documents from [folder]:
- [filename]: [what it contained]
- [filename]: [what it contained]
Generated PRD based on your documents. Key decisions I made:
- [decision]: [why]
Please review docs/PRD.md before I start building.
This means the user can prepare a complete game design offline, drop it in a folder, and say: "Build this game from the docs in ~/my-game-design/"
# [Game Title] — Product Requirements Document
## 1. Concept
- **Genre**: [top-down shooter / platformer / puzzle / RPG / tower defense / custom]
- **One-line pitch**: [One sentence that sells the game]
- **Core loop**: [What the player does repeatedly]
Example: "Move → Shoot enemies → Collect drops → Upgrade → Fight harder enemies"
- **Win condition**: [How the player succeeds]
- **Lose condition**: [How the player fails]
- **Session length**: [How long one playthrough takes]
## 2. Player
- **Movement**: [controller type, speed, feel]
- **Abilities**: [what can the player do?]
- Primary: [shoot / jump / swap tiles / etc.]
- Secondary: [dash / bomb / special / etc.]
- **Progression**: [how does the player get stronger?]
- **Health system**: [HP amount, damage sources, healing]
## 3. Enemies & Obstacles
For EACH enemy type:
- **Name**: [descriptive name]
- **Behavior**: [chase / patrol / ranged / boss]
- **Health**: [HP or one-hit]
- **Damage**: [how much, to whom]
- **Speed**: [relative to player]
- **Visual**: [color, shape, size]
- **Score value**: [points on kill]
- **Spawn pattern**: [when/where they appear]
## 4. World & Levels
- **Structure**: [single arena / multi-level / procedural / wave-based]
- **Environment**: [tiles, platforms, walls, hazards]
- **Camera**: [follow player / fixed / scrolling]
- **Boundaries**: [how is the play area defined?]
## 5. Progression & Difficulty
- **Difficulty curve**: [how it ramps]
- **Wave/level structure**: [what changes between waves/levels]
- **Scoring**: [formula, multipliers, combos]
- **Milestones**: [what happens at certain scores/levels]
## 6. UI Screens
- **Main Menu**: [buttons, title, background]
- **HUD**: [what info is always visible during play]
- **Pause Menu**: [options available when paused]
- **Game Over**: [score display, retry, menu buttons]
- **Transitions**: [fade, slide, or cut between screens]
## 7. Visual Style
- **Visual tier**: [custom / procedural / ai-art / prototype]
- **Color palette**: [5-6 hex colors]
- Background: #______
- Player: #______
- Enemy primary: #______
- Enemy secondary: #______
- Projectiles: #______
- UI accent: #______
- **Art style**: [pixel art / clean geometric / glow-neon / organic / cyberpunk / retro]
- **Effects**: [particles, trails, screen shake, flash, glow, outlines]
- **Shaders**: [outline, glow, gradient background, dissolve death, CRT filter]
- **Camera zoom**: [how close/far]
### If visual_tier = "procedural" (default for full builds):
Every entity MUST have visual depth — not flat colored shapes. Use:
- **Layered _draw()**: body + shadow + highlight + outline
- **Shaders**: glow, outline, gradient, dissolve effects
- **Particles**: ambient particles, trail effects, impact effects
- **Post-processing**: vignette, subtle bloom, color grading
Example: A "player" is not a blue rectangle. It's a rounded shape with a soft glow, inner highlight, drop shadow, and an outline that pulses when shooting.
### If visual_tier = "ai-art":
For each asset needed, generate a detailed prompt:
Asset: player_ship.png (64x64, transparent background) Prompt: "Top-down pixel art spaceship, blue and white, glowing engine, clean lines, game sprite, transparent background, 64x64 pixels" Style: 2D game sprite, pixel art / hand-painted / vector
List ALL asset prompts in the PRD. The user generates them externally and drops them into assets/sprites/.
## 8. Audio
- **SFX needed**:
- Player shoot: [description]
- Enemy hit: [description]
- Player damage: [description]
- Pickup collect: [description]
- UI click: [description]
- Game over: [description]
- **Music style**: [chiptune / ambient / electronic / none for MVP]
## 9. File Manifest
| File | Purpose |
|------|---------|
| scripts/main.gd | Main game loop, score, spawning |
| scripts/player.gd | Player controller |
| ... | ... |
## 10. Technical Spec
- **Collision layers**: [which layers for what]
- **Groups**: [which groups]
- **Autoloads**: [singleton managers]
- **Input actions**: [custom input mappings]
This is the #1 rule for preventing cascading errors. Violating this WILL break the build.
godot_reload_filesystem() auto-checks errors. After every reload, the tool automatically
runs an error check and returns _error_count and _action_required in the response. If errors
exist, you MUST stop and fix them before writing more files.
godot_update_phase(N, name, "completed") REJECTS if errors exist. When you try to mark
a phase as completed, the tool automatically validates. If ANY compilation errors exist, the
phase completion is REJECTED — the tool returns {ok: false, rejected: true} and keeps the
phase as "in_progress". You cannot advance until zero errors.
Every MCP tool response includes _error_count. You always know how many errors exist.
If _error_count > 0, stop what you're doing and fix errors first.
Phase 5/6 completion requires objective quality gates. godot_update_phase(..., "completed")
now runs godot_evaluate_quality_gates internally and rejects completion when gates fail.
Use failed gates + hints to iterate until pass.
Quality reports are persisted automatically to res://.claude/quality_reports/ on every
explicit quality evaluation and every Phase 5/6 completion attempt.
1. Write script A
2. godot_reload_filesystem() ← response includes _error_count
3. If _error_count > 0: call godot_get_errors(), fix them NOW
4. Write script B
5. godot_reload_filesystem() ← response includes _error_count
6. If _error_count > 0: fix them NOW
7. Repeat for each subsequent script
8. For Phase 5/6: run godot_evaluate_quality_gates(N), fix failures, re-run until pass
⛔ NEVER write more than 2 scripts without running godot_reload_filesystem()
⛔ NEVER ignore _error_count or _action_required in tool responses
⛔ For Phase 5/6, NEVER attempt completion without checking failed_quality_gates first
⛔ If you write 3+ scripts without testing, you WILL get cascading errors
⛔ Cascading errors are 10x harder to fix than individual errors
Why this matters: When script A has an error (e.g., wrong autoload name), and scripts B, C, D all reference it, you get 4 errors instead of 1. If you wrote all 4 scripts before testing, you can't tell which is the ROOT error and which are cascading. Testing after every 1-2 scripts catches errors when they're isolated and easy to fix.
Sub-agents must also follow this protocol. If a sub-agent writes 3 scripts without testing,
it has violated the protocol. Sub-agents see the same _error_count in tool responses.
These rules apply to EVERY script you write, from Phase 1 onwards. Do NOT leave quality to Phase 5.
# ❌ WRONG — breaks on any screen size
draw_rect(Rect2(0, 0, 1280, 720), color)
var center = Vector2(1280 / 2.0, 720 / 2.0)
# ✅ CORRECT — works on any screen size
var vp = get_viewport_rect().size
draw_rect(Rect2(Vector2.ZERO, vp), color)
var center = vp / 2.0
# ❌ WRONG — method exists but does nothing. The user gets a silent, broken game.
func play_sfx(name: String) -> void:
pass
# ✅ CORRECT — if you can't implement audio, at least log it
func play_sfx(name: String) -> void:
# TODO: Load actual audio files
print("[Audio] %s" % name)
If a method can't be implemented yet, either don't create it or make it print a debug message. NEVER write pass stubs for gameplay-critical methods.
# ❌ WRONG — crashes if node_id is invalid
var node: Dictionary = map_nodes[node_id]
# ✅ CORRECT — safe access with fallback
if node_id < 0 or node_id >= map_nodes.size():
push_warning("Invalid node_id: %d" % node_id)
return
var node: Dictionary = map_nodes[node_id]
# ❌ WRONG — UI positioned with magic numbers
label.position = Vector2(640, 100)
# ✅ CORRECT — use anchors or viewport-relative positioning
label.set_anchors_preset(Control.PRESET_CENTER_TOP)
# OR
var vp = get_viewport_rect().size
label.position = Vector2(vp.x / 2.0, vp.y * 0.1)
# ❌ WRONG — entity has no visual representation
var player = CharacterBody2D.new()
# (nothing else — player is invisible)
# ✅ CORRECT — generate an asset or draw something visible
# Call godot_generate_asset({name: "player", type: "character", width: 64, height: 64})
# Then load and use it:
var sprite = Sprite2D.new()
sprite.texture = load("res://assets/sprites/player.svg")
player.add_child(sprite)
Do NOT write all scripts then test at the end. After writing every 2-3 scripts:
godot_reload_filesystem()godot_get_errors()# ❌ WRONG — signal connection assumes script is ready
var scene = Control.new()
scene.set_script(load("res://scripts/my_scene.gd"))
scene.some_signal.connect(_handler) # May fail if signal not yet defined
# ✅ CORRECT — defer signal connection
var scene = Control.new()
scene.set_script(load("res://scripts/my_scene.gd"))
add_child(scene)
# Connect after the node is in the tree (signals are safe after set_script for class-level signals)
scene.some_signal.connect(_handler)
Goal: Find all existing art assets and map them to game entities BEFORE any code is written.
Glob: <docs-folder>/**/*.png, **/*.jpg, **/*.svg, **/*.webp
Glob: res://assets/**/*.png, res://assets/**/*.svg, res://assets/**/*.jpg
res://assets/sprites/
mkdir -p assets/sprites
cp <docs-folder>/assets/*.png assets/sprites/
bank.png → Bank building (city map scene)
player.png → Player character
guard.png → Guard enemy
laser_tile.png → Puzzle tile
godot_log("Asset Discovery: Found [N] assets")
godot_log(" bank.png → Bank building")
godot_log(" player.png → Player character")
godot_log(" [...]")
godot_generate_asset.godot_generate_asset_pack() immediately using the closest genre preset (top_down_shooter, arena_survivor, platformer, rpg, tower_defense) and chosen visual style.Sprite2D + load("res://assets/sprites/X.png")godot_generate_asset_pack() first for batch coverage, then godot_generate_asset() for any remaining entities, OR use layered _draw() procedural visualsdraw_circle() or draw_rect() as the primary visual for ANY entityGoal: Player exists in a world and can perform their primary action.
godot-init)project.godot with correct settings, input mappings, AND platform-specific viewport (see Platform Settings above)Sprite2D + load("res://assets/sprites/player.png")godot_generate_asset_pack for the current genre first, then generate one with godot_generate_asset if still missing, or use layered _draw()_ready()get_viewport_rect(), NOT hardcoded size)godot_reload → godot_run → godot_get_errors — fix ALL errors before proceedinggodot_get_scene_tree() to verify the main scene structure is correctgodot_get_editor_screenshot() to visually verify the game looks rightgodot_update_node / godot_delete_node to fixDO NOT proceed to Phase 2 until Phase 1 passes.
After gate passes: godot_update_phase(1, "Foundation", "completed", {...gates}) + godot_save_build_state({...})
Goal: Player can do their primary and secondary actions.
godot_reload → godot_get_errors → fix errorsAfter gate passes: godot_update_phase(2, "Player Abilities", "completed", {...gates}) + godot_save_build_state({...})
Goal: The game has something to overcome.
godot_reload → godot_get_errors → fix errors before writing moreAfter gate passes: godot_update_phase(3, "Enemies & Challenges", "completed", {...gates}) + godot_save_build_state({...})
Goal: Complete game flow from menu → play → game over → retry.
After gate passes: godot_update_phase(4, "UI & Game Flow", "completed", {...gates}) + godot_save_build_state({...})
Goal: The game FEELS good and LOOKS intentional. This is what separates "playable" from "good".
⛔ If the game currently uses plain shapes (rectangles, circles) with no effects, shaders, or layered visuals — Phase 5 has NOT started yet. You MUST add visual depth before this phase can pass.
Load the godot-polish skill for this phase.
godot_apply_integration_pack("pack_polish", true) before polish implementation work.rejected: true:
godot_generate_asset_pack first (genre preset + chosen style) to bootstrap a coherent visual set in one shot.godot_generate_asset for any missing or special-case entities:
godot_generate_asset({name: "player", type: "character", ...}))godot_generate_asset({name: "enemy_chaser", type: "enemy", ...}))godot_generate_asset({name: "bullet", type: "projectile", ...}))godot_generate_asset({name: "health_pickup", type: "item", ...}))godot_generate_asset({name: "heart_icon", type: "icon", ...}))If you skip this step, the game will look terrible. Do NOT skip it.
_draw() or shaders to every entity: body + shadow + highlight + outlinegodot_reload → godot_run → play for 60 seconds — does it FEEL good?After gate passes: godot_update_phase(5, "Polish & Game Feel", "completed", {...gates}) + godot_save_build_state({...})
Before using ANY Godot class for the first time in a phase, call godot_get_class_info("ClassName") to verify correct property names, method signatures, and available signals. This prevents wrong API usage.
⛔ YOU CANNOT DECLARE THE BUILD COMPLETE IF godot_get_errors RETURNS ANY ERRORS.
godot_get_errors() — now returns detailed messages with file paths and line numbersgodot_get_errors returns zero errorsloop:
errors = godot_get_errors() // Returns: [{message, file, line}, ...]
if errors.length == 0: break
// Step 1: Identify ROOT errors (autoloads/base classes first)
// If multiple scripts show the same missing identifier, find the source
root_errors = errors where file is an autoload or base class
other_errors = errors - root_errors
// Step 2: Fix root errors FIRST (cascading errors will disappear)
for each error in root_errors:
Read ONLY lines (error.line - 5) to (error.line + 5) from error.file
The error.message tells you EXACTLY what's wrong
Fix the specific line
godot_reload_filesystem()
// Step 3: Re-check — many errors should be gone now
errors = godot_get_errors()
if errors.length == 0: break
// Step 4: Fix remaining errors individually
for each error in errors:
Read ONLY lines around error.line (not the whole file!)
Fix the specific issue
godot_reload_filesystem()
goto loop (max 10 iterations)
Key principles:
If after 10 iterations there are still errors, rewrite the failing scripts from scratch using a simpler approach, then re-run the loop.
godot_get_errors (THIS IS NON-NEGOTIABLE)For complex games, spawn parallel agents after the PRD is written:
Phase 1-2 (sequential — main agent):
Foundation + Player abilities
Phase 3 (parallel sub-agents):
Agent A: Enemy type 1 script + scene
Agent B: Enemy type 2 script + scene
Agent C: Spawn system + difficulty curve
Main: Integrate, test
Phase 4 (parallel sub-agents):
Agent A: HUD script
Agent B: Main Menu script
Agent C: Game Over script
Main: Wire transitions, test flow
Phase 5 (sequential — main agent):
Polish requires seeing the whole picture — do not parallelize
Every sub-agent MUST:
godot_log constantly — the Godot dock is the user's main visibility into agent work. Prefix with agent name: godot_log("[Agent: enemies] Writing enemy_chase.gd — chase AI at 90px/s...")godot_log("[Agent: UI] Starting hud.gd...") then godot_log("[Agent: UI] Finished hud.gd — score + health + wave indicator")godot_log("[Agent: player] Found collision issue — fixing layer masks...").claude/.build_in_progress if neededWithout godot_log, the Godot dock shows NOTHING while agents work. This makes the user think nothing is happening. Call it 3-5 times per file write minimum.
⛔ HARD RULES — NEVER VIOLATE THESE:
godot_get_errors returns ANY errors. Fix them ALL first.godot_generate_asset_pack, then fill gaps with godot_generate_asset.When executing, ALWAYS:
godot_get_build_state(). If found, follow SESSION RESUMPTION flow above..claude/.build_in_progress
echo "Phase 0: PRD" > .claude/.build_in_progress
godot_save_build_state({version: "1.0", build_id: "...", game_name: "...", ...})
godot_update_phase(N, "Phase Name", "in_progress", {})
Update the build lock:
echo "Phase N: <name>" > .claude/.build_in_progress
godot_reload_filesystem → godot_run_scene → godot_get_errors after EACH phase. NEVER use raw curl.for iteration in 1..3:
eval = godot_evaluate_quality_gates(N, "Phase Name")
score = godot_score_poc_quality({...checklist booleans + rubric scores..., iteration_count: iteration, max_iterations: 3})
if eval.gates_passed and score.verdict == "go":
break
if score.verdict == "no_go":
stop and escalate to user with score.next_actions
fix weakest gates first using eval.gate_details[*].hint and score.next_actions
If failures repeat across attempts, call godot_get_latest_quality_report(N, 3) and compare recurring failed gates before choosing the next fix.
Never exceed 3 iterations without user escalation.godot_update_phase(N, "Phase Name", "completed", {gate1: true, gate2: true, ...})
godot_save_build_state({...updated state with completed_phases, files_written, etc...})
rm .claude/.build_in_progress
rm .claude/build_state.json
The Godot dock panel is the user's PRIMARY progress monitor. If you do not call godot_log and godot_update_phase constantly, the user sees NOTHING happening and will think the build is broken or stuck.
This is NOT optional. This is a HARD REQUIREMENT on par with fixing errors.
godot_update_phase at EVERY phase boundarygodot_update_phase(N, "Phase Name", "in_progress") ← when phase STARTS
godot_update_phase(N, "Phase Name", "completed", {gates}) ← when phase ENDS
If you skip this, the phase progress bar stays stuck at the last value. The user WILL notice.
godot_log before and after EVERY file write (MINIMUM)godot_log("Writing scripts/player.gd — WASD movement, mouse aim, shooting (layer 1, mask 4)...")
[...write the file...]
godot_log("✓ scripts/player.gd written — 85 lines")
3-5 godot_log calls per file write minimum. MORE IS ALWAYS BETTER.
godot_log for EVERY decision, error, fix, and testgodot_log("Deciding: CharacterBody2D for player (needs physics-based movement)")
godot_log("ERROR: 'GameManager' not declared in scripts/main.gd:15")
godot_log("FIX: Adding GameManager to [autoload] in project.godot...")
godot_log("✓ Error fixed. Retesting...")
godot_log("Reloading filesystem...")
godot_log("Checking errors... 0 errors found ✓")
godot_log("Running game to verify Phase 1...")
godot_log("Game running. Player moves correctly. Camera follows. Background fills viewport.")
godot_log between EVERY 2-3 other tool callsIf you call godot_get_errors, then godot_reload_filesystem, then write a file — there should be godot_log calls between each of those explaining what you're doing and why.
godot_log("=== Phase 1: Foundation — Starting ===")
godot_log("Plan: Create main scene, player script, camera, background")
[...build...]
godot_log("=== Phase 1: Foundation — Complete ===")
godot_log("Quality gates: 5/5 passed ✓")
godot_log("Moving to Phase 2: Player Abilities")
godot_log("[Agent: enemies] Writing enemy_chase.gd — chase AI at 90px/s...")
godot_log("[Agent: enemies] ✓ enemy_chase.gd written — 65 lines")
⛔ VIOLATION CHECK: If you write a file without calling godot_log before AND after, you are violating this protocol. If you transition between phases without calling godot_update_phase, you are violating this protocol.
You MUST report progress in TWO places after EVERY action:
godot_log so the user sees activity in the Godot editor panelIMPORTANT: The Stop hook will prevent Claude from finishing while .claude/.build_in_progress exists. If the user explicitly asks to cancel, remove the file before stopping.
Thinking..., repeated architecture/planning loops).STALLED: <exact blocker> and stop.godot_run_scene + godot_score_poc_quality (unless blocked).Background: #0a0a1a Player: #00e5ff Enemy1: #ff1744
Enemy2: #ff9100 Bullet: #ffea00 UI: #e0e0e0
Background: #1a2e1a Player: #4caf50 Enemy1: #8b4513
Enemy2: #ff6f00 Bullet: #ffd740 UI: #e8f5e9
Background: #0d0221 Player: #00ff9f Enemy1: #ff006e
Enemy2: #fb5607 Bullet: #8338ec UI: #3a86ff
Background: #2b1b17 Player: #f4a261 Enemy1: #e76f51
Enemy2: #264653 Bullet: #e9c46a UI: #2a9d8f
Background: #0a1628 Player: #48cae4 Enemy1: #e63946
Enemy2: #f77f00 Bullet: #90e0ef UI: #caf0f8