summer-engine 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -0
- package/package.json +5 -3
- package/skills/_meta/skill-test/SKILL.md +1 -1
- package/skills/_shared/summer-folder.md +44 -0
- package/skills/_tests/specs/art-direction.md +115 -0
- package/skills/_tests/specs/audio-direction.md +123 -0
- package/skills/_tests/specs/brainstorm-game.md +99 -0
- package/skills/_tests/specs/design-level.md +113 -0
- package/skills/_tests/specs/design-mechanic.md +112 -0
- package/skills/_tests/specs/design-npc.md +112 -0
- package/skills/_tests/specs/export-and-ship.md +114 -0
- package/skills/_tests/specs/fps-controller.md +5 -5
- package/skills/_tests/specs/setup-multiplayer.md +106 -0
- package/skills/_tests/specs/tune-performance.md +104 -0
- package/skills/_tests/specs/vfx.md +98 -0
- package/skills/ai-and-npcs/design-npc/SKILL.md +343 -0
- package/skills/audio/audio-direction/SKILL.md +258 -0
- package/skills/deployment/export-and-ship/SKILL.md +300 -0
- package/skills/gameplay-mechanics/design-mechanic/SKILL.md +265 -0
- package/skills/level-design/design-level/SKILL.md +266 -0
- package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +328 -0
- package/skills/performance/tune-performance/SKILL.md +219 -0
- package/skills/rendering-and-lighting/art-direction/SKILL.md +284 -0
- package/skills/scene-and-project/brainstorm-game/SKILL.md +210 -0
- package/skills/visual-effects/vfx/SKILL.md +280 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Skill Spec: /design-mechanic
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project with `World/Player` (CharacterBody3D + CollisionShape3D + Camera3D) already in the main scene.
|
|
6
|
+
- A `scripts/player_controller.gd` exists with single-jump logic.
|
|
7
|
+
- `.summer/GameSoul.md` exists, brief says: "core loop is precise platforming, three mechanics: dash, double-jump, parry".
|
|
8
|
+
- Summer MCP available.
|
|
9
|
+
|
|
10
|
+
## Case 1: Happy Path — design double-jump
|
|
11
|
+
|
|
12
|
+
**Input:** "Design the double-jump mechanic."
|
|
13
|
+
|
|
14
|
+
**Expected MCP tool sequence (in order):**
|
|
15
|
+
|
|
16
|
+
1. (Skill asks one clarifying question if any — e.g., "Tap or hold-and-release?" — and waits.)
|
|
17
|
+
2. `Read .summer/GameSoul.md` — anchor to the brief
|
|
18
|
+
3. (Skill walks the five layers: input, response, feedback (visual/audio/mechanical), failure modes, depth)
|
|
19
|
+
4. (Skill names tunables as `@export` vars)
|
|
20
|
+
5. (Skill sketches the node-graph plan and asks "May I add `DoubleJumpFX` and `JumpAudio` to `./World/Player`?")
|
|
21
|
+
6. `summer_get_scene_tree` — confirm Player exists
|
|
22
|
+
7. `summer_add_node(parent="./World/Player", type="GPUParticles3D", name="DoubleJumpFX")`
|
|
23
|
+
8. `summer_set_prop("./World/Player/DoubleJumpFX", "emitting", "false")`
|
|
24
|
+
9. `summer_add_node(parent="./World/Player", type="AudioStreamPlayer3D", name="JumpAudio")`
|
|
25
|
+
10. `summer_input_map_bind(name="jump", events=[{type:"key", key:"Space"}])` (idempotent)
|
|
26
|
+
11. (Skill asks "May I modify `scripts/player_controller.gd` to add double-jump logic?")
|
|
27
|
+
12. `Edit scripts/player_controller.gd` — merge double-jump logic
|
|
28
|
+
13. (Skill asks "May I create `.summer/mechanics/double-jump.md` with the design doc?")
|
|
29
|
+
14. `Write .summer/mechanics/double-jump.md`
|
|
30
|
+
15. `summer_save_scene`
|
|
31
|
+
16. `summer_get_script_errors`
|
|
32
|
+
|
|
33
|
+
**Assertions:**
|
|
34
|
+
|
|
35
|
+
- [ ] Skill reads `.summer/GameSoul.md` to anchor the design to the brief.
|
|
36
|
+
- [ ] Skill walks all five layers (input, response, feedback, failure modes, depth) before scaffolding.
|
|
37
|
+
- [ ] Skill enforces all THREE feedback channels (visual, audio, mechanical) — pushes back if user only names two.
|
|
38
|
+
- [ ] Skill lists 3-7 tunables as `@export` vars (not `const`).
|
|
39
|
+
- [ ] Skill asks "May I add ..." before scene mutations.
|
|
40
|
+
- [ ] Skill asks "May I modify ..." before script edits.
|
|
41
|
+
- [ ] Skill writes the design doc to `.summer/mechanics/<name>.md`.
|
|
42
|
+
- [ ] Skill never calls `summer_set_resource_property` on an inline sub_resource (silent-fail trap).
|
|
43
|
+
- [ ] Generated GDScript uses typed vars, `@export`, `class_name`, `@onready`, signals (matches `_shared/gd-style.md`).
|
|
44
|
+
- [ ] Final step is `summer_save_scene` then `summer_get_script_errors`.
|
|
45
|
+
|
|
46
|
+
## Case 2: Failure Path — user names a system, not a mechanic
|
|
47
|
+
|
|
48
|
+
**Fixture:** Same as Case 1.
|
|
49
|
+
|
|
50
|
+
**Input:** "Design the inventory."
|
|
51
|
+
|
|
52
|
+
**Expected behavior:**
|
|
53
|
+
|
|
54
|
+
- Skill recognizes "inventory" is a system, not a mechanic.
|
|
55
|
+
- Skill pushes back: "Inventory is a system. The mechanics inside it are pickup, equip, drop, use, swap. Which one?"
|
|
56
|
+
- Does NOT start designing a generic "inventory mechanic".
|
|
57
|
+
- Waits for the user to pick a verb.
|
|
58
|
+
|
|
59
|
+
**Assertions:**
|
|
60
|
+
|
|
61
|
+
- [ ] Skill explicitly distinguishes system vs. mechanic.
|
|
62
|
+
- [ ] Skill asks the user to pick a verb before walking the five layers.
|
|
63
|
+
- [ ] No scene mutations or file writes happen until the user picks.
|
|
64
|
+
|
|
65
|
+
## Case 3: Edge Case — user can't articulate depth
|
|
66
|
+
|
|
67
|
+
**Fixture:** Same as Case 1.
|
|
68
|
+
|
|
69
|
+
**Input:** "Design the double-jump."
|
|
70
|
+
|
|
71
|
+
**During step 3, on Layer 5 (depth):**
|
|
72
|
+
|
|
73
|
+
User says: "Players will use it strategically."
|
|
74
|
+
|
|
75
|
+
**Expected behavior:**
|
|
76
|
+
|
|
77
|
+
- Skill rejects the hand-wave: "That's not depth — name the choice the player makes."
|
|
78
|
+
- Skill offers a concrete frame: "Depth = the resource is finite or has a cost, and level design forces a choice between using it now or saving it. If neither is true, this is just a higher-jumping single-jump."
|
|
79
|
+
- Skill asks the user to either (a) name the cost / choice, or (b) cut the mechanic.
|
|
80
|
+
- Skill does NOT scaffold a depth-less mechanic.
|
|
81
|
+
|
|
82
|
+
**Assertions:**
|
|
83
|
+
|
|
84
|
+
- [ ] Skill does not accept "strategically" / "for skilled play" / "it's interesting" as depth.
|
|
85
|
+
- [ ] Skill names a concrete depth-vector (cost, resource, choice).
|
|
86
|
+
- [ ] Skill explicitly offers "cut the mechanic" as a valid outcome.
|
|
87
|
+
- [ ] No scaffolding happens until depth is articulated.
|
|
88
|
+
|
|
89
|
+
## Case 4: No Summer MCP — file-edit fallback
|
|
90
|
+
|
|
91
|
+
**Fixture:** Same as Case 1, but Summer MCP is unavailable (engine not connected).
|
|
92
|
+
|
|
93
|
+
**Input:** "Design the double-jump mechanic."
|
|
94
|
+
|
|
95
|
+
**Expected behavior:**
|
|
96
|
+
|
|
97
|
+
- Skill detects no MCP and falls back to file edits.
|
|
98
|
+
- Walks the five layers normally.
|
|
99
|
+
- Instead of `summer_add_node`, prints the `.tscn` snippet for `DoubleJumpFX` and `JumpAudio` nodes for the user to paste into the scene file (or asks the user which `.tscn` to edit).
|
|
100
|
+
- Asks before each file write.
|
|
101
|
+
- Still writes the GDScript stub via `Edit` and the design doc via `Write`.
|
|
102
|
+
|
|
103
|
+
**Assertions:**
|
|
104
|
+
|
|
105
|
+
- [ ] Skill identifies that MCP is unavailable; does not blindly call `summer_*` tools.
|
|
106
|
+
- [ ] Generated `.tscn` snippet is syntactically valid Godot 4 scene format.
|
|
107
|
+
- [ ] Skill still asks "May I write ..." before each file write.
|
|
108
|
+
- [ ] Skill still produces both the GDScript stub AND the design doc at `.summer/mechanics/<name>.md`.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
This spec runs via `/skill-test design-mechanic spec` (see `_meta/skill-test/SKILL.md`).
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Skill Spec: /design-npc
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project, main scene with `World/Player` (CharacterBody3D in `player` group) and an empty `World/Enemies` parent.
|
|
6
|
+
- Summer MCP tools available.
|
|
7
|
+
- Host file tools available (Read, Edit, Write).
|
|
8
|
+
|
|
9
|
+
## Case 1: Happy Path — basic patrol-and-chase enemy
|
|
10
|
+
|
|
11
|
+
**Input:** "Add a basic enemy that chases the player when it sees them."
|
|
12
|
+
|
|
13
|
+
**Expected MCP tool sequence (in order):**
|
|
14
|
+
|
|
15
|
+
1. (Skill asks the archetype question and waits.)
|
|
16
|
+
2. User confirms "basic enemy".
|
|
17
|
+
3. `summer_get_scene_tree`
|
|
18
|
+
4. `summer_inspect_node "./World/Player"` — confirms it's in `player` group
|
|
19
|
+
5. (Skill proposes the bundle: scene tree + script + states + telegraph + loot hook + "May I create?")
|
|
20
|
+
6. After user OK:
|
|
21
|
+
- `summer_add_node(parent="./World/Enemies", type="CharacterBody3D", name="Enemy")`
|
|
22
|
+
- `summer_add_node(parent="./World/Enemies/Enemy", type="CollisionShape3D", name="Body")`
|
|
23
|
+
- `summer_add_node(parent="./World/Enemies/Enemy", type="MeshInstance3D", name="Mesh")`
|
|
24
|
+
- `summer_add_node(parent="./World/Enemies/Enemy", type="Area3D", name="Vision")`
|
|
25
|
+
- `summer_add_node(parent="./World/Enemies/Enemy/Vision", type="CollisionShape3D", name="VisionShape")`
|
|
26
|
+
- `summer_add_node(parent="./World/Enemies/Enemy", type="RayCast3D", name="Sight")`
|
|
27
|
+
- (Vision SphereShape3D saved as standalone `.tres`, NOT inline)
|
|
28
|
+
- `summer_set_prop` on Sight: `enabled = true`
|
|
29
|
+
- `Write scripts/enemy_ai.gd`
|
|
30
|
+
- `summer_connect_signal(from="./World/Enemies/Enemy/Vision", signal="body_entered", to="./World/Enemies/Enemy", method="_on_body_entered")`
|
|
31
|
+
- `summer_save_scene`
|
|
32
|
+
- `summer_get_script_errors`
|
|
33
|
+
|
|
34
|
+
**Assertions:**
|
|
35
|
+
|
|
36
|
+
- [ ] Skill asks the archetype question before any tool call.
|
|
37
|
+
- [ ] Scene has BOTH a Vision Area3D AND a Sight RayCast3D (the two-step perception pattern).
|
|
38
|
+
- [ ] Vision shape is saved as a standalone `.tres`, NOT inline sub_resource (silent-fail trap).
|
|
39
|
+
- [ ] Script defines an `enum State` with at least 4 states (idle / alert / attack / dead).
|
|
40
|
+
- [ ] Script has an attack `telegraph` parameter in 0.3–0.7 sec range.
|
|
41
|
+
- [ ] Script emits a `died` signal.
|
|
42
|
+
- [ ] Script uses `distance_squared_to` (NOT `distance_to`) for range comparisons.
|
|
43
|
+
- [ ] Script uses typed GDScript per `_shared/gd-style.md`.
|
|
44
|
+
- [ ] Skill asks "May I create / write …" before each user-visible mutation.
|
|
45
|
+
- [ ] Final step is `summer_save_scene` then `summer_get_script_errors`.
|
|
46
|
+
|
|
47
|
+
## Case 2: Failure Path — wave-mob archetype but user asks for full FSM
|
|
48
|
+
|
|
49
|
+
**Fixture:** User wants 100+ enemies on screen at once.
|
|
50
|
+
|
|
51
|
+
**Input:** "Spawn 100 enemies that chase the player. Each one should perceive, decide, telegraph attacks, and drop loot."
|
|
52
|
+
|
|
53
|
+
**Expected behavior:**
|
|
54
|
+
|
|
55
|
+
- Skill recognizes the scale conflict.
|
|
56
|
+
- Says: "100 enemies with full FSM + LOS perception will eat your frame budget. For wave mobs at this scale, the right archetype is the wave-mob (2 states, no LOS, direct line to player). Want me to build that instead?"
|
|
57
|
+
- Does NOT silently build 100 expensive enemies.
|
|
58
|
+
- Offers the trade-off explicitly.
|
|
59
|
+
|
|
60
|
+
**Assertions:**
|
|
61
|
+
|
|
62
|
+
- [ ] Skill names the performance trade-off, not just "this is hard".
|
|
63
|
+
- [ ] Skill points to the wave-mob archetype as the right answer.
|
|
64
|
+
- [ ] Skill does NOT proceed without confirmation.
|
|
65
|
+
- [ ] Skill never starts spawning 100 expensive nodes.
|
|
66
|
+
|
|
67
|
+
## Case 3: Edge Case — boss with phases
|
|
68
|
+
|
|
69
|
+
**Fixture:** Same as Case 1.
|
|
70
|
+
|
|
71
|
+
**Input:** "Design a 3-phase boss for the dungeon room."
|
|
72
|
+
|
|
73
|
+
**Expected behavior:**
|
|
74
|
+
|
|
75
|
+
- Skill picks the **boss** archetype (different complexity budget).
|
|
76
|
+
- Calls out: "Boss complexity (6–10 states, scripted phases) is at the threshold where a behavior tree might pay off, but I recommend a hand-coded FSM with phase enum first since you're a single dev."
|
|
77
|
+
- Walks the four pillars but at boss scale: more tells per state, telegraph 0.5–0.7 sec, distinct mechanics per phase (cap at 4–6 total mechanics).
|
|
78
|
+
- Defers to `ai-and-npcs/boss-patterns/SKILL.md` for the deeper phase-transition patterns.
|
|
79
|
+
- Does NOT just scale up the basic-enemy stub.
|
|
80
|
+
|
|
81
|
+
**Assertions:**
|
|
82
|
+
|
|
83
|
+
- [ ] Skill recognizes "boss" requires a different design.
|
|
84
|
+
- [ ] Skill caps at 4–6 distinct mechanics across phases.
|
|
85
|
+
- [ ] Skill mentions phase enum as the FSM extension.
|
|
86
|
+
- [ ] Skill defers to boss-patterns for deeper detail rather than trying to one-shot it.
|
|
87
|
+
|
|
88
|
+
## Case 4: No Summer MCP — fallback path
|
|
89
|
+
|
|
90
|
+
**Fixture:** Same as Case 1, but Summer MCP unavailable.
|
|
91
|
+
|
|
92
|
+
**Input:** "Add a basic enemy that chases the player."
|
|
93
|
+
|
|
94
|
+
**Expected behavior:**
|
|
95
|
+
|
|
96
|
+
- Skill detects MCP unavailable.
|
|
97
|
+
- Asks user to paste the existing scene tree (or the relevant `.tscn` snippet) so node paths are right.
|
|
98
|
+
- Generates a `.tscn` snippet (Enemy + Vision + Sight + Mesh + CollisionShape) with valid Godot 4 scene syntax.
|
|
99
|
+
- Writes `scripts/enemy_ai.gd` directly.
|
|
100
|
+
- Provides manual editor instructions for connecting the `body_entered` signal (or a connection block in the `.tscn`).
|
|
101
|
+
- Still asks "May I write …" before each file write.
|
|
102
|
+
|
|
103
|
+
**Assertions:**
|
|
104
|
+
|
|
105
|
+
- [ ] Skill does not blindly call `summer_*` tools and fail.
|
|
106
|
+
- [ ] Generated `.tscn` is valid Godot 4 syntax (parseable).
|
|
107
|
+
- [ ] Generated GDScript has the same FSM structure (states / telegraph / died signal).
|
|
108
|
+
- [ ] Skill still asks "May I" on writes.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
This spec runs via `/skill-test design-npc spec` (see `_meta/skill-test/SKILL.md`).
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Skill Spec: /export-and-ship
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project, complete game with main scene set, no script errors, basic icon at `icon.png` (256×256).
|
|
6
|
+
- Existing `export_presets.cfg` with Windows/Mac/Linux presets, all `debug = true` (development defaults).
|
|
7
|
+
- No `LICENSE` file at repo root.
|
|
8
|
+
- No `attribution.md`.
|
|
9
|
+
- Two CC-BY 4.0 assets imported from public sources (used in scene).
|
|
10
|
+
- Summer MCP tools available.
|
|
11
|
+
|
|
12
|
+
## Case 1: Happy Path — Steam (Windows + Mac + Linux)
|
|
13
|
+
|
|
14
|
+
**Input:** "I'm ready to ship to Steam. Build me Windows, Mac, and Linux releases."
|
|
15
|
+
|
|
16
|
+
**Expected MCP tool sequence (in order):**
|
|
17
|
+
|
|
18
|
+
1. (Skill asks the destination question and waits — confirms Steam, Win/Mac/Linux.)
|
|
19
|
+
2. Pre-flight:
|
|
20
|
+
- `summer_get_diagnostics` — clean
|
|
21
|
+
- `summer_get_console` — clean
|
|
22
|
+
- Read `project.godot` — main scene set, no version, no name
|
|
23
|
+
- Read `LICENSE` — does not exist
|
|
24
|
+
- Read `attribution.md` — does not exist
|
|
25
|
+
- Read `export_presets.cfg` — `debug = true` on all presets
|
|
26
|
+
- Grep for hardcoded paths
|
|
27
|
+
3. (Skill lists the pre-flight failures: missing LICENSE, missing attribution.md, missing version, missing game name, debug=true on release presets, missing Steam-required assets like trailer + capsules.)
|
|
28
|
+
4. Skill asks: "Pre-flight failed on N items: <list>. Want me to walk these one by one?"
|
|
29
|
+
5. (Does NOT proceed to build.)
|
|
30
|
+
|
|
31
|
+
**Assertions:**
|
|
32
|
+
|
|
33
|
+
- [ ] Skill asks the destination question first.
|
|
34
|
+
- [ ] Skill runs the FULL pre-flight checklist before any build.
|
|
35
|
+
- [ ] Skill detects missing LICENSE and missing `attribution.md`.
|
|
36
|
+
- [ ] Skill detects `debug = true` and flags it as a blocker for release.
|
|
37
|
+
- [ ] Skill detects missing Steam-specific assets (capsules, trailer) and lists them.
|
|
38
|
+
- [ ] Skill does NOT produce a build until the user fixes the blockers OR explicitly waives them.
|
|
39
|
+
- [ ] Skill never auto-uploads to Steam Pipe — only points at the upload command.
|
|
40
|
+
|
|
41
|
+
## Case 2: Failure Path — pre-flight passes, but iOS targeted without Apple Developer setup
|
|
42
|
+
|
|
43
|
+
**Fixture:** Project is clean (LICENSE present, no script errors, version + name set).
|
|
44
|
+
|
|
45
|
+
**Input:** "Ship to iOS App Store."
|
|
46
|
+
|
|
47
|
+
**Expected behavior:**
|
|
48
|
+
|
|
49
|
+
- Skill runs pre-flight — clean.
|
|
50
|
+
- Skill walks iOS-specific requirements: 1024×1024 icon, screenshots at 6.5" iPhone resolution, App Store description, privacy policy URL, support URL, bundle ID, Apple Developer cert + provisioning profile.
|
|
51
|
+
- Skill asks: "iOS submission requires (a) Apple Developer account ($99/yr), (b) Bundle ID configured in Apple Developer portal, (c) distribution certificate + provisioning profile, (d) macOS machine with Xcode for the final archive step. Do you have these set up? If not, those are the prerequisites — I can help with the build config but not the Apple Developer side."
|
|
52
|
+
- Does NOT silently produce an unsigned `.ipa` that can't be submitted.
|
|
53
|
+
|
|
54
|
+
**Assertions:**
|
|
55
|
+
|
|
56
|
+
- [ ] Skill names the iOS prerequisites that aren't satisfiable from inside Godot.
|
|
57
|
+
- [ ] Skill names the bundle-ID convention (`com.<org>.<game>`).
|
|
58
|
+
- [ ] Skill mentions TestFlight before App Store review.
|
|
59
|
+
- [ ] Skill does NOT pretend to do code signing it can't actually do.
|
|
60
|
+
- [ ] Skill names AAB-vs-APK if the user mistakenly says "Android APK" (different ticket but related anti-pattern).
|
|
61
|
+
|
|
62
|
+
## Case 3: Edge Case — multi-platform, web HTML5 included
|
|
63
|
+
|
|
64
|
+
**Fixture:** Same as Case 1 but post-fix (LICENSE added, attribution.md added, presets `debug = false`, version = "1.0.0", screenshots ready, trailer recorded).
|
|
65
|
+
|
|
66
|
+
**Input:** "Ship to Steam + itch + web."
|
|
67
|
+
|
|
68
|
+
**Expected behavior:**
|
|
69
|
+
|
|
70
|
+
- Pre-flight clean.
|
|
71
|
+
- Skill walks each platform's requirements separately.
|
|
72
|
+
- For web: explicitly flags the multiplayer transport (ENet doesn't work in browser), the audio autoplay block (Chrome blocks until first user click), and the file-size matters trap.
|
|
73
|
+
- Web export preset configured: encryption disabled, no JS eval, GLES3 fallback to GLES2 on if old browsers targeted.
|
|
74
|
+
- Skill asks: "May I produce 5 builds (Win + Mac + Linux + itch packages + web)?"
|
|
75
|
+
- Produces builds via `godot --headless --export-release` invocations after user OK.
|
|
76
|
+
- Verifies each build size and lists post-build warnings (e.g. "Web build is 180 MB — consider stripping unused textures").
|
|
77
|
+
- Points at upload commands for each: `steamcmd`, `butler push`, manual itch web upload.
|
|
78
|
+
|
|
79
|
+
**Assertions:**
|
|
80
|
+
|
|
81
|
+
- [ ] Skill walks per-platform requirements separately, NOT a generic checklist.
|
|
82
|
+
- [ ] For web: skill flags the autoplay + multiplayer + file-size traps explicitly.
|
|
83
|
+
- [ ] Skill produces builds in correct order (build, then verify, then point at upload — never auto-upload).
|
|
84
|
+
- [ ] Skill provides per-platform upload commands (steamcmd / butler / etc).
|
|
85
|
+
- [ ] Skill does NOT execute uploads itself.
|
|
86
|
+
|
|
87
|
+
## Case 4: No Summer MCP — fallback path
|
|
88
|
+
|
|
89
|
+
**Fixture:** Same as Case 1, MCP unavailable.
|
|
90
|
+
|
|
91
|
+
**Input:** "I want to ship to Steam."
|
|
92
|
+
|
|
93
|
+
**Expected behavior:**
|
|
94
|
+
|
|
95
|
+
- Skill detects MCP unavailable.
|
|
96
|
+
- Asks user to confirm via the editor: main scene set, no errors in Output panel, no errors in Debugger panel.
|
|
97
|
+
- Asks user to paste contents of `project.godot` and `export_presets.cfg`.
|
|
98
|
+
- Walks the pre-flight checklist by reasoning over the pasted text.
|
|
99
|
+
- Provides per-platform asset list and config recommendations.
|
|
100
|
+
- Provides build commands the user can run manually (`godot --headless --export-release ...`).
|
|
101
|
+
- Provides upload commands the user can run manually (`steamcmd ...`).
|
|
102
|
+
- Still applies "May I write" before any file edit (e.g. `LICENSE` creation).
|
|
103
|
+
|
|
104
|
+
**Assertions:**
|
|
105
|
+
|
|
106
|
+
- [ ] Skill does not blindly call `summer_*` tools and fail.
|
|
107
|
+
- [ ] Skill asks for the specific files it needs (project.godot, export_presets.cfg).
|
|
108
|
+
- [ ] Skill still runs the full pre-flight check via reading.
|
|
109
|
+
- [ ] Skill names the same blockers (LICENSE, debug=true, missing trailer).
|
|
110
|
+
- [ ] Skill asks "May I write" before creating LICENSE / attribution.md / etc.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
This spec runs via `/skill-test export-and-ship spec` (see `_meta/skill-test/SKILL.md`).
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
5. `summer_set_prop("./World/Player/Collision", "shape", "CapsuleShape3D")` (creates standalone, NOT inline sub-resource)
|
|
21
21
|
6. `summer_set_resource_property("./World/Player/Collision", "shape.height", "1.8")` (only after the shape is standalone)
|
|
22
22
|
7. `summer_set_prop("./World/Player/Camera", "position", "Vector3(0, 1.6, 0)")`
|
|
23
|
-
8. `summer_input_map_bind("move_forward", "key:W")`
|
|
24
|
-
9. `summer_input_map_bind("move_back", "key:S")`
|
|
25
|
-
10. `summer_input_map_bind("move_left", "key:A")`
|
|
26
|
-
11. `summer_input_map_bind("move_right", "key:D")`
|
|
27
|
-
12. `summer_input_map_bind("jump", "key:Space")`
|
|
23
|
+
8. `summer_input_map_bind(name="move_forward", events=[{type:"key", key:"W"}])`
|
|
24
|
+
9. `summer_input_map_bind(name="move_back", events=[{type:"key", key:"S"}])`
|
|
25
|
+
10. `summer_input_map_bind(name="move_left", events=[{type:"key", key:"A"}])`
|
|
26
|
+
11. `summer_input_map_bind(name="move_right", events=[{type:"key", key:"D"}])`
|
|
27
|
+
12. `summer_input_map_bind(name="jump", events=[{type:"key", key:"Space"}])`
|
|
28
28
|
13. (User-side write) `Write` script file `scripts/player_controller.gd` after the agent asks "May I attach the controller script to ./World/Player?"
|
|
29
29
|
14. `summer_save_scene`
|
|
30
30
|
15. `summer_get_script_errors`
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Skill Spec: /setup-multiplayer
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project, single-player game with `World/Player` (CharacterBody3D) and a working camera + movement script.
|
|
6
|
+
- Summer MCP tools available.
|
|
7
|
+
- Host file tools available (Read, Edit, Write).
|
|
8
|
+
- No multiplayer setup yet (no autoloads, no MultiplayerSpawner, no Synchronizer).
|
|
9
|
+
|
|
10
|
+
## Case 1: Happy Path — co-op LAN (2–4 players)
|
|
11
|
+
|
|
12
|
+
**Input:** "Add multiplayer to my game. Co-op for me and three friends."
|
|
13
|
+
|
|
14
|
+
**Expected MCP tool sequence (in order):**
|
|
15
|
+
|
|
16
|
+
1. (Skill asks the four blocking questions — type / count / authority / network — and waits.)
|
|
17
|
+
2. User confirms: co-op online, 4 players, host one of the players, public internet.
|
|
18
|
+
3. (Skill explicitly states the locked decision: "Going with **host authority**, ENet transport, 30 Hz input / 20 Hz position. Refactoring authority later is brutal — confirm.")
|
|
19
|
+
4. After user OK:
|
|
20
|
+
- `summer_get_scene_tree`
|
|
21
|
+
- `summer_inspect_node "./World/Player"`
|
|
22
|
+
- `Write scripts/network.gd` (autoload)
|
|
23
|
+
- `summer_project_setting(name="autoload/Network", value="*res://scripts/network.gd")`
|
|
24
|
+
- `summer_add_node(parent="./World/Players/Player", type="MultiplayerSynchronizer", name="Sync")` (or the equivalent on the player scene)
|
|
25
|
+
- SceneReplicationConfig saved as standalone `.tres` (NOT inline)
|
|
26
|
+
- `Write scripts/player_net.gd`
|
|
27
|
+
- `summer_save_scene`
|
|
28
|
+
- `summer_get_script_errors`
|
|
29
|
+
|
|
30
|
+
**Assertions:**
|
|
31
|
+
|
|
32
|
+
- [ ] Skill asks all four blocking questions BEFORE any tool call.
|
|
33
|
+
- [ ] Skill explicitly names the authority model (host) and gets a confirmation before mutating.
|
|
34
|
+
- [ ] Skill picks ENet (NOT custom transport, NOT WebRTC).
|
|
35
|
+
- [ ] Generated script uses `MultiplayerSpawner` pattern (host spawns, clients receive).
|
|
36
|
+
- [ ] Player script disables `_physics_process` for non-local peers.
|
|
37
|
+
- [ ] Camera is local-only (`camera.current = is_local`).
|
|
38
|
+
- [ ] Damage RPC checks `multiplayer.is_server()` before applying.
|
|
39
|
+
- [ ] At least one `any_peer` RPC validates `get_remote_sender_id()`.
|
|
40
|
+
- [ ] SceneReplicationConfig is a standalone `.tres`, NOT inline sub_resource.
|
|
41
|
+
- [ ] Skill does NOT replicate cosmetic VFX or local UI.
|
|
42
|
+
- [ ] Final step is `summer_save_scene` then `summer_get_script_errors`.
|
|
43
|
+
|
|
44
|
+
## Case 2: Failure Path — user wants competitive PvP without dedicated server
|
|
45
|
+
|
|
46
|
+
**Input:** "Add competitive PvP for 8 players, hosted by one of them, with anti-cheat."
|
|
47
|
+
|
|
48
|
+
**Expected behavior:**
|
|
49
|
+
|
|
50
|
+
- Skill names the conflict: "Anti-cheat with host-authority is fundamentally broken — the host can always cheat. For competitive PvP at this scale, you need a dedicated server. Want me to scaffold that path (different code, different deploy story), or are we doing trusted-host co-op-style PvP?"
|
|
51
|
+
- Does NOT silently scaffold host-authority code that the user thinks has anti-cheat.
|
|
52
|
+
- Does NOT scaffold dedicated-server code without explicit confirmation (different complexity).
|
|
53
|
+
|
|
54
|
+
**Assertions:**
|
|
55
|
+
|
|
56
|
+
- [ ] Skill flags the architectural impossibility, not just "this is hard".
|
|
57
|
+
- [ ] Skill names the trade-off explicitly (host = host can cheat; dedicated = ops cost).
|
|
58
|
+
- [ ] Skill stops to ask before generating any code.
|
|
59
|
+
- [ ] Skill does NOT just pick host-authority because it's the default.
|
|
60
|
+
|
|
61
|
+
## Case 3: Edge Case — user says "let's also do rollback netcode for our co-op"
|
|
62
|
+
|
|
63
|
+
**Fixture:** Same as Case 1.
|
|
64
|
+
|
|
65
|
+
**Input:** "Add multiplayer with rollback netcode so we don't see lag."
|
|
66
|
+
|
|
67
|
+
**Expected behavior:**
|
|
68
|
+
|
|
69
|
+
- Skill calls out: "Rollback netcode is a 6-month project on its own and is the right answer for fighting games / lock-step RTS, not co-op. For co-op, host authority + smooth interpolation gives you 95% of the perceived smoothness for 5% of the work. Want me to scaffold the standard host model?"
|
|
70
|
+
- Does NOT start scaffolding rollback.
|
|
71
|
+
- Does NOT silently downgrade to host-authority — names the choice and the trade-off.
|
|
72
|
+
|
|
73
|
+
**Assertions:**
|
|
74
|
+
|
|
75
|
+
- [ ] Skill names rollback as wrong-tool-for-job for co-op.
|
|
76
|
+
- [ ] Skill names the standard alternative (host authority + interpolation).
|
|
77
|
+
- [ ] Skill stops to confirm before scaffolding.
|
|
78
|
+
- [ ] Skill points to specialist skill for lag compensation if user insists on competitive shooter.
|
|
79
|
+
|
|
80
|
+
## Case 4: No Summer MCP — fallback path
|
|
81
|
+
|
|
82
|
+
**Fixture:** Same as Case 1, but Summer MCP unavailable.
|
|
83
|
+
|
|
84
|
+
**Input:** "Add co-op multiplayer for 4 players."
|
|
85
|
+
|
|
86
|
+
**Expected behavior:**
|
|
87
|
+
|
|
88
|
+
- Skill detects MCP unavailable.
|
|
89
|
+
- Asks the user to paste their existing main scene `.tscn` so the autoload + spawn paths reference real nodes.
|
|
90
|
+
- Asks the user to paste `project.godot` so the autoload entry can be added by hand.
|
|
91
|
+
- Writes `scripts/network.gd` + `scripts/player_net.gd` directly via host file tools.
|
|
92
|
+
- Provides a manual `project.godot` patch (autoload entry + replication config path) as text the user can paste.
|
|
93
|
+
- Provides scene-editor instructions for adding the MultiplayerSynchronizer + setting up replication properties.
|
|
94
|
+
- Still asks "May I write …" before each file write.
|
|
95
|
+
|
|
96
|
+
**Assertions:**
|
|
97
|
+
|
|
98
|
+
- [ ] Skill does not blindly call `summer_*` tools and fail.
|
|
99
|
+
- [ ] Generated scripts compile in Godot 4.5 / Summer Engine.
|
|
100
|
+
- [ ] Skill provides a `project.godot` patch in valid Godot project format.
|
|
101
|
+
- [ ] Skill still asks for confirmation on each write.
|
|
102
|
+
- [ ] Same opinionated decisions hold (host authority, ENet, no replication of cosmetic VFX).
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
This spec runs via `/skill-test setup-multiplayer spec` (see `_meta/skill-test/SKILL.md`).
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Skill Spec: /tune-performance
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project with a 3D scene.
|
|
6
|
+
- Summer MCP tools available (engine running on localhost:6550).
|
|
7
|
+
- Host file tools available (Read, Edit, Write).
|
|
8
|
+
|
|
9
|
+
## Case 1: Happy Path — rendering hotspot (foliage)
|
|
10
|
+
|
|
11
|
+
**Fixture:** `World/Foliage` contains 240 individual MeshInstance3D children, all using the same tree mesh. Game runs at ~22 fps, render time ~14 ms / frame.
|
|
12
|
+
|
|
13
|
+
**Input:** "My game is slow when I look at the forest."
|
|
14
|
+
|
|
15
|
+
**Expected MCP tool sequence (in order):**
|
|
16
|
+
|
|
17
|
+
1. (Skill asks one focused question and waits — confirms it's framerate-drops-when-looking-at-X.)
|
|
18
|
+
2. `summer_clear_console`
|
|
19
|
+
3. `summer_play`
|
|
20
|
+
4. (Skill asks user to look at the forest for 5–10 seconds.)
|
|
21
|
+
5. `summer_get_diagnostics` — baseline numbers
|
|
22
|
+
6. `summer_stop`
|
|
23
|
+
7. (Skill identifies render time > 50% frame budget, dominant cost = rendering.)
|
|
24
|
+
8. `summer_get_scene_tree` + `summer_inspect_node "./World/Foliage"` — confirms 240 MeshInstance3D children.
|
|
25
|
+
9. (Skill states hypothesis: "240 MeshInstance3D = 240 draw calls. MultiMeshInstance3D will drop this to ~1.")
|
|
26
|
+
10. (Skill asks: "May I refactor `./World/Foliage` to use a MultiMeshInstance3D? Expected render time: 14 ms → 3–5 ms.")
|
|
27
|
+
11. After OK: applies fix, `summer_save_scene`, `summer_clear_console`, `summer_play`, `summer_get_diagnostics`, `summer_stop`.
|
|
28
|
+
12. Reports before/after.
|
|
29
|
+
|
|
30
|
+
**Assertions:**
|
|
31
|
+
|
|
32
|
+
- [ ] Skill takes a baseline measurement BEFORE proposing a fix.
|
|
33
|
+
- [ ] Skill identifies the dominant cost using actual numbers, not a guess.
|
|
34
|
+
- [ ] Skill proposes ONE fix, not a bundle of three.
|
|
35
|
+
- [ ] Proposal includes an expected metric movement (e.g. "14 ms → 3–5 ms").
|
|
36
|
+
- [ ] Skill asks "May I" before mutating.
|
|
37
|
+
- [ ] Skill re-measures after applying the fix and reports before/after.
|
|
38
|
+
- [ ] Skill never optimizes physics or scripting in this scenario (since rendering was dominant).
|
|
39
|
+
|
|
40
|
+
## Case 2: Failure Path — wrong subsystem hypothesis
|
|
41
|
+
|
|
42
|
+
**Fixture:** Game stutters every ~3 seconds. User suspects "lag spikes from too many enemies".
|
|
43
|
+
|
|
44
|
+
**Input:** "Game stutters every few seconds. I think it's the enemy AI."
|
|
45
|
+
|
|
46
|
+
**Expected behavior:**
|
|
47
|
+
|
|
48
|
+
- Skill resists the user's guess and takes a baseline.
|
|
49
|
+
- `summer_get_diagnostics` shows: avg frame time fine, but periodic 80 ms spikes.
|
|
50
|
+
- `summer_get_console` shows shader-compilation warnings: "Compiling SpatialMaterial #1234".
|
|
51
|
+
- Skill identifies: this is shader compile jitter, not AI.
|
|
52
|
+
- Skill says: "The spikes correlate with shader compilation, not the AI loop. Fix is a warmup pass on scene load (force-render off-screen to compile materials). Should I add the warmup pass?"
|
|
53
|
+
|
|
54
|
+
**Assertions:**
|
|
55
|
+
|
|
56
|
+
- [ ] Skill verifies via diagnostics + console BEFORE accepting the user's hypothesis.
|
|
57
|
+
- [ ] Skill names the actual cause (shader compile) explicitly.
|
|
58
|
+
- [ ] Skill does NOT optimize AI code that wasn't the cause.
|
|
59
|
+
- [ ] Skill proposes a targeted fix (warmup) rather than a generic one.
|
|
60
|
+
|
|
61
|
+
## Case 3: Edge Case — Summer MCP available but engine not currently running
|
|
62
|
+
|
|
63
|
+
**Fixture:** Same as Case 1 but the engine is open and idle, not playing.
|
|
64
|
+
|
|
65
|
+
**Input:** "Why is my game slow?"
|
|
66
|
+
|
|
67
|
+
**Expected behavior:**
|
|
68
|
+
|
|
69
|
+
- Skill calls `summer_is_running` → false.
|
|
70
|
+
- Skill explains: "I need to play the game and reproduce the slowdown to get real numbers."
|
|
71
|
+
- Asks user permission: "May I `summer_play` and ask you to reproduce the slow scenario?"
|
|
72
|
+
- After OK: runs the play → reproduce → diagnostics → stop loop.
|
|
73
|
+
- Does NOT skip baseline measurement and just guess from reading code.
|
|
74
|
+
|
|
75
|
+
**Assertions:**
|
|
76
|
+
|
|
77
|
+
- [ ] Skill checks `summer_is_running` first.
|
|
78
|
+
- [ ] Skill asks before invoking `summer_play`.
|
|
79
|
+
- [ ] Skill insists on baseline numbers before fixing anything.
|
|
80
|
+
- [ ] Skill does NOT skip straight to "let me read your scripts and guess".
|
|
81
|
+
|
|
82
|
+
## Case 4: No Summer MCP — fallback path
|
|
83
|
+
|
|
84
|
+
**Fixture:** Same as Case 1, but Summer MCP unavailable.
|
|
85
|
+
|
|
86
|
+
**Input:** "My forest scene is slow."
|
|
87
|
+
|
|
88
|
+
**Expected behavior:**
|
|
89
|
+
|
|
90
|
+
- Skill detects MCP unavailable.
|
|
91
|
+
- Asks the user to enable Godot's Monitor panel (`Debug → Monitors`) and paste at minimum: FPS, frame time (ms), draw calls, video/video memory used, physics active objects.
|
|
92
|
+
- Reasons over the pasted numbers the same way it would over diagnostics.
|
|
93
|
+
- Continues with hypothesis → proposal → "May I edit?" → manual verification (asks the user to re-run and paste new numbers).
|
|
94
|
+
|
|
95
|
+
**Assertions:**
|
|
96
|
+
|
|
97
|
+
- [ ] Skill does not blindly call `summer_*` tools and fail.
|
|
98
|
+
- [ ] Skill asks for the specific numbers it needs (not a vague "tell me more").
|
|
99
|
+
- [ ] Skill still anchors on baseline-first, ONE-fix-at-a-time loop.
|
|
100
|
+
- [ ] Skill names the dominant cost from the user-pasted numbers.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
This spec runs via `/skill-test tune-performance spec` (see `_meta/skill-test/SKILL.md`).
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Skill Spec: /vfx
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project, main scene with `World/Player` (CharacterBody3D + Camera3D) and `World/Enemy` (CharacterBody3D + MeshInstance3D + a `damaged` signal on a script).
|
|
6
|
+
- Summer MCP tools available (engine running on localhost:6550).
|
|
7
|
+
- Host file tools available (Read, Edit, Write).
|
|
8
|
+
|
|
9
|
+
## Case 1: Happy Path — combat hits feel flat
|
|
10
|
+
|
|
11
|
+
**Input:** "My combat feels flat. Add some juice."
|
|
12
|
+
|
|
13
|
+
**Expected behavior:**
|
|
14
|
+
|
|
15
|
+
1. Skill asks one focused question: "What feels flat? combat hits / movement / pickups / damage / explosions / spell casts."
|
|
16
|
+
2. User says "combat hits".
|
|
17
|
+
3. Skill calls `summer_get_scene_tree`, then `summer_inspect_node "./World/Enemy"` to confirm a MeshInstance3D and a `damaged` signal exist.
|
|
18
|
+
4. Skill proposes hit flash + camera shake bundle: "I'm about to add HitFlash on `./World/Enemy`, attach `scripts/hit_flash.gd`, attach `scripts/camera_shake.gd` to `./World/Player/Camera3D`, and connect the `damaged` signal. OK?"
|
|
19
|
+
5. After user OK:
|
|
20
|
+
- `summer_add_node(parent="./World/Enemy", type="Node", name="HitFlash")`
|
|
21
|
+
- `Write scripts/hit_flash.gd`
|
|
22
|
+
- `Write scripts/camera_shake.gd`
|
|
23
|
+
- `summer_connect_signal(from="./World/Enemy", signal="damaged", to="./World/Enemy/HitFlash", method="flash")`
|
|
24
|
+
- `summer_save_scene`
|
|
25
|
+
- `summer_get_script_errors`
|
|
26
|
+
|
|
27
|
+
**Assertions:**
|
|
28
|
+
|
|
29
|
+
- [ ] Skill asks the "what feels flat?" question before any tool call.
|
|
30
|
+
- [ ] Skill reads the scene tree and inspects the relevant node before adding nodes.
|
|
31
|
+
- [ ] Skill explicitly states the bundle of changes and asks "May I" / "OK?" before mutation.
|
|
32
|
+
- [ ] HitFlash script uses Tween + `set_surface_override_material`, NOT a polled timer in `_process`.
|
|
33
|
+
- [ ] CameraShake uses quadratic falloff (`_trauma * _trauma`), NOT linear.
|
|
34
|
+
- [ ] Skill never calls `summer_set_resource_property` on an inline sub_resource (e.g. ParticleProcessMaterial).
|
|
35
|
+
- [ ] Skill ends with `summer_save_scene` then `summer_get_script_errors`.
|
|
36
|
+
- [ ] Final hit flash duration is 0.06–0.12 sec (NOT 0.3 sec).
|
|
37
|
+
|
|
38
|
+
## Case 2: Failure Path — no Camera3D in scene
|
|
39
|
+
|
|
40
|
+
**Fixture:** `World/Player` exists but has no Camera3D child. User asks for screen shake.
|
|
41
|
+
|
|
42
|
+
**Input:** "Add screen shake when I take damage."
|
|
43
|
+
|
|
44
|
+
**Expected behavior:**
|
|
45
|
+
|
|
46
|
+
- Skill calls `summer_get_scene_tree` and `summer_inspect_node "./World/Player"`, sees no Camera3D.
|
|
47
|
+
- Skill does NOT silently spawn a Camera3D — it asks: "I don't see a Camera3D under `./World/Player`. Should I add one (and risk conflicting with an existing camera elsewhere), or do you have a camera node I should target?"
|
|
48
|
+
- Waits for the answer.
|
|
49
|
+
|
|
50
|
+
**Assertions:**
|
|
51
|
+
|
|
52
|
+
- [ ] Skill detects the missing Camera3D and stops to ask.
|
|
53
|
+
- [ ] Skill does NOT add a Camera3D unilaterally.
|
|
54
|
+
- [ ] Skill names a concrete next-step path (point to existing camera OR add new one explicitly).
|
|
55
|
+
|
|
56
|
+
## Case 3: Edge Case — user wants "all the juice"
|
|
57
|
+
|
|
58
|
+
**Fixture:** Same as Case 1.
|
|
59
|
+
|
|
60
|
+
**Input:** "Add all the VFX. Make it feel like Hades."
|
|
61
|
+
|
|
62
|
+
**Expected behavior:**
|
|
63
|
+
|
|
64
|
+
- Skill resists the temptation to stack 5 recipes at once.
|
|
65
|
+
- Anchors on combat hits first (per skill's own guidance: "loudest perceived improvement per minute spent").
|
|
66
|
+
- Says: "I'd rather land hit-flash + screen-shake first so we can see them work, then stack pickups/explosions next. Sound good?"
|
|
67
|
+
- Does NOT propose a single bundle of 5 recipes.
|
|
68
|
+
|
|
69
|
+
**Assertions:**
|
|
70
|
+
|
|
71
|
+
- [ ] Skill explicitly chooses ONE recipe to start with, not all.
|
|
72
|
+
- [ ] Skill names "combat hits" as the anchor.
|
|
73
|
+
- [ ] Skill defers other recipes to a follow-up pass.
|
|
74
|
+
|
|
75
|
+
## Case 4: No Summer MCP — file-edit fallback
|
|
76
|
+
|
|
77
|
+
**Fixture:** Same as Case 1, but Summer MCP is unavailable (Cursor in a project where the engine is not connected).
|
|
78
|
+
|
|
79
|
+
**Input:** "Add a hit flash to my enemy."
|
|
80
|
+
|
|
81
|
+
**Expected behavior:**
|
|
82
|
+
|
|
83
|
+
- Skill detects MCP unavailable.
|
|
84
|
+
- Asks the user to paste the relevant `.tscn` snippet (the Enemy node + its children) so the skill can write the right node-path references.
|
|
85
|
+
- Writes `scripts/hit_flash.gd` directly via host file tools.
|
|
86
|
+
- Provides a `.tscn` patch (or step-by-step manual editor instructions) for adding the HitFlash node and connecting the signal — does NOT blindly call `summer_*` tools.
|
|
87
|
+
- Still asks "May I write `scripts/hit_flash.gd`?" before each file write.
|
|
88
|
+
|
|
89
|
+
**Assertions:**
|
|
90
|
+
|
|
91
|
+
- [ ] Skill identifies MCP is unavailable and adapts.
|
|
92
|
+
- [ ] Generated GDScript is syntactically valid Godot 4 GDScript with type hints.
|
|
93
|
+
- [ ] Skill asks the user to paste the `.tscn` snippet for accurate node paths.
|
|
94
|
+
- [ ] Skill still applies the "May I write …" protocol on file writes.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
This spec runs via `/skill-test vfx spec` (see `_meta/skill-test/SKILL.md`).
|