summer-engine 3.5.1 → 3.6.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 (60) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +3 -2
  3. package/.codex-plugin/plugin.json +4 -3
  4. package/.cursor-plugin/plugin.json +3 -2
  5. package/.factory-plugin/plugin.json +3 -2
  6. package/CHANGELOG.md +22 -1
  7. package/commands/summer.md +1 -0
  8. package/dist/core/capabilities/sfx-choices.d.ts +91 -0
  9. package/dist/core/capabilities/sfx-choices.js +291 -0
  10. package/dist/core/capabilities/tool-dispatch.js +35 -0
  11. package/dist/mcp/hosted-mount.js +2 -1
  12. package/dist/mcp/provider-safe-schema.d.ts +10 -0
  13. package/dist/mcp/provider-safe-schema.js +96 -0
  14. package/dist/mcp/server.js +3 -0
  15. package/dist/mcp/tools/generate-tools.js +70 -3
  16. package/gemini-extension.json +2 -1
  17. package/library/references/mcp-tools-reference/mcp-tools-reference.md +5 -3
  18. package/library/references/mcp-tools-reference/resource.yaml +1 -1
  19. package/library/skills/README.md +4 -3
  20. package/library/skills/ambient-bed/SKILL.md +3 -1
  21. package/library/skills/ambient-bed/resource.yaml +1 -1
  22. package/library/skills/audio-direction/SKILL.md +5 -5
  23. package/library/skills/audio-direction/resource.yaml +1 -1
  24. package/library/skills/export-and-ship/SKILL.md +4 -0
  25. package/library/skills/make-game/SKILL.md +21 -2
  26. package/library/skills/make-game/resource.yaml +1 -0
  27. package/library/skills/multiplayer/SKILL.md +3 -1
  28. package/library/skills/multiplayer/resource.yaml +1 -0
  29. package/library/skills/multiplayer-movement/SKILL.md +1 -1
  30. package/library/skills/multiplayer-movement/files.md +2 -3
  31. package/library/skills/multiplayer-project/SKILL.md +20 -4
  32. package/library/skills/multiplayer-project/files.md +2 -3
  33. package/library/skills/multiplayer-publish/SKILL.md +90 -5
  34. package/library/skills/multiplayer-publish/resource.yaml +1 -0
  35. package/library/skills/multiplayer-state/SKILL.md +1 -1
  36. package/library/skills/multiplayer-state/files.md +2 -3
  37. package/library/skills/multiplayer-testing/SKILL.md +13 -0
  38. package/library/skills/multiplayer-testing/resource.yaml +1 -0
  39. package/library/skills/publish-your-game/SKILL.md +2 -0
  40. package/library/skills/release-readiness/SKILL.md +437 -0
  41. package/library/skills/release-readiness/resource.yaml +44 -0
  42. package/library/skills/sound-effect/SKILL.md +83 -158
  43. package/library/skills/sound-effect/resource.yaml +8 -2
  44. package/library/skills/summer-parties/SKILL.md +1 -1
  45. package/library/skills/ui-basics/SKILL.md +1 -0
  46. package/library/tools/generate-audio/resource.yaml +6 -2
  47. package/library/tools/generate-sfx-choices/resource.yaml +69 -0
  48. package/library/tools/get-choices/resource.yaml +50 -0
  49. package/package.json +1 -1
  50. package/registry/generated/aliases.json +2 -0
  51. package/registry/generated/counts.json +3 -3
  52. package/registry/generated/gemini-extension.json +2 -1
  53. package/registry/generated/index.json +163 -24
  54. package/registry/generated/marketplace.claude.json +2 -2
  55. package/registry/generated/plugin.claude.json +3 -2
  56. package/registry/generated/plugin.codex.json +4 -3
  57. package/registry/generated/plugin.cursor.json +3 -2
  58. package/registry/generated/plugin.factory.json +3 -2
  59. package/registry/generated/skills-index.md +4 -3
  60. package/registry/generated/skills-registry.json +15 -1
@@ -1,150 +1,143 @@
1
1
  ---
2
2
  name: sound-effect
3
- description: "Generate short SFX one-shots — footsteps, weapon swings, UI clicks, hit impacts — wired as AudioStreamPlayer/2D/3D that auto-frees on finished."
3
+ description: "Make SFX one-shots and timed sequences (swings, hits, whooshes, reloads, UI) - offer three model versions to pick from, then wire them as AudioStreamPlayers."
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_audio summer_search_assets summer_import_from_url summer_add_node summer_set_prop summer_instantiate_scene summer_inspect_node summer_get_scene_tree
8
+ allowed-tools: Read Grep Glob Write Edit summer_generate_sfx_choices summer_get_choices summer_generate_audio summer_search_assets summer_import_from_url summer_import_asset_by_id summer_add_node summer_set_prop summer_instantiate_scene summer_inspect_node summer_get_scene_tree
9
9
  paths: ["audio/sfx/**", "scripts/**", "**/*.tscn"]
10
10
  ---
11
11
 
12
- # /sound-effect — Generate a Short SFX One-Shot and Wire It
12
+ # /sound-effect — Make a Sound Effect and Wire It
13
13
 
14
- ## Overview
15
-
16
- This skill produces one named SFX clip that follows the audio bible's vocabulary, then wires it into the scene as an AudioStreamPlayer that plays once and frees itself (or stops cleanly if it is a short loop). The prompt shape decides the result: "metal sword swing whoosh, dry, sharp, 250ms" returns the right clip on the first try; "epic battle sound" returns twenty seconds of musical noise.
17
-
18
- ElevenLabs SFX (the `sound_effects` capability of `summer_generate_audio`) is literal. It treats the prompt as a description of a real sound. Concrete material, action and intensity beat adjectives.
14
+ > **IMPORTANT — the first sound effect in a chat:** before you generate it, ask the person one short question:
15
+ >
16
+ > > Do you want me to create three versions with three different models, and show them to you in a page where you pick?
17
+ >
18
+ > Say why in one plain line: the best model changes a lot from one sound to the next, so picking by ear gives a better result.
19
+ >
20
+ > - **Yes** → `summer_generate_sfx_choices`, tell them the returned `say` text, then `summer_get_choices` until they decide. Import the approved clips and wire them. The model they approve becomes their default.
21
+ > - **No** → `summer_generate_audio` with `capability: "sound_effects"` and **no** `modelId` (it uses their approved default, else ElevenLabs).
22
+ >
23
+ > Ask once per chat. After they answer, do not ask again in the same chat; follow their answer for the rest of it.
19
24
 
20
25
  ## When to use
21
26
 
22
- - One-shot SFX: footstep, swing, click, hit, impact, pickup, jump, land, door, breath.
23
- - Short loops < 2s: hum, drone snippet, rain texture (for longer looping ambience use `ambient-bed`).
24
- - Replacing a placeholder beep with something on-bible.
25
-
26
- ## When NOT to use
27
+ - One-shots: swing, clash, scrape, hit, punch, impact, whoosh, pickup, jump, land, door, UI click.
28
+ - Timed sequences tied to an animation: reload, attack combo, door unlock.
29
+ - Short loops (hum, servo, energy field) up to a few seconds.
27
30
 
28
- - Music or musical stings → `music-track`.
29
- - Long location ambience (>5s) → `ambient-bed`.
30
- - Voice / dialogue → `voice-line`.
31
- - Defining the *vocabulary* of SFX → `audio-direction`. This skill executes against an existing bible.
31
+ Not for: music or stingers (`music-track`), long location ambience (`ambient-bed`), voice (`voice-line`), the SFX vocabulary of the game (`audio-direction`).
32
32
 
33
33
  ## Steps
34
34
 
35
35
  ### 1. Read the audio bible
36
36
 
37
- ```
38
- Read .summer/audio-bible.md
39
- ```
40
-
41
- If it doesn't exist, ask:
37
+ Read `.summer/audio-bible.md` if it exists and map the request to one of its SFX classes; obey its character and DON'Ts. If it is missing, offer `/audio-direction` or go on with sensible defaults.
42
38
 
43
- > No audio bible at `.summer/audio-bible.md`. Want to run `/audio-direction` first to define the SFX vocabulary, or shall I just one-shot this with sensible defaults?
39
+ ### 2. Reuse before you generate
44
40
 
45
- The bible defines an SFX *class* (UI, Pickup positive, Damage, Footstep, Attack, Stinger, Ambient layer, Pickup neutral). Map the user's request to a class. Quote the class's character and DON'Ts back so the prompt obeys them.
41
+ Generation costs credits. `summer_search_assets(query="<subject>", assetType="audio", source="all")`; if a clip fits, ask whether to use it.
46
42
 
47
- ### 2. Search for an existing clip first
43
+ ### 3. Write the prompt
48
44
 
49
- Generation uses credits. Reuse an existing clip when one fits.
45
+ Describe the physical event, not a mood. The shape that tested well:
50
46
 
51
47
  ```
52
- summer_search_assets(query="<class> <subject>", assetType="audio", source="all")
48
+ Foley one-shot: <physical event with materials>, <transient + tail described>, close-mic, dry, no reverb, no music, no voices.
53
49
  ```
54
50
 
55
- If something fits, ask:
51
+ - Sword clash: `Foley one-shot: two steel longswords strike edge to edge, bright sharp metallic impact, short ringing tail that dies in half a second, close-mic, dry, no reverb, no music, no voices.`
52
+ - Punch: `Foley one-shot: a bare fist hits a heavy leather bag, deep thud with a slap on top, no tail, close-mic, dry, no reverb, no music, no voices.`
53
+ - Boulder drop: `Foley one-shot: a large boulder drops onto packed dirt, heavy low thump with a short rumble and a few small stones settling, close-mic, dry, no music, no voices.`
56
54
 
57
- > Found `audio/sfx/sword_swing_01.wav`. Use this, or generate fresh?
55
+ **Whooshes and swings:** say `air movement only, no metal ring, no impact`, or the model adds a clang.
58
56
 
59
- ### 3. Build the prompt — subject + material + action + intensity + duration cue
60
-
61
- ElevenLabs SFX responds to literal sound descriptions. Pattern:
57
+ **Timed sequences:** give the exact total length and the time of each event, and set `durationSeconds` to that length:
62
58
 
63
59
  ```
64
- <subject> <material> <action>, <intensity>, <character>, <duration cue>
60
+ Foley sequence, exactly 2 seconds, three distinct mechanical sounds: at 0.2 s the empty magazine is released and pulled out with a metal click; at 1.0 s a full magazine is slammed in with a solid clack; at 1.6 s the charging handle is pulled back and released with a sharp metallic snap. Close-mic, dry, no gunshot, no music.
65
61
  ```
66
62
 
67
- Working examples:
63
+ **Loops:** write `seamless loop` in the text and pass `loop: true`. Only ElevenLabs SFX v2 makes loops: use `summer_generate_audio` with `modelId: "eleven_text_to_sound_v2"`, or include it in a choice set.
64
+
65
+ Avoid: vibe words (`epic`, `cool`, `realistic`), several unrelated events in one prompt (split them, unless it is a timed sequence), and no length.
66
+
67
+ ### 4. Length
68
68
 
69
- | Goal | Prompt that works | Why |
69
+ - One-shots: 0.5-2 s.
70
+ - Animation-synced sounds (reloads, attacks): `durationSeconds` = the animation length, with the event times written in the prompt.
71
+ - Minimums: Stable Audio 3 SFX >= 1 s, Sonilo SFX 1.1 >= 0.5 s, ElevenLabs SFX v2 0.5-30 s. When a choice set includes Stable Audio 3, use at least 1 s and let the player use the front of the clip.
72
+
73
+ ### 5. Pick the models
74
+
75
+ | Model id | Name | Use it for |
70
76
  |---|---|---|
71
- | Sword swing | `metal sword swing whoosh, dry, sharp, 250ms` | material + action + dry rules out reverb |
72
- | UI click | `soft woody UI click, short, neutral pitch, 80ms` | material + duration; "click" alone is too vague |
73
- | Footstep on stone | `single footstep on dry stone, leather sole, mid-weight, 180ms` | surface + footwear + body weight |
74
- | Player hit | `punchy low-mid body hit impact, slight detune, no tail, 200ms` | "no tail" kills reverb the bible forbids |
75
- | Coin pickup | `bright metallic coin pickup, warm major-third interval, 300ms, light room reverb` | named interval = melodic shape |
76
- | Door creak open | `old wooden door creak opening slowly, 1.2s, dry interior` | duration + space |
77
- | Bow draw | `recurve bow draw, taut string, leather grip, 600ms` | material specificity |
78
- | Magic cast | `short ice magic cast, crystalline shimmer, ascending, 500ms` | element + pitch motion |
79
-
80
- Prompts that DON'T work (and why):
81
-
82
- | Bad prompt | Failure mode |
83
- |---|---|
84
- | `epic sword sound` | "Epic" is a vibe; the model can't render a vibe. Returns generic noise. |
85
- | `cool UI click` | No material, no duration. Returns a 5-second synth blip. |
86
- | `the sound when the player gets hit really hard and falls down` | Multiple events. Model tries to render all and returns nothing coherent. Split into two SFX. |
87
- | `swoosh` | Underspecified. Returns inconsistent character every regen. |
88
- | `realistic gunshot` | "Realistic" is a constraint, not a description. Use `9mm pistol shot, indoor, sharp crack, short tail, 400ms`. |
77
+ | `eleven_text_to_sound_v2` | ElevenLabs SFX v2 | Strong default on most sounds; the only one with seamless loops |
78
+ | `sonilo-sfx-1.1` | Sonilo SFX 1.1 | Strong default on most sounds |
79
+ | `stable-audio-3-sfx` | Stable Audio 3 SFX | Sometimes the best on fast movement (swings, whooshes); less consistent |
89
80
 
90
- ### 4. Confirm and call
81
+ A choice set makes all three by default. To compare only two, pass `models`: ElevenLabs + Sonilo is the strong pair; include Stable Audio 3 for movement sounds.
91
82
 
92
- Show the prompt and the call before running:
83
+ ### 6. Generate
93
84
 
94
- > Prompt: `metal sword swing whoosh, dry, sharp, 250ms`. Duration 0.5s (model floor). Model: ElevenLabs SFX. Generate?
85
+ Show the prompt and the length before you call; every version is a billed generation.
95
86
 
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.
87
+ **Choice set (the person said yes):**
97
88
 
98
89
  ```
99
- summer_generate_audio(
100
- capability: "sound_effects",
101
- text: "metal sword swing whoosh, dry, sharp, 250ms",
102
- durationSeconds: 0.5
103
- )
104
- // Then: summer_import_from_url(url: "<fileUrl>", path: "res://audio/sfx/sword_swing_01.wav")
90
+ summer_generate_sfx_choices(text: "<prompt>", durationSeconds: 1.0)
105
91
  ```
106
92
 
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.
93
+ The page opens in their open Summer Studio tab, else in the browser. Tell them the returned `say` text; if `shown` is `not_opened`, give them `reviewUrl`. Do not pick for them. Then:
108
94
 
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.
95
+ ```
96
+ summer_get_choices(choiceSetId: "<id>", waitSeconds: 50)
97
+ ```
110
98
 
111
- ### 5. Decision: one-shot vs loop
99
+ Call it again while `status` is `pending`. When it is `decided`, each entry in `approved` has `audioUrl`, `assetId`, `fileExtension` and the person's `note`. If they approved none, ask what to change and make a new set.
112
100
 
113
- | Use case | Setup |
114
- |---|---|
115
- | Footstep, swing, click, hit | One-shot AudioStreamPlayer, `autoplay=false`, fired by code or animation. |
116
- | Short hum / drone < 2s | Set the imported `AudioStream` `loop=true` in the import dock. |
101
+ **One version (the person said no, or later sounds after a decided set):**
102
+
103
+ ```
104
+ summer_generate_audio(capability: "sound_effects", text: "<prompt>", durationSeconds: 1.0)
105
+ ```
106
+
107
+ Leave out `modelId` so their approved default runs. The description goes in `text`, not `prompt` (`prompt` gives a 400 `text_required` here).
108
+
109
+ ### 7. Import
110
+
111
+ ```
112
+ summer_import_from_url(url: "<audioUrl>", path: "res://audio/sfx/sword_clash_01.<fileExtension>")
113
+ ```
117
114
 
118
- For one-shots, set `Loop` OFF on the import. Default ElevenLabs returns are not loop-clean — looping a one-shot will click.
115
+ or `summer_import_asset_by_id(assetId: "<assetId>", path: "res://audio/sfx/sword_clash_01.<fileExtension>")`. Keep the extension of the file you got. When the person approved several versions, import each one (`_01`, `_02`, …) and play a random one per event for variety.
119
116
 
120
- ### 6. Wire it into the scene
117
+ One-shots keep loop OFF in the Import dock; looping a one-shot clicks. For a loop: WAV uses Edit > Loop Mode = Forward; OGG/MP3 use Loop = on.
121
118
 
122
- Choose the right player node:
119
+ ### 8. Wire
123
120
 
124
121
  | Node | Use for |
125
122
  |---|---|
126
- | `AudioStreamPlayer` | UI, music, non-positional (HUD click, menu confirm) |
127
- | `AudioStreamPlayer2D` | 2D positional (top-down hit, 2D pickup) |
128
- | `AudioStreamPlayer3D` | 3D positional (footstep on a 3D character, weapon swing in world) |
123
+ | `AudioStreamPlayer` | UI and non-positional sounds |
124
+ | `AudioStreamPlayer2D` | 2D positional |
125
+ | `AudioStreamPlayer3D` | 3D positional (weapon swing in the world, footstep) |
129
126
 
130
- Add it under the emitting node:
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`:
127
+ Every scene-mutating tool takes an explicit `scenePath`, node paths are relative to the scene root (`./`), and the property argument is `key`:
133
128
 
134
129
  ```
135
130
  summer_add_node(scenePath="res://main.tscn", parent="./Player", type="AudioStreamPlayer3D", name="SwingSFX")
136
131
  summer_set_prop(scenePath="res://main.tscn", path="./Player/SwingSFX", key="stream", value="res://audio/sfx/sword_swing_01.wav")
137
132
  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
133
  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)
141
134
  ```
142
135
 
143
- Bus name must match the bible (`SFX`, `UI`, `Ambient`, etc.). If the bus doesn't exist, run `/audio-direction` step 8.
136
+ The bus must match the bible (`SFX`, `UI`, `Ambient`, …); the default bus is `Master`. If the bus does not exist, run `/audio-direction`.
144
137
 
145
- ### 7. Spawn-and-free pattern (one-shots in flight)
138
+ Fire animation-synced sounds from the animation's Call Method Track (`play()`), not from `_process`.
146
139
 
147
- For SFX that needs to outlive the emitter (player dies but the death-blow SFX should finish), instantiate a small scene with this script:
140
+ For a sound that must outlive its emitter (a death blow), spawn a self-freeing player at runtime:
148
141
 
149
142
  ```gdscript
150
143
  # scripts/audio/SfxOneShot.gd
@@ -155,88 +148,20 @@ func _ready() -> void:
155
148
  play()
156
149
  ```
157
150
 
158
- Save it as a `.tscn`, then `summer_instantiate_scene(scenePath, parent, scene, name)` to place it. That only places the node at author time. To spawn one per event at the emitter's position at runtime, use GDScript (`preload(...).instantiate()` + `add_child`). The node frees itself when the stream finishes.
159
-
160
- ### 8. Volume calibration
161
-
162
- If the clip comes back too quiet:
163
-
164
- - First try `volume_db` on the player (+3 to +9 typical).
165
- - If still quiet, the clip itself is hot-low — regenerate with a louder intensity word: `loud`, `forceful`, `heavy`.
166
- - Never push `volume_db` past +12; clipping artifacts.
167
-
168
- If it comes back too loud (rare): negative `volume_db`, or trim attack in an editor.
169
-
170
- ### 9. Confirm in scene
171
-
172
- ```
173
- summer_inspect_node(path="Player/SwingSFX")
174
- ```
175
-
176
- Verify `stream`, `bus`, `volume_db`. Trigger it via `summer_play` if the user wants to hear it now.
151
+ Save it as a `.tscn` and instantiate it per event in GDScript (`preload(...).instantiate()` + `add_child`).
177
152
 
178
- ## Reference card — prompt patterns by class
153
+ ### 9. Check
179
154
 
180
- ```
181
- UI click: soft woody UI click, neutral pitch, 80ms
182
- UI confirm: affirmative UI chime, warm minor-third, 250ms
183
- UI error: flat UI buzz, slight dissonance, 200ms
184
- Pickup positive: bright pickup, ascending major-third, 300ms, light reverb
185
- Pickup neutral: small tactile pickup, no melody, 150ms
186
- Footstep wood: single footstep on hollow wood floor, leather sole, 180ms
187
- Footstep grass: single footstep on damp grass, soft, 200ms
188
- Footstep stone: single footstep on dry stone, mid-weight, 180ms
189
- Hit body: punchy body hit, low-mid thump, no tail, 200ms
190
- Hit metal: metal-on-metal clang, sharp transient, short ring, 350ms
191
- Swing whoosh: fast air whoosh from a swung blade, dry, 250ms
192
- Door creak: old wooden door creak opening, 1.2s, dry interior
193
- Magic ice: crystalline ice cast, ascending shimmer, 500ms
194
- Magic fire: whoosh of fire ignition, low rumble, 700ms
195
- Stinger event: short triumphant brass stinger, 1.5s, hall reverb
196
- ```
197
-
198
- ## Anti-patterns
199
-
200
- - **Adjective-only prompts.** `epic`, `cool`, `realistic`, `professional` — meaningless to the model.
201
- - **Multiple events in one prompt.** Split into two generations.
202
- - **Looping a non-loop-clean clip.** It clicks. Use `ambient-bed` for real loops.
203
- - **Skipping the bus.** Default bus is `Master`. SFX must route to the `SFX` bus or the mix breaks.
204
- - **Generating before searching.** Reuse before regenerate.
205
- - **Generating before reading the bible.** The clip will fight the rest of the audio.
206
-
207
- ## Edge cases
208
-
209
- - **Clip too quiet:** `volume_db` first; regenerate with louder intensity word second.
210
- - **Clip too long:** trim in audio editor or set `AudioStreamPlayer` to `stop()` on a timer.
211
- - **Footstep needs surface variants:** generate one per material (wood / stone / grass / metal / dirt) and switch in code based on raycast on the floor's `physics_material`.
212
- - **SFX for an animation event:** wire to the animation's `Call Method Track`, not to `_process`.
155
+ `summer_inspect_node(path="Player/SwingSFX")`: verify `stream`, `bus`, `volume_db`. Too quiet: raise `volume_db` (+3 to +9, never past +12), else regenerate with a heavier description. Too long: `stop()` on a timer.
213
156
 
214
157
  ## Fallback (no MCP)
215
158
 
216
- Print the call:
217
-
218
- ```
219
- ElevenLabs SFX prompt: "metal sword swing whoosh, dry, sharp, 250ms"
220
- Duration: 0.5s
221
- Save to: audio/sfx/sword_swing_01.wav
222
- ```
223
-
224
- Tell the user to run it via the Summer dashboard, then `summer_import_from_url` the result.
225
-
226
- ## Handoff
227
-
228
- After the SFX is wired:
229
-
230
- > SFX `sword_swing_01.wav` wired to `Player/SwingSFX` on the `SFX` bus. Next:
231
- > - Trigger it from your attack animation's `Call Method Track` → `play()`.
232
- > - Generate the parry / clash counterpart with `/sound-effect` again.
233
- > - For footsteps across surfaces, generate one clip per material and switch on the floor's `physics_material` (see Edge cases).
159
+ Print the prompt, the length and the target path (`res://audio/sfx/<name>.wav`), and tell the person to make it in Summer Studio, then import it.
234
160
 
235
161
  ## See also
236
162
 
237
- - `audio-direction` — defines the vocabulary this skill obeys
163
+ - `audio-direction` — the SFX vocabulary this skill obeys
238
164
  - `ambient-bed` — long looping textures
239
165
  - `music-track` — music
240
- - `voice-line` — TTS
166
+ - `voice-line` — speech
241
167
  - `../../references/mcp-tools-reference/mcp-tools-reference.md`
242
- - `../../references/godot-version/godot-version.md` — Summer compatibility for audio nodes
@@ -1,10 +1,12 @@
1
1
  id: skill/sound-effect
2
2
  kind: skill
3
- version: 1.0.3
4
- summary: Generate short SFX one-shots — footsteps, weapon swings, UI clicks, hit impacts — wired as AudioStreamPlayer/2D/3D that auto-frees on finished.
3
+ version: 1.1.0
4
+ summary: "Make SFX one-shots and timed sequences (swings, hits, whooshes, reloads, UI) - offer three model versions to pick from, then wire them as AudioStreamPlayers."
5
5
  use_when:
6
6
  - generating short SFX one-shots — footsteps, weapon swings, UI clicks, hit impacts, environmental cues
7
7
  - an action, impact, or UI interaction is silent and needs a short one-shot sound wired to it
8
+ - a timed sound that must match an animation, such as a rifle reload or an attack combo
9
+ - the person wants several versions of a sound to pick from
8
10
  facets:
9
11
  lifecycle:
10
12
  - build
@@ -19,6 +21,10 @@ compatibility:
19
21
  related:
20
22
  skills:
21
23
  - skill/audio-direction
24
+ tools:
25
+ - tool/generate-sfx-choices
26
+ - tool/get-choices
27
+ - tool/generate-audio
22
28
  source: official
23
29
  license: MIT
24
30
  status: stable
@@ -57,7 +57,7 @@ func _ready() -> void:
57
57
  spawner.state_group_created.connect(_on_group_created)
58
58
  spawner.entity_spawned.connect(_on_entity_spawned)
59
59
  spawner.event_received.connect(_on_event)
60
- var initialized: SummerResult = await Summer.initialize(Game.GAME_ID).get_result_or_completed_signal()
60
+ var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
61
61
  if not initialized.ok:
62
62
  push_error(initialized.message)
63
63
  return
@@ -137,6 +137,7 @@ The default font only has letters, digits and common punctuation. Anything else
137
137
  - Never put emoji or Unicode symbols in Label, Button or RichTextLabel text: arrows (▲ ▼ ◀ ▶ ← →), stars, hearts, check marks, music notes, keycap symbols. Write the words instead ("Up", "Next"), or show an icon.
138
138
  - Draw icons as nodes: a TextureRect with a small texture, a Polygon2D triangle for arrows, or a `_draw()` shape. Key prompts are a rounded StyleBoxFlat panel with the key's letter in it.
139
139
  - If the game really needs symbols or another script (Japanese, Arabic, Cyrillic), add a font file that contains them: import a TTF/OTF that covers the characters, set it as the theme's default font, and add it to the fallbacks of any other font you use.
140
+ - Never use `SystemFont` for text players see on iPhone or Android, not even as a fallback: in the Summer Games app on iPhone it has no system fonts and draws every glyph as a box, while desktop looks fine. Import a TTF/OTF into the project, and fall back to `ThemeDB.fallback_font`. If you load font bytes with `FileAccess` instead, the file must be in the pack (`release-readiness` check 8).
140
141
  - After adding text, take one screenshot and look for boxes with hex codes; fix any you find before moving on.
141
142
 
142
143
  ## Fallback (no MCP — edit `.tscn` directly)
@@ -1,6 +1,6 @@
1
1
  id: tool/generate-audio
2
2
  kind: tool
3
- version: 1.0.2
3
+ version: 1.1.0
4
4
  summary: "Generate audio via Summer Studio: text-to-speech, sound effects, music, or multi-voice dialogue."
5
5
  use_when:
6
6
  - creating sound effects, music beds, or spoken lines for the game
@@ -8,6 +8,7 @@ use_when:
8
8
  - '"read this dialogue line in a gruff voice" or "background music for the menu"'
9
9
  do_not_use_when:
10
10
  - a .wav/.ogg already exists online — summer_import_from_url
11
+ - the first sound effect in a chat and the person wants to pick between models — summer_generate_sfx_choices
11
12
  facets:
12
13
  lifecycle:
13
14
  - build
@@ -45,10 +46,13 @@ input_schema:
45
46
  description: ElevenLabs voice ID for TTS
46
47
  modelId:
47
48
  type: string
48
- description: ElevenLabs model ID (e.g. 'eleven_multilingual_v2')
49
+ description: "Model id. text_to_speech: an ElevenLabs model (e.g. 'eleven_multilingual_v2'). sound_effects: eleven_text_to_sound_v2, sonilo-sfx-1.1 or stable-audio-3-sfx; omit to use the person's approved default"
49
50
  durationSeconds:
50
51
  type: number
51
52
  description: Duration in seconds for SFX or music
53
+ loop:
54
+ type: boolean
55
+ description: "sound_effects only: ask for a seamless loop (eleven_text_to_sound_v2 only)"
52
56
  inputs:
53
57
  type: array
54
58
  items:
