summer-engine 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +7 -2
  3. package/dist/bin/summer.js +24 -1
  4. package/dist/commands/doctor.js +44 -20
  5. package/dist/commands/setup.js +77 -6
  6. package/dist/commands/skills.js +5 -3
  7. package/dist/lib/format.d.ts +23 -0
  8. package/dist/lib/format.js +60 -0
  9. package/dist/lib/format.test.d.ts +1 -0
  10. package/dist/lib/format.test.js +36 -0
  11. package/dist/lib/skills-registry.d.ts +16 -0
  12. package/dist/lib/skills-registry.js +35 -0
  13. package/package.json +5 -3
  14. package/skills/_meta/skill-test/SKILL.md +1 -1
  15. package/skills/_shared/summer-folder.md +44 -0
  16. package/skills/_tests/specs/art-direction.md +115 -0
  17. package/skills/_tests/specs/audio-direction.md +123 -0
  18. package/skills/_tests/specs/brainstorm-game.md +99 -0
  19. package/skills/_tests/specs/debug.md +94 -0
  20. package/skills/_tests/specs/design-level.md +113 -0
  21. package/skills/_tests/specs/design-mechanic.md +112 -0
  22. package/skills/_tests/specs/design-npc.md +112 -0
  23. package/skills/_tests/specs/export-and-ship.md +114 -0
  24. package/skills/_tests/specs/fps-controller.md +5 -5
  25. package/skills/_tests/specs/play.md +88 -0
  26. package/skills/_tests/specs/setup-multiplayer.md +106 -0
  27. package/skills/_tests/specs/tune-performance.md +104 -0
  28. package/skills/_tests/specs/vfx.md +98 -0
  29. package/skills/ai-and-npcs/design-npc/SKILL.md +343 -0
  30. package/skills/asset-pipeline/asset-strategy/SKILL.md +1 -0
  31. package/skills/audio/audio-direction/SKILL.md +258 -0
  32. package/skills/catalog.yaml +13 -3
  33. package/skills/character-controllers/fps-controller/SKILL.md +1 -0
  34. package/skills/debugging/debug/SKILL.md +137 -0
  35. package/skills/deployment/export-and-ship/SKILL.md +300 -0
  36. package/skills/gameplay-mechanics/design-mechanic/SKILL.md +265 -0
  37. package/skills/level-design/design-level/SKILL.md +266 -0
  38. package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +328 -0
  39. package/skills/performance/tune-performance/SKILL.md +219 -0
  40. package/skills/rendering-and-lighting/3d-lighting/SKILL.md +1 -0
  41. package/skills/rendering-and-lighting/art-direction/SKILL.md +284 -0
  42. package/skills/scene-and-project/brainstorm-game/SKILL.md +210 -0
  43. package/skills/scene-and-project/make-game/SKILL.md +1 -0
  44. package/skills/scene-and-project/play/SKILL.md +108 -0
  45. package/skills/scene-and-project/scene-composition/SKILL.md +1 -0
  46. package/skills/scripting-patterns/gdscript-patterns/SKILL.md +1 -0
  47. package/skills/ui-and-ux/ui-basics/SKILL.md +1 -0
  48. package/skills/visual-effects/vfx/SKILL.md +280 -0
