summer-engine 2.3.0 → 2.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 (237) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +24 -8
  3. package/.codex-plugin/plugin.json +19 -8
  4. package/.cursor-plugin/plugin.json +18 -7
  5. package/.factory-plugin/plugin.json +3 -3
  6. package/.opencode/INSTALL.md +1 -1
  7. package/AGENTS.md +6 -4
  8. package/CHANGELOG.md +46 -7
  9. package/CLAUDE.md +2 -2
  10. package/GEMINI.md +5 -6
  11. package/README.md +116 -109
  12. package/_persona/summer/SKILL.md +5 -6
  13. package/commands/gameskill.md +103 -0
  14. package/dist/bin/summer.js +17 -4
  15. package/dist/commands/cloud.d.ts +2 -0
  16. package/dist/commands/cloud.js +80 -0
  17. package/dist/commands/create.js +2 -0
  18. package/dist/commands/doctor.js +90 -1
  19. package/dist/commands/install.d.ts +17 -0
  20. package/dist/commands/install.js +63 -4
  21. package/dist/commands/login.js +4 -1
  22. package/dist/commands/logout.js +1 -1
  23. package/dist/commands/memory.d.ts +14 -0
  24. package/dist/commands/memory.js +196 -0
  25. package/dist/commands/open.js +1 -1
  26. package/dist/commands/plan.d.ts +2 -0
  27. package/dist/commands/plan.js +60 -0
  28. package/dist/commands/run.js +132 -35
  29. package/dist/commands/setup.js +8 -2
  30. package/dist/commands/skills.js +90 -6
  31. package/dist/commands/status.js +3 -0
  32. package/dist/lib/agent-config.d.ts +2 -2
  33. package/dist/lib/agent-config.js +134 -7
  34. package/dist/lib/api-client.d.ts +13 -0
  35. package/dist/lib/api-client.js +63 -26
  36. package/dist/lib/async-op-lifecycle.d.ts +60 -0
  37. package/dist/lib/async-op-lifecycle.js +83 -0
  38. package/dist/lib/auth.d.ts +2 -0
  39. package/dist/lib/auth.js +13 -0
  40. package/dist/lib/cloud/api.d.ts +79 -0
  41. package/dist/lib/cloud/api.js +107 -0
  42. package/dist/lib/cloud/apply.d.ts +32 -0
  43. package/dist/lib/cloud/apply.js +294 -0
  44. package/dist/lib/cloud/checkpoint.d.ts +26 -0
  45. package/dist/lib/cloud/checkpoint.js +142 -0
  46. package/dist/lib/cloud/conflicts.d.ts +55 -0
  47. package/dist/lib/cloud/conflicts.js +131 -0
  48. package/dist/lib/cloud/containment.d.ts +8 -0
  49. package/dist/lib/cloud/containment.js +52 -0
  50. package/dist/lib/cloud/diff.d.ts +39 -0
  51. package/dist/lib/cloud/diff.js +138 -0
  52. package/dist/lib/cloud/engine-bridge.d.ts +21 -0
  53. package/dist/lib/cloud/engine-bridge.js +105 -0
  54. package/dist/lib/cloud/hash-cache.d.ts +23 -0
  55. package/dist/lib/cloud/hash-cache.js +44 -0
  56. package/dist/lib/cloud/hash.d.ts +10 -0
  57. package/dist/lib/cloud/hash.js +111 -0
  58. package/dist/lib/cloud/http.d.ts +17 -0
  59. package/dist/lib/cloud/http.js +47 -0
  60. package/dist/lib/cloud/lock-path.d.ts +1 -0
  61. package/dist/lib/cloud/lock-path.js +5 -0
  62. package/dist/lib/cloud/lock.d.ts +14 -0
  63. package/dist/lib/cloud/lock.js +143 -0
  64. package/dist/lib/cloud/manifest.d.ts +6 -0
  65. package/dist/lib/cloud/manifest.js +41 -0
  66. package/dist/lib/cloud/paths.d.ts +20 -0
  67. package/dist/lib/cloud/paths.js +90 -0
  68. package/dist/lib/cloud/project-godot-merge.d.ts +32 -0
  69. package/dist/lib/cloud/project-godot-merge.js +185 -0
  70. package/dist/lib/cloud/rules.d.ts +39 -0
  71. package/dist/lib/cloud/rules.js +159 -0
  72. package/dist/lib/cloud/sync.d.ts +21 -0
  73. package/dist/lib/cloud/sync.js +518 -0
  74. package/dist/lib/cloud/transfer.d.ts +23 -0
  75. package/dist/lib/cloud/transfer.js +184 -0
  76. package/dist/lib/cloud/types.d.ts +62 -0
  77. package/dist/lib/cloud/validate-path.d.ts +23 -0
  78. package/dist/lib/cloud/validate-path.js +103 -0
  79. package/dist/lib/engine.d.ts +6 -0
  80. package/dist/lib/engine.js +36 -1
  81. package/dist/lib/game-task-plan.d.ts +42 -0
  82. package/dist/lib/game-task-plan.js +376 -0
  83. package/dist/lib/project-memory.d.ts +33 -0
  84. package/dist/lib/project-memory.js +220 -0
  85. package/dist/lib/skills-registry.d.ts +134 -61
  86. package/dist/lib/skills-registry.js +102 -4
  87. package/dist/lib/version-check.d.ts +106 -0
  88. package/dist/lib/version-check.js +338 -0
  89. package/dist/mcp/server.d.ts +2 -0
  90. package/dist/mcp/server.js +83 -0
  91. package/dist/mcp/tools/asset-tools.js +265 -45
  92. package/dist/mcp/tools/cloud-tools.d.ts +2 -0
  93. package/dist/mcp/tools/cloud-tools.js +42 -0
  94. package/dist/mcp/tools/debug-tools.js +32 -2
  95. package/dist/mcp/tools/generate-tools.js +101 -13
  96. package/dist/mcp/tools/project-tools.js +76 -21
  97. package/dist/mcp/tools/with-engine.d.ts +14 -0
  98. package/dist/mcp/tools/with-engine.js +52 -7
  99. package/gemini-extension.json +3 -3
  100. package/hooks/pre-commit-doctor.sh +0 -0
  101. package/hooks/run-hook.cmd +0 -0
  102. package/hooks/session-start.sh +0 -0
  103. package/package.json +20 -7
  104. package/skills/2d-assets/character-portrait/SKILL.md +1 -1
  105. package/skills/2d-assets/concept-art/SKILL.md +1 -1
  106. package/skills/2d-assets/create-asset-sheet/SKILL.md +163 -0
  107. package/skills/2d-assets/instantiate-asset-pack/SKILL.md +245 -0
  108. package/skills/2d-assets/pixel-art/SKILL.md +1 -1
  109. package/skills/2d-assets/skybox-panorama/SKILL.md +1 -1
  110. package/skills/2d-assets/sprite-sheet/SKILL.md +1 -1
  111. package/skills/2d-assets/tileable-texture/SKILL.md +1 -1
  112. package/skills/2d-assets/ui-graphics/SKILL.md +1 -1
  113. package/skills/2d-assets/use-widget-asset/SKILL.md +217 -0
  114. package/skills/3d-assets/character-model/SKILL.md +28 -6
  115. package/skills/3d-assets/environment-kit/SKILL.md +7 -2
  116. package/skills/3d-assets/organic-model/SKILL.md +5 -4
  117. package/skills/3d-assets/prop-model/SKILL.md +17 -9
  118. package/skills/3d-assets/vehicle-model/SKILL.md +5 -4
  119. package/skills/README.md +37 -30
  120. package/skills/ai-and-npcs/design-npc/SKILL.md +6 -6
  121. package/skills/animation/animation-tree/SKILL.md +4 -2
  122. package/skills/animation/facial-and-lipsync/SKILL.md +1 -1
  123. package/skills/animation/generate-motion/SKILL.md +26 -5
  124. package/skills/animation/procedural-animation/SKILL.md +2 -2
  125. package/skills/asset-pipeline/asset-strategy/SKILL.md +3 -2
  126. package/skills/audio/adaptive-music/SKILL.md +1 -1
  127. package/skills/audio/audio-direction/SKILL.md +5 -5
  128. package/skills/audio/sound-effect/SKILL.md +2 -2
  129. package/skills/audio/voice-line/SKILL.md +25 -3
  130. package/skills/character-controllers/fps-controller/SKILL.md +5 -5
  131. package/skills/debugging/debug/SKILL.md +39 -1
  132. package/skills/deployment/export-and-ship/SKILL.md +4 -4
  133. package/skills/gameplay-mechanics/auto-fire-targeting/SKILL.md +170 -0
  134. package/skills/gameplay-mechanics/design-mechanic/SKILL.md +8 -8
  135. package/skills/level-design/design-level/SKILL.md +5 -5
  136. package/skills/level-design/scene-to-level/SKILL.md +125 -0
  137. package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +4 -4
  138. package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +4 -4
  139. package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +7 -7
  140. package/skills/performance/tune-performance/SKILL.md +5 -5
  141. package/skills/rendering-and-lighting/3d-lighting/SKILL.md +1 -1
  142. package/skills/rendering-and-lighting/art-direction/SKILL.md +5 -5
  143. package/skills/scene-and-project/brainstorm-game/SKILL.md +4 -4
  144. package/skills/scene-and-project/play/SKILL.md +1 -1
  145. package/skills/scene-and-project/scene-composition/SKILL.md +30 -1
  146. package/skills/scripting-patterns/gdscript-patterns/SKILL.md +53 -0
  147. package/skills/ui-and-ux/ui-basics/SKILL.md +1 -1
  148. package/skills/video/animated-loop/SKILL.md +1 -1
  149. package/skills/video/cinematic-cutscene/SKILL.md +1 -1
  150. package/skills/video/trailer-shot/SKILL.md +1 -1
  151. package/skills/visual-effects/game-feel/SKILL.md +6 -6
  152. package/skills/workflow/brainstorming/SKILL.md +164 -0
  153. package/skills/workflow/brainstorming/scripts/frame-template.html +214 -0
  154. package/skills/workflow/brainstorming/scripts/helper.js +88 -0
  155. package/skills/workflow/brainstorming/scripts/server.cjs +354 -0
  156. package/skills/workflow/brainstorming/scripts/start-server.sh +148 -0
  157. package/skills/workflow/brainstorming/scripts/stop-server.sh +56 -0
  158. package/skills/workflow/brainstorming/spec-document-reviewer-prompt.md +49 -0
  159. package/skills/workflow/brainstorming/visual-companion.md +287 -0
  160. package/skills/workflow/debugging-game-feel/SKILL.md +174 -0
  161. package/skills/workflow/diagnosing-perf-regressions/SKILL.md +190 -0
  162. package/skills/workflow/dispatching-parallel-agents/SKILL.md +182 -0
  163. package/skills/workflow/gameskill/SKILL.md +111 -0
  164. package/skills/workflow/investigating-bugs/CREATION-LOG.md +119 -0
  165. package/skills/workflow/investigating-bugs/SKILL.md +296 -0
  166. package/skills/workflow/investigating-bugs/condition-based-waiting-example.ts +158 -0
  167. package/skills/workflow/investigating-bugs/condition-based-waiting.md +115 -0
  168. package/skills/workflow/investigating-bugs/defense-in-depth.md +122 -0
  169. package/skills/workflow/investigating-bugs/find-polluter.sh +63 -0
  170. package/skills/workflow/investigating-bugs/root-cause-tracing.md +169 -0
  171. package/skills/workflow/investigating-bugs/test-academic.md +14 -0
  172. package/skills/workflow/investigating-bugs/test-pressure-1.md +58 -0
  173. package/skills/workflow/investigating-bugs/test-pressure-2.md +68 -0
  174. package/skills/workflow/investigating-bugs/test-pressure-3.md +69 -0
  175. package/skills/workflow/mcpupdate/SKILL.md +134 -0
  176. package/skills/workflow/playtesting-a-feature/SKILL.md +173 -0
  177. package/skills/{_meta → workflow}/skill-create/SKILL.md +32 -22
  178. package/skills/{_meta → workflow}/skill-improve/SKILL.md +9 -10
  179. package/skills/{_meta → workflow}/skill-test/SKILL.md +12 -12
  180. package/skills/{_meta → workflow}/using-summer/SKILL.md +5 -2
  181. package/skills/workflow/verification-before-completion/SKILL.md +139 -0
  182. package/skills/workflow/writing-plans/SKILL.md +152 -0
  183. package/skills/workflow/writing-plans/plan-document-reviewer-prompt.md +49 -0
  184. package/skills/workflow/writing-skills/SKILL.md +655 -0
  185. package/skills/workflow/writing-skills/anthropic-best-practices.md +1150 -0
  186. package/skills/workflow/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
  187. package/skills/workflow/writing-skills/graphviz-conventions.dot +172 -0
  188. package/skills/workflow/writing-skills/persuasion-principles.md +187 -0
  189. package/skills/workflow/writing-skills/render-graphs.js +168 -0
  190. package/skills/workflow/writing-skills/testing-skills-with-subagents.md +384 -0
  191. package/dist/commands/assets.d.ts +0 -2
  192. package/dist/commands/assets.js +0 -189
  193. package/dist/commands/debug.d.ts +0 -2
  194. package/dist/commands/debug.js +0 -127
  195. package/dist/commands/doctor.test.js +0 -29
  196. package/dist/commands/project.d.ts +0 -2
  197. package/dist/commands/project.js +0 -170
  198. package/dist/commands/scene.d.ts +0 -2
  199. package/dist/commands/scene.js +0 -290
  200. package/dist/lib/agent-config.test.d.ts +0 -1
  201. package/dist/lib/agent-config.test.js +0 -80
  202. package/dist/lib/format.test.d.ts +0 -1
  203. package/dist/lib/format.test.js +0 -36
  204. package/dist/lib/plugin-manifests.test.d.ts +0 -1
  205. package/dist/lib/plugin-manifests.test.js +0 -134
  206. package/dist/lib/with-engine.d.ts +0 -14
  207. package/dist/lib/with-engine.js +0 -109
  208. package/skills/_shared/collaborative-protocol.md +0 -50
  209. package/skills/_shared/gd-style.md +0 -121
  210. package/skills/_shared/godot-version.md +0 -32
  211. package/skills/_shared/mcp-tools-reference.md +0 -133
  212. package/skills/_shared/summer-folder.md +0 -44
  213. package/skills/_shared/template-registry.md +0 -40
  214. package/skills/_tests/runner.md +0 -90
  215. package/skills/_tests/specs/3d-lighting.md +0 -19
  216. package/skills/_tests/specs/art-direction.md +0 -115
  217. package/skills/_tests/specs/asset-strategy.md +0 -19
  218. package/skills/_tests/specs/audio-direction.md +0 -123
  219. package/skills/_tests/specs/brainstorm-game.md +0 -99
  220. package/skills/_tests/specs/debug.md +0 -94
  221. package/skills/_tests/specs/design-level.md +0 -113
  222. package/skills/_tests/specs/design-mechanic.md +0 -112
  223. package/skills/_tests/specs/design-npc.md +0 -143
  224. package/skills/_tests/specs/export-and-ship.md +0 -114
  225. package/skills/_tests/specs/fps-controller.md +0 -113
  226. package/skills/_tests/specs/gdscript-patterns.md +0 -19
  227. package/skills/_tests/specs/host-authoritative-state.md +0 -104
  228. package/skills/_tests/specs/make-game.md +0 -19
  229. package/skills/_tests/specs/peer-to-peer-multiplayer.md +0 -99
  230. package/skills/_tests/specs/play.md +0 -88
  231. package/skills/_tests/specs/scene-composition.md +0 -19
  232. package/skills/_tests/specs/setup-multiplayer.md +0 -106
  233. package/skills/_tests/specs/tune-performance.md +0 -104
  234. package/skills/_tests/specs/ui-basics.md +0 -19
  235. package/skills/_tests/specs/vfx.md +0 -116
  236. package/skills/catalog.yaml +0 -991
  237. /package/dist/{commands/doctor.test.d.ts → lib/cloud/types.js} +0 -0