@@ -0,0 +1,69 @@
1
+ id: tool/generate-sfx-choices
2
+ kind: tool
3
+ version: 1.0.0
4
+ summary: "Make one sound effect with several models and show the versions in Summer Studio; the person approves one or more and that model becomes their default."
5
+ use_when:
6
+ - the first sound effect in a chat, after the person said yes to three versions to pick from
7
+ - '"give me a few versions of this sword clash to choose from"'
8
+ - '"compare the sound effect models on this whoosh"'
9
+ do_not_use_when:
10
+ - the person already said no to choosing in this chat — summer_generate_audio with no modelId
11
+ - music, speech or dialogue — summer_generate_audio
12
+ facets:
13
+ lifecycle:
14
+ - build
15
+ domains:
16
+ - generate
17
+ - audio
18
+ compatibility:
19
+ engine: ">=4.6"
20
+ related:
21
+ skills:
22
+ - skill/sound-effect
23
+ source: official
24
+ license: MIT
25
+ status: preview
26
+ aliases:
27
+ - summer_generate_sfx_choices
28
+ implementation:
29
+ module: src/mcp/tools/generate-tools.ts
30
+ export: registerGenerateTools
31
+ surfaces:
32
+ mcp:
33
+ tool_name: summer_generate_sfx_choices
34
+ remote: true
35
+ input_schema:
36
+ type: object
37
+ properties:
38
+ text:
39
+ type: string
40
+ description: The sound to make, written as a Foley description (what hits what, the attack and the tail, close-mic, dry)
41
+ durationSeconds:
42
+ type: number
43
+ description: Exact length in seconds. One-shots 0.5-2; animation-synced sounds match the animation. stable-audio-3-sfx needs >= 1, sonilo-sfx-1.1 >= 0.5
44
+ loop:
45
+ type: boolean
46
+ description: Ask for a seamless loop (eleven_text_to_sound_v2 only; say 'seamless loop' in text too)
47
+ models:
48
+ type: array
49
+ items:
50
+ type: string
51
+ enum:
52
+ - eleven_text_to_sound_v2
53
+ - sonilo-sfx-1.1
54
+ - stable-audio-3-sfx
55
+ description: "2-4 model ids to compare. Default: eleven_text_to_sound_v2, sonilo-sfx-1.1, stable-audio-3-sfx"
56
+ open:
57
+ type: boolean
58
+ description: "Show the choices page to the person (their open Studio tab, else the browser). false: only return the URL"
59
+ required:
60
+ - text
61
+ additionalProperties: false
62
+ authority:
63
+ filesystem: false
64
+ editor_mutation: false
65
+ network: true
66
+ credentials: false
67
+ publish: false
68
+ evidence_checks:
69
+ - asset-created
@@ -0,0 +1,50 @@
1
+ id: tool/get-choices
2
+ kind: tool
3
+ version: 1.0.0
4
+ summary: "Read a sound-effect choice set: whether the person decided, which versions they approved (audioUrl, assetId, note) and their default sound-effect model."
5
+ use_when:
6
+ - after summer_generate_sfx_choices, to learn which versions the person approved
7
+ - '"I picked the sounds I like in Studio"'
8
+ do_not_use_when:
9
+ - no choice set exists yet — summer_generate_sfx_choices first
10
+ facets:
11
+ lifecycle:
12
+ - build
13
+ domains:
14
+ - generate
15
+ - audio
16
+ compatibility:
17
+ engine: ">=4.6"
18
+ related:
19
+ skills:
20
+ - skill/sound-effect
21
+ source: official
22
+ license: MIT
23
+ status: preview
24
+ aliases:
25
+ - summer_get_choices
26
+ implementation:
27
+ module: src/mcp/tools/generate-tools.ts
28
+ export: registerGenerateTools
29
+ surfaces:
30
+ mcp:
31
+ tool_name: summer_get_choices
32
+ remote: true
33
+ input_schema:
34
+ type: object
35
+ properties:
36
+ choiceSetId:
37
+ type: string
38
+ description: The choiceSetId from summer_generate_sfx_choices
39
+ waitSeconds:
40
+ type: integer
41
+ description: "Wait up to this many seconds (max 50) for the person to decide before answering. 0 or omitted: answer now"
42
+ required:
43
+ - choiceSetId
44
+ additionalProperties: false
45
+ authority:
46
+ filesystem: false
47
+ editor_mutation: false
48
+ network: true
49
+ credentials: false
50
+ publish: false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "summer-engine",
3
- "version": "3.5.1",
3
+ "version": "3.6.0",
4
4
  "description": "Local Summer CLI and MCP server for Summer Engine. Install and run the engine, connect Claude Code, Cursor, Codex, Gemini, and other agents, and build real games with bundled skills, hooks, and plugins.",
5
5
  "keywords": [
6
6
  "summer-engine",
@@ -126,11 +126,13 @@
126
126
  "summer_generate_audio": "tool/generate-audio",
127
127
  "summer_generate_image": "tool/generate-image",
128
128
  "summer_generate_motion": "tool/generate-motion",
129
+ "summer_generate_sfx_choices": "tool/generate-sfx-choices",
129
130
  "summer_generate_video": "tool/generate-video",
130
131
  "summer_get_agent_playbook": "tool/get-agent-playbook",
131
132
  "summer_get_asset": "tool/get-asset",
132
133
  "summer_get_asset_download_url": "tool/get-asset-download-url",
133
134
  "summer_get_board": "tool/get-board",
135
+ "summer_get_choices": "tool/get-choices",
134
136
  "summer_get_console": "tool/get-console",
135
137
  "summer_get_debugger_errors": "tool/get-debugger-errors",
136
138
  "summer_get_debugger_warnings": "tool/get-debugger-warnings",
@@ -4,9 +4,9 @@
4
4
  "collection": 0,
5
5
  "example": 0,
6
6
  "reference": 9,
7
- "skill": 122,
7
+ "skill": 123,
8
8
  "template": 19,
9
- "tool": 105
9
+ "tool": 107
10
10
  },
11
- "total": 255
11
+ "total": 258
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "_generated": "GENERATED from integrations/gemini — do not edit; npm run generate:registry",
3
3
  "name": "summer",
4
- "version": "3.5.1",
4
+ "version": "3.6.0",
5
5
  "description": "Agent tooling for Summer Engine: MCP bridge, context primer, and game-dev skills. Use with the npm CLI for skill files on disk.",
6
6
  "contextFileName": "GEMINI.md",
7
7
  "mcpServers": {
@@ -93,6 +93,7 @@
93
93
  "./library/skills/psx-retro-rendering/",
94
94
  "./library/skills/publish-your-game/",
95
95
  "./library/skills/realtime-wet-surfaces/",
96
+ "./library/skills/release-readiness/",
96
97
  "./library/skills/remote-deploy/",
97
98
  "./library/skills/retarget/",
98
99
  "./library/skills/running-in-the-cloud/",