with one click
game-define
// Define game feature requirements and architecture with structured output. Use with /game-define to create detailed game feature specifications before building.
// Define game feature requirements and architecture with structured output. Use with /game-define to create detailed game feature specifications before building.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | game-define |
| description | Define game feature requirements and architecture with structured output. Use with /game-define to create detailed game feature specifications before building. |
| writes | ["feature.requirements","backlog.stage"] |
| metadata | {"author":"mileszeilstra","version":"2.3.0","category":"game"} |
This skill defines game feature requirements and architecture for Godot 4.x projects. It is FASE 1 of the gamedev workflow: plan -> define -> build -> test -> refactor.
The skill gathers requirements through targeted questions, optionally researches Godot scene architecture, and designs the implementation. Output is a consolidated documentation file ready for the build phase.
Trigger: /game-define or /game-define [feature-name]
Triggers:
/game-define - Start with feature name prompt/game-define abilities - Define ability system/game-define player-movement - Define player movementWorks best with:
If name provided (/game-define abilities):
If no name (/game-define):
a) Check backlog for next feature:
Read(".project/backlog.html")
<script id="backlog-data"> blok (zie shared/BACKLOG.md)data.features.find(f => f.status === "TODO")b) If backlog has a next feature:
Use AskUserQuestion tool:
header: "Feature Name"
question: "Volgende feature uit backlog: {feature-name}. Hiermee doorgaan?"
options:
multiSelect: false
If user picks the backlog feature → use that name, continue to step 3
If user picks "Andere feature" → fall through to option (c)
c) No backlog but concept exists:
Check of .project/project-concept.md bestaat (of project.json → concept.content niet leeg).
Als concept gevonden:
AskUserQuestion:
header: "Concept zonder backlog"
question: "Er is een concept maar nog geen backlog. Wil je eerst een backlog genereren?"
options:
- label: "Ja, eerst /project-plan (Recommended)", description: "Genereer backlog uit concept, dan features definiëren"
- label: "Nee, direct definiëren", description: "Definieer een losse feature zonder backlog"
multiSelect: false
"Ja" → stop, toon: Draai /project-plan om je concept om te zetten in een backlog.
"Nee" → ga door naar optie d.
d) No backlog, no concept (or user chose direct define):
Use AskUserQuestion tool:
The user can type any feature name via the built-in "Other" option.
Tag backlog card als actief (direct na feature naam bepaling):
Lees .project/backlog.html (als bestaat), parse JSON (zie shared/BACKLOG.md).
Zoek feature op naam → behoud "status": "TODO", zet "stage": "defining", data.updated naar nu.
Schrijf terug via Edit (keep <script> tags intact).
Niet gevonden → skip (feature wordt pas bij FASE 5 aan backlog toegevoegd).
De card blijft in TODO maar krijgt een pulserende defining stage-badge.
2b. Feature existence check (na naam-bepaling, vóór context-load):
Check: .project/features/{feature-name}/feature.json bestaat?
Create project folder + signal active feature:
mkdir -p .project/features/{feature-name}
mkdir -p .project/session
echo '{"feature":"{feature-name}","skill":"define","startedAt":"{ISO timestamp}"}' > .project/session/active-{feature-name}.json
Load architecture-baseline as context:
Read(".claude/research/architecture-baseline.md")
ℹ Architecture baseline loaded — context available for all phases.
Or if not found:
⚠ Architecture baseline not found — run /core-setup to generate.
Load project context (paralleliseer met stap 4):
.project/project.json → extract:
stack — framework, language, packages (fallback als architecture-baseline niet bestaat)concept.pitch als feature context (korte samenvatting). Fallback: als pitch leeg, lees .project/project-concept.md → eerste 2 zinnenfeatures[] — bestaande features (voorkomt duplicaten/overlap)data.entities — bestaand data modelthinking[] — scan voor entries met newFeature veld matching de feature-naam (toegevoegd via /project-todo). Laad die als context..project/thinking/*.md op feature-naam (bestandsnaam + content). Bij 1+ match: lees de match(es) en gebruik als input voor FASE 1 vragen. De .md bestanden zijn bron van waarheid voor thinking-output — geen 7-dagen window meer..project/project-context.json (als bestaat) → extract:
context.patterns — bestaande code patternsscopes: [component, architectural]
pitfall-prefix: true
current-feature: <feature-name>
Toon de geladen output vóór FASE 1 vragen. Component-scoped patterns en architectural patterns geven richting bij architectuur-keuzes en requirement-formulering. Pitfall-prefix voorkomt herhaling van eerdere bugs.project.json niet aanwezig → toon: ⚠️ Geen project.json gevonden. Overweeg eerst /core-setup te draaien voor betere codebase-context. Ga door zonder (non-blocking).context, stack, én features) → toon: ℹ️ project.json bestaat maar mist codebase-context. /core-setup kan dit aanvullen..project/features/*/feature.json → flatten alle durableDecisions[]. Tag elke entry met [feature-X]..project/thinking/*-decision-*.md → lees eerste ~30 regels per file, extract THINK: regel (titel), AANBEVELING: regel (chosen), en CONSTRAINT sectie. Tag elke entry met [project].Lees .project/features/{feature-name}/feature.json.
Toon bestaande requirements samenvatting:
| ID | Beschrijving (eerste 60 chars) | Status |
|---|---|---|
| REQ-001 | {beschrijving} | pending |
AskUserQuestion: "Feature {name} bestaat al met {N} requirements. Wat wil je aanpassen?"
header: "Update-mode"
options:
- label: "Requirements toevoegen (Recommended)", description: "Nieuwe requirements, doorgenummerd vanaf REQ-{N+1}"
- label: "Requirements wijzigen", description: "Bestaande requirements herformuleren of acceptance aanpassen"
- label: "Requirements verwijderen", description: "Requirements uit scope halen (soft-delete)"
- label: "Meerdere van bovenstaande", description: "Combinatie van toevoegen, wijzigen en/of verwijderen"
multiSelect: false
Verwerk delta op basis van keuze:
REQ-{N+1}.[{ when, then }] per scenario.deltaOp: "REMOVED" — verwijder niet fysiek uit de array. Ook: verwijder het REQ-ID uit alle buildSequence[].requirements[] arrays; als een step daarna leeg is → verwijder de step.Sla deltaOp op per requirement:
"deltaOp": "UNCHANGED""deltaOp": "ADDED""deltaOp": "MODIFIED" + "previousDescription": "{oorspronkelijke tekst}""deltaOp": "REMOVED" (blijft in array, wordt niet gebouwd of getest)Status-reset: als feature status was "DOING" → zet terug naar "DEFINED" in feature.json en backlog.
Skip FASE 1b (feature splitting) tenzij het aantal requirements na update boven 6 stijgt én er duidelijke clusters zijn.
Ga naar FASE 2 voor alleen ADDED en MODIFIED requirements. Bij FASE 5 write: merge delta naar bestaand feature.json — overschrijf niet volledig. Bewaar bestaande build, tests en UNCHANGED requirements intact. buildSequence: verwijder stappen die leeg zijn na REMOVED-filtering; voeg nieuwe stappen toe voor ADDED requirements (uit FASE 2 architectuur output); bestaande stappen voor UNCHANGED requirements ongewijzigd laten.
Risk-check (alleen als feature.risk >= 4):
Als de geladen backlog-feature een risk-score van 4 of 5 heeft, toon deze waarschuwing vóór de eerste vraag:
⚠ HOOG RISICO — Complexiteit {risk}/5
Deze feature heeft een hoge complexiteitsscore. Overweeg vóór de definitie:
- Splits de feature op in kleinere onderdelen
- Verifieer dat dependencies beschikbaar zijn
- Bespreek scope als onderdelen onduidelijk zijn
Surface relevant past decisions (alleen bij ≥1 match uit FASE 0 scan, anders skip stilzwijgend):
EERDER BESLOTEN (mogelijk relevant)
- [project] {decision} → koos {chosen} (constraint: {constraint})
- [feature-X] {decision} → koos {chosen} (constraint: {constraint})
Toon vóór de eerste AskUserQuestion. Geen actie-vraag — alleen context zodat vraag-1 antwoorden niet conflicteren met eerder besloten richtingen. Als een huidige antwoord-optie direct conflicteert, noem dat kort in de optie-description ("Wijkt af van {feature-X} decision").
Ask 5 targeted questions using AskUserQuestion:
Question 1: Core Function
Question 2: Game Mechanics
Question 3: Player Interactions
Question 4: Visual Feedback
Question 5: Data Requirements
User-delegatie: als de user antwoordt met "wat denk jij?" of vergelijkbaar, geef een korte aanbeveling met trade-off en ga door met die keuze.
Na de initiële vragen, evalueer of er open branches zijn:
≤3 requirements verwacht: skip doorvraag, ga naar extraction. >3 requirements verwacht: stel 1-2 gerichte doorvragen over de belangrijkste open branch. Formuleer als "Wat gebeurt er als...?" of "Hoe gaat dit om met...?"
Max 2 extra vragen, dan door naar extraction.
Skip als doorvraag-check geen open branches heeft gevonden.
Anders: voor elke geïdentificeerde open branch (max 3):
Formuleer de ambiguïteit als concrete keuze via AskUserQuestion:
Noteer de keuze als clarification:
{ "question": "{open branch}", "answer": "{gekozen optie}", "impact": "kort welk requirement-gebied dit raakt" }
"Niet relevant" → noteer als scoped-out, niet als requirement. >3 open branches → verwerk overige inline bij requirement extraction als edge case.
Max 3 AskUserQuestion calls. Dan door naar extraction.
After questions, extract testable requirements:
{ when, then } paren (concrete, verifiable)Show requirements table with acceptance scenarios:
| ID | Requirement | Category | Test Type | Acceptance |
|---|---|---|---|---|
| REQ-001 | {description} | {category} | {type} | WHEN {trigger} → THEN {verwacht result} |
Meerdere scenario's per requirement → meerdere rijen met hetzelfde REQ-ID, of bullets.
Voor requirements die getallen of timing bevatten (damage, speed, cooldown, radius, etc.), extraheer tuning levers:
| Parameter | Default | Min | Max | Impact |
|---|---|---|---|---|
| {naam} | {waarde} | {min} | {max} | {wat verandert er voor de speler} |
Markeer defaults als [PLACEHOLDER] als ze nog niet geplaytest zijn.
Voor requirements met interacties of state changes, documenteer edge cases:
Alleen relevante edge cases — niet elk requirement heeft ze. Skip bij simpele features (≤3 requirements zonder getallen).
Tuning levers worden opgeslagen in feature.json per requirement als tuningLevers[].
Print 8 blank lines as whitespace buffer (keeps the requirements table above visible when the modal panel opens).
Confirm with user via AskUserQuestion:
If "Aanpassen" → ask what to change, update requirements table, re-confirm. If "Opnieuw beginnen" → restart FASE 1 from Question 1.
Na de requirements tabel bevestiging, presenteer een compleet overzicht:
| Aspect | Waarde |
|---|---|
| Feature | {naam} |
| Core function | {vanuit spelersperspectief} |
| Mechanics | {gekozen mechanics} |
| Interactions | {gekozen interacties} |
| Visuals | {gekozen visuele feedback} |
| Data | {gekozen data management} |
| Requirements | {N} requirements |
Print 8 blank lines as whitespace buffer (keeps the overview table above visible when the modal panel opens).
Vraag via AskUserQuestion:
Goal: Analyze gathered requirements and decide whether to keep as a single feature or split into multiple sub-features for optimal build execution.
Steps:
Analyze requirement scope:
Count requirements and map dependency graph from FASE 1 output.
SCOPE ANALYSIS:
Total requirements: {count}
Categories: {list of unique categories}
Dependency depth: {max chain length}
Identify dependency clusters:
Group requirements that depend on each other into clusters:
Apply decision logic:
IF requirements ≤ 6 AND single category/concern:
→ SINGLE feature (continue normally)
IF requirements 7-10:
→ EVALUATE: check if ≥2 natural clusters exist with ≤2 cross-dependencies
→ If clusters found: RECOMMEND SPLIT
→ If tightly coupled: SINGLE feature
IF requirements > 10:
→ RECOMMEND SPLIT (unless linear dependency chain with single concern)
If SINGLE feature:
✓ Scope analysis: SINGLE FEATURE
Requirements: {count}
Reason: {e.g., "tightly coupled, single concern", "≤6 requirements"}
→ Continuing to architecture design.
Proceed to FASE 2.
If SPLIT recommended:
Show proposed split:
SPLIT RECOMMENDATION:
Requirements: {count} → {n} sub-features
1. {feature-name}-{sub1} (REQ-001, REQ-002, REQ-003)
Focus: {description of this group's concern}
2. {feature-name}-{sub2} (REQ-004, REQ-005)
Focus: {description of this group's concern}
Build order: {sub1} → {sub2}
Cross-dependencies: {list or "none"}
Print 8 blank lines as whitespace buffer (keeps the SPLIT RECOMMENDATION above visible when the modal panel opens).
Use AskUserQuestion for confirmation:
Response Handling:
Execute split (if approved):
a. Create parent documentation:
Write .project/features/{feature-name}/00-split.md:
# Feature Split: {Feature Name}
**Created:** {date}
**Status:** split
**Original requirements:** {count}
**Sub-features:** {count}
## Split Decision
Reason: {why split was recommended}
## Sub-features
| # | Sub-feature | Requirements | Focus |
| --- | ------------- | ------------------------- | ------- |
| 1 | {name}-{sub1} | REQ-001, REQ-002, REQ-003 | {focus} |
| 2 | {name}-{sub2} | REQ-004, REQ-005 | {focus} |
## Build Order
1. {name}-{sub1} (base, no dependencies)
2. {name}-{sub2} (after {sub1})
## Commands
```
/game-build {name}-{sub1}
/game-build {name}-{sub2}
```
b. Create sub-feature project folders:
mkdir -p .project/features/{feature-name}-{sub1}
mkdir -p .project/features/{feature-name}-{sub2}
c. Continue FASE 2-5 for EACH sub-feature sequentially:
Update backlog (split only):
If .project/backlog.html exists:
(split from {original-name}) annotationGoal: Automatisch bepalen of research nodig is op basis van architecture-baseline.
Steps:
Use pre-loaded architecture-baseline:
Extract feature type from requirements: Map the feature to a category:
Check Feature Pattern Index in baseline:
Look for matching row in ## Feature Pattern Index table:
| Feature Type | Node Type | Pattern | State Machine |
|--------------|-----------|---------|---------------|
| Player | CharacterBody2D | Composition | Enum-based |
| Projectile | Area2D | Instancing | None |
| Ability System | Node | Signal-based | None |
| UI | Control | Sub-scenes | None |
| Arena | Node2D | Coordinator | Round states |
Decision:
A) Pattern FOUND in baseline:
✓ Architecture pattern gevonden in baseline
| Field | Value |
|-------|-------|
| Feature Type | {type} |
| Node Type | {from baseline} |
| Pattern | {from baseline} |
| State Machine | {from baseline} |
→ Baseline gebruiken, research overgeslagen.
B) Pattern NOT FOUND in baseline:
⚠ Geen architecture pattern gevonden voor "{feature-type}"
→ Research wordt uitgevoerd en baseline wordt bijgewerkt.
Task(subagent_type="godot-scene-researcher", prompt="
Feature: {feature-name}
Type: {feature-type}
Requirements:
{list of requirements}
Mechanics: {selected}
Interactions: {selected}
Research Godot 4.x scene architecture patterns for this feature.
Return: Node type, scene pattern, signal patterns, state machine approach.
")
Baseline not found fallback:
If .claude/research/architecture-baseline.md does not exist:
⚠ Architecture baseline niet gevonden.
→ Volledige research wordt uitgevoerd.
Tip: Run /core-setup om baseline te genereren.
Goal: Define visual scene layout and gameplay state flow before architecture design.
Condition: Only execute this phase if the feature involves visual elements (scenes, sprites, UI, particles). If the feature is non-visual (pure data, logic, resources), skip with:
FASE 2b: N/A — non-visual feature
Steps:
Describe layout in ASCII scene layout:
┌─────────────────────────────┐
│ Camera2D (viewport) │
│ ┌──────┐ ┌──────────┐ │
│ │Player│→ │ Projectile│ │
│ └──────┘ └──────────┘ │
│ ┌────────┐ │
│ │ Puddle │ │
│ └────────┘ │
└─────────────────────────────┘
Define gameplay state diagram:
idle → casting → cooldown → idle
↓
cancelled
Map nodes to scene layout:
Confirm with user: Use AskUserQuestion:
Design based on requirements (and research if done). Genereer een ASCII state machine van de core gameplay loop (states + transitions + triggers) naast de scene tree:
Scene Tree:
{RootNodeType} ({feature-name})
├── {ChildNode} ({NodeType})
└── {ChildNode} ({NodeType})
Scripts:
| File | Class | Purpose |
|---|---|---|
| {path}.gd | {ClassName} | {purpose} |
Signals:
| Signal | Emitter | Receivers | Purpose |
|---|
Resources:
| File | Type | Purpose |
|---|
Test Strategy:
| REQ ID | Test File | Test Function | Type |
|---|
Determine implementation order based on requirement dependencies:
Analysis process:
Output format:
DEPENDENCY ANALYSIS:
REQ-001: {description}
└── Dependencies: None (BASE)
REQ-002: {description}
└── Dependencies: REQ-001 (needs {reason})
REQ-003: {description}
└── Dependencies: REQ-002 (needs {reason})
IMPLEMENTATION ORDER:
1. REQ-001 (base)
2. REQ-002 (after REQ-001)
3. REQ-003 (after REQ-002)
Schrijf .project/features/{feature-name}/feature.json (zie shared/FEATURE.md voor volledig schema):
| Veld | Conditie |
|---|---|
name, created, status | altijd (status = "DEFINED", geen stage — wacht op /game-build) |
summary | altijd |
depends | altijd (lege array als geen) |
choices | altijd (user antwoorden) |
requirements | altijd (elke REQ met status: "pending") |
files | altijd (genormaliseerd: path, type, action, purpose, requirements) |
architecture | altijd (componentTree, interfaces) |
design | alleen visuele features (wireframe, components, sceneLayout, gameplayFlow) |
buildSequence | altijd |
testStrategy | altijd |
clarifications | alleen als gray-area resolution is uitgevoerd |
durableDecisions | bij >3 requirements — beslissingen die over alle REQs gelden |
research | alleen als research is gedaan |
durableDecisions — beslissingen die tijdens de build NIET veranderen:
Volg shared/SYNC.md 3-File Sync Pattern. Skill-specifieke mutaties hieronder.
Lees parallel direct voor het editen (skip als niet bestaat) — vertrouw NIET op reads uit eerdere fases (Prettier/linters kunnen bestanden tussentijds wijzigen):
.project/backlog.html.project/project.json.project/project-context.jsonMuteer in memory:
Backlog (zie shared/BACKLOG.md):
data.features.find(f => f.name === "{feature-name}").status = "DEFINED", verwijder .stage (geen stage in DEFINED-kolom) en zet .date = "{current date}"{ "name": "{feature}", "type": "FEATURE", "status": "DEFINED", "phase": "P4", "description": "{from feature.json summary}", "dependencies": [], "source": "/game-define" }data.updated naar huidige datumDashboard (zie shared/DASHBOARD.md):
data.entities al entry heeft met die naam → nee: push met fields/relations → ja: merge nieuwe velden. Als feature geen entities heeft (UI-only scene, pure gameplay, utility): skip, log Skipped data.entities: no entities.stack.packages op naam → nee: push { name, version, purpose }{ name, status: "DEFINED", summary, depends: [], created } → ja: update status naar "DEFINED", verwijder stage.project/project-context.json: genereer/update als feature scene tree en/of signals heeft. Volg component-first model uit shared/DASHBOARD.md:
layers: definieer lagen met { name, order } (bijv. Scenes order 1, Systems order 2, Resources order 3)dataFlow: één-regel samenvatting van de scene/signal flowcomponents: per component { name, layer, description, status, connects_to }. Scene tree als componenten. connects_to[] als typed edges { to, type } (calls voor signal emits/method calls, reads/writes voor shared state of autoloads, depends_on voor scene-tree parent of resource references). Alle features DOING → status: "planned", bestaande → "done"name al bestaat → nee: push → ja: mergeSchrijf parallel terug:
backlog.html (keep <script> tags intact)project.json (stack, features, data)project-context.json (als architecture gewijzigd)Auto-build markering (na sync):
Lees backlog opnieuw, zoek feature, zet "auto": true, schrijf terug via Edit. Geen user-prompt — altijd auto markeren zodat de card een AUTO-badge krijgt en het clipboard het juiste /game-build-commando geeft.
Clean up: rm -f .project/session/active-{feature-name}.json
Output:
DASHBOARD SYNCED
Data: {N} entities ({new} nieuw)
Stack: {N} packages ({new} nieuw)
Next steps:
1. /project-plan → genereer backlog uit concept (als nog geen backlog)
2. /game-build {feature-name} → start implementatie (als backlog al bestaat)
This skill must NEVER:
This skill must ALWAYS: