with one click
game-build
// Build features with technique mapping (TDD, Implementation First, or Implementation Only) for Godot 4.x. Use with /game-build after /game-define.
// Build features with technique mapping (TDD, Implementation First, or Implementation Only) for Godot 4.x. Use with /game-build after /game-define.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | game-build |
| description | Build features with technique mapping (TDD, Implementation First, or Implementation Only) for Godot 4.x. Use with /game-build after /game-define. |
| reads | ["feature.requirements","backlog.stage"] |
| writes | ["feature.requirements","feature.build","backlog.stage","learnings"] |
| metadata | {"author":"mileszeilstra","version":"2.7.0","category":"game"} |
FASE 2 of the gamedev workflow: plan -> define -> build -> test -> refactor
The build phase implements features from requirements using technique mapping: TDD for logic/calculations, Implementation First for visual/scene setup, Implementation Only for pure visual/config without testable logic. It generates tests, iterates through RED-GREEN-REFACTOR cycles, and syncs codebase understanding.
Trigger: /game-build or /game-build [feature-name]
Reads .project/features/{feature-name}/feature.json: requirements (REQ-XXX), architecture, files, buildSequence.
.project/features/{feature-name}/
├── feature.json # Enriched with build, packages, tests.checklist sections
├── playtest_scene.tscn # Auto-generated test scene
└── debug_listener.gd # Debug signal capture script
scenes/ # Created .tscn files
scripts/ # Created .gd files
resources/ # Created .tres files
tests/
├── test_{feature}.gd # Unit tests (GUT)
└── scenes/ # Integration test scenes
└── test_{feature}_runtime.tscn
ALL test runs must have their output PARSED before showing in context.
Raw GUT output is ~500 lines per run. With 15 runs per build = 7500 lines of context bloat.
Parsing rules:
After running any GUT test command, parse the output to this format:
PASS scenario (1 line):
TESTS: 141/141 PASS (10.2s)
FAIL scenario (max 10 lines):
TESTS: 139/141 PASS (10.2s)
FAILED:
- test_health_system.test_req001: expected 100, got 0
- test_player.test_knockback: signal not emitted
PENDING scenario (max 5 lines):
TESTS: 4/15 PASS, 11 PENDING (2.1s)
Parse logic:
This reduces context by ~99% per test run.
Fase tracking — eerste actie van de skill: roep TaskCreate aan met deze 10 items (status pending), daarna gebruik TaskUpdate om per fase in_progress te zetten aan begin en completed aan einde. Bij context compaction blijft de task list zichtbaar — geen risico op vergeten fases.
Todo: roep
TaskCreateaan met de 10 fase-items (zie boven). Markeer FASE 0 →in_progressviaTaskUpdate.
If no feature name provided — check backlog:
.project/backlog.html, parse JSON uit <script id="backlog-data"> blok (zie shared/BACKLOG.md)data.features.filter(f => f.status === "DEFINED")Backlog suggests: {feature-name}
Defined features available: {list}
Build {feature-name}? (or specify another)
Load architecture baseline:
Read(".claude/research/architecture-baseline.md")WARNING: No architecture-baseline.md found.
Run /project-plan or create .claude/research/architecture-baseline.md for better context.
Continuing without baseline...
Project context (optioneel, skip als niet bestaat):
Lees .project/project.json. Extract:
stack — framework, language, packages (fallback voor architecture-baseline)data.entities — bestaand data model (voorkomt conflicten)Lees .project/project-context.json (als bestaat). Extract:
context.structure — waar bestanden horen (map structuur)context.patterns — bestaande code patterns om te volgenarchitecture — huidige architectuur diagram en beschrijvingLearnings load (via shared/LEARNINGS-LOAD.md):
Configuratie:
scopes: [component]
pitfall-prefix: true
current-feature: <feature-name>
Toon de geladen output. Pitfall-prefix sectie + component-scoped patterns geven context voor de build (geen constraint — bij twijfel ga uit van root cause, niet pattern-match).
Bewaar de geladen learnings voor FASE 1 (Technique Mapping).
Als project.json niet bestaat → ga door zonder (backwards compatible).
Stel PROJECT_CONTEXT samen (wordt meegegeven aan technique execution in FASE 2/3):
Bouw selectief op basis van feature.json → files[] paden:
Structure en Patterns → altijd meenemen (compact)Entities → alleen als feature scenes/resources met data raaktPROJECT CONTEXT:
Structure: {context.structure of "niet beschikbaar"}
Patterns: {context.patterns of "niet beschikbaar"}
Entities: {data.entities of "niet beschikbaar" — skip als feature geen data raakt}
Load feature.json:
Ready queue (alleen als geen feature-naam via CLI opgegeven):
Parse .project/backlog.html. Bereken per DEFINED feature of alle dependencies[] status === "DONE" hebben (of dep-lijst leeg is). Toon vóór de feature-selectie:
Ready om te bouwen:
✓ jump-mechanic P1 (geen deps)
✓ enemy-ai P2 deps: [pathfinding ✓]
Geblokkeerd:
✗ boss-fight P1 wacht op: [enemy-ai — DOING]
If no feature name provided:
.project/backlog.html (zie shared/BACKLOG.md). Filter status === "DEFINED" → suggest via AskUserQuestion (ready features bovenaan).project/features/ met feature.json, let user selectLoad feature.json. Extract: requirements[], buildSequence[], files[], testStrategy[]. Als clarifications[] aanwezig: behandel als harde constraints tijdens implementatie (gray-area beslissingen van de user).
Niet gevonden → exit: "Run /game-define eerst."
Dependency check:
Skip als geen depends[] of leeg.
.project/backlog.html. Niet gevonden → skip."DONE" zijn.Workspace setup (optioneel):
Alleen tonen als we NIET al in een worktree zitten:
git rev-parse --show-toplevel vs eerste pad uit git worktree list --porcelain
→ Verschillend: al in worktree → skipheader: "Workspace"
question: "Wil je in een worktree werken voor deze build?"
options:
- label: "Nee, huidige directory (Recommended)"
description: "Werk op de huidige branch"
- label: "Ja, worktree aanmaken"
description: "Geïsoleerde workspace — ideaal bij parallel werken"
multiSelect: false
EnterWorktree(name: "{feature-name}")Branch-naming:
EnterWorktreemaakt branchworktree-{feature-name}(NIET{feature-name}). Vervolgskills (game-verify,game-debug,game-refactorsingle-mode) detecteren deze worktree automatisch viashared/WORKTREE.mden switchen erin. Voor merge/cleanup gebruik je/core-mergeof handmatiggit worktree remove --force+git branch -D worktree-{feature-name}.
Tag backlog card als actief (direct na feature laden):
Lees .project/backlog.html (als bestaat), parse JSON (zie shared/BACKLOG.md).
Zoek feature op naam → zet "status": "DOING", "stage": "building", data.updated naar nu (overgang DEFINED → DOING bij build-start).
Schrijf terug via Edit (keep <script> tags intact).
De card verhuist naar DOING-kolom met stage building.
Read implementation order:
Extract the buildSequence[] from feature.json (sorted by step).
This was determined during the define phase.
Implementation order (from define phase):
1. REQ-001 (base)
2. REQ-002 (after REQ-001)
3. REQ-003 (after REQ-002)
Display context:
FEATURE: {feature-name}
REQUIREMENTS:
- REQ-001: [description]
- REQ-002: [description]
...
ARCHITECTURE:
- Scenes: [list]
- Scripts: [list]
- Resources: [list]
IMPLEMENTATION ORDER:
1. REQ-001 (base)
2. REQ-002 -> REQ-001
...
Capture git baseline (for scoped commit at end of skill):
mkdir -p .project/session
# Cleanup stale session state from previous crashed runs (>1 dag oud)
find .project/session -maxdepth 1 \( -name "active-*.json" -o -name "pre-skill-*.txt" \) -mtime +1 -delete 2>/dev/null
git status --porcelain | sort > .project/session/pre-skill-status.txt
echo '{"feature":"{feature-name}","skill":"build","startedAt":"{ISO timestamp}"}' > .project/session/active-{feature-name}.json
Risk-check (alleen als backlog feature risk >= 4):
Als de geladen backlog-feature een risk-score van 4 of 5 heeft, toon deze waarschuwing vóór FASE 1:
⚠ HOOG RISICO — Complexiteit {risk}/5
Overweeg vóór de bouw:
- Zijn alle dependencies beschikbaar (status DONE)?
- Is de feature-definitie volledig (alle REQs helder)?
- Bouw in kleine stappen — commit na elke werkende REQ
Todo: markeer FASE 0 →
completed, FASE 1 →in_progress.
REMOVED filter: Requirements met deltaOp === "REMOVED" overslaan — geen technique toewijzen, niet tonen in technique map tabel.
Per requirement, assign a technique: TDD, Implementation First, or Implementation Only.
TDD (test first, then implement):
Implementation First (implement, then write verification test):
Implementation Only (geen tests — alleen wanneer automated tests geen waarde toevoegen):
visual-only, config-only, of prototypeSee techniques/implementation-first.md for the full Implementation First process.
Pitfall overlap check: voor elke requirement, vergelijk met de pitfall-lijst uit FASE 0. Bij duidelijke thematische overlap (zelfde domein, zelfde type bug-risico) → log expliciet welke pitfall geraakt wordt en hoe deze build het voorkomt. Geen forcing — alleen markeren waar relevant.
TECHNIQUE MAPPING:
TDD:
- REQ-001: Water ability deals 20 damage [logic]
- REQ-003: Puddle slows enemies by 30% [calculation]
IMPLEMENTATION FIRST:
- REQ-002: Puddle spawns at impact location [scene setup]
IMPLEMENTATION ONLY:
- REQ-004: Water splash particle effect [visual-only]
Proceed automatically — do NOT confirm with the user. The decision logic above is deterministic enough to auto-assign. Display the mapping for visibility, then continue to the next phase.
Todo: markeer FASE 1 →
completed, FASE 2 →in_progress.
Read references/gut-conventions.md voor test file structure, assertions en mock patronen. Geen sub-agent nodig — patronen zijn lokaal beschikbaar.
For each TDD requirement, generate a corresponding test stub:
extends GutTest
## Tests for {Feature}
## Generated from feature.json requirements
var _sut: ClassName # System Under Test
func before_each() -> void:
pass # Setup
func after_each() -> void:
pass # Cleanup
# REQ-001: {requirement description}
func test_req001_{snake_case_description}() -> void:
pending("Not implemented")
# REQ-003: {requirement description}
func test_req003_{snake_case_description}() -> void:
pending("Not implemented")
Actions:
tests/test_{feature}.gd with all test stubs"{godot_executable}" --headless --path . -s addons/gut/gut_cmdln.gd -gexit -gtest=res://tests/test_{feature}.gd
Output:
FASE 2 COMPLETE
Tests generated: {count} (TDD requirements only)
Status: All PENDING
Ready for TDD cycle.
Todo: markeer FASE 2 →
completed, FASE 3 →in_progress.
Two tracks run based on technique mapping from FASE 1.
Use the IMPLEMENTATION ORDER determined in FASE 0 (no re-analysis needed).
implemented := []
files_created := []
FOR each TDD REQ-XXX in DEPENDENCY ORDER:
|
+-- Gather current state:
| files_list := list all .gd files in scripts/
| classes := extract class names from files
|
+-- Build context string:
| context := "ALREADY IMPLEMENTED:\n"
| FOR each prev_req in implemented:
| context += "- {prev_req}: {files created}\n"
| context += "\nEXISTING CLASSES:\n"
| FOR each class in classes:
| context += "- {class} at {path}\n"
|
+-- Task(subagent_type="godot-tdd-implementer", prompt="
Feature: {feature-name}
{context}
YOUR TASK:
Requirement: {REQ-XXX}: {description}
Test file: tests/test_{feature}.gd
Test function: test_req{xxx}_{description}
RULES:
- DO NOT recreate existing classes
- EXTEND existing code if needed
- READ existing files before modifying
Implement this requirement using TDD.
")
|
+-- On SUCCESS:
| implemented.append(REQ-XXX)
| files_created.extend(result.files)
| Log: "[REQ-XXX] PASS"
|
+-- On FAIL:
Log: "[REQ-XXX] FAIL - {reason}"
Analyze error, fix implementation, re-run test
Only continue to next requirement when PASS
After all TDD requirements processed:
All TDD requirements should be PASS before proceeding to Track B. If any requirement cannot pass, log as BLOCKED in feature.json build.blockers.
RED (Test Fails):
pending() with actual test)RED: test_req001 - FAIL (expected)# REQ-001: Water ability deals 20 damage
func test_req001_water_deals_20_damage() -> void:
# Arrange
var ability := WaterAbility.new()
var target := MockTarget.new()
add_child(ability)
add_child(target)
# Act
ability.execute(target)
# Assert
assert_eq(target.damage_taken, 20, "Water should deal 20 damage")
GREEN (Minimal Implementation):
Before implementing, check if research is needed:
Research Decision Logic:
IF implementation involves:
- State machines -> research needed
- Custom signals -> research needed
- Custom Resources -> research needed
- Complex node hierarchy -> research needed
- Physics/collision -> research needed
- Animation integration -> research needed
ELSE:
- Basic property changes -> no research
- Simple methods -> no research
- Already researched -> no research (use cache)
If research IS needed:
Task(subagent_type="godot-code-researcher", prompt="
Feature: {feature-name}
Requirement: {REQ-XXX}: {description}
Pattern needed: {state machine / signals / resources / etc.}
Return COMPACT summary (max 50 lines):
- Key signals if needed (1 line each)
- 1 code pattern example (max 15 lines)
- Gotchas (1 line each)
DO NOT return full documentation.
")
Then implement:
GREEN: test_req001 - PASSREFACTOR (Clean Up):
REFACTOR: complete, all tests still PASSAdd Debug Hooks:
After each requirement is implemented and refactored, add debug tracking for playtest:
# Debug hooks pattern - add to key methods
func execute(target: Node) -> void:
print("[DEBUG] %s.execute() called - target: %s" % [name, target.name])
# ... implementation
print("[DEBUG] %s.execute() complete - damage: %d" % [name, _damage_dealt])
# For key events, emit debug signals
signal debug_ability_used(ability_name: String, data: Dictionary)
func _on_ability_complete() -> void:
debug_ability_used.emit(name, {"damage": _damage_dealt, "target": _target.name})
print("[DEBUG] Signal emitted: debug_ability_used")
Debug hook rules:
[DEBUG] ClassName.method() - key: valuedebug_* signals for key events (captured by DebugListener in playtest)When to add hooks:
Output per iteration:
[ITERATION {n}]
Test: test_req{xxx}_{description}
RED: FAIL (class not found)
GREEN: PASS (implemented WaterAbility.execute())
REFACTOR: PASS (added type hints)
Progress: {passed}/{total} tests passing
For each Implementation First requirement (in dependency order):
# Written AFTER implementation to verify behavior
func test_req{xxx}_{description}() -> void:
var scene := preload("res://scenes/{feature}.tscn").instantiate()
add_child(scene)
await get_tree().process_frame
# Assert scene structure
assert_not_null(scene.get_node("ExpectedChild"))
# Assert configuration
assert_eq(scene.some_property, expected_value)
scene.queue_free()
IMPL-FIRST: REQ-{xxx} implemented + verifiedSee techniques/implementation-first.md for detailed patterns.
For each Implementation Only requirement (in dependency order):
requirements[].status → "built", voeg technique: "implementation-only" en skipTestReason toe (visual-only, config-only, of prototype)IMPL-ONLY: REQ-{xxx} implemented (reason: {skipTestReason})Loop completion:
BUILD CYCLE COMPLETE
TDD: {tdd_passed}/{tdd_total} tests PASS
Impl-First: {impl_passed}/{impl_total} verified
Impl-Only: {only_count} implemented (no tests)
Files created:
- scripts/abilities/water_ability.gd
- resources/abilities/water.tres
...
Todo: markeer FASE 3 →
completed, FASE 3a →in_progress.
Goal: Verify that the new feature hasn't broken existing features.
Na succesvolle afronding van alle tracks, run de volledige GUT test suite (niet alleen de huidige feature):
"{godot_executable}" --headless --path . -s addons/gut/gut_cmdln.gd -gexit
Parse output met dezelfde regels als alle test runs (zie Test Output Parsing).
PASS: Alle tests slagen — ga door naar FASE 3b.
REGRESSION CHECK: {total}/{total} PASS — geen regressies
FAIL: Andere feature tests falen — dit is een gate.
REGRESSION CHECK: {passed}/{total} PASS
REGRESSIES GEVONDEN:
- test_{other_feature}.test_xxx: {reason}
- test_{other_feature}.test_yyy: {reason}
Bestanden overlap: {lijst van bestanden die zowel door deze feature als de falende feature worden gebruikt}
Bij regressie:
Skip condition: Als er geen andere test-bestanden bestaan (eerste feature), skip met:
REGRESSION CHECK: overgeslagen (geen eerdere features met tests)
Todo: markeer FASE 3a →
completed, FASE 3b →in_progress.
These two tasks have NO dependencies on each other - run them in parallel.
Create runtime test scenes for MCP verification:
File: tests/scenes/test_{feature}_runtime.tscn
Script: tests/scenes/test_{feature}_runtime.gd
extends Node2D
## Integration test scene for {Feature}
## Run via MCP to verify runtime behavior
var _results: Dictionary = {}
var _all_passed: bool = false
func _ready() -> void:
await _run_all_tests()
_report_and_quit()
func _run_all_tests() -> void:
print("INTEGRATION TEST START: {feature}")
_results["req001_damage"] = await _test_req001_damage()
_results["req002_spawn"] = await _test_req002_spawn()
_all_passed = _results.values().all(func(r): return r)
func _test_req001_damage() -> bool:
var ability := WaterAbility.new()
add_child(ability)
# ... test logic
return true
func _report_and_quit() -> void:
print("")
print("INTEGRATION TEST RESULTS:")
for test_name in _results:
var status := "PASS" if _results[test_name] else "FAIL"
print("TEST:%s:%s" % [test_name, status])
print("")
var final_status := "PASS" if _all_passed else "FAIL"
print("FINAL:%s" % final_status)
get_tree().quit(0 if _all_passed else 1)
Run via MCP:
run_project(projectPath=".", scene="res://tests/scenes/test_{feature}_runtime.tscn")
get_debug_output()
# Parse output for FINAL:PASS or FINAL:FAIL
Build tests.checklist[] data for feature.json (written in FASE 4b):
{
"tests": {
"checklist": [
{
"id": 1,
"title": "{wat te verifiëren}",
"type": "MANUAL",
"requirementId": "REQ-001",
"steps": [
"open game",
"gebruik ability op vijand",
"observeer schade-effect"
],
"expected": "vijand toont damage number, health bar daalt",
"status": "pending"
}
]
}
}
Include both automated test results and manual playtest items in the checklist. Automated items get type: "AUTO", manual playtest items get type: "MANUAL".
Richtlijnen voor checklist items:
Create playtest scene at .project/features/{feature-name}/playtest_scene.tscn:
PlaytestArena (Node2D)
+-- Camera2D (current=true)
+-- PlayerSpawn (Marker2D)
+-- Player (instanced from scenes/player/ if exists)
+-- TestTarget (CharacterBody2D for ability targets)
+-- ArenaBounds (ColorRect, visual boundary)
+-- FeatureUnderTest (instanced based on feature type)
+-- DebugListener (captures debug signals)
DebugListener script at .project/features/{feature-name}/debug_listener.gd:
extends Node
## Auto-generated debug listener for playtest
## Captures all debug_* signals and logs them for analysis
var _debug_log: Array[Dictionary] = []
func _ready() -> void:
_connect_debug_signals(get_parent())
print("[PLAYTEST] Debug listener active - tracking %d signals" % _debug_log.size())
func _connect_debug_signals(node: Node) -> void:
for signal_info in node.get_signal_list():
if signal_info.name.begins_with("debug_"):
node.connect(signal_info.name, _on_debug_signal.bind(node.name, signal_info.name))
for child in node.get_children():
_connect_debug_signals(child)
func _on_debug_signal(data: Variant, node_name: String, signal_name: String) -> void:
var entry := {
"time": Time.get_ticks_msec(),
"node": node_name,
"signal": signal_name,
"data": data
}
_debug_log.append(entry)
print("[PLAYTEST] %s.%s: %s" % [node_name, signal_name, str(data)])
func get_log() -> Array[Dictionary]:
return _debug_log
func get_log_summary() -> String:
var summary := "Debug Log (%d entries):\n" % _debug_log.size()
for entry in _debug_log:
summary += " %dms: %s.%s\n" % [entry.time, entry.node, entry.signal]
return summary
Todo: markeer FASE 3b →
completed, FASE 4 →in_progress.
STOP — ga NIET door naar de sync zonder deze fase volledig af te ronden.
Display een visuele separator:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
WAT HEBBEN WE GEBOUWD?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Stap 1 — Uitleg displayen (verplicht, niet overslaan)
De gebruiker moet begrijpen hoe de feature werkt voor goede beslissingen in test- en refactor-fases. Display de volgende uitleg alsof je het aan een student uitlegt:
Stap 2 — Begripscheck (verplicht, niet overslaan)
AskUserQuestion direct na de uitleg:
Vraag: "Snap je hoe de feature werkt?" Opties: "Ja, helder" / "Leg het uitgebreider uit" / "Ik heb een vraag"
Follow-up loop tot "Ja, helder". Sla uitleg op als build.explanation in feature.json (targeted Edit).
Todo: markeer FASE 4 →
completed, FASE 4b →in_progress.
Volg shared/SYNC.md 3-File Sync Pattern. Skill-specifieke mutaties hieronder.
Lees parallel (skip als niet bestaat):
.project/features/{feature-name}/feature.json.project/backlog.html.project/project.json.project/project-context.jsonMuteer in memory:
feature.json: status → "DOING", stage → "built", requirements[] → enrich with technique, syncNote, status: "built", files[] → merge with actual files. Add: build {} (started, completed, techniques, testsPass, testsTotal, decisions), packages[], tests.checklist[] (status: "pending"). Bestaande secties NIET overschrijven.
Backlog (zie shared/BACKLOG.md): stage → "built", data.updated → nu. Status blijft "DOING".
Context (in project-context.json, zie shared/DASHBOARD.md → context): identify new scenes (.tscn), scripts (.gd) with class names, signals, resources (.tres). Update context.structure (overwrite), context.patterns (merge signals, autoloads, conventions), context.updated. Skip als geen structurele impact.
Dashboard (zie shared/DASHBOARD.md): feature status → "DOING", stage → "built". Als feature niet bestaat: push met { name, status: "DOING", stage: "built", summary, created }.
Architecture (in project-context.json, volg component-first model uit shared/DASHBOARD.md): update architecture.components[] — gebouwde componenten status: "planned" → "done", vul description (korte functionele beschrijving, max 200 chars — wat doet dit component?), src, test, connects_to (typed edges { to, type } — calls voor signal emits/method calls, reads/writes voor autoload/state IO, depends_on voor scene-tree parent of resource references), feature (huidige feature naam). Nieuwe componenten: push met alle velden inclusief feature. Als layers/components niet bestaan EN meerdere scenes/signals → genereer initiële architecture met layers + components. Skip als geen structurele impact. Log: architecture: updated of architecture: no updates needed.
Learning extraction (na feature.json sync): schrijf naar project-context.json learnings[] (append-only, identiek formaat als game-verify/game-refactor):
build.decisions[] → type: "pattern" (architecturale keuze gemaakt)build.blockers[] waar de blocker opgelost is (niet meer BLOCKED aan einde build) → type: "pitfall"{
"date": "...",
"feature": "{naam}",
"type": "pattern|pitfall",
"source": "extracted",
"summary": "..."
}
Alleen schrijven als er decisions of opgeloste blockers aanwezig zijn — geen lege entries.
Schrijf parallel terug:
feature.jsonbacklog.html (keep <script> tags intact)project.jsonproject-context.json (als context/architecture gewijzigd)Todo: markeer FASE 4b →
completed, FASE 5 →in_progress.
BUILD COMPLETE: {feature}
========================
Techniques: TDD ({n}), Implementation First ({n}), Implementation Only ({n})
Tests: {passed}/{total} PASS
Files created: {count}
Created files:
- tests/test_{feature}.gd
- tests/scenes/test_{feature}_runtime.tscn
- scripts/...
- scenes/...
Todo: markeer FASE 5 →
completed, FASE 6 →in_progress.
Stap 0: Pre-commit gdlint check (GDScript):
gdlint beschikbaar is: command -v gdlint.gd bestanden gewijzigd → skipBij beschikbaar: run op gewijzigde .gd bestanden van deze build:
timeout 60 gdlint $(git diff --name-only $(cat .project/session/pre-skill-status.txt) 2>/dev/null | grep '\.gd$') 2>&1
DIAGNOSTICS: PASS, door naar commit-flow"Fix eerst (Recommended)" — stop FASE 6, geen commit"Toch committen" — door; voeg [diagnostics-warnings] toe aan commit messageScoped auto-commit (only this skill's changes):
Compare current git status with baseline from FASE 0:
git status --porcelain | sort > /tmp/current-status.txt
Categorize files by comparing with .project/session/pre-skill-status.txt:
git add automaticallyIf baseline file doesn't exist, fall back to git add -A.
git commit -m "build({feature}): {n} requirements ({tdd} TDD, {impl} impl-first, {only} impl-only)"
Clean up: rm -f .project/session/pre-skill-status.txt .project/session/active-{feature-name}.json /tmp/current-status.txt
Output:
BUILD COMPLETE: {feature}
========================
Techniques: TDD ({n}), Implementation First ({n}), Implementation Only ({n})
Tests: {passed}/{total} PASS
Files created: {count}
Next steps:
1. /game-verify {feature} → playtest verificatie
2. /game-debug → als er onverwachte failures zijn
Worktree reminder — voeg één extra blok toe aan de output als de huidige branch matcht worktree-* pattern (git branch --show-current):
💡 Worktree actief: {worktree_path}
Volgende skills (/game-verify, /game-refactor, /game-debug) starten in een NIEUWE chat —
ze detecteren deze worktree automatisch en switchen erin.
Voor merge/cleanup: /core-merge {feature}
Todo: markeer FASE 6 →
completed. Alle 10 fases moeten nucompletedzijn.
Just-In-Time Read() deze tijdens specifieke fases — niet vooraf laden.
| File | Wanneer laden |
|---|---|
references/gut-conventions.md | FASE 2 — bij genereren van test files (file structure, assertions, mocks) |
references/gut-commands.md | FASE 3, 3a, 3b — bij draaien van GUT tests |
references/troubleshooting.md | FASE 3 — bij test failures of build blockers |
Completion claims vereisen verse output (R009 — zie
../shared/RULES.md)
{godot_executable} in commands wordt opgelost via paths.yaml:
/Applications/Godot.app/Contents/MacOS/GodotC:\Godot\Godot_v4.4.1-stable_win64.exeOverride: env var CLAUDE_GODOT_EXECUTABLE of .claude/paths.local.yaml. Canonical defaults staan in skills/project-add/paths.yaml.