@@ -0,0 +1,287 @@
1
+ # Visual Companion Guide
2
+
3
+ Browser-based visual brainstorming companion for showing mockups, diagrams, and options.
4
+
5
+ ## When to Use
6
+
7
+ Decide per-question, not per-session. The test: **would the user understand this better by seeing it than reading it?**
8
+
9
+ **Use the browser** when the content itself is visual:
10
+
11
+ - **UI mockups** — wireframes, layouts, navigation structures, component designs
12
+ - **Architecture diagrams** — system components, data flow, relationship maps
13
+ - **Side-by-side visual comparisons** — comparing two layouts, two color schemes, two design directions
14
+ - **Design polish** — when the question is about look and feel, spacing, visual hierarchy
15
+ - **Spatial relationships** — state machines, flowcharts, entity relationships rendered as diagrams
16
+
17
+ **Use the terminal** when the content is text or tabular:
18
+
19
+ - **Requirements and scope questions** — "what does X mean?", "which features are in scope?"
20
+ - **Conceptual A/B/C choices** — picking between approaches described in words
21
+ - **Tradeoff lists** — pros/cons, comparison tables
22
+ - **Technical decisions** — API design, data modeling, architectural approach selection
23
+ - **Clarifying questions** — anything where the answer is words, not a visual preference
24
+
25
+ A question *about* a UI topic is not automatically a visual question. "What kind of wizard do you want?" is conceptual — use the terminal. "Which of these wizard layouts feels right?" is visual — use the browser.
26
+
27
+ ## How It Works
28
+
29
+ The server watches a directory for HTML files and serves the newest one to the browser. You write HTML content to `screen_dir`, the user sees it in their browser and can click to select options. Selections are recorded to `state_dir/events` that you read on your next turn.
30
+
31
+ **Content fragments vs full documents:** If your HTML file starts with `<!DOCTYPE` or `<html`, the server serves it as-is (just injects the helper script). Otherwise, the server automatically wraps your content in the frame template — adding the header, CSS theme, selection indicator, and all interactive infrastructure. **Write content fragments by default.** Only write full documents when you need complete control over the page.
32
+
33
+ ## Starting a Session
34
+
35
+ ```bash
36
+ # Start server with persistence (mockups saved to project)
37
+ scripts/start-server.sh --project-dir /path/to/project
38
+
39
+ # Returns: {"type":"server-started","port":52341,"url":"http://localhost:52341",
40
+ # "screen_dir":"/path/to/project/.superpowers/brainstorm/12345-1706000000/content",
41
+ # "state_dir":"/path/to/project/.superpowers/brainstorm/12345-1706000000/state"}
42
+ ```
43
+
44
+ Save `screen_dir` and `state_dir` from the response. Tell user to open the URL.
45
+
46
+ **Finding connection info:** The server writes its startup JSON to `$STATE_DIR/server-info`. If you launched the server in the background and didn't capture stdout, read that file to get the URL and port. When using `--project-dir`, check `<project>/.superpowers/brainstorm/` for the session directory.
47
+
48
+ **Note:** Pass the project root as `--project-dir` so mockups persist in `.superpowers/brainstorm/` and survive server restarts. Without it, files go to `/tmp` and get cleaned up. Remind the user to add `.superpowers/` to `.gitignore` if it's not already there.
49
+
50
+ **Launching the server by platform:**
51
+
52
+ **Claude Code (macOS / Linux):**
53
+ ```bash
54
+ # Default mode works — the script backgrounds the server itself
55
+ scripts/start-server.sh --project-dir /path/to/project
56
+ ```
57
+
58
+ **Claude Code (Windows):**
59
+ ```bash
60
+ # Windows auto-detects and uses foreground mode, which blocks the tool call.
61
+ # Use run_in_background: true on the Bash tool call so the server survives
62
+ # across conversation turns.
63
+ scripts/start-server.sh --project-dir /path/to/project
64
+ ```
65
+ When calling this via the Bash tool, set `run_in_background: true`. Then read `$STATE_DIR/server-info` on the next turn to get the URL and port.
66
+
67
+ **Codex:**
68
+ ```bash
69
+ # Codex reaps background processes. The script auto-detects CODEX_CI and
70
+ # switches to foreground mode. Run it normally — no extra flags needed.
71
+ scripts/start-server.sh --project-dir /path/to/project
72
+ ```
73
+
74
+ **Gemini CLI:**
75
+ ```bash
76
+ # Use --foreground and set is_background: true on your shell tool call
77
+ # so the process survives across turns
78
+ scripts/start-server.sh --project-dir /path/to/project --foreground
79
+ ```
80
+
81
+ **Other environments:** The server must keep running in the background across conversation turns. If your environment reaps detached processes, use `--foreground` and launch the command with your platform's background execution mechanism.
82
+
83
+ If the URL is unreachable from your browser (common in remote/containerized setups), bind a non-loopback host:
84
+
85
+ ```bash
86
+ scripts/start-server.sh \
87
+ --project-dir /path/to/project \
88
+ --host 0.0.0.0 \
89
+ --url-host localhost
90
+ ```
91
+
92
+ Use `--url-host` to control what hostname is printed in the returned URL JSON.
93
+
94
+ ## The Loop
95
+
96
+ 1. **Check server is alive**, then **write HTML** to a new file in `screen_dir`:
97
+ - Before each write, check that `$STATE_DIR/server-info` exists. If it doesn't (or `$STATE_DIR/server-stopped` exists), the server has shut down — restart it with `start-server.sh` before continuing. The server auto-exits after 30 minutes of inactivity.
98
+ - Use semantic filenames: `platform.html`, `visual-style.html`, `layout.html`
99
+ - **Never reuse filenames** — each screen gets a fresh file
100
+ - Use Write tool — **never use cat/heredoc** (dumps noise into terminal)
101
+ - Server automatically serves the newest file
102
+
103
+ 2. **Tell user what to expect and end your turn:**
104
+ - Remind them of the URL (every step, not just first)
105
+ - Give a brief text summary of what's on screen (e.g., "Showing 3 layout options for the homepage")
106
+ - Ask them to respond in the terminal: "Take a look and let me know what you think. Click to select an option if you'd like."
107
+
108
+ 3. **On your next turn** — after the user responds in the terminal:
109
+ - Read `$STATE_DIR/events` if it exists — this contains the user's browser interactions (clicks, selections) as JSON lines
110
+ - Merge with the user's terminal text to get the full picture
111
+ - The terminal message is the primary feedback; `state_dir/events` provides structured interaction data
112
+
113
+ 4. **Iterate or advance** — if feedback changes current screen, write a new file (e.g., `layout-v2.html`). Only move to the next question when the current step is validated.
114
+
115
+ 5. **Unload when returning to terminal** — when the next step doesn't need the browser (e.g., a clarifying question, a tradeoff discussion), push a waiting screen to clear the stale content:
116
+
117
+ ```html
118
+ <!-- filename: waiting.html (or waiting-2.html, etc.) -->
119
+ <div style="display:flex;align-items:center;justify-content:center;min-height:60vh">
120
+ <p class="subtitle">Continuing in terminal...</p>
121
+ </div>
122
+ ```
123
+
124
+ This prevents the user from staring at a resolved choice while the conversation has moved on. When the next visual question comes up, push a new content file as usual.
125
+
126
+ 6. Repeat until done.
127
+
128
+ ## Writing Content Fragments
129
+
130
+ Write just the content that goes inside the page. The server wraps it in the frame template automatically (header, theme CSS, selection indicator, and all interactive infrastructure).
131
+
132
+ **Minimal example:**
133
+
134
+ ```html
135
+ <h2>Which layout works better?</h2>
136
+ <p class="subtitle">Consider readability and visual hierarchy</p>
137
+
138
+ <div class="options">
139
+ <div class="option" data-choice="a" onclick="toggleSelect(this)">
140
+ <div class="letter">A</div>
141
+ <div class="content">
142
+ <h3>Single Column</h3>
143
+ <p>Clean, focused reading experience</p>
144
+ </div>
145
+ </div>
146
+ <div class="option" data-choice="b" onclick="toggleSelect(this)">
147
+ <div class="letter">B</div>
148
+ <div class="content">
149
+ <h3>Two Column</h3>
150
+ <p>Sidebar navigation with main content</p>
151
+ </div>
152
+ </div>
153
+ </div>
154
+ ```
155
+
156
+ That's it. No `<html>`, no CSS, no `<script>` tags needed. The server provides all of that.
157
+
158
+ ## CSS Classes Available
159
+
160
+ The frame template provides these CSS classes for your content:
161
+
162
+ ### Options (A/B/C choices)
163
+
164
+ ```html
165
+ <div class="options">
166
+ <div class="option" data-choice="a" onclick="toggleSelect(this)">
167
+ <div class="letter">A</div>
168
+ <div class="content">
169
+ <h3>Title</h3>
170
+ <p>Description</p>
171
+ </div>
172
+ </div>
173
+ </div>
174
+ ```
175
+
176
+ **Multi-select:** Add `data-multiselect` to the container to let users select multiple options. Each click toggles the item. The indicator bar shows the count.
177
+
178
+ ```html
179
+ <div class="options" data-multiselect>
180
+ <!-- same option markup — users can select/deselect multiple -->
181
+ </div>
182
+ ```
183
+
184
+ ### Cards (visual designs)
185
+
186
+ ```html
187
+ <div class="cards">
188
+ <div class="card" data-choice="design1" onclick="toggleSelect(this)">
189
+ <div class="card-image"><!-- mockup content --></div>
190
+ <div class="card-body">
191
+ <h3>Name</h3>
192
+ <p>Description</p>
193
+ </div>
194
+ </div>
195
+ </div>
196
+ ```
197
+
198
+ ### Mockup container
199
+
200
+ ```html
201
+ <div class="mockup">
202
+ <div class="mockup-header">Preview: Dashboard Layout</div>
203
+ <div class="mockup-body"><!-- your mockup HTML --></div>
204
+ </div>
205
+ ```
206
+
207
+ ### Split view (side-by-side)
208
+
209
+ ```html
210
+ <div class="split">
211
+ <div class="mockup"><!-- left --></div>
212
+ <div class="mockup"><!-- right --></div>
213
+ </div>
214
+ ```
215
+
216
+ ### Pros/Cons
217
+
218
+ ```html
219
+ <div class="pros-cons">
220
+ <div class="pros"><h4>Pros</h4><ul><li>Benefit</li></ul></div>
221
+ <div class="cons"><h4>Cons</h4><ul><li>Drawback</li></ul></div>
222
+ </div>
223
+ ```
224
+
225
+ ### Mock elements (wireframe building blocks)
226
+
227
+ ```html
228
+ <div class="mock-nav">Logo | Home | About | Contact</div>
229
+ <div style="display: flex;">
230
+ <div class="mock-sidebar">Navigation</div>
231
+ <div class="mock-content">Main content area</div>
232
+ </div>
233
+ <button class="mock-button">Action Button</button>
234
+ <input class="mock-input" placeholder="Input field">
235
+ <div class="placeholder">Placeholder area</div>
236
+ ```
237
+
238
+ ### Typography and sections
239
+
240
+ - `h2` — page title
241
+ - `h3` — section heading
242
+ - `.subtitle` — secondary text below title
243
+ - `.section` — content block with bottom margin
244
+ - `.label` — small uppercase label text
245
+
246
+ ## Browser Events Format
247
+
248
+ When the user clicks options in the browser, their interactions are recorded to `$STATE_DIR/events` (one JSON object per line). The file is cleared automatically when you push a new screen.
249
+
250
+ ```jsonl
251
+ {"type":"click","choice":"a","text":"Option A - Simple Layout","timestamp":1706000101}
252
+ {"type":"click","choice":"c","text":"Option C - Complex Grid","timestamp":1706000108}
253
+ {"type":"click","choice":"b","text":"Option B - Hybrid","timestamp":1706000115}
254
+ ```
255
+
256
+ The full event stream shows the user's exploration path — they may click multiple options before settling. The last `choice` event is typically the final selection, but the pattern of clicks can reveal hesitation or preferences worth asking about.
257
+
258
+ If `$STATE_DIR/events` doesn't exist, the user didn't interact with the browser — use only their terminal text.
259
+
260
+ ## Design Tips
261
+
262
+ - **Scale fidelity to the question** — wireframes for layout, polish for polish questions
263
+ - **Explain the question on each page** — "Which layout feels more professional?" not just "Pick one"
264
+ - **Iterate before advancing** — if feedback changes current screen, write a new version
265
+ - **2-4 options max** per screen
266
+ - **Use real content when it matters** — for a photography portfolio, use actual images (Unsplash). Placeholder content obscures design issues.
267
+ - **Keep mockups simple** — focus on layout and structure, not pixel-perfect design
268
+
269
+ ## File Naming
270
+
271
+ - Use semantic names: `platform.html`, `visual-style.html`, `layout.html`
272
+ - Never reuse filenames — each screen must be a new file
273
+ - For iterations: append version suffix like `layout-v2.html`, `layout-v3.html`
274
+ - Server serves newest file by modification time
275
+
276
+ ## Cleaning Up
277
+
278
+ ```bash
279
+ scripts/stop-server.sh $SESSION_DIR
280
+ ```
281
+
282
+ If the session used `--project-dir`, mockup files persist in `.superpowers/brainstorm/` for later reference. Only `/tmp` sessions get deleted on stop.
283
+
284
+ ## Reference
285
+
286
+ - Frame template (CSS reference): `scripts/frame-template.html`
287
+ - Helper script (client-side): `scripts/helper.js`
@@ -0,0 +1,174 @@
1
+ ---
2
+ name: debugging-game-feel
3
+ description: Use when a gameplay feature works correctly but feels wrong — floaty jumps, mushy combat, sluggish camera, weightless impacts. Different from logical bug debugging; the bug is subjective and lives in tuning, timing, and feedback layers.
4
+ ---
5
+
6
+ # Debugging Game Feel
7
+
8
+ ## Overview
9
+
10
+ "Works but feels wrong" is its own debugging discipline. The code is correct. No diagnostic flags it. The unit tests pass. And yet the jump is floaty, the sword has no weight, the camera lags the player, the dash is unsatisfying.
11
+
12
+ **Core principle:** Game-feel bugs are tuning bugs, not logic bugs. Treat them with discipline — isolate one variable, compare to a reference, measure what you can, feel what you can't.
13
+
14
+ This skill is for the diagnostic phase. The polish-and-juice layer (screen shake, hit-stop, particles, sound design) is `summer:visual-effects/game-feel` — go there once you've identified WHICH variable is wrong.
15
+
16
+ ## When To Use
17
+
18
+ - The user says: "feels floaty", "feels mushy", "feels off", "feels sluggish", "doesn't feel right", "lacks impact", "lacks weight", "doesn't feel satisfying".
19
+ - The feature passes `summer:playtesting-a-feature` (no errors, golden path runs) but still doesn't feel right.
20
+ - You're tuning movement, combat, camera, or any interaction with frame-level timing.
21
+
22
+ ## When NOT To Use
23
+
24
+ - The feature has a **concrete reproducible bug** — go to `summer:investigating-bugs`.
25
+ - The feature **crashes or throws** — go to `summer:debug`.
26
+ - The feature **hasn't been built yet** — design it via `summer:brainstorming` first.
27
+
28
+ ## The Iron Law
29
+
30
+ ```
31
+ ONE VARIABLE AT A TIME. ALWAYS.
32
+ ```
33
+
34
+ Game-feel debugging is the place where engineers most often violate this rule, because each variable is a small tweak. "Let me bump acceleration AND friction AND max speed all together" produces a result you cannot reason about. You learn nothing. The bug returns.
35
+
36
+ ## The Loop
37
+
38
+ ```
39
+ Anchor → Isolate → Tweak one variable → Compare → Decide → Repeat
40
+ ```
41
+
42
+ ### 1. Anchor: name the reference
43
+
44
+ Before touching any value, decide what "right" feels like. Game feel is subjective; without an anchor, you are debugging air.
45
+
46
+ Two ways to anchor:
47
+
48
+ | Anchor type | When to use | Example |
49
+ |---|---|---|
50
+ | **Reference game footage** | The user has a target in mind (Hollow Knight jumps, Dark Souls weight, Hades dashes) | "Match the Hollow Knight jump arc — peak in ~0.25s, fall ~0.35s, terminal velocity around frame 30" |
51
+ | **Internal known-good** | An older build / a sibling feature in the same game already feels right | "The pistol fires snappy. Make the rifle feel as snappy as the pistol minus the recovery frames." |
52
+
53
+ Write the anchor down in one sentence. If the user can't articulate it, ask. "What game does this remind you of when it's working?" is a fast way to extract the reference.
54
+
55
+ ### 2. Isolate: name the suspect variable
56
+
57
+ Game-feel bugs almost always live in one of a small set of axes. Pick the most likely one first.
58
+
59
+ | Domain | Common suspect variables |
60
+ |---|---|
61
+ | Jump | gravity, jump velocity, terminal velocity, coyote-time window, jump-buffer window, variable-jump cutoff, apex hang time |
62
+ | Run | acceleration, max speed, friction (ground vs air), deceleration on input release, turn-around speed |
63
+ | Combat hit | hit-stop duration (attacker), hit-stop duration (target), screen shake amplitude + duration, knockback velocity + decay, recovery frames |
64
+ | Camera | follow lag (lerp factor or spring stiffness), lookahead distance, deadzone size, snap-vs-smooth on direction change |
65
+ | Dash | distance, duration, ease curve, cooldown, i-frame window, end-lag |
66
+ | UI feedback | input-to-response frame count, tween duration, easing function, sound onset delay |
67
+
68
+ If you cannot pick one suspect: state the top two, pick the one you think is most likely (say which), tweak it, see if it moved the feel. Do not tweak both.
69
+
70
+ ### 3. Tweak one variable
71
+
72
+ - Read the current value via `summer_inspect_node` or open the relevant `.tres` / `.gd` file.
73
+ - Change ONE value. Save.
74
+ - Trigger `summer_play` and walk the feature.
75
+ - Ask: did the feel move toward or away from the anchor?
76
+
77
+ ### 4. Compare
78
+
79
+ Two compare modes:
80
+
81
+ **Feel:** subjective. The user (or you, if you have eyes on the screen) reports "warmer" or "colder." This is fine. Most game-feel work is felt, not measured.
82
+
83
+ **Measure:** objective. When the feel is ambiguous, drop down to frame counts.
84
+
85
+ | Question | Measurement |
86
+ |---|---|
87
+ | "Does the jump peak too fast?" | `print` the y-velocity in `_physics_process`, count frames from launch to peak |
88
+ | "Is the camera too laggy?" | `print` `camera.global_position - target.global_position` per frame |
89
+ | "Is the input dead?" | Log input event frame and resulting state-machine transition frame; subtract |
90
+ | "Is the hit-stop too short?" | Log frame at hit + frame at unfreeze |
91
+
92
+ The point of measurement is to ground the conversation in numbers when "feels off" stops being useful. You do not need to measure most tweaks — only the ambiguous ones.
93
+
94
+ ### 5. Decide
95
+
96
+ After the tweak:
97
+
98
+ - **Felt closer to the anchor** → commit the change, move to the next suspect variable if the feel still isn't right.
99
+ - **Felt further** → revert the change, pick a different suspect variable.
100
+ - **No change in feel** → revert the change, you tweaked the wrong variable.
101
+
102
+ Never leave a tweak in the codebase that you couldn't tell did anything. It will compound with the next tweak and you will lose the thread.
103
+
104
+ ## The Compounding Tweaks Trap
105
+
106
+ The most common failure mode in game-feel work:
107
+
108
+ ```
109
+ Jump feels floaty.
110
+ Bump gravity from 980 → 1200. Still floaty.
111
+ Bump it to 1500. A bit better.
112
+ Also reduce jump velocity from 500 → 450.
113
+ Also tweak terminal velocity 1500 → 2000.
114
+ Also add a 3-frame coyote window because why not.
115
+ Now it feels... different. But the dash that used to feel great no longer does.
116
+ Try to undo? You don't remember the starting point.
117
+ ```
118
+
119
+ **Antidote:**
120
+
121
+ 1. Note the starting values before you begin.
122
+ 2. One variable at a time.
123
+ 3. After every tweak, ask: anchor closer or farther? If unsure, revert.
124
+ 4. Commit small revertible changes — one variable per commit during a feel-tuning session. Easy to bisect.
125
+
126
+ ## Feel Principles (Briefly)
127
+
128
+ Game feel rests on three small ideas. Most "feels wrong" bugs trace to one of these being undertuned:
129
+
130
+ | Principle | What it means | What it looks like when broken |
131
+ |---|---|---|
132
+ | **Anticipation** | A small wind-up before a big action | Sword swings feel like they "appear" instead of being thrown |
133
+ | **Follow-through** | The action continues past the input | Player snaps to a stop on input release — feels robotic |
134
+ | **Weight** | Visible cost to changing direction or stopping | Player turns on a dime at full speed — feels weightless |
135
+
136
+ These are diagnostic tools, not lecture material. When the user says "feels weightless," your suspect-variable shortlist is: deceleration on input release, friction, turn-around speed, animation cross-fade time.
137
+
138
+ ## Red Flags — STOP
139
+
140
+ | Red flag | Reality |
141
+ |---|---|
142
+ | Tweaking 2+ variables in one play session without reverting between | You will lose the signal. |
143
+ | "Let me just feel it out without an anchor" | You will tune in circles. Name the reference. |
144
+ | "The user said floaty so I'm jacking gravity" | "Floaty" can also mean weak air control, slow terminal velocity, or too-long apex hang. Confirm before tweaking. |
145
+ | Skipping the play step ("I'll just bump the number and trust the feel") | Game feel is felt, not predicted. Play every tweak. |
146
+ | Adding "while I'm here" tweaks to unrelated features | Game feel debugging is a focused activity. Stay on the one feature. |
147
+ | Going to `summer:visual-effects/game-feel` before identifying the broken variable | Juice on top of a broken tuning makes the bug louder. Fix tuning first. |
148
+ | Spending >30 minutes on one variable without progress | The anchor is wrong, or the variable is wrong. Step back, re-anchor. |
149
+
150
+ ## Rationalization Prevention
151
+
152
+ | Excuse | Reality |
153
+ |---|---|
154
+ | "It's subjective — I'll just iterate fast" | Fast iteration without isolation is thrashing, not iteration. |
155
+ | "I know game feel, I don't need an anchor" | Even pros anchor. Especially pros anchor. |
156
+ | "Two variables are coupled, I have to tune them together" | Then tune one, ship that delta, tune the other separately. |
157
+ | "The user can't articulate the anchor" | "What game does this remind you of when it works?" — one question, anchor obtained. |
158
+ | "Adding juice will hide the bad tuning" | It won't. It amplifies it. |
159
+
160
+ ## When To Escalate
161
+
162
+ After diagnosis pins down which variable(s) are wrong, the tuning is done — but the feature may still want polish. Hand off to:
163
+
164
+ - `summer:visual-effects/game-feel` — for the screen-shake, hit-stop, particle, sound layer once tuning is locked.
165
+ - `summer:debug` — if mid-debug you discover an actual error (signal not firing, node freed) hiding under the feel issue.
166
+
167
+ ## The Bottom Line
168
+
169
+ Feel bugs are tuning bugs. Tuning is a one-variable-at-a-time discipline. Anchor to a reference. Tweak one number. Play it. Decide. Repeat.
170
+
171
+ **Related skills:**
172
+ - `summer:investigating-bugs` — for logical bugs with concrete repros, not feel.
173
+ - `summer:playtesting-a-feature` — the playtest discipline this skill plugs into.
174
+ - `summer:debug` — when the feel investigation surfaces an actual error.
@@ -0,0 +1,190 @@
1
+ ---
2
+ name: diagnosing-perf-regressions
3
+ description: Use when frame rate, frame time, or load time has gotten worse since a known-good state — "it used to run at 60, now it's at 30." Focused on finding the cause of a regression, not general performance tuning.
4
+ ---
5
+
6
+ # Diagnosing Performance Regressions
7
+
8
+ ## Overview
9
+
10
+ There is a difference between "this game is slow" and "this game got slow." This skill is for the second one.
11
+
12
+ **Core principle:** A regression has a cause. The cause is a specific change. Bisect to find the change, then root-cause from there.
13
+
14
+ This skill is **not** general performance tuning. If the game has always run at 30fps and you want to push it to 60, that is `summer:tune-performance` (the domain skill for budget-driven optimization). This skill is the diagnostic — what broke, where, when.
15
+
16
+ ## When To Use
17
+
18
+ - "It used to run at 60fps, now it's at 30."
19
+ - "Load time was 3s yesterday, now it's 15s."
20
+ - "Frame stutters started after I added X."
21
+ - "Build went from buttery to choppy and I don't know why."
22
+
23
+ ## When NOT To Use
24
+
25
+ - "The game has always been slow, help me speed it up." → `summer:tune-performance`.
26
+ - "I want to know if my game is fast enough to ship." → `summer:tune-performance`.
27
+ - "The game crashes." → `summer:debug`.
28
+
29
+ ## The Iron Law
30
+
31
+ ```
32
+ NO PERF FIX WITHOUT A KNOWN-GOOD vs KNOWN-BAD MEASUREMENT
33
+ ```
34
+
35
+ You cannot fix a regression you have not measured. Eyeballing "feels laggy" is not a measurement. Get a number for the good state and a number for the bad state before touching code.
36
+
37
+ ## The Loop
38
+
39
+ ```
40
+ Measure now → Find last good → Bisect changes → Match to a cliff → A/B fix → Re-measure
41
+ ```
42
+
43
+ ### 1. Measure now
44
+
45
+ ```
46
+ summer_play (on the scene that's slow)
47
+ ── wait 5-10 seconds of normal play ──
48
+ summer_get_diagnostics
49
+ summer_get_console
50
+ summer_stop
51
+ ```
52
+
53
+ What to capture:
54
+
55
+ | Metric | Source | Why |
56
+ |---|---|---|
57
+ | Avg FPS / frame time | `summer_get_diagnostics` or in-game perf monitor | Headline number |
58
+ | Spike pattern | `summer_get_console` if user has frame-time prints, else in-game monitor | Steady 30 vs intermittent stutters → different causes |
59
+ | Scene complexity | `summer_get_scene_tree` (root counts) | Establishes baseline for instance/body count cliffs |
60
+
61
+ Write the bad-state number down. "Scene `Level3` runs at 31fps avg, drops to 12fps when 5+ enemies are on screen."
62
+
63
+ ### 2. Find the last known-good state
64
+
65
+ Ask the user: when did it last run well? Then go to the VCS:
66
+
67
+ ```bash
68
+ git log --oneline --since="<last good date>" --until="now"
69
+ ```
70
+
71
+ If they can name a commit ("it was fine on Monday's build"), check that out and measure it the same way. You now have:
72
+
73
+ - Known good: commit X, scene `Level3`, 60fps avg.
74
+ - Known bad: HEAD, scene `Level3`, 31fps avg.
75
+
76
+ If they can't name a date: ask for the rough window, list the commits, ask which ones are likely candidates. Do not bisect blind across 200 commits.
77
+
78
+ ### 3. Bisect the changes
79
+
80
+ ```bash
81
+ git log --oneline <last-good>..HEAD
82
+ ```
83
+
84
+ Read the list. Group commits into suspects:
85
+
86
+ | Likely culprit | Why |
87
+ |---|---|
88
+ | Big asset imports (.glb, textures, audio) | GPU memory, draw-call count |
89
+ | New shaders or material changes | Compilation stalls, overdraw, pipeline switches |
90
+ | Scene additions (enemies, props, lights) | Physics-body count, instance count, light count |
91
+ | `_process` / `_physics_process` additions | CPU per-frame cost |
92
+ | Signal connections in tight loops | Hidden per-frame cost |
93
+ | Particle systems | GPU + CPU |
94
+ | `@tool` scripts running in editor | Misleading editor FPS |
95
+ | Resource preload changes | First-use stalls |
96
+
97
+ If a single commit is the obvious suspect (e.g. "Added 200 enemies to spawner"), test it first. Otherwise actually `git bisect` — check out the midpoint, measure FPS, repeat. Don't theorize through it; the bisect is fast and definitive.
98
+
99
+ ### 4. Match to one of the four Godot perf cliffs
100
+
101
+ Godot 4.x regressions cluster heavily into four categories. Knowing them shortens diagnosis to minutes.
102
+
103
+ | Cliff | Symptom | How to verify | Common cause |
104
+ |---|---|---|---|
105
+ | **Too many physics bodies** | FPS scales inversely with on-screen actor count, no GPU pressure | Count active `CharacterBody`/`RigidBody`/`Area` nodes; FPS doubles when half are queue_freed | Spawner with no upper cap; bullets/particles using physics bodies; collision layers too broad |
106
+ | **Shader compilation stalls** | First-frame or first-effect-fire stutter, then smooth; only on shipped builds, not editor | Frame-time spike on first cast/shot; clean after; `OS.has_feature("editor")` differences | New shader added; `unique` material not pre-warmed; pipeline cache not built |
107
+ | **GPU instance count / draw calls** | Steady low FPS, scales with what's on screen, no CPU pressure | RenderingServer perf monitors show high draw call count; FPS recovers when camera looks away | Forgot to enable MultiMeshInstance; unique materials per instance breaking instancing; too-detailed LOD0 |
108
+ | **Transparent overdraw** | FPS tanks when looking at smoke, fire, foliage, glass — fine otherwise | Look at the offending region, FPS drops; look away, recovers | New particle effect with large quads; transparent UI over the viewport; fog/volumetrics |
109
+
110
+ If the bad-state symptom matches one row, you have your hypothesis. Verify by reverting just the change you suspect and re-measuring.
111
+
112
+ ### 5. A/B with one variable
113
+
114
+ This is the most violated step. Discipline:
115
+
116
+ - **Revert one suspect commit** (or stub the suspect feature behind a flag).
117
+ - Rebuild / reload the scene.
118
+ - Measure FPS the same way you did in step 1.
119
+ - Compare to known-bad. Did it recover?
120
+
121
+ If yes → root cause confirmed. Now decide: fix the change, or accept the perf cost.
122
+ If no → that wasn't it. Restore. Try the next suspect.
123
+
124
+ **Never** revert multiple changes at once during diagnosis. You will not know which one was the cause, and the bug will return on the next merge.
125
+
126
+ ### 6. Re-measure after the fix
127
+
128
+ The fix is not done until the same measurement that found the regression returns the good number. Same scene, same play duration, same warm-up.
129
+
130
+ ```
131
+ summer_clear_console
132
+ summer_play
133
+ ── 5-10 seconds of play ──
134
+ summer_get_diagnostics
135
+ summer_stop
136
+ ```
137
+
138
+ State the result with the number: "Reverted the per-frame `get_tree().get_nodes_in_group()` call in `enemy_manager.gd`. Level3 back to 58fps avg." Not "should be faster now."
139
+
140
+ ## When To Escalate
141
+
142
+ | Situation | Go to |
143
+ |---|---|
144
+ | Regression confirmed and root cause known, but the fix is "make the feature cheaper" rather than "undo the change" | `summer:tune-performance` for the optimization pass |
145
+ | The regression turns out to be a crash or error in disguise (the slow path is throwing exceptions in a tight loop) | `summer:debug` |
146
+ | The cause is a Godot version change or engine-side regression | Surface to the user; this is not a project-side fix |
147
+ | Bisect lands on a commit that touches 40 files | Subdivide the commit: check out the commit, revert subsets, re-measure |
148
+
149
+ ## Red Flags — STOP
150
+
151
+ | Red flag | Reality |
152
+ |---|---|
153
+ | "Just optimize the whole scene" | That's tuning, not regression diagnosis. Find what changed first. |
154
+ | Reverting 3 commits at once to "see if it helps" | You learn nothing. Revert one. |
155
+ | Eyeballing "feels slow" without measuring | You will optimize the wrong thing. Get a number. |
156
+ | Skipping the known-good measurement | Without a baseline, you don't know when you're done. |
157
+ | Reading the slow scene's code top-to-bottom looking for inefficiency | The regression is in what changed, not in what was already there. |
158
+ | Adding caching / pooling / LOD before identifying the cause | These are tuning moves. They can hide the regression instead of fixing it. |
159
+ | Trusting editor FPS as ground truth | Editor runs `@tool` scripts, debug overlays, and a different render pipeline. Measure in a built or `--game` run when possible. |
160
+ | "Maybe it's just a Tuesday thing" | Performance does not regress randomly. There is a cause. |
161
+
162
+ ## Rationalization Prevention
163
+
164
+ | Excuse | Reality |
165
+ |---|---|
166
+ | "User wants it fixed now, no time to bisect" | Bisect is 5-15 minutes. Blind optimization can burn a day. |
167
+ | "The slow commit is obvious, no need to A/B" | The "obvious" cause is wrong ~30% of the time. Verify before fixing. |
168
+ | "I'll measure after I fix it" | If you don't have the bad number, you can't prove the fix worked. |
169
+ | "It's probably just Godot" | Engine-side regressions exist but are rare. Suspect your project first. |
170
+ | "Adding a pool / LOD / cache will help anyway" | Premature optimization on the wrong system is wasted work. |
171
+
172
+ ## When The Engine Isn't Running
173
+
174
+ If `summer_play` is unavailable:
175
+
176
+ 1. Ask the user for an in-game perf overlay screenshot (FPS, frame time, draw call count).
177
+ 2. Walk the bisect logically with them: "Run on commit X, tell me the FPS. Run on commit Y, tell me the FPS."
178
+ 3. Do not claim a fix is verified from code reading alone.
179
+
180
+ ## The Bottom Line
181
+
182
+ A regression is a delta. Diagnose the delta, not the codebase.
183
+
184
+ Measure now. Measure last-good. Bisect what changed. Match to a Godot perf cliff. A/B one variable. Re-measure. Done.
185
+
186
+ **Related skills:**
187
+ - `summer:tune-performance` — for general optimization once the regression is fixed or when no regression exists.
188
+ - `summer:investigating-bugs` — when the slow path turns out to be a logic bug (errors in a tight loop).
189
+ - `summer:debug` — when the perf issue is actually a crash or freeze.
190
+ - `summer:verification-before-completion` — to claim the fix worked, with numbers.