@@ -0,0 +1,300 @@
1
+ ---
2
+ name: export-and-ship
3
+ description: Use when the user is ready to export a build for distribution to Steam, itch.io, web (HTML5), iOS, Android, or any combination. Validates icons, store banners, screenshots, build config, and runs a pre-flight checklist before producing a release build. Trigger on "export", "ship", "release", "build", "Steam", "itch", "HTML5", "iOS", "Android", "submit", "publish".
4
+ license: MIT
5
+ compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
+ category: deployment
7
+ user-invocable: true
8
+ allowed-tools: Read Grep Glob Edit Write summer_get_scene_tree summer_inspect_node summer_project_setting summer_get_console summer_get_diagnostics
9
+ paths: ["**/*.gd", "**/*.tscn", "project.godot", "export_presets.cfg", "**/*.png", "**/*.svg", "**/*.icns", "**/*.ico"]
10
+ ---
11
+
12
+ # /export-and-ship — Export and Prep Distribution
13
+
14
+ ## Overview
15
+
16
+ Shipping is a checklist, not a creative act. This skill walks the platform-specific asset and config requirements, runs a pre-flight check against the project, and produces a release build only after every blocker is green. Better to fail at this step than fail submission.
17
+
18
+ **Core principle:** every platform has a list. Read the list, satisfy the list, ship.
19
+
20
+ ## Steps
21
+
22
+ ### 1. Pick the destination(s)
23
+
24
+ Open with the question. Multi-select.
25
+
26
+ > Where to? Pick all that apply: **Steam** / **itch.io** / **web (HTML5)** / **iOS App Store** / **Google Play** / **macOS DMG** / **Windows installer** / **other**.
27
+
28
+ Each destination has a different list. Multiple destinations = multiple lists. Don't shortcut — the iOS list does not satisfy the Steam list.
29
+
30
+ ### 2. Run the pre-flight checklist
31
+
32
+ Always do this first, regardless of destination.
33
+
34
+ **Preferred (Summer MCP):**
35
+
36
+ ```
37
+ summer_get_diagnostics # any errors? if yes, abort.
38
+ summer_get_console # any "import failed" warnings?
39
+ summer_get_scene_tree # is the main scene set?
40
+ ```
41
+
42
+ **Fallback (no MCP):** ask the user to confirm via the Godot editor: Project → Project Settings → Application → Run → Main Scene is set; no errors in Output panel.
43
+
44
+ #### Pre-flight blockers (any one = stop)
45
+
46
+ | Check | How | Blocker because |
47
+ |---|---|---|
48
+ | Main scene is set | `project.godot` has `application/run/main_scene` | Game launches to nothing without it |
49
+ | No script errors | `summer_get_script_errors` clean | Won't compile in export |
50
+ | No `print()` debug spam in hot loops | `Grep "print(" -- "**/*.gd"` | Spammy console for users |
51
+ | No hardcoded debug paths | `Grep "user://debug" or "/Users/" or "C:\\\\"` | Breaks on user machines |
52
+ | `.gitignore` excludes `.godot/`, `.import/`, `*.tmp` | Read `.gitignore` | Build artifacts in repo |
53
+ | LICENSE file present | Read `LICENSE` at repo root | Steam + itch require licensing clarity |
54
+ | `attribution.md` for community assets | Read `attribution.md` or equivalent | CC-BY assets need credit; missing = takedown risk |
55
+ | Version number set | `application/config/version` in `project.godot` | Required by Steam, useful everywhere |
56
+ | Game name set | `application/config/name` | Window title, build artifact name |
57
+
58
+ If any check fails, list them in one message and ask:
59
+
60
+ > Pre-flight failed on N items: <list>. Fix these before exporting? I can take them one by one.
61
+
62
+ ### 3. Per-platform asset requirements
63
+
64
+ Walk the list for each chosen destination. Each is non-negotiable.
65
+
66
+ #### a) Steam
67
+
68
+ | Asset | Resolution | Format | Path / use |
69
+ |---|---|---|---|
70
+ | Game icon | 256×256 | PNG, transparent | Used in Steam library, taskbar |
71
+ | Library capsule | 600×900 | PNG | "Box art" in library grid |
72
+ | Library hero | 3840×1240 | PNG | Wide banner at top of game's library page |
73
+ | Library logo | 1280×720, transparent BG | PNG | Title overlay on hero |
74
+ | Header capsule | 460×215 | PNG | Store search results, friend activity |
75
+ | Main capsule | 616×353 | PNG | Front-page features |
76
+ | Small capsule | 231×87 | PNG | Sidebar |
77
+ | Page background | 1438×810 | JPG | Behind store page content |
78
+ | Screenshots | ≥ 1280×720, 16:9 | PNG/JPG | At least 5 |
79
+ | Trailer | 1080p, MP4, ≤ 2 min | MP4 | Required for Coming Soon → Released |
80
+ | Steam page text | English required + any localized | Markdown / plaintext | Short description (300 chars), full description, controls |
81
+
82
+ Build config for Steam:
83
+
84
+ - Export preset: **Windows Desktop** (x86_64) + **Linux** (x86_64) + **macOS** (universal). Steam requires all three for max reach; 99% of Steam revenue is Windows but Linux/macOS doesn't hurt.
85
+ - Export options: `Embed PCK = true` for single-EXE distribution.
86
+ - Steam SDK integration: GodotSteam (`https://godotsteam.com`) is the standard. Add the GDExtension before exporting.
87
+ - App ID must be set in the Steam SDK init code.
88
+ - Build separately for each platform; Steam Pipe uploads handle distribution.
89
+
90
+ #### b) itch.io
91
+
92
+ Lower bar than Steam. itch is forgiving.
93
+
94
+ | Asset | Resolution | Required? |
95
+ |---|---|---|
96
+ | Cover image | 630×500 | Yes |
97
+ | Screenshots | Any 16:9 | At least 3 |
98
+ | Game title + tagline | text | Yes |
99
+ | Description | Markdown | Yes |
100
+ | Build files | ZIP per platform OR `butler` upload | Yes |
101
+
102
+ Build config:
103
+ - Export preset: Windows + macOS + Linux; package as ZIP.
104
+ - Or use `butler push` (itch's CLI) for atomic versioning and patches.
105
+ - Web build (HTML5) is free real estate on itch — also do it.
106
+
107
+ #### c) Web (HTML5)
108
+
109
+ Browser export. Constraints:
110
+
111
+ - No threading without `cross-origin-isolated` headers (most hosts don't set them).
112
+ - No ENet — use WebSocket / WebRTC if multiplayer.
113
+ - Long initial load — first-paint is critical. Add a loading screen.
114
+ - File size matters — strip unused features in export preset (no encryption, no debugging, no JavaScript eval if not needed).
115
+
116
+ Build config:
117
+ - Export preset: **Web**.
118
+ - Output `.html` + `.wasm` + `.pck` + `.js`.
119
+ - Disable: "Variant: Editor support", "Encryption". Keep: "GLES3 Fallback to GLES2" if targeting old browsers.
120
+
121
+ Known traps:
122
+ - Audio: Chrome blocks autoplay. First user click must trigger audio context resume.
123
+ - Local saves: use `user://` (maps to IndexedDB on web). Test that saves persist across reload.
124
+
125
+ #### d) iOS App Store
126
+
127
+ | Asset | Resolution / Format |
128
+ |---|---|
129
+ | App icon | 1024×1024 PNG (Apple generates the rest) |
130
+ | Launch screen | Storyboard (Godot generates) |
131
+ | Screenshots | 6.5" iPhone: 1242×2688 / 2688×1242 (≥ 3); 12.9" iPad if iPad-eligible |
132
+ | App Store description | text per locale, ≤ 4000 chars |
133
+ | Keywords | ≤ 100 chars, comma-separated |
134
+ | Support URL | required |
135
+ | Privacy policy URL | required (any data collection) |
136
+
137
+ Build config:
138
+ - Export preset: **iOS**.
139
+ - Bundle ID: `com.<your-org>.<game-name>`. Must match Apple Developer portal.
140
+ - Apple Developer account required ($99/year).
141
+ - Code signing: distribution certificate + provisioning profile.
142
+ - Build via macOS only (Xcode toolchain).
143
+ - TestFlight first (always). Don't go straight to App Store review.
144
+
145
+ #### e) Google Play (Android)
146
+
147
+ | Asset | Resolution / Format |
148
+ |---|---|
149
+ | App icon | 512×512 PNG (32-bit, transparent) |
150
+ | Feature graphic | 1024×500 PNG |
151
+ | Phone screenshots | 16:9 or 9:16, ≥ 1080p, ≥ 2 |
152
+ | Tablet screenshots | optional but boosts visibility |
153
+ | App description | text per locale, ≤ 4000 chars |
154
+ | Short description | ≤ 80 chars |
155
+
156
+ Build config:
157
+ - Export preset: **Android**.
158
+ - Build as **AAB** (Android App Bundle), NOT APK — Play Store requires AAB since 2021.
159
+ - Signing: Play App Signing (Google holds the key) + an upload key.
160
+ - Target API level: latest required by Play Store policy (typically the previous year's API level).
161
+ - Test on real device + emulator before submission.
162
+
163
+ #### f) macOS DMG (outside Steam)
164
+
165
+ - Export preset: **macOS** (universal binary).
166
+ - Codesign + notarize via Apple — unsigned builds get a Gatekeeper warning users can't easily bypass.
167
+ - Notarization requires Apple Developer account ($99/year).
168
+ - DMG packaging: `create-dmg` CLI or `hdiutil`.
169
+
170
+ #### g) Windows installer (outside Steam)
171
+
172
+ - Export preset: **Windows Desktop** (x86_64).
173
+ - Code-signing certificate ($75–$300/year from a CA) — without it, SmartScreen flags the EXE.
174
+ - Installer: NSIS or InnoSetup are the standards. Or just ship a ZIP.
175
+
176
+ ### 4. Build config consistency check
177
+
178
+ Before producing builds, verify `export_presets.cfg` for each target:
179
+
180
+ ```
181
+ Read export_presets.cfg
182
+ ```
183
+
184
+ For each preset:
185
+
186
+ | Field | Production value | Why |
187
+ |---|---|---|
188
+ | `binary_format/embed_pck` | `true` | Single EXE per platform |
189
+ | `debug` | `false` | Debug builds leak source paths and run slower |
190
+ | `texture_format/etc2_astc` | `true` for mobile | Smaller texture compression |
191
+ | `application/short_version` | matches `application/config/version` | Steam reads it |
192
+ | `script/encryption_key` | set if you don't want PCK extracted | Optional but recommended for paid games |
193
+ | `application/icon` | path to your `.ico` / `.icns` / `.png` | Otherwise generic Godot icon ships |
194
+
195
+ ### 5. Propose the build sequence
196
+
197
+ > Pre-flight: clean. Targets confirmed: Steam (Win + Mac + Linux) + itch (same builds) + web. Required assets: I see all icons + 5 screenshots in `marketing/`. Missing: trailer (Steam blocks Coming Soon → Released without one). May I produce the builds now and flag the trailer as a follow-up?
198
+
199
+ ### 6. Produce the builds
200
+
201
+ Godot's CLI export is the standard scripted path:
202
+
203
+ ```
204
+ godot --headless --export-release "Windows Desktop" build/win/MyGame.exe
205
+ godot --headless --export-release "Linux" build/linux/MyGame.x86_64
206
+ godot --headless --export-release "macOS" build/mac/MyGame.app
207
+ godot --headless --export-release "Web" build/web/index.html
208
+ godot --headless --export-release "Android" build/android/MyGame.aab
209
+ godot --headless --export-release "iOS" build/ios/MyGame.xcodeproj
210
+ ```
211
+
212
+ For Summer Engine: replace `godot` with `summer` (or the local binary path). Same flags.
213
+
214
+ If the user is on a CI system (GitHub Actions etc), this is the right place to point them at a cross-compile workflow — Godot can export Windows + Linux from a Linux runner.
215
+
216
+ ### 7. Verify each build
217
+
218
+ For each build:
219
+ - Launch it. Confirm the title screen renders.
220
+ - Run for 30 seconds. Confirm no console errors.
221
+ - Check the file size (anything over 500 MB needs justification — usually unstripped textures or unused assets).
222
+ - For mobile: install on a real device, not just the emulator.
223
+
224
+ ### 8. Submit / upload
225
+
226
+ Per platform, point the user at the correct upload path:
227
+
228
+ - **Steam:** `steamcmd` + Steam Pipe (`builder_app_xxx.vdf`). Set up depots first in Steamworks.
229
+ - **itch.io:** `butler push <path> <user>/<game>:<channel>` (e.g. `butler push build/win <user>/mygame:windows`).
230
+ - **Web (itch hosted):** zip + drop into itch upload UI as "playable in browser".
231
+ - **iOS:** Archive in Xcode → upload via Xcode Organizer → TestFlight → App Store.
232
+ - **Android:** Play Console → Internal testing → Closed → Open → Production.
233
+
234
+ Skill does NOT execute these uploads itself. It produces the builds and points at the right command.
235
+
236
+ ## Pre-flight checklist (master)
237
+
238
+ Use this as a one-shot grep before any export:
239
+
240
+ | Check | Pass condition |
241
+ |---|---|
242
+ | Main scene set | `project.godot` has `application/run/main_scene = "res://..."` |
243
+ | No script errors | `summer_get_script_errors` empty |
244
+ | No debug `print()` spam | Grep returns < 20 hits across project (or each is intentional) |
245
+ | No hardcoded user paths | Grep for `/Users/`, `C:\\`, `/home/` returns 0 hits |
246
+ | Version number set | `application/config/version = "1.0.0"` (or higher) |
247
+ | Game name set | `application/config/name = "<actual name>"` |
248
+ | Icon assets present | Per-platform icon files exist at the paths referenced in `export_presets.cfg` |
249
+ | LICENSE file | Exists at repo root |
250
+ | Attribution file | Exists if any community assets used |
251
+ | Export preset `debug = false` | For all release presets |
252
+ | Export preset `embed_pck = true` | For all desktop release presets |
253
+ | `.gitignore` excludes build artifacts | `build/`, `.godot/`, `.import/`, `*.tmp` listed |
254
+ | Screenshots ≥ minimum count for platform | 3 for itch, 5 for Steam, 2 for Play |
255
+ | No leftover dev assets in `res://` | No `_test_`, `_old_`, `_temp_` files in the export paths |
256
+
257
+ ## Common mistakes
258
+
259
+ | Don't | Do | Why |
260
+ |---|---|---|
261
+ | Ship debug builds to Steam | `debug = false` in release export preset | Slower, leaks paths, larger |
262
+ | Use 256×256 icon for iOS | 1024×1024 (Apple downscales) | iOS rejects undersized icons |
263
+ | Skip Steam trailer | Record at least 30 sec gameplay before launch | Steam blocks the release without it |
264
+ | Ship APK to Play Store | Build AAB | Play requires AAB since 2021 |
265
+ | Skip code-signing on macOS / Windows | Get a cert; without it, users can't run the build | Gatekeeper / SmartScreen blocks unsigned binaries |
266
+ | Skip notarization on macOS | Notarize after signing | Quarantined apps can't run on most modern macOS |
267
+ | Ship without `LICENSE` | Add MIT or commercial license to repo root | Steam + itch + most platforms require it |
268
+ | Forget attribution for CC-BY assets | `attribution.md` listing each asset's source + license | Otherwise = takedown notice + ban |
269
+ | Auto-upload via skill | Produce builds; user uploads | Uploads have side effects (versioning, refunds, metadata changes) |
270
+ | Push 1.0.0 first | Push 0.9.0 internal first, then 1.0.0 to public | Internal testing catches the embarrassing-launch-day bugs |
271
+ | Same build for all stores | Per-store metadata + separate upload | Steam wants `.exe`, Play wants `.aab`, web wants `.html` |
272
+
273
+ ## Anti-patterns
274
+
275
+ - **"Just enable all export options."** Encryption + JS eval + edit-time features bloat the binary. Disable what you don't use.
276
+ - **"I'll fix the icon later."** Apple and Google reject submissions with placeholder icons. They'll take a week to re-review.
277
+ - **Unsigned macOS builds outside Steam.** Apple Gatekeeper is strict. The user-facing workaround ("right-click → Open → confirm") is bad UX.
278
+ - **Embed PCK = false on desktop.** Splits the binary into multiple files; users delete the PCK by accident; bad first-run experience.
279
+ - **Trailer is a slideshow.** Steam's algorithm down-weights gameplay-less trailers. Show actual gameplay in the first 5 seconds.
280
+
281
+ ## Collaborative protocol
282
+
283
+ This skill produces release artifacts. Always ask before each build is invoked. Group platforms — "I'm about to build Windows + Mac + Linux release configs into `build/`. OK?". See `_shared/collaborative-protocol.md`.
284
+
285
+ ## Want a working starter?
286
+
287
+ No template — this is a workflow. Each project's export config and store assets are project-specific. For the Steam-specific GodotSteam GDExtension setup, see `deployment/steam-uploader/SKILL.md` (when shipped).
288
+
289
+ ## See also
290
+
291
+ - `_shared/mcp-tools-reference.md` — full MCP tool list
292
+ - `_shared/godot-version.md` — Godot 4.5 export-template versioning
293
+ - `_shared/collaborative-protocol.md` — "May I write" pattern
294
+ - `deployment/export-presets/SKILL.md` — preset config deep dive
295
+ - `deployment/web-html5-export/SKILL.md` — HTML5-specific traps
296
+ - `deployment/steam-uploader/SKILL.md` — `steamcmd` + GodotSteam (when shipped)
297
+ - `deployment/itch-uploader/SKILL.md` — `butler` workflow (when shipped)
298
+ - `deployment/mobile-export/SKILL.md` — iOS / Android specifics (when shipped)
299
+ - `asset-pipeline/attribution-and-licensing/SKILL.md` — community asset attribution
300
+ - `performance/tune-performance/SKILL.md` — pre-ship performance pass
@@ -0,0 +1,265 @@
1
+ ---
2
+ name: design-mechanic
3
+ description: Use when designing one specific game mechanic in detail — input, response, feedback, failure modes, depth, tunables. Outputs a design doc and a scaffolding-ready node-graph sketch + GDScript stub. Trigger on "design a mechanic", "how should X work", "design the parry", "design the dash", "design the inventory", "the loop is broken".
4
+ license: MIT
5
+ compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
+ category: gameplay-mechanics
7
+ user-invocable: true
8
+ allowed-tools: Read Grep Glob Write Edit summer_get_scene_tree summer_inspect_node summer_add_node summer_set_prop summer_input_map_bind summer_save_scene summer_get_script_errors
9
+ paths: ["**/*.gd", "**/*.tscn", ".summer/**"]
10
+ ---
11
+
12
+ # /design-mechanic — Design One Mechanic in Detail
13
+
14
+ ## Overview
15
+
16
+ A "mechanic" is a verb the player performs that produces a meaningful response from the world. Not a system. Not a feature. A verb with feedback. This skill walks the five layers of a real mechanic: **input → response → feedback → failure modes → depth** — then drops a node-graph sketch + GDScript stub into the project so the next session can implement it.
17
+
18
+ **Core principle:** a mechanic is only as good as its weakest feedback layer. A perfect parry with no audio cue is broken. A great audio cue with floaty input is broken. Walk all five layers before scaffolding.
19
+
20
+ ## Steps
21
+
22
+ ### 1. Pin which mechanic
23
+
24
+ Ask exactly one question and wait:
25
+
26
+ > Which mechanic? (e.g., "double-jump", "parry", "stamina-dash", "pickup", "lock-on", "crafting-recipe-craft").
27
+
28
+ If the user gives a system name ("inventory", "combat"), push back:
29
+
30
+ > Inventory is a system, not a mechanic. The mechanics inside it are: pickup, equip, drop, use, swap. Which one?
31
+
32
+ ### 2. Read context if available
33
+
34
+ If `.summer/GameSoul.md` exists, read it. The mechanic should fit the game brief, not exist in isolation.
35
+
36
+ ```
37
+ Read .summer/GameSoul.md
38
+ ```
39
+
40
+ Quote the relevant constraint back at the user:
41
+
42
+ > Brief says core loop is "see obstacle, attempt, fail, learn, retry". A double-jump only matters if it changes which obstacles are reachable. Confirm that's what we're solving.
43
+
44
+ ### 3. Walk the five layers — one at a time
45
+
46
+ **Layer 1: Input.** Exactly what does the player press, hold, release, time?
47
+
48
+ State a candidate, ask for refinement:
49
+
50
+ > Input candidate: tap Space mid-air. Or: hold-and-release for variable height? Or: requires direction + Space? Pick one.
51
+
52
+ **Layer 2: Response.** What changes in the world the moment the input fires?
53
+
54
+ State the deltas. For double-jump:
55
+
56
+ > Response: vertical velocity set to (jump_velocity * 0.85). `_can_double_jump` flag flips false. Visual rig plays "jump_2" anim. Audio cue. Particle burst at feet.
57
+
58
+ **Layer 3: Feedback** — and this is where most amateur designs collapse. Three sub-channels, all required:
59
+
60
+ | Channel | Question to answer | Bad example | Good example |
61
+ |---|---|---|---|
62
+ | Visual | Can a player who can't hear tell it worked? | "It just jumps." | "GPUParticles3D burst at feet, 0.1s slow-mo on apex, after-image trail behind." |
63
+ | Audio | Can a player who can't see tell it worked? | "Plays jump.wav." | "Layered: short whoosh on input, ambient pitch-up while airborne, soft thud on second jump start." |
64
+ | Mechanical | Does the input feel different from a single-jump? | "Same jump, just twice." | "Second jump has tighter air control, slightly lower height, different particle color." |
65
+
66
+ Force the user to answer all three. If they hand-wave one, name it:
67
+
68
+ > You named visual and audio. Mechanical-feel is missing — what makes the second jump feel different from the first beyond just being a second one?
69
+
70
+ **Layer 4: Failure modes.** What happens when the input fires but conditions aren't met?
71
+
72
+ For double-jump:
73
+
74
+ - Already used? → no input registered? Or denied with a UI shake? Or a small audio cue?
75
+ - During wall-slide? → does it count as airborne or grounded?
76
+ - During cutscene? → is input gated entirely?
77
+ - Spammed input? → buffered or ignored?
78
+
79
+ State the rules, ask:
80
+
81
+ > Failure rules: (a) already-used → silent ignore. (b) during wall-slide → counts as airborne, can double-jump off wall. (c) cutscene → input fully gated. (d) spam → input buffer of 0.1s. OK?
82
+
83
+ **Layer 5: Depth.** What makes this mechanic interesting after 5 minutes of play?
84
+
85
+ This is the hardest layer. State the depth-vector explicitly:
86
+
87
+ > Depth: double-jump becomes interesting when level design forces a *choice* — jump now to clear obstacle A, or save it to escape enemy B coming at you. Without that choice, it's just a longer jump. The level-design implication: every double-jump gap should pair with a near-future threat that also wants the resource.
88
+
89
+ If the user can't articulate depth, the mechanic might not be needed. Say it:
90
+
91
+ > If the only purpose is "can reach higher platforms", that's just a higher-jumping single-jump. Either change the input shape (give it a cost), or cut it.
92
+
93
+ ### 4. List the tunables
94
+
95
+ Every mechanic has 3-7 numbers a designer will tweak. Name them. For double-jump:
96
+
97
+ ```
98
+ @export var double_jump_velocity: float = 4.0 # vertical speed of second jump
99
+ @export var double_jump_air_control: float = 0.7 # multiplier vs ground control
100
+ @export var input_buffer_time: float = 0.1 # window to register early input
101
+ @export var ground_grace_period: float = 0.05 # coyote time before lockout
102
+ @export var slow_mo_on_apex: float = 0.0 # 0 = off, 0.05 = brief
103
+ ```
104
+
105
+ These become `@export` vars in the stub. The user tunes in the inspector, no recompile.
106
+
107
+ ### 5. Sketch the node graph
108
+
109
+ Describe what nodes the mechanic touches in the existing scene. Don't add yet — sketch first.
110
+
111
+ ```
112
+ World/Player (CharacterBody3D) # existing
113
+ ├── CollisionShape3D # existing
114
+ ├── Camera3D # existing
115
+ ├── DoubleJumpFX (GPUParticles3D) # NEW — particles on second jump
116
+ ├── JumpAudio (AudioStreamPlayer3D) # NEW — input + apex cues
117
+ └── (script: player_controller.gd, modify) # MODIFY — add _can_double_jump state
118
+ ```
119
+
120
+ Show this to the user. Ask:
121
+
122
+ > Node-graph plan above. May I add `DoubleJumpFX` and `JumpAudio` to `./World/Player`, and modify `player_controller.gd` to add the double-jump logic?
123
+
124
+ ### 6. Scaffold via MCP
125
+
126
+ **Preferred (Summer MCP):**
127
+
128
+ ```
129
+ summer_get_scene_tree # confirm Player exists where expected
130
+ summer_add_node(parent="./World/Player", type="GPUParticles3D", name="DoubleJumpFX")
131
+ summer_set_prop("./World/Player/DoubleJumpFX", "emitting", "false")
132
+ summer_add_node(parent="./World/Player", type="AudioStreamPlayer3D", name="JumpAudio")
133
+ summer_input_map_bind(name="jump", events=[{type:"key", key:"Space"}]) # idempotent
134
+ summer_save_scene
135
+ summer_get_script_errors
136
+ ```
137
+
138
+ **Fallback (no MCP):** Print the `.tscn` snippet for the user to paste:
139
+
140
+ ```
141
+ [node name="DoubleJumpFX" type="GPUParticles3D" parent="Player"]
142
+ emitting = false
143
+ amount = 16
144
+ lifetime = 0.4
145
+
146
+ [node name="JumpAudio" type="AudioStreamPlayer3D" parent="Player"]
147
+ ```
148
+
149
+ ### 7. Write the GDScript stub
150
+
151
+ Stub only — implementation is the next session. Use `_shared/gd-style.md` conventions. For double-jump:
152
+
153
+ ```gdscript
154
+ class_name PlayerController
155
+ extends CharacterBody3D
156
+
157
+ # Tunables
158
+ @export var jump_velocity: float = 4.5
159
+ @export var double_jump_velocity: float = 4.0
160
+ @export var double_jump_air_control: float = 0.7
161
+ @export var input_buffer_time: float = 0.1
162
+
163
+ # State
164
+ var _can_double_jump: bool = false
165
+ var _input_buffer_t: float = 0.0
166
+
167
+ @onready var fx: GPUParticles3D = $DoubleJumpFX
168
+ @onready var audio: AudioStreamPlayer3D = $JumpAudio
169
+
170
+ signal jumped
171
+ signal double_jumped
172
+
173
+ func _physics_process(delta: float) -> void:
174
+ _input_buffer_t = max(0.0, _input_buffer_t - delta)
175
+
176
+ if Input.is_action_just_pressed("jump"):
177
+ _input_buffer_t = input_buffer_time
178
+
179
+ if _input_buffer_t > 0.0:
180
+ if is_on_floor():
181
+ velocity.y = jump_velocity
182
+ _can_double_jump = true
183
+ _input_buffer_t = 0.0
184
+ jumped.emit()
185
+ elif _can_double_jump:
186
+ velocity.y = double_jump_velocity
187
+ _can_double_jump = false
188
+ _input_buffer_t = 0.0
189
+ fx.emitting = true
190
+ audio.play()
191
+ double_jumped.emit()
192
+
193
+ move_and_slide()
194
+ ```
195
+
196
+ Ask:
197
+
198
+ > May I write `scripts/player_controller.gd` (or merge into the existing script if one is attached)?
199
+
200
+ ### 8. Save the design doc
201
+
202
+ Always write the design doc — it's the artifact the next session reads. Path: `.summer/mechanics/<mechanic-name>.md`.
203
+
204
+ ```markdown
205
+ # Mechanic: Double-Jump
206
+
207
+ **Input:** Tap Space mid-air. Buffered 0.1s before ground.
208
+ **Response:** velocity.y = double_jump_velocity. `_can_double_jump` flag false.
209
+ **Feedback:**
210
+ - Visual: GPUParticles3D burst, 0.1s slow-mo on apex
211
+ - Audio: short whoosh on input
212
+ - Mechanical: 70% air control on second jump
213
+ **Failure modes:**
214
+ - Already used → silent ignore
215
+ - During wall-slide → counts as airborne
216
+ - Cutscene → input gated
217
+ - Spam → buffered (0.1s window)
218
+ **Depth:**
219
+ - Resource the player chooses when to spend
220
+ - Level design pairs every gap with a near-future threat
221
+ **Tunables:** see @export vars in player_controller.gd
222
+ **Open questions:** <list any the user couldn't answer>
223
+ ```
224
+
225
+ Ask:
226
+
227
+ > May I create `.summer/mechanics/double-jump.md` with this design doc?
228
+
229
+ ## Common mistakes
230
+
231
+ | Mistake | Fix |
232
+ |---|---|
233
+ | Designing the system, not the verb | "Combat" is a system. "Parry" is a mechanic. Pick the verb. |
234
+ | Skipping mechanical-feel in feedback | Visual + audio alone produce hollow mechanics. Mechanical difference is required. |
235
+ | No failure modes | Players spam, edge into states you didn't plan for, and find the hole. Plan the failure cases up front. |
236
+ | Hand-wave depth | "Players will use it strategically" is not depth. Name the choice the player makes. |
237
+ | Tunables hard-coded as `const` | Use `@export` so designers tune in the inspector. |
238
+ | Adding the mechanic without the FX/audio nodes | Without nodes for feedback, the mechanic ships feeling cheap. Scaffold the nodes alongside the script. |
239
+ | Setting `position` for movement instead of `velocity` | Physics objects use `velocity` in `_physics_process`. See `_shared/gd-style.md`. |
240
+ | Calling SetResourceProperty on inline sub_resources | Silent fail. See `_shared/mcp-tools-reference.md` § Trap. |
241
+
242
+ ## Collaborative protocol
243
+
244
+ This skill writes scene nodes and one or more files (`.gd`, `.summer/mechanics/<name>.md`). Group writes into one ask per phase. See `_shared/collaborative-protocol.md`.
245
+
246
+ ## Want a working starter?
247
+
248
+ For full character mechanics in a runnable starter:
249
+
250
+ - FPS variant → `template-id: template-3d-fps` (https://github.com/SummerEngine/FPS-template-Summer-Engine)
251
+ - Platformer → `template-id: template-3d-platformer` (TBD)
252
+
253
+ This skill is a workflow that designs and scaffolds — the templates are runnable bases the mechanic plugs into.
254
+
255
+ ## See also
256
+
257
+ - `_shared/collaborative-protocol.md`
258
+ - `_shared/mcp-tools-reference.md`
259
+ - `_shared/gd-style.md` — GDScript conventions
260
+ - `_shared/godot-version.md` — Godot 4.5 API notes
261
+ - `scene-and-project/brainstorm-game/SKILL.md` — produces `.summer/GameSoul.md` this skill reads
262
+ - `level-design/design-level/SKILL.md` — design the levels that exercise the mechanic
263
+ - `character-controllers/fps-controller/SKILL.md` — FPS movement scaffolding
264
+ - `scripting-patterns/state-machine-patterns/SKILL.md` — state machines for complex mechanics
265
+ - `audio/audio-direction/SKILL.md` — defines the SFX vocabulary the mechanic draws from