summer-engine 1.3.1 → 1.4.0

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.
Files changed (49) hide show
  1. package/.claude-plugin/plugin.json +59 -0
  2. package/.codex-plugin/plugin.json +38 -0
  3. package/.cursor-plugin/plugin.json +42 -0
  4. package/.mcp.json +8 -0
  5. package/.opencode/plugins/summer.js +49 -0
  6. package/CHANGELOG.md +67 -0
  7. package/README.md +13 -0
  8. package/dist/lib/skills-registry.d.ts +80 -0
  9. package/dist/lib/skills-registry.js +172 -0
  10. package/gemini-extension.json +21 -0
  11. package/hooks/hooks-cursor.json +21 -0
  12. package/hooks/hooks.json +31 -0
  13. package/hooks/pre-commit-doctor.sh +123 -0
  14. package/hooks/run-hook.cmd +23 -0
  15. package/hooks/session-start.sh +120 -0
  16. package/marketplace.json +24 -0
  17. package/package.json +13 -3
  18. package/skills/_meta/skill-test/SKILL.md +1 -1
  19. package/skills/_shared/summer-folder.md +44 -0
  20. package/skills/_tests/specs/art-direction.md +115 -0
  21. package/skills/_tests/specs/audio-direction.md +123 -0
  22. package/skills/_tests/specs/brainstorm-game.md +99 -0
  23. package/skills/_tests/specs/design-level.md +113 -0
  24. package/skills/_tests/specs/design-mechanic.md +112 -0
  25. package/skills/_tests/specs/design-npc.md +112 -0
  26. package/skills/_tests/specs/export-and-ship.md +114 -0
  27. package/skills/_tests/specs/fps-controller.md +5 -5
  28. package/skills/_tests/specs/peer-to-peer-multiplayer.md +99 -0
  29. package/skills/_tests/specs/setup-multiplayer.md +106 -0
  30. package/skills/_tests/specs/tune-performance.md +104 -0
  31. package/skills/_tests/specs/vfx.md +98 -0
  32. package/skills/ai-and-npcs/design-npc/SKILL.md +343 -0
  33. package/skills/asset-pipeline/asset-strategy/SKILL.md +8 -0
  34. package/skills/audio/audio-direction/SKILL.md +258 -0
  35. package/skills/catalog.yaml +82 -0
  36. package/skills/character-controllers/fps-controller/SKILL.md +27 -0
  37. package/skills/deployment/export-and-ship/SKILL.md +300 -0
  38. package/skills/gameplay-mechanics/design-mechanic/SKILL.md +265 -0
  39. package/skills/level-design/design-level/SKILL.md +266 -0
  40. package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +378 -0
  41. package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +328 -0
  42. package/skills/performance/tune-performance/SKILL.md +219 -0
  43. package/skills/rendering-and-lighting/3d-lighting/SKILL.md +20 -0
  44. package/skills/rendering-and-lighting/art-direction/SKILL.md +284 -0
  45. package/skills/scene-and-project/brainstorm-game/SKILL.md +210 -0
  46. package/skills/scene-and-project/make-game/SKILL.md +10 -0
  47. package/skills/scene-and-project/scene-composition/SKILL.md +8 -0
  48. package/skills/ui-and-ux/ui-basics/SKILL.md +28 -0
  49. package/skills/visual-effects/vfx/SKILL.md +280 -0
@@ -0,0 +1,99 @@
1
+ # Skill Spec: /peer-to-peer-multiplayer
2
+
3
+ ## Fixture
4
+
5
+ - A Godot 4.5 / Summer Engine project that does NOT yet have multiplayer.
6
+ - Project may be empty or may have an existing single-player scene.
7
+ - Summer MCP tools available; engine running on localhost:6550.
8
+
9
+ ## Case 1: Happy Path — fresh multiplayer architecture from scratch
10
+
11
+ **Input:** "I want to add 2-player co-op to my game. Players will connect through Steam friend invites."
12
+
13
+ **Expected behavior:**
14
+
15
+ 1. Skill confirms P2P is the right architecture (Steam friend invite ≤8 players → P2P, not dedicated server).
16
+ 2. Skill walks the four layers in order, checkpointing between each.
17
+ 3. Layer 1: asks "May I create `autoloads/network_manager.gd`?" — creates it on user OK, calls `summer_project_setting` to register the autoload.
18
+ 4. Layer 2: asks "May I create `autoloads/game_state.gd` and walk through the authority decision matrix?" — creates it, prompts user for game-specific state fields and proposes ownership.
19
+ 5. Layer 3: explains the three RPC patterns with examples; doesn't auto-apply (this is reference material until concrete game logic exists).
20
+ 6. Layer 4: defers prediction/interpolation until there's a player scene to apply it to.
21
+
22
+ **Expected MCP tool sequence (in order, partial):**
23
+
24
+ 1. `summer_get_scene_tree` — see what already exists.
25
+ 2. `summer_get_project_context` — read autoload list to avoid name collisions.
26
+ 3. (User approves Layer 1) `Write autoloads/network_manager.gd`.
27
+ 4. `summer_project_setting(key="autoload/NetworkManager", value="*res://autoloads/network_manager.gd")`.
28
+ 5. (User approves Layer 2) `Write autoloads/game_state.gd`.
29
+ 6. `summer_project_setting(key="autoload/GameState", value="*res://autoloads/game_state.gd")`.
30
+ 7. `summer_save_scene` and `summer_get_script_errors` to verify clean.
31
+
32
+ **Assertions:**
33
+
34
+ - [ ] Skill explicitly checks Step 0 (P2P vs. client-server) before any code is written.
35
+ - [ ] Skill creates Layer 1 (NetworkManager) before Layer 2 (GameState).
36
+ - [ ] NetworkManager is the only place that calls `multiplayer.peer_connected.connect()` directly. GameState listens to NetworkManager signals, NOT to the multiplayer API directly.
37
+ - [ ] GameState uses `@rpc("authority", "call_remote", "reliable")` for host-broadcast functions and `@rpc("any_peer", "call_remote", "reliable")` with a `is_host` guard for client-request functions.
38
+ - [ ] Skill walks the user through the authority decision matrix before writing GameState. Doesn't dump generic state fields without asking what the game has.
39
+ - [ ] Skill asks "May I…" before each new file creation and before the autoload registration.
40
+ - [ ] Skill does NOT apply prediction/interpolation in Layer 4 unless there's an existing player scene to wire into.
41
+ - [ ] At any layer, `summer_get_script_errors` is called after the file write to confirm clean compile.
42
+
43
+ ## Case 2: Failure Path — user wants matchmaking at scale
44
+
45
+ **Input:** "I'm building a competitive shooter. I want matchmaking with anti-cheat for 10,000 concurrent matches."
46
+
47
+ **Expected behavior:**
48
+
49
+ - Skill recognizes Step 0: this is dedicated client-server territory, not P2P.
50
+ - Skill explains why P2P is wrong (host can cheat, no anti-cheat hooks, scale concerns).
51
+ - Skill defers to `/summer:client-server-multiplayer` (when shipped) OR explains the user needs to roll a custom server.
52
+ - Does NOT start writing P2P NetworkManager code anyway.
53
+
54
+ **Assertions:**
55
+
56
+ - [ ] Skill stops at Step 0 — does NOT proceed to Layer 1.
57
+ - [ ] Skill explains the architecture mismatch in one sentence.
58
+ - [ ] Skill names the right alternative (client-server) and which skill to use instead.
59
+
60
+ ## Case 3: Edge Case — retrofitting multiplayer to a single-player game
61
+
62
+ **Input:** "I have a single-player platformer that's mostly done. Can you add multiplayer?"
63
+
64
+ **Expected behavior:**
65
+
66
+ - Skill is honest about the cost: retrofitting multiplayer is 5× harder than starting MP-first.
67
+ - Skill asks: "Are you committed? It will require auditing every state mutation in your existing code. Time estimate: significant."
68
+ - If user proceeds: skill walks the same 4 layers but adds an AUDIT phase before Layer 2: identify every place existing code writes to state that should be host-authoritative.
69
+ - If user balks: skill points to alternatives (release MP as a sequel; ship single-player; add async leaderboards instead).
70
+
71
+ **Assertions:**
72
+
73
+ - [ ] Skill warns about retrofit cost BEFORE starting Layer 1.
74
+ - [ ] Skill adds an AUDIT step that doesn't exist in the happy-path workflow.
75
+ - [ ] Skill never silently proceeds as if the game were greenfield.
76
+
77
+ ## Case 4: No Summer MCP — fallback path
78
+
79
+ **Fixture:** Same as Case 1, but Summer MCP unavailable.
80
+
81
+ **Input:** "Add multiplayer to my Godot game (P2P, friend invite)."
82
+
83
+ **Expected behavior:**
84
+
85
+ - Skill detects MCP unavailable.
86
+ - Walks the same 4 layers.
87
+ - Instead of `summer_project_setting`, asks the user to manually edit `project.godot`'s `[autoload]` section — provides the exact lines to paste.
88
+ - Instead of `summer_save_scene` / `summer_get_script_errors`, asks the user to save and check errors via the Godot editor.
89
+ - All file writes still go through `Write` host tool with "May I…" approval per file.
90
+
91
+ **Assertions:**
92
+
93
+ - [ ] Skill detects MCP unavailable; doesn't blindly call `summer_*` tools and fail.
94
+ - [ ] Project.godot edits are provided as exact paste-able lines.
95
+ - [ ] Workflow shape (4 layers, checkpoints between) is identical regardless of MCP availability.
96
+
97
+ ---
98
+
99
+ This spec runs via `/skill-test peer-to-peer-multiplayer spec` (see `_meta/skill-test/SKILL.md`).
@@ -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`).