summer-engine 2.7.0 → 2.8.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 (150) hide show
  1. package/.claude-plugin/plugin.json +2 -1
  2. package/.codex-plugin/plugin.json +3 -2
  3. package/.cursor-plugin/plugin.json +2 -1
  4. package/.opencode/INSTALL.md +1 -1
  5. package/.opencode/plugins/summer.js +1 -1
  6. package/AGENTS.md +4 -4
  7. package/CHANGELOG.md +10 -0
  8. package/GEMINI.md +5 -4
  9. package/README.md +58 -19
  10. package/assets/autopilot/README.md +51 -0
  11. package/assets/autopilot/autopilot.gd +222 -0
  12. package/assets/autopilot/probe_base.gd +262 -0
  13. package/assets/autopilot/run.sh +78 -0
  14. package/commands/gameskill.md +11 -2
  15. package/dist/bin/summer.js +8 -0
  16. package/dist/commands/config.d.ts +2 -0
  17. package/dist/commands/config.js +53 -0
  18. package/dist/commands/create.d.ts +1 -0
  19. package/dist/commands/create.js +38 -6
  20. package/dist/commands/list.js +1 -1
  21. package/dist/commands/login.d.ts +19 -0
  22. package/dist/commands/login.js +123 -36
  23. package/dist/commands/logout.js +3 -16
  24. package/dist/commands/logs.d.ts +2 -0
  25. package/dist/commands/logs.js +19 -0
  26. package/dist/commands/mcp.js +7 -2
  27. package/dist/commands/open.js +1 -1
  28. package/dist/commands/publish.d.ts +2 -0
  29. package/dist/commands/publish.js +20 -0
  30. package/dist/commands/releases.d.ts +2 -0
  31. package/dist/commands/releases.js +20 -0
  32. package/dist/commands/run.js +1 -1
  33. package/dist/lib/api-client.d.ts +4 -2
  34. package/dist/lib/api-client.js +28 -4
  35. package/dist/lib/auth.d.ts +40 -12
  36. package/dist/lib/auth.js +173 -37
  37. package/dist/lib/cloud/engine-bridge.d.ts +17 -4
  38. package/dist/lib/cloud/engine-bridge.js +32 -6
  39. package/dist/lib/config.d.ts +20 -0
  40. package/dist/lib/config.js +142 -0
  41. package/dist/lib/creator.d.ts +93 -0
  42. package/dist/lib/creator.js +393 -0
  43. package/dist/lib/engine.d.ts +35 -2
  44. package/dist/lib/engine.js +240 -6
  45. package/dist/lib/public-surface-paths.d.ts +13 -0
  46. package/dist/lib/public-surface-paths.js +42 -0
  47. package/dist/lib/skills-registry.d.ts +8 -0
  48. package/dist/lib/skills-registry.js +9 -0
  49. package/dist/lib/store.d.ts +14 -0
  50. package/dist/lib/store.js +145 -0
  51. package/dist/lib/summer-compatibility.d.ts +6 -0
  52. package/dist/lib/summer-compatibility.js +22 -0
  53. package/dist/mcp/server.d.ts +8 -1
  54. package/dist/mcp/server.js +25 -4
  55. package/dist/mcp/tools/creator-tools.d.ts +2 -0
  56. package/dist/mcp/tools/creator-tools.js +105 -0
  57. package/dist/mcp/tools/generate-tools.js +16 -6
  58. package/dist/mcp/tools/project-tools.js +12 -7
  59. package/dist/mcp/tools/scene-tools.js +6 -6
  60. package/dist/mcp/tools/visual-tools.js +4 -3
  61. package/hooks/pre-commit-doctor.sh +0 -0
  62. package/hooks/run-hook.cmd +0 -0
  63. package/hooks/session-start.sh +5 -5
  64. package/package.json +3 -1
  65. package/references/collaborative-protocol.md +50 -0
  66. package/references/gd-style.md +121 -0
  67. package/references/godot-version.md +51 -0
  68. package/references/mcp-tools-reference.md +199 -0
  69. package/references/public-surface-language.md +30 -0
  70. package/references/summer-folder.md +90 -0
  71. package/references/template-registry.md +73 -0
  72. package/skills/2d-assets/character-portrait/SKILL.md +17 -12
  73. package/skills/2d-assets/concept-art/SKILL.md +10 -9
  74. package/skills/2d-assets/pixel-art/SKILL.md +36 -20
  75. package/skills/2d-assets/skybox-panorama/SKILL.md +32 -37
  76. package/skills/2d-assets/sprite-sheet/SKILL.md +40 -35
  77. package/skills/2d-assets/tileable-texture/SKILL.md +28 -22
  78. package/skills/2d-assets/ui-graphics/SKILL.md +46 -32
  79. package/skills/2d-assets/use-widget-asset/SKILL.md +8 -6
  80. package/skills/3d-assets/character-model/SKILL.md +34 -19
  81. package/skills/3d-assets/environment-kit/SKILL.md +11 -5
  82. package/skills/3d-assets/organic-model/SKILL.md +8 -5
  83. package/skills/3d-assets/prop-model/SKILL.md +9 -3
  84. package/skills/3d-assets/vehicle-model/SKILL.md +32 -19
  85. package/skills/README.md +1 -1
  86. package/skills/ai-and-npcs/design-npc/SKILL.md +31 -13
  87. package/skills/animation/animation-tree/SKILL.md +39 -15
  88. package/skills/animation/facial-and-lipsync/SKILL.md +25 -8
  89. package/skills/animation/generate-motion/SKILL.md +47 -15
  90. package/skills/animation/procedural-animation/SKILL.md +31 -13
  91. package/skills/animation/retarget/SKILL.md +127 -79
  92. package/skills/audio/adaptive-music/SKILL.md +24 -20
  93. package/skills/audio/ambient-bed/SKILL.md +22 -16
  94. package/skills/audio/audio-direction/SKILL.md +15 -10
  95. package/skills/audio/music-track/SKILL.md +18 -12
  96. package/skills/audio/sound-effect/SKILL.md +17 -12
  97. package/skills/audio/voice-line/SKILL.md +42 -42
  98. package/skills/character-controllers/fps-controller/SKILL.md +26 -16
  99. package/skills/debugging/debug/SKILL.md +52 -20
  100. package/skills/deployment/export-and-ship/SKILL.md +105 -38
  101. package/skills/deployment/remote-deploy/SKILL.md +56 -23
  102. package/skills/gameplay-mechanics/auto-fire-targeting/SKILL.md +26 -1
  103. package/skills/gameplay-mechanics/design-mechanic/SKILL.md +23 -15
  104. package/skills/level-design/design-level/SKILL.md +22 -8
  105. package/skills/level-design/scene-to-level/SKILL.md +13 -7
  106. package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +8 -8
  107. package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +2 -7
  108. package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +26 -18
  109. package/skills/performance/tune-performance/SKILL.md +51 -32
  110. package/skills/rendering-and-lighting/3d-lighting/SKILL.md +34 -5
  111. package/skills/rendering-and-lighting/art-direction/SKILL.md +6 -8
  112. package/skills/scene-and-project/brainstorm-game/SKILL.md +3 -5
  113. package/skills/scene-and-project/make-game/SKILL.md +2 -1
  114. package/skills/scene-and-project/play/SKILL.md +10 -4
  115. package/skills/scene-and-project/scene-composition/SKILL.md +21 -8
  116. package/skills/scene-and-project/summer-cloud/SKILL.md +1 -1
  117. package/skills/ui-and-ux/ui-basics/SKILL.md +16 -7
  118. package/skills/video/animated-loop/SKILL.md +63 -39
  119. package/skills/video/cinematic-cutscene/SKILL.md +66 -30
  120. package/skills/video/trailer-shot/SKILL.md +30 -21
  121. package/skills/visual-effects/_building-blocks/additive-billboard-particles.md +25 -16
  122. package/skills/visual-effects/_building-blocks/trauma-shake-snippet.md +5 -3
  123. package/skills/visual-effects/game-feel/SKILL.md +51 -33
  124. package/skills/visual-effects/recipes/dissolve/SKILL.md +51 -9
  125. package/skills/visual-effects/recipes/fire/SKILL.md +136 -49
  126. package/skills/visual-effects/recipes/hit-spark/SKILL.md +45 -8
  127. package/skills/visual-effects/recipes/lightning/SKILL.md +59 -27
  128. package/skills/visual-effects/recipes/magic-glow/SKILL.md +59 -26
  129. package/skills/visual-effects/recipes/muzzle-flash/SKILL.md +68 -25
  130. package/skills/visual-effects/recipes/smoke/SKILL.md +89 -28
  131. package/skills/visual-effects/recipes/water-ripple/SKILL.md +83 -23
  132. package/skills/workflow/brainstorming/SKILL.md +1 -1
  133. package/skills/workflow/brainstorming/scripts/start-server.sh +0 -0
  134. package/skills/workflow/brainstorming/scripts/stop-server.sh +0 -0
  135. package/skills/workflow/debugging-game-feel/SKILL.md +29 -9
  136. package/skills/workflow/diagnosing-perf-regressions/SKILL.md +46 -21
  137. package/skills/workflow/gameskill/SKILL.md +11 -2
  138. package/skills/workflow/headless-scripting/SKILL.md +407 -0
  139. package/skills/workflow/investigating-bugs/SKILL.md +4 -2
  140. package/skills/workflow/investigating-bugs/find-polluter.sh +0 -0
  141. package/skills/workflow/mcpupdate/SKILL.md +3 -3
  142. package/skills/workflow/playtesting-a-feature/SKILL.md +94 -21
  143. package/skills/workflow/skill-create/SKILL.md +7 -7
  144. package/skills/workflow/skill-test/SKILL.md +3 -3
  145. package/skills/workflow/using-summer/SKILL.md +12 -2
  146. package/skills/workflow/verification-before-completion/SKILL.md +2 -0
  147. package/skills/workflow/writing-plans/SKILL.md +7 -7
  148. package/skills/workflow/writing-skills/SKILL.md +7 -5
  149. package/skills/workflow/writing-skills/render-graphs.js +0 -0
  150. package/skills/workflow/writing-skills/testing-skills-with-subagents.md +1 -1
@@ -49,7 +49,7 @@ The bible defines an SFX *class* (UI, Pickup positive, Damage, Footstep, Attack,
49
49
  Generation is metered. Reuse beats regenerate.
50
50
 
51
51
  ```
52
- summer_search_assets(query="<class> <subject>", filter={ kind: "audio" })
52
+ summer_search_assets(query="<class> <subject>", assetType="audio", source="all")
53
53
  ```
54
54
 
55
55
  If something fits, ask:
@@ -93,18 +93,21 @@ Show the prompt and the call before running:
93
93
 
94
94
  > Prompt: `metal sword swing whoosh, dry, sharp, 250ms`. Duration 0.5s (model floor). Model: ElevenLabs SFX. Cost: ~1 credit. Generate?
95
95
 
96
+ The `sound_effects` capability reads the description from **`text`**, not `prompt`. Passing `prompt` here is a 400 `text_required` — `prompt` is only for the `music` capability.
97
+
96
98
  ```
97
99
  summer_generate_audio(
98
100
  capability: "sound_effects",
99
- prompt: "metal sword swing whoosh, dry, sharp, 250ms",
101
+ text: "metal sword swing whoosh, dry, sharp, 250ms",
100
102
  durationSeconds: 0.5
101
103
  )
102
- // Result: { asset: { fileUrl, ... } }
103
104
  // Then: summer_import_from_url(url: "<fileUrl>", path: "res://audio/sfx/sword_swing_01.wav")
104
105
  ```
105
106
 
106
107
  `durationSeconds` floor is 0.5, ceiling is 22. If the user wants a 100ms click, generate 0.5s and the player only plays the front; or trim in the engine.
107
108
 
109
+ SFX comes back as **WAV**, not MP3 — Summer requests raw PCM from the provider, trims the model's lead-in silence, applies short anti-click fades, and emits a 16-bit mono WAV. A `.wav` target path is therefore correct, and the usual "ElevenLabs one-shots start with dead air" problem is already handled upstream.
110
+
108
111
  ### 5. Decision: one-shot vs loop
109
112
 
110
113
  | Use case | Setup |
@@ -126,13 +129,15 @@ Choose the right player node:
126
129
 
127
130
  Add it under the emitting node:
128
131
 
132
+ Every scene-mutating tool takes an explicit `scenePath`, node paths are relative to the scene root (`./`), and the property argument is named `key`, not `property`:
133
+
129
134
  ```
130
- summer_add_node(parentPath="/root/Game/Player", type="AudioStreamPlayer3D", name="SwingSFX")
131
- summer_set_prop(path="/root/Game/Player/SwingSFX", property="stream", value="res://audio/sfx/sword_swing_01.wav")
132
- summer_set_prop(path="/root/Game/Player/SwingSFX", property="bus", value="SFX")
133
- summer_set_prop(path="/root/Game/Player/SwingSFX", property="volume_db", value=0.0)
134
- summer_set_prop(path="/root/Game/Player/SwingSFX", property="max_distance", value=25.0)
135
- summer_set_prop(path="/root/Game/Player/SwingSFX", property="attenuation_model", value=0)
135
+ summer_add_node(scenePath="res://main.tscn", parent="./Player", type="AudioStreamPlayer3D", name="SwingSFX")
136
+ summer_set_prop(scenePath="res://main.tscn", path="./Player/SwingSFX", key="stream", value="res://audio/sfx/sword_swing_01.wav")
137
+ summer_set_prop(scenePath="res://main.tscn", path="./Player/SwingSFX", key="bus", value="SFX")
138
+ summer_set_prop(scenePath="res://main.tscn", path="./Player/SwingSFX", key="volume_db", value=0.0)
139
+ summer_set_prop(scenePath="res://main.tscn", path="./Player/SwingSFX", key="max_distance", value=25.0)
140
+ summer_set_prop(scenePath="res://main.tscn", path="./Player/SwingSFX", key="attenuation_model", value=0)
136
141
  ```
137
142
 
138
143
  Bus name must match the bible (`SFX`, `UI`, `Ambient`, etc.). If the bus doesn't exist, run `/audio-direction` step 8.
@@ -150,7 +155,7 @@ func _ready() -> void:
150
155
  play()
151
156
  ```
152
157
 
153
- Save it as a `.tscn`, then `summer_instantiate_scene` at the emitter's global position when the event fires. The node frees itself when the stream finishes — no leaks.
158
+ Save it as a `.tscn`, then `summer_instantiate_scene(scenePath, parent, scene, name)` to place it. Note this only wires the node into a scene at author time — spawning one per event at the emitter's runtime position is a job for GDScript (`preload(...).instantiate()` + `add_child`), not for an MCP call. The node frees itself when the stream finishes — no leaks.
154
159
 
155
160
  ### 8. Volume calibration
156
161
 
@@ -233,5 +238,5 @@ After the SFX is wired:
233
238
  - `audio/ambient-bed` — long looping textures
234
239
  - `audio/music-track` — music
235
240
  - `audio/voice-line` — TTS
236
- - `references/mcp-tools-reference.md`
237
- - `references/godot-version.md` — Godot 4.5 audio nodes
241
+ - `../../../references/mcp-tools-reference.md`
242
+ - `../../../references/godot-version.md` — Summer compatibility for audio nodes
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: voice-line
3
- description: Use when generating TTS voice lines — NPC barks, narrator, dialogue. Includes voice-id discovery via summer_list_models family:'audio-voice', a character-to-voice decision tree, stability/style/similarity guidance, and the multi-line dialogue case via text_to_dialogue. Trigger on "make a voice line", "narrator", "NPC says", "voice for the merchant", "TTS line", "dialogue".
3
+ description: Use when generating TTS voice lines — NPC barks, narrator, dialogue. Covers where voice ids come from, a character-to-voice decision tree, stability/style/similarity guidance, and the multi-line dialogue case via text_to_dialogue. Trigger on "make a voice line", "narrator", "NPC says", "voice for the merchant", "TTS line", "dialogue".
4
4
  license: MIT
5
5
  compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
6
  category: audio
7
7
  user-invocable: true
8
- allowed-tools: Read Grep Glob Write Edit summer_generate_voice summer_generate_audio summer_list_models summer_search_assets summer_import_from_url summer_add_node summer_set_prop summer_inspect_node
8
+ allowed-tools: Read Grep Glob Write Edit summer_generate_audio summer_search_assets summer_import_from_url summer_add_node summer_set_prop summer_inspect_node
9
9
  paths: [".summer/**", "audio/voice/**", "scripts/**", "**/*.tscn"]
10
10
  ---
11
11
 
@@ -13,7 +13,7 @@ paths: [".summer/**", "audio/voice/**", "scripts/**", "**/*.tscn"]
13
13
 
14
14
  ## Overview
15
15
 
16
- The hardest part of TTS isn't the line — it's picking the right voice. ElevenLabs ships hundreds; pick wrong and a tough warlord NPC sounds like a podcast host. This skill walks the voice-id discovery flow (`summer_list_models` family `audio-voice`), narrows by gender / accent / age / energy, presents 4–5 finalists with sample URLs for the user to audition, and locks the pick before generating.
16
+ The hardest part of TTS isn't the line — it's picking the right voice. ElevenLabs ships hundreds; pick wrong and a tough warlord NPC sounds like a podcast host. **There is no MCP tool that lists voices** — the only voice-related input Summer exposes is the `voiceId` string on `summer_generate_audio`. So the voice pick has to come from the user (or from the project's cast bible), and this skill's job is to get that pick made deliberately and then locked.
17
17
 
18
18
  Then it generates one line (or a multi-turn dialogue) with the right stability / style / similarity / speed for the delivery — flat for narration, expressive for a bark, fast for an excited shout.
19
19
 
@@ -44,24 +44,21 @@ If a character bible exists, the voice should match the character's age / gender
44
44
 
45
45
  > Tell me the character: gender, rough age, accent or regional flavor, and energy (calm / measured / excited / gruff). Or just give me a reference — "sounds like the captain in Mass Effect" works.
46
46
 
47
- ### 2. Browse the voice catalog
47
+ ### 2. Get the voice id
48
48
 
49
- ```
50
- summer_list_models(family="audio-voice")
51
- ```
49
+ Check the cast bible first (step 1). If the character already has a locked id, use it and skip to step 5.
52
50
 
53
- Returns a list with `id`, `name`, `accent`, `gender`, `age`, `description`, and `previewUrl`. Filter mentally to 8–12 candidates by the character's hard constraints (gender + age + accent), then pick 4–5 finalists with maximally distinct character (gruff vs warm vs neutral vs theatrical).
51
+ If not, you need a `voiceId` from the user. There is no catalog tool and no preview-URL endpoint on this surface — do not invent one, and do not claim you auditioned anything. Ask:
54
52
 
55
- Present them to the user like this:
53
+ > I need an ElevenLabs voice id for `<character>`. Two ways to get one:
54
+ > - Browse and audition at `elevenlabs.io/app/voice-library` (or your Voices page) and paste me the voice id.
55
+ > - Or say "use the default" and I'll generate with Summer's default voice so you can hear the line, then we swap the id later.
56
+ >
57
+ > Describe the target if it helps me sanity-check the pick: gender, rough age, accent, and energy (calm / measured / excited / gruff).
56
58
 
57
- > Four finalists for "old gruff dwarven warlord":
58
- > 1. **Brogan** — male, 50s, rough Scottish, gravelly. Sample: `<previewUrl>`
59
- > 2. **Hodge** — male, 60s, neutral, weathered baritone. Sample: `<previewUrl>`
60
- > 3. **Marrick** — male, 40s, rough English, mid-energy. Sample: `<previewUrl>`
61
- > 4. **Old Drum** — male, 70s, deep, slow speech. Sample: `<previewUrl>`
62
- > Audition and pick one. Or ask for four more.
59
+ Omitting `voiceId` entirely is valid — `summer_generate_audio` falls back to a single default voice (`JBFqnCBsd6RMkjVDRZzb`). That is fine for a throwaway read-through, never for a shipped cast.
63
60
 
64
- Wait for the user. Do not pick for them — voice is the highest-stakes audio decision in the project.
61
+ Voice is the highest-stakes audio decision in the project. Do not pick an id for the user and do not guess ids — a wrong id is a hard provider error, not a different-sounding voice.
65
62
 
66
63
  ### 3. Character-to-voice decision tree (when the user wants a recommendation)
67
64
 
@@ -117,18 +114,18 @@ If legacy `.summer/voice-cast.md` already exists, read it first and either keep
117
114
 
118
115
  ### 5. Tune stability / similarity / style / speed for delivery
119
116
 
120
- ElevenLabs voice options:
117
+ These are **not** top-level tool arguments. They go inside `options.voiceSettings`, in camelCase, exactly as the ElevenLabs SDK's `VoiceSettings` type spells them — `stability`, `similarityBoost`, `style`, `speed`, `useSpeakerBoost`. `options` is spread straight into the SDK call, so a flat `similarity_boost` at the top of `options` is silently dropped.
121
118
 
122
119
  | Param | Range | Effect |
123
120
  |---|---|---|
124
121
  | `stability` | 0.0–1.0 | Higher = monotone, consistent. Lower = expressive, variable. |
125
- | `similarity_boost` | 0.0–1.0 | Higher = closer to the original sample. Lower = more freedom (can drift). |
122
+ | `similarityBoost` | 0.0–1.0 | Higher = closer to the original sample. Lower = more freedom (can drift). |
126
123
  | `style` | 0.0–1.0 | Higher = more theatrical / exaggerated. 0 = neutral. |
127
124
  | `speed` | 0.7–1.2 | Speech speed multiplier. |
128
125
 
129
126
  Defaults that work as a starting point:
130
127
 
131
- | Delivery | stability | similarity_boost | style | speed |
128
+ | Delivery | stability | similarityBoost | style | speed |
132
129
  |---|---|---|---|---|
133
130
  | Calm narration | 0.75 | 0.75 | 0.0 | 1.0 |
134
131
  | Cinematic narration | 0.5 | 0.85 | 0.4 | 0.95 |
@@ -166,50 +163,52 @@ Example lines:
166
163
  ### 7. Confirm and call
167
164
 
168
165
  ```
169
- summer_generate_voice(
166
+ summer_generate_audio(
167
+ capability="text_to_speech",
170
168
  text="Hold the line. They're coming through the south gate. Ready arrows.",
171
169
  voiceId="21m00Tcm4TlvDq8ikWAM",
172
170
  modelId="eleven_multilingual_v2",
173
- stability=0.6,
174
- similarity_boost=0.75,
175
- style=0.2,
176
- speed=1.0,
177
- outputPath="audio/voice/hodge_hold_the_line.mp3"
171
+ options={ voiceSettings: { stability: 0.6, similarityBoost: 0.75, style: 0.2, speed: 1.0 } }
178
172
  )
179
173
  ```
180
174
 
181
175
  `modelId` defaults to `eleven_multilingual_v2`. For very short / latency-sensitive in-game barks, `eleven_turbo_v2_5` is faster; for highest fidelity, `eleven_multilingual_v2` is the default.
182
176
 
177
+ There is no `outputPath` — the tool returns a hosted asset (MP3, `audio/mpeg`). Land it in the project explicitly:
178
+
179
+ ```
180
+ summer_import_from_url(url="<fileUrl>", path="res://audio/voice/hodge_hold_the_line.mp3")
181
+ ```
182
+
183
183
  ### 8. Multi-line dialogue (two or more speakers)
184
184
 
185
185
  Use `summer_generate_audio` with `capability: "text_to_dialogue"`:
186
186
 
187
+ There is no `speakers` roster and no `script` array. The whole conversation is one flat `inputs` array of `{ text, voiceId }` objects, in turn order — the voice id is repeated on every line:
188
+
187
189
  ```
188
190
  summer_generate_audio(
189
191
  capability="text_to_dialogue",
190
- speakers=[
191
- { name: "Hodge", voiceId: "21m00Tcm4TlvDq8ikWAM" },
192
- { name: "Brogan", voiceId: "<brogan-id>" }
193
- ],
194
- script=[
195
- { speaker: "Hodge", text: "They're at the gate." },
196
- { speaker: "Brogan", text: "Aye. Let 'em come." },
197
- { speaker: "Hodge", text: "Steady. On my mark." }
198
- ],
199
- outputPath="audio/voice/dialogue_gate_warning.mp3"
192
+ inputs=[
193
+ { text: "They're at the gate.", voiceId: "21m00Tcm4TlvDq8ikWAM" },
194
+ { text: "Aye. Let 'em come.", voiceId: "<brogan-id>" },
195
+ { text: "Steady. On my mark.", voiceId: "21m00Tcm4TlvDq8ikWAM" }
196
+ ]
200
197
  )
201
198
  ```
202
199
 
203
- This produces a single MP3 with both voices, with dialogue-aware pacing the model handles internally. For very long scripts, split into chunks of ~6 turns and concatenate.
200
+ `inputs` is required for this capability; omitting it is a 400 `inputs_required`. `modelId` defaults to `eleven_v3` here, not `eleven_multilingual_v2`. The result is a single MP3 with both voices and dialogue-aware pacing the model handles internally — import it with `summer_import_from_url` like any other clip. For very long scripts, split into chunks of ~6 turns and concatenate.
204
201
 
205
202
  ### 9. Wire the line as `AudioStreamPlayer` on the Voice bus
206
203
 
204
+ Every scene-mutating tool takes an explicit `scenePath`, node paths are relative to the scene root (`./`), and the property argument is named `key`, not `property`:
205
+
207
206
  ```
208
- summer_add_node(parentPath="/root/Game/NPC", type="AudioStreamPlayer", name="VoiceLine")
209
- summer_set_prop(path="/root/Game/NPC/VoiceLine", property="stream", value="res://audio/voice/hodge_hold_the_line.mp3")
210
- summer_set_prop(path="/root/Game/NPC/VoiceLine", property="bus", value="Voice")
211
- summer_set_prop(path="/root/Game/NPC/VoiceLine", property="volume_db", value=0.0)
212
- summer_set_prop(path="/root/Game/NPC/VoiceLine", property="autoplay", value=false)
207
+ summer_add_node(scenePath="res://main.tscn", parent="./NPC", type="AudioStreamPlayer", name="VoiceLine")
208
+ summer_set_prop(scenePath="res://main.tscn", path="./NPC/VoiceLine", key="stream", value="res://audio/voice/hodge_hold_the_line.mp3")
209
+ summer_set_prop(scenePath="res://main.tscn", path="./NPC/VoiceLine", key="bus", value="Voice")
210
+ summer_set_prop(scenePath="res://main.tscn", path="./NPC/VoiceLine", key="volume_db", value=0.0)
211
+ summer_set_prop(scenePath="res://main.tscn", path="./NPC/VoiceLine", key="autoplay", value=false)
213
212
  ```
214
213
 
215
214
  For positional NPCs, `AudioStreamPlayer3D` with `max_distance=15.0` so distant NPCs aren't audible.
@@ -239,7 +238,8 @@ Narrator intimate: warmer mid pitch, lower stability for breath
239
238
 
240
239
  ## Anti-patterns
241
240
 
242
- - **Picking a voice without auditioning samples.** The user must hear it.
241
+ - **Inventing a voice catalog.** There is no `summer_list_models`, no voice-listing tool, and no preview URLs on this surface. Ask the user for the id.
242
+ - **Guessing a voice id.** A wrong id is a provider error, not a different voice.
243
243
  - **Reusing a voice id across two characters.** Players notice instantly. Lock the cast.
244
244
  - **Changing a locked voice without approval.** A cast voice is project memory, not a throwaway generation option.
245
245
  - **Stage directions in the text.** `(angrily) Get out!` is read literally as "angrily get out". Use stability/style.
@@ -35,27 +35,40 @@ Always call `summer_get_scene_tree` before mutating. If `World/Player`, `World/P
35
35
  ### 2. Add the Player root
36
36
 
37
37
  ```
38
- summer_add_node(parent="./World", type="CharacterBody3D", name="Player")
39
- summer_set_prop(path="./World/Player", key="position", value="Vector3(0, 1, 0)")
38
+ summer_add_node(scenePath="res://main.tscn", parent="./World", type="CharacterBody3D", name="Player")
39
+ summer_set_prop(scenePath="res://main.tscn", path="./World/Player", key="position", value="Vector3(0, 1, 0)")
40
40
  ```
41
41
 
42
- ### 3. Add the collision shape (standalone resource, NOT inline)
42
+ ### 3. Add the collision shape and size it
43
43
 
44
44
  ```
45
- summer_add_node(parent="./World/Player", type="CollisionShape3D", name="Collision")
46
- summer_set_prop(path="./World/Player/Collision", key="shape", value="CapsuleShape3D")
47
- summer_set_resource_property(nodePath="./World/Player/Collision", resourceProperty="shape", subProperty="radius", value="0.4")
48
- summer_set_resource_property(nodePath="./World/Player/Collision", resourceProperty="shape", subProperty="height", value="1.8")
45
+ summer_add_node(scenePath="res://main.tscn", parent="./World/Player", type="CollisionShape3D", name="Collision")
46
+ summer_set_prop(scenePath="res://main.tscn", path="./World/Player/Collision", key="shape", value="CapsuleShape3D")
47
+ summer_set_resource_property(scenePath="res://main.tscn", nodePath="./World/Player/Collision", resourceProperty="shape", subProperty="radius", value="0.4")
48
+ summer_set_resource_property(scenePath="res://main.tscn", nodePath="./World/Player/Collision", resourceProperty="shape", subProperty="height", value="1.8")
49
49
  ```
50
50
 
51
- `summer_set_prop` with a class-name string creates a standalone sub-resource. NEVER call `summer_set_resource_property` against an inline `sub_resource` — the value is silently dropped. See `references/mcp-tools-reference.md`.
51
+ Two things the older version of this skill got wrong:
52
+
53
+ - **`scenePath` is required** on `summer_add_node`, `summer_set_prop`,
54
+ `summer_set_resource_property` and `summer_save_scene`. Omit it and the call
55
+ never reaches the engine. (`summer_input_map_bind` is the exception — it edits
56
+ `project.godot`, not a scene, and takes only `name` + `events`.)
57
+ - **This inline-resource sequence is the supported pattern, not a trap.**
58
+ `summer_set_prop` with a class-name string instantiates a scene-embedded
59
+ (`[sub_resource]`) resource, and `summer_set_resource_property` then reads that
60
+ property off the node and writes the sub-property straight onto it. Embedded
61
+ and external `.tres` resources take the same path. The op has no silent-drop
62
+ branch: the only failures are explicit — `node not found`, `property is not a
63
+ resource`, or `resource is null` when the property was never assigned. Assign
64
+ the resource first, then set its sub-properties.
52
65
 
53
66
  ### 4. Add the Head pivot + Camera
54
67
 
55
68
  ```
56
- summer_add_node(parent="./World/Player", type="Node3D", name="Head")
57
- summer_set_prop(path="./World/Player/Head", key="position", value="Vector3(0, 1.6, 0)")
58
- summer_add_node(parent="./World/Player/Head", type="Camera3D", name="Camera")
69
+ summer_add_node(scenePath="res://main.tscn", parent="./World/Player", type="Node3D", name="Head")
70
+ summer_set_prop(scenePath="res://main.tscn", path="./World/Player/Head", key="position", value="Vector3(0, 1.6, 0)")
71
+ summer_add_node(scenePath="res://main.tscn", parent="./World/Player/Head", type="Camera3D", name="Camera")
59
72
  ```
60
73
 
61
74
  Eye height of 1.6 sits the camera right at the top of a 1.8-tall capsule (capsule center 0.9, plus 0.7 to the eye). Tweak per art style.
@@ -73,7 +86,7 @@ summer_input_map_bind(name="sprint", events=[{type:"key", key:"Shift"}])
73
86
 
74
87
  ### 6. Attach the controller script
75
88
 
76
- Ask before writing: "May I create `scripts/player_controller.gd` and attach it to `./World/Player`?" Then `Write` the file with the skeleton in the next section, attach via inspector, and finish with `summer_save_scene` + `summer_get_script_errors`.
89
+ Ask before writing: "May I create `scripts/player_controller.gd` and attach it to `./World/Player`?" Then `Write` the file with the skeleton in the next section, attach via inspector, and finish with `summer_save_scene(scenePath="res://main.tscn")` + `summer_get_script_errors(path="res://scripts/player_controller.gd")` (that tool checks one file and requires `path`).
77
90
 
78
91
  ## Physics-Process Flow (the order matters)
79
92
 
@@ -328,14 +341,11 @@ Then patch `project.godot` with the InputMap actions (`input/move_forward = { ..
328
341
 
329
342
  ## Collaborative Protocol
330
343
 
331
- This skill writes scene nodes, an InputMap, and a `.gd` script. Always ask before applying. Group writes per phase: "May I add the Player + Collision + Head + Camera, bind WASD/jump/sprint, and attach `player_controller.gd`?" See `../../references/collaborative-protocol.md`.
344
+ This skill writes scene nodes, an InputMap, and a `.gd` script. Always ask before applying. Group writes per phase: "May I add the Player + Collision + Head + Camera, bind WASD/jump/sprint, and attach `player_controller.gd`?"
332
345
 
333
346
  If the user asks for a "third-person FPS", flag the contradiction: FPS = first-person. Either clarify, or hand off to the `tps-controller` skill when it ships.
334
347
 
335
348
  ## See Also
336
349
 
337
- - `references/gd-style.md` — typed GDScript conventions used in the skeleton.
338
- - `references/mcp-tools-reference.md` — `summer_set_resource_property` rules + the inline-sub-resource silent-fail trap.
339
- - `references/collaborative-protocol.md` — when to ask before writing.
340
350
  - `scripting-patterns/state-machine-patterns/SKILL.md` — once movement grows past this skeleton (slide, grapple, hover), refactor into a state machine instead of stuffing more branches into `_physics_process`.
341
351
  - `physics/character-body-tuning/SKILL.md` (when shipped) — slope handling, step-up, floor-snap.
@@ -1,17 +1,19 @@
1
1
  ---
2
2
  name: debug
3
- description: Use when the user reports a bug, crash, error, or unexpected behavior in a Godot/Summer project, before making any code or scene changes — runs a disciplined script-errors → console → debugger → hypothesis → fix → verify loop. Trigger on "debug", "crash", "error", "broken", "not working", "freezes", "wrong".
3
+ description: Use when the user reports a bug, crash, error, or unexpected behavior in a Summer project, before making code or scene changes. Runs a disciplined script-errors, console, debugger, hypothesis, fix, and verify loop. Trigger on "debug", "crash", "error", "broken", "not working", "freezes", "wrong".
4
4
  license: MIT
5
5
  compatibility: [Cursor, Claude Code, Codex, Windsurf, Gemini, OpenCode]
6
6
  category: debugging
7
7
  user-invocable: true
8
- allowed-tools: Read Edit Grep summer_create_debug_report summer_get_diagnostics summer_get_script_errors summer_get_console summer_clear_console summer_get_debugger_errors summer_play summer_stop summer_is_running summer_inspect_node summer_inspect_resource summer_get_scene_tree
8
+ allowed-tools: Read Edit Grep summer_create_debug_report summer_get_diagnostics summer_get_script_errors summer_get_console summer_clear_console summer_get_debugger_errors summer_get_debugger_warnings summer_play summer_stop summer_is_running summer_inspect_node summer_inspect_resource summer_get_scene_tree summer_screenshot summer_batch
9
9
  paths: ["**/*.gd", "**/*.cs", "**/*.tscn", "**/*.tres", "project.godot"]
10
10
  ---
11
11
 
12
12
  # /debug — Triage and Fix a Bug End-to-End
13
13
 
14
- The disciplined debugging loop for Godot/Summer projects. Read the error before guessing. Form a hypothesis before editing. Verify the fix before declaring victory. Never grep the codebase before reading the actual error.
14
+ The disciplined debugging loop for Summer projects. Read the error before
15
+ guessing. Form a hypothesis before editing. Verify the fix before declaring
16
+ victory. Never grep the codebase before reading the actual error.
15
17
 
16
18
  **Core principle:** The debugger already knows what's wrong. Your job is to listen to it before doing anything else.
17
19
 
@@ -76,29 +78,37 @@ In strict order. Stop at the first one that returns useful signal.
76
78
  | 2 | `summer_get_diagnostics` | Aggregate console + debugger error counts. One call, broad picture. |
77
79
  | 3 | `summer_get_console` | Read the editor Output panel — print statements, warnings, errors that didn't crash. |
78
80
  | 4 | `summer_get_debugger_errors` | Runtime errors caught by the debugger. Use AFTER `summer_play` for runtime-only bugs. |
81
+ | 5 | `summer_get_debugger_warnings` | Warning bodies (file/line/function/callstack). Use when diagnostics reports a non-zero `debugger.warnings`. |
79
82
 
80
83
  **If `summer_get_script_errors` is clean and the user says it crashes only when running:** it's a runtime bug. Go to step 2b.
81
84
 
82
85
  ### 2b. Runtime-only bugs
83
86
 
87
+ **Reproduce it yourself first.** Write a `RunVerification` probe that performs the repro steps (`press` / `key`), reports the state you expect to be wrong, and saves a frame. See "Drive the game yourself" below for the exact call. The returned `results.errors_seen` and `reports` are the diagnostic. This costs one call, touches nothing the user owns, and gives you a repro you can re-run after the fix.
88
+
89
+ Fall back to the editor session only when the repro genuinely needs a human (feel, hardware, "is this what you meant?"):
90
+
84
91
  ```
85
92
  summer_clear_console
86
93
  summer_play
87
94
  ─▶ ASK USER: "Reproduce the bug now."
88
95
  (wait for confirmation)
89
96
  summer_get_debugger_errors
97
+ summer_get_debugger_warnings (if diagnostics showed warnings)
90
98
  summer_stop
91
99
  ```
92
100
 
93
- Do not skip the "reproduce now" prompt. Auto-running and grabbing whatever's in the buffer leads you to chase ghosts from previous sessions.
101
+ If you go this route, do not skip the "reproduce now" prompt. Auto-running and grabbing whatever's in the buffer leads you to chase ghosts from previous sessions.
94
102
 
95
103
  ### 2c. MCP unavailable (engine not running, or no Summer install)
96
104
 
97
105
  If `summer_get_script_errors` returns "Summer Engine is not running" or the tool isn't available:
98
106
 
99
- 1. Ask the user to copy-paste the Output panel and the Debugger panel from the Godot editor.
100
- 2. Reason over the pasted text exactly as you would over MCP output.
101
- 3. Continue with the rest of the loop unchanged.
107
+ 1. Tell the user `summer run` starts it. One command restores every tool in this loop — try that before degrading to an interview.
108
+ 2. If they cannot or will not, ask the user to copy-paste the Output panel and
109
+ the Debugger panel from Summer Engine.
110
+ 3. Reason over the pasted text exactly as you would over MCP output.
111
+ 4. Continue with the rest of the loop unchanged.
102
112
 
103
113
  Do NOT loop on MCP retry. Do NOT pretend the engine will come back. Use the fallback the moment it fails once.
104
114
 
@@ -133,7 +143,7 @@ Surface the proposed fix in plain language and ask permission. Two patterns:
133
143
 
134
144
  - For GDScript edits: `Read` the 20–40 lines around the error, `Edit` the exact change. Don't read the whole file. Don't reformat. Don't rename other things.
135
145
  - For scene edits: use the appropriate `summer_*` tool (`summer_add_node`, `summer_set_prop`, `summer_replace_node`). Group multi-step changes in `summer_batch` for one undo step.
136
- - **Trap to avoid:** never call `summer_set_resource_property` against an inline `sub_resource` — the value is silently dropped. If the property is on a nested resource, first call `summer_set_prop` with the resource class name to instantiate a standalone resource, then drill in. See `references/mcp-tools-reference.md`.
146
+ - **Trap to avoid:** never call `summer_set_resource_property` against an inline `sub_resource` — the value is silently dropped. If the property is on a nested resource, first call `summer_set_prop` with the resource class name to instantiate a standalone resource, then drill in. See `../../../references/mcp-tools-reference.md`.
137
147
 
138
148
  ### 6. Verify — re-run the diagnostic that found it
139
149
 
@@ -158,7 +168,7 @@ If the diagnostic is still red after the fix, you formed the wrong hypothesis. G
158
168
  | Auto-fix linter warnings unrelated to the bug | Same reason. |
159
169
  | Declare victory after editing | Re-run the diagnostic. Always. |
160
170
 
161
- ## Quick reference — common Godot bug families
171
+ ## Quick reference — common Summer Engine bug families
162
172
 
163
173
  | Symptom | First tool | Common cause |
164
174
  |---|---|---|
@@ -180,24 +190,45 @@ Tell the user one short sentence: "Fixed `<file>:<line>` — `<change>`. Diagnos
180
190
 
181
191
  ## What the MCP debug tools CAN and CAN'T see (read this before claiming "clean")
182
192
 
183
- The `summer_*` tools are powerful for static + boot-time issues but **can't substitute for play-testing**. Knowing the gaps prevents false-clean reports.
193
+ The static and boot-time tools (`summer_get_script_errors`, `summer_get_console`, `summer_get_diagnostics`) **can't substitute for play-testing** — but you have a play-testing route, so a false-clean report is a choice, not a limitation. Know which tool answers which question.
184
194
 
185
195
  ### What the MCP CAN see
186
196
 
187
197
  - **Script parse errors** (`summer_get_script_errors`) — full text + file:line. Reliable.
188
198
  - **Editor console output** (`summer_get_console`) — `print` statements, editor-side warnings, std startup messages. Full text.
189
199
  - **Runtime debugger error count + full text** (`summer_get_debugger_errors`) — returns `errors_data` with `error`, `error_descr`, `callstack`, `file`, `function`, `line`. Reliable for errors.
190
- - **Diagnostics summary** (`summer_get_diagnostics`) — counts of console errors, debugger errors, debugger warnings, script errors. Tells you where to drill.
200
+ - **Runtime debugger warning text** (`summer_get_debugger_warnings`) — same structured shape as the errors tool, filtered to severity `warning`. Use it whenever `summer_get_diagnostics` shows a non-zero `debugger.warnings`; do not report a warning count you never read.
201
+ - **Diagnostics summary** (`summer_get_diagnostics`) — counts of console errors, debugger errors, debugger warnings, script errors. Tells you where to drill. **Counts only** — it carries no FPS, frame time, draw calls, or physics-body numbers.
191
202
  - **Scene tree + node properties** (`summer_get_scene_tree`, `summer_inspect_node`) — only the **edited** scene, not the running game's live tree.
203
+ - **Rendered pixels** (`summer_screenshot`) — `target:"viewport"` for the editor's current view, `target:"scene"` for an offscreen render of a scene file, `target:"game"` for a frame of the running game (that one needs the Summer desktop app bridge and fails cleanly over a plain local connection). You look at the actual image, not a description of it.
204
+ - **Gameplay behaviour, driven by you** (`RunVerification` via `summer_batch`) — see the next section. Input, live tree, and frames from a real running instance.
192
205
  - **Whether the game is running** (`summer_is_running`) — and on which scene.
193
206
 
194
- ### What the MCP CAN'T see (right now)
207
+ ### Drive the game yourself — `RunVerification`
208
+
209
+ For any bug that only fires from gameplay (movement, weapon firing, level transitions, button clicks), do **not** hand the repro to the user first. Spawn a hidden, disposable game instance that runs a GDScript probe and dies. It never touches the user's editor session.
210
+
211
+ ```
212
+ summer_batch ops:[{
213
+ "op": "RunVerification",
214
+ "probe_source": "extends SummerProbeBase\nfunc _ready() -> void:\n\tawait super._ready()\n\tawait get_tree().process_frame\n\tvar p := get_tree().root.find_child(\"Player\", true, false)\n\treport(\"y0\", p.global_position.y)\n\tawait press(\"jump\", 120)\n\tawait get_tree().create_timer(0.4).timeout\n\treport(\"y1\", p.global_position.y)\n\tsave_frame(\"after\")\n\tdump_tree()\n\tfinish()",
215
+ "max_seconds": 20
216
+ }]
217
+ ```
218
+
219
+ Probe API: `report(key, value)`, `save_frame(name)`, `dump_tree(max_depth)`, `press(action, hold_ms)`, `key(keycode, hold_ms)`, `finish()`. Returns `{ok, results, frames, out_dir}`; `results.errors_seen` carries error-level engine/script messages from that run, so a probe is also a clean way to catch a runtime error without polluting the editor's debugger buffer.
220
+
221
+ This covers what static diagnostics cannot: pressed input, live scene tree (`dump_tree` reads the *running* tree, unlike `summer_get_scene_tree`), state sampled over several frames, and real rendered frames.
222
+
223
+ `summer_batch` forwards unknown ops verbatim, which is how you reach `RunVerification` with no dedicated tool. Note that the sibling `SimulateInput` op is **not** reachable this way — non-bridge callers get `{ok:false, failure_reason:"unsupported_transport"}`; it only works from the in-editor chat bridge. Drive input with `press()` / `key()` inside a probe instead.
224
+
225
+ ### What still genuinely needs the user
226
+
227
+ - **Whether it feels right.** Frame counts and reports cannot tell you the jump feels floaty. See `summer:debugging-game-feel`.
228
+ - **Hardware-specific and non-deterministic behaviour.** A bug that only fires on their GPU, their controller, or one run in twenty.
229
+ - **A judgement call on intent.** "Is this the behaviour you wanted?" is a question, not a measurement.
195
230
 
196
- - **Debugger warning text.** `summer_get_debugger_errors` returns a `warnings: <count>` integer but no `warnings_data` array. You see "the game has 66 warnings" but you can't read them through MCP. **Tell the user: "I see N warnings exist but the MCP doesn't expose their text — paste the Debugger panel if any feel relevant."**
197
- - **Live runtime scene tree.** `summer_get_scene_tree` returns the editor's edited scene, not what's currently instantiated in the running game. When debugging runtime state, you can't introspect the live nodes.
198
- - **Keyboard / mouse / controller input simulation.** No tool sends key presses or mouse motion. So bugs that only fire from gameplay (player movement, weapon firing, level transitions, button clicks) require the user to play.
199
- - **Screenshot / visual diff.** No tool captures the rendered viewport. Visual regressions ("the floor looks wrong", "the camera clips through terrain") require user eyes.
200
- - **Frame-by-frame physics state.** No tool steps the simulation or watches for transient errors over time.
231
+ Everything else — press the button, read the state, look at the frame — is yours to do.
201
232
 
202
233
  ### The "static-only is not testing" rule
203
234
 
@@ -207,11 +238,12 @@ When you've made code changes and want to declare them "verified":
207
238
 
208
239
  1. **Required**: `summer_get_script_errors` clean on every modified file.
209
240
  2. **Required**: `summer_play` boot returns 0 errors (use the scene most likely to exercise the change).
210
- 3. **Recommended**: ask the user to play through the specific scenario the change touches, then re-run `summer_get_diagnostics`.
211
- 4. **Never claim "verified" from static analysis alone.** Say "compiles and boots clean — needs play-test to confirm <specific behavior>."
241
+ 3. **Required**: exercise the specific scenario the change touches with a `RunVerification` probe — press the input, assert the state, save a frame. Quote the reports you got back.
242
+ 4. Ask the user to play only for what a probe cannot judge: feel, hardware-specific behaviour, or whether the result is what they wanted.
243
+ 5. **Never claim "verified" from static analysis alone.** Say "compiles and boots clean — needs play-test to confirm <specific behavior>."
212
244
 
213
245
  ### The cost of skipping it
214
246
 
215
- A typical cautionary scenario: many parallel agents write thousands of lines of game code in one batch with verification static-only. The build is "diagnostic-clean" yet the running game has telegraph meshes that render the wrong axis, parse-valid scripts that crash on first autoload because of a guard pattern that doesn't compile, projectile tracers sized so they read as straight lines instead of projectiles, transform-leaked colliders from a copied scene, and `@onready` paths that throw on every boot when the script is loaded into a sibling scene that lacks one of the referenced children. None of these surface in `summer_get_diagnostics` until the user actually plays.
247
+ A typical cautionary scenario: many parallel agents write thousands of lines of game code in one batch with verification static-only. The build is "diagnostic-clean" yet the running game has telegraph meshes that render the wrong axis, parse-valid scripts that crash on first autoload because of a guard pattern that doesn't compile, projectile tracers sized so they read as straight lines instead of projectiles, transform-leaked colliders from a copied scene, and `@onready` paths that throw on every boot when the script is loaded into a sibling scene that lacks one of the referenced children. None of these surface in `summer_get_diagnostics` until something actually plays the game — which is exactly what a `RunVerification` probe does, and why "I had no way to test it" is not an available excuse.
216
248
 
217
249
  Static analysis is necessary but never sufficient.