summer-engine 3.3.0 → 3.4.1

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 (293) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +4 -2
  3. package/.codex-plugin/plugin.json +5 -3
  4. package/.cursor-plugin/plugin.json +4 -2
  5. package/.factory-plugin/plugin.json +4 -2
  6. package/.opencode/INSTALL.md +8 -8
  7. package/.opencode/plugins/summer.js +2 -2
  8. package/AGENTS.md +7 -7
  9. package/CHANGELOG.md +50 -0
  10. package/GEMINI.md +1 -1
  11. package/NOTICE +1 -1
  12. package/README.md +32 -35
  13. package/assets/api-docs.json.gz +0 -0
  14. package/assets/autopilot/run.sh +2 -2
  15. package/assets/navigation/web-routes.json +1 -1
  16. package/commands/gameskill.md +2 -2
  17. package/commands/summer.md +25 -25
  18. package/dist/cli/commands/install.d.ts +10 -0
  19. package/dist/cli/commands/install.js +55 -10
  20. package/dist/cli/commands/open.d.ts +1 -1
  21. package/dist/cli/commands/run.d.ts +1 -1
  22. package/dist/cli/commands/run.js +1 -1
  23. package/dist/cli/commands/skills.js +2 -2
  24. package/dist/cli/commands/tool.d.ts +7 -0
  25. package/dist/cli/commands/tool.js +36 -1
  26. package/dist/core/api-client.d.ts +5 -6
  27. package/dist/core/api-client.js +12 -15
  28. package/dist/core/auth.js +2 -2
  29. package/dist/core/capabilities/asset-import.d.ts +0 -1
  30. package/dist/core/capabilities/camera-view.d.ts +1 -1
  31. package/dist/core/capabilities/camera-view.js +2 -2
  32. package/dist/core/capabilities/capture-gameplay.d.ts +69 -0
  33. package/dist/core/capabilities/capture-gameplay.js +283 -0
  34. package/dist/core/capabilities/connect-signal.d.ts +1 -2
  35. package/dist/core/capabilities/connect-signal.js +1 -2
  36. package/dist/core/capabilities/console-read.d.ts +2 -2
  37. package/dist/core/capabilities/console-read.js +2 -2
  38. package/dist/core/capabilities/creator.js +1 -1
  39. package/dist/core/capabilities/doctor.d.ts +9 -1
  40. package/dist/core/capabilities/doctor.js +47 -4
  41. package/dist/core/capabilities/engine-receipt.d.ts +5 -7
  42. package/dist/core/capabilities/engine-receipt.js +7 -9
  43. package/dist/core/capabilities/engine-run.d.ts +4 -0
  44. package/dist/core/capabilities/engine-run.js +33 -5
  45. package/dist/core/capabilities/export-engine-version.d.ts +15 -0
  46. package/dist/core/capabilities/export-engine-version.js +24 -0
  47. package/dist/core/capabilities/export-game.d.ts +9 -1
  48. package/dist/core/capabilities/export-game.js +115 -39
  49. package/dist/core/capabilities/export-presets.d.ts +1 -1
  50. package/dist/core/capabilities/export-presets.js +1 -1
  51. package/dist/core/capabilities/fabricate-mesh.d.ts +2 -3
  52. package/dist/core/capabilities/fabricate-mesh.js +2 -3
  53. package/dist/core/capabilities/frame-quality.d.ts +4 -4
  54. package/dist/core/capabilities/frame-quality.js +4 -4
  55. package/dist/core/capabilities/grep.d.ts +1 -1
  56. package/dist/core/capabilities/grep.js +1 -1
  57. package/dist/core/capabilities/image-generation.d.ts +9 -0
  58. package/dist/core/capabilities/image-generation.js +19 -1
  59. package/dist/core/capabilities/navigation/open.d.ts +1 -1
  60. package/dist/core/capabilities/navigation/open.js +1 -1
  61. package/dist/core/capabilities/navigation/render-product-map.js +1 -1
  62. package/dist/core/capabilities/navigation/targets.js +2 -2
  63. package/dist/core/capabilities/placement-batch.d.ts +1 -1
  64. package/dist/core/capabilities/placement-batch.js +2 -2
  65. package/dist/core/capabilities/play-determinism.d.ts +1 -1
  66. package/dist/core/capabilities/play-determinism.js +1 -1
  67. package/dist/core/capabilities/publish-build.d.ts +15 -2
  68. package/dist/core/capabilities/publish-build.js +78 -28
  69. package/dist/core/capabilities/publish-download.d.ts +1 -2
  70. package/dist/core/capabilities/publish-download.js +2 -3
  71. package/dist/core/capabilities/replace-node.d.ts +1 -3
  72. package/dist/core/capabilities/replace-node.js +1 -3
  73. package/dist/core/capabilities/runtime-control.d.ts +5 -7
  74. package/dist/core/capabilities/runtime-control.js +7 -9
  75. package/dist/core/capabilities/scene-batch.d.ts +1 -1
  76. package/dist/core/capabilities/scene-batch.js +1 -1
  77. package/dist/core/capabilities/scene-kind.js +1 -1
  78. package/dist/core/capabilities/scene-readback.d.ts +3 -4
  79. package/dist/core/capabilities/scene-readback.js +3 -4
  80. package/dist/core/capabilities/scene-script.d.ts +2 -2
  81. package/dist/core/capabilities/scene-script.js +2 -2
  82. package/dist/core/capabilities/seeing/shot-store.d.ts +1 -1
  83. package/dist/core/capabilities/seeing/shot-store.js +1 -1
  84. package/dist/core/capabilities/summer-bundle.d.ts +2 -3
  85. package/dist/core/capabilities/summer-bundle.js +2 -3
  86. package/dist/core/capabilities/surface-snap.d.ts +1 -1
  87. package/dist/core/capabilities/surface-snap.js +1 -1
  88. package/dist/core/capabilities/tool-dispatch.js +11 -1
  89. package/dist/core/capabilities/ui-control.d.ts +1 -2
  90. package/dist/core/capabilities/ui-control.js +1 -2
  91. package/dist/core/capabilities/world-snapshot.d.ts +1 -1
  92. package/dist/core/capabilities/world-snapshot.js +1 -1
  93. package/dist/core/capability-skew.d.ts +2 -3
  94. package/dist/core/capability-skew.js +4 -5
  95. package/dist/core/config.js +2 -2
  96. package/dist/core/engine-install.d.ts +16 -0
  97. package/dist/core/engine-install.js +32 -2
  98. package/dist/core/feedback/client.js +1 -1
  99. package/dist/core/hosted-mcp.d.ts +115 -0
  100. package/dist/core/hosted-mcp.js +164 -0
  101. package/dist/core/launch-posture.d.ts +6 -3
  102. package/dist/core/launch-posture.js +18 -5
  103. package/dist/core/library-read.js +1 -2
  104. package/dist/core/templates.d.ts +1 -2
  105. package/dist/core/templates.js +1 -2
  106. package/dist/mcp/hosted-mount.d.ts +13 -59
  107. package/dist/mcp/hosted-mount.js +24 -30
  108. package/dist/mcp/server.d.ts +2 -2
  109. package/dist/mcp/server.js +5 -4
  110. package/dist/mcp/tools/creator-tools.js +14 -4
  111. package/dist/mcp/tools/debug-tools.js +1 -1
  112. package/dist/mcp/tools/generate-tools.js +19 -9
  113. package/dist/mcp/tools/navigation-tools.d.ts +1 -1
  114. package/dist/mcp/tools/navigation-tools.js +1 -1
  115. package/dist/mcp/tools/spatial-tools.js +1 -1
  116. package/dist/mcp/tools/visual-tools.js +2 -2
  117. package/dist/mcp/tools/with-engine.d.ts +1 -2
  118. package/dist/mcp/tools/with-engine.js +1 -2
  119. package/gemini-extension.json +3 -1
  120. package/hooks/session-start.sh +2 -2
  121. package/integrations/README.md +70 -76
  122. package/integrations/claude/README.md +0 -3
  123. package/integrations/codex/README.md +1 -2
  124. package/integrations/copilot-jetbrains/README.md +1 -1
  125. package/integrations/cursor/README.md +1 -2
  126. package/integrations/factory/README.md +15 -11
  127. package/integrations/mistral-vibe/README.md +1 -1
  128. package/integrations/opencode/README.md +1 -1
  129. package/integrations/roo-code/README.md +1 -1
  130. package/integrations/rovo-dev/README.md +1 -1
  131. package/integrations/trae/README.md +1 -1
  132. package/integrations/windsurf/README.md +3 -3
  133. package/library/references/collaborative-protocol/collaborative-protocol.md +5 -5
  134. package/library/references/gd-style/gd-style.md +4 -6
  135. package/library/references/godot-version/godot-version.md +3 -3
  136. package/library/references/headless-routing/headless-routing.md +2 -2
  137. package/library/references/mcp-fresh-chat-playbook/mcp-fresh-chat-playbook.md +2 -2
  138. package/library/references/mcp-tools-reference/mcp-tools-reference.md +18 -16
  139. package/library/references/product-map/product-map.md +1 -1
  140. package/library/references/public-surface-language/public-surface-language.md +1 -1
  141. package/library/references/summer-folder/summer-folder.md +1 -1
  142. package/library/skills/3d-lighting/SKILL.md +4 -4
  143. package/library/skills/README.md +11 -9
  144. package/library/skills/adaptive-music/SKILL.md +7 -7
  145. package/library/skills/ai-characters-in-games/SKILL.md +1 -1
  146. package/library/skills/ambient-bed/SKILL.md +12 -14
  147. package/library/skills/animated-loop/SKILL.md +42 -42
  148. package/library/skills/animation-tree/SKILL.md +6 -6
  149. package/library/skills/art-direction/SKILL.md +8 -11
  150. package/library/skills/asset-strategy/SKILL.md +3 -3
  151. package/library/skills/audio-direction/SKILL.md +8 -10
  152. package/library/skills/auto-fire-targeting/SKILL.md +4 -3
  153. package/library/skills/bounded-engine-runs/SKILL.md +95 -0
  154. package/library/skills/bounded-engine-runs/resource.yaml +29 -0
  155. package/library/skills/brainstorm-game/SKILL.md +5 -5
  156. package/library/skills/brainstorming/SKILL.md +9 -15
  157. package/library/skills/celeste-momentum-platforming/SKILL.md +8 -13
  158. package/library/skills/celeste-momentum-platforming/resource.yaml +1 -1
  159. package/library/skills/character-animation-wiring/SKILL.md +2 -2
  160. package/library/skills/character-model/SKILL.md +15 -26
  161. package/library/skills/character-movement/SKILL.md +1 -1
  162. package/library/skills/character-movement/references/movement-3d.md +1 -1
  163. package/library/skills/character-portrait/SKILL.md +4 -4
  164. package/library/skills/cinematic-cutscene/SKILL.md +38 -38
  165. package/library/skills/combat-basics/SKILL.md +1 -1
  166. package/library/skills/compatibility-renderer-traps/SKILL.md +78 -0
  167. package/library/skills/compatibility-renderer-traps/resource.yaml +28 -0
  168. package/library/skills/concept-art/SKILL.md +4 -4
  169. package/library/skills/create-asset-sheet/SKILL.md +12 -31
  170. package/library/skills/debug/SKILL.md +5 -4
  171. package/library/skills/debugging-game-feel/SKILL.md +1 -4
  172. package/library/skills/debugging-game-feel/resource.yaml +1 -1
  173. package/library/skills/design-level/SKILL.md +5 -5
  174. package/library/skills/design-mechanic/SKILL.md +6 -6
  175. package/library/skills/design-npc/SKILL.md +8 -15
  176. package/library/skills/diagnosing-perf-regressions/SKILL.md +5 -10
  177. package/library/skills/dispatching-parallel-agents/SKILL.md +1 -19
  178. package/library/skills/environment-kit/SKILL.md +5 -5
  179. package/library/skills/export-and-ship/SKILL.md +25 -24
  180. package/library/skills/fabricating-assets/SKILL.md +1 -1
  181. package/library/skills/facial-and-lipsync/SKILL.md +5 -5
  182. package/library/skills/fps-controller/SKILL.md +17 -16
  183. package/library/skills/fps-controller/resource.yaml +0 -2
  184. package/library/skills/game-feel/SKILL.md +6 -7
  185. package/library/skills/gameskill/SKILL.md +3 -3
  186. package/library/skills/gdscript-patterns/SKILL.md +3 -3
  187. package/library/skills/generate-motion/SKILL.md +5 -22
  188. package/library/skills/godogen-visual-proof-game-generation/SKILL.md +72 -90
  189. package/library/skills/godogen-visual-proof-game-generation/resource.yaml +0 -1
  190. package/library/skills/headless-scripting/SKILL.md +8 -8
  191. package/library/skills/headless-scripting/resource.yaml +1 -0
  192. package/library/skills/in-game-purchases/SKILL.md +123 -118
  193. package/library/skills/in-game-purchases/resource.yaml +2 -2
  194. package/library/skills/instantiate-asset-pack/SKILL.md +7 -3
  195. package/library/skills/investigating-bugs/SKILL.md +3 -11
  196. package/library/skills/investigating-bugs/condition-based-waiting.md +0 -10
  197. package/library/skills/investigating-bugs/root-cause-tracing.md +0 -8
  198. package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +15 -15
  199. package/library/skills/lumera-single-image-scene-reconstruction/resource.yaml +0 -1
  200. package/library/skills/make-game/SKILL.md +3 -5
  201. package/library/skills/make-game/references/2d-platformer.md +1 -1
  202. package/library/skills/multiplayer-project/SKILL.md +1 -1
  203. package/library/skills/multiplayer-testing/SKILL.md +4 -4
  204. package/library/skills/music-track/SKILL.md +40 -38
  205. package/library/skills/new-project/SKILL.md +4 -6
  206. package/library/skills/organic-model/SKILL.md +9 -9
  207. package/library/skills/pixel-art/SKILL.md +6 -6
  208. package/library/skills/play/SKILL.md +3 -4
  209. package/library/skills/playtesting-a-feature/SKILL.md +4 -6
  210. package/library/skills/procedural-animation/SKILL.md +10 -11
  211. package/library/skills/prop-model/SKILL.md +4 -4
  212. package/library/skills/psx-retro-rendering/SKILL.md +20 -20
  213. package/library/skills/psx-retro-rendering/resource.yaml +2 -3
  214. package/library/skills/realtime-wet-surfaces/SKILL.md +15 -15
  215. package/library/skills/realtime-wet-surfaces/resource.yaml +1 -2
  216. package/library/skills/remote-deploy/SKILL.md +20 -21
  217. package/library/skills/retarget/SKILL.md +19 -23
  218. package/library/skills/running-in-the-cloud/SKILL.md +5 -5
  219. package/library/skills/scene-composition/SKILL.md +5 -5
  220. package/library/skills/scene-hierarchy-design/SKILL.md +3 -3
  221. package/library/skills/scene-hierarchy-design/resource.yaml +0 -1
  222. package/library/skills/scene-scripting/SKILL.md +3 -3
  223. package/library/skills/scene-to-level/SKILL.md +28 -31
  224. package/library/skills/skill-create/SKILL.md +1 -1
  225. package/library/skills/skill-improve/SKILL.md +9 -9
  226. package/library/skills/skill-test/SKILL.md +10 -10
  227. package/library/skills/skintokens-auto-rigging/SKILL.md +18 -18
  228. package/library/skills/skintokens-auto-rigging/resource.yaml +3 -3
  229. package/library/skills/skybox-panorama/SKILL.md +8 -9
  230. package/library/skills/sound-effect/SKILL.md +19 -19
  231. package/library/skills/spatial-placement/SKILL.md +2 -2
  232. package/library/skills/spatial-placement/references/kit-placement-tools.md +12 -22
  233. package/library/skills/sprite-sheet/SKILL.md +10 -10
  234. package/library/skills/summer-analytics/SKILL.md +3 -3
  235. package/library/skills/summer-friends/SKILL.md +10 -10
  236. package/library/skills/summer-leaderboards/SKILL.md +6 -6
  237. package/library/skills/summer-match-results/SKILL.md +13 -13
  238. package/library/skills/summer-matchmaking/SKILL.md +11 -11
  239. package/library/skills/summer-parties/SKILL.md +9 -9
  240. package/library/skills/summer-player-data/SKILL.md +12 -12
  241. package/library/skills/summer-store/SKILL.md +6 -6
  242. package/library/skills/summer-world-chat/SKILL.md +9 -9
  243. package/library/skills/summer-world-saves/SKILL.md +7 -7
  244. package/library/skills/text-to-motion/rigging-for-text-motion.md +1 -1
  245. package/library/skills/tileable-texture/SKILL.md +1 -1
  246. package/library/skills/trailer-shot/SKILL.md +36 -36
  247. package/library/skills/tune-performance/SKILL.md +13 -13
  248. package/library/skills/tune-performance/resource.yaml +1 -1
  249. package/library/skills/ui-graphics/SKILL.md +7 -7
  250. package/library/skills/use-widget-asset/SKILL.md +7 -7
  251. package/library/skills/using-summer/SKILL.md +5 -7
  252. package/library/skills/vehicle-model/SKILL.md +6 -7
  253. package/library/skills/vehicle-model/resource.yaml +2 -2
  254. package/library/skills/verification-before-completion/SKILL.md +5 -6
  255. package/library/skills/vfx-dissolve/SKILL.md +4 -4
  256. package/library/skills/vfx-fire/SKILL.md +6 -6
  257. package/library/skills/vfx-fire/_building-blocks/additive-billboard-particles.md +3 -3
  258. package/library/skills/vfx-hit-spark/SKILL.md +4 -4
  259. package/library/skills/vfx-hit-spark/_building-blocks/additive-billboard-particles.md +3 -3
  260. package/library/skills/vfx-lightning/SKILL.md +5 -5
  261. package/library/skills/vfx-lightning/_building-blocks/additive-billboard-particles.md +3 -3
  262. package/library/skills/vfx-lightning/_building-blocks/trauma-shake-snippet.md +9 -3
  263. package/library/skills/vfx-magic-glow/SKILL.md +4 -4
  264. package/library/skills/vfx-magic-glow/_building-blocks/additive-billboard-particles.md +3 -3
  265. package/library/skills/vfx-muzzle-flash/SKILL.md +5 -5
  266. package/library/skills/vfx-muzzle-flash/_building-blocks/additive-billboard-particles.md +3 -3
  267. package/library/skills/vfx-muzzle-flash/_building-blocks/trauma-shake-snippet.md +9 -3
  268. package/library/skills/vfx-smoke/SKILL.md +5 -5
  269. package/library/skills/vfx-water-ripple/SKILL.md +2 -2
  270. package/library/skills/vfx-water-ripple/_building-blocks/additive-billboard-particles.md +3 -3
  271. package/library/skills/voice-line/SKILL.md +9 -9
  272. package/library/skills/web-compatibility-look/resource.yaml +1 -0
  273. package/library/skills/world-building-3d/references/spatial-tools.md +2 -2
  274. package/library/skills/writing-plans/SKILL.md +4 -4
  275. package/library/skills/writing-skills/SKILL.md +8 -8
  276. package/library/tools/capture-gameplay/resource.yaml +73 -0
  277. package/library/tools/creator-publish/resource.yaml +4 -4
  278. package/library/tools/creator-releases/resource.yaml +5 -5
  279. package/library/tools/generate-image/resource.yaml +15 -1
  280. package/library/tools/publish-build/resource.yaml +6 -2
  281. package/package.json +1 -1
  282. package/registry/generated/aliases.json +1 -0
  283. package/registry/generated/counts.json +3 -3
  284. package/registry/generated/gemini-extension.json +3 -1
  285. package/registry/generated/index.json +248 -135
  286. package/registry/generated/marketplace.claude.json +2 -2
  287. package/registry/generated/plugin.claude.json +4 -2
  288. package/registry/generated/plugin.codex.json +5 -3
  289. package/registry/generated/plugin.cursor.json +4 -2
  290. package/registry/generated/plugin.factory.json +4 -2
  291. package/registry/generated/skills-index.md +11 -9
  292. package/registry/generated/skills-registry.json +33 -6
  293. package/registry/schemas/domains.json +1 -1
@@ -1,6 +1,6 @@
1
1
  # Additive Billboard Particles — Canonical Material Settings
2
2
 
3
- Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `magic-glow`, optionally substitutable in `hit-spark` and `fire` if a custom shader is overkill.
3
+ Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `vfx-magic-glow`, optionally substitutable in `vfx-hit-spark` and `vfx-fire` if a custom shader is overkill.
4
4
 
5
5
  `BaseMaterial3D` is abstract — `BaseMaterial3D.new()` is a parse error ("Native class
6
6
  "BaseMaterial3D" cannot be constructed as it is abstract"). Instantiate
@@ -27,8 +27,8 @@ bm.emission = Color(R, G, B) # usually same as albedo for single-color
27
27
 
28
28
  ## When to use this vs a custom shader
29
29
 
30
- - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free Godot-managed billboard math.
31
- - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all verified present in 4.6) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
30
+ - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free engine-managed billboard math.
31
+ - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all present on the shipped engine) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
32
32
  - **Use a custom `ShaderMaterial`** when you need per-fragment shape masks (muzzle flash star burst), noise-distorted UVs (fire, smoke), or anything that varies *within* the quad. Those are what `StandardMaterial3D` genuinely can't express.
33
33
  - If a custom shader does need the particle age, note that the age lives in `INSTANCE_CUSTOM.y` (normalized by `INSTANCE_CUSTOM.w`, the lifetime), that `INSTANCE_CUSTOM.x` is the rotation angle — not the age — and that `INSTANCE_CUSTOM` is **vertex-stage only**. Pass it to `fragment()` through a `varying`.
34
34
 
@@ -21,14 +21,14 @@ Tiny stretched additive billboards spraying outward from an impact point, orient
21
21
  - "Footstep sparks on stone for the heavy armor."
22
22
  - "Ricochet sparks when the projectile glances off."
23
23
  - "Mining: sparks fly when pickaxe hits rock."
24
- - Endpoint sparks on `lightning` and `muzzle-flash` recipes (they reference this).
24
+ - Endpoint sparks on `vfx-lightning` and `vfx-muzzle-flash` recipes (they reference this).
25
25
 
26
26
  ## When NOT to use
27
27
 
28
- - The user wants a *flash* at the impact, not a spray of particles — use `muzzle-flash` (recolor it).
28
+ - The user wants a *flash* at the impact, not a spray of particles — use `vfx-muzzle-flash` (recolor it).
29
29
  - The user wants debris chunks (rock pieces, splinters) — those are physics objects, not particles. Spawn `RigidBody3D` shards, then sparks on top.
30
- - The user wants water droplets at a water impact — recolor this recipe blue/white (it works) or pair with `water-ripple` for the ring on the surface.
31
- - The user wants persistent burning sparks that linger and cool down — that's a hybrid; use this for the burst, then tiny `fire` particles for residual embers.
30
+ - The user wants water droplets at a water impact — recolor this recipe blue/white (it works) or pair with `vfx-water-ripple` for the ring on the surface.
31
+ - The user wants persistent burning sparks that linger and cool down — that's a hybrid; use this for the burst, then tiny `vfx-fire` particles for residual embers.
32
32
 
33
33
  ## Recipe
34
34
 
@@ -1,6 +1,6 @@
1
1
  # Additive Billboard Particles — Canonical Material Settings
2
2
 
3
- Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `magic-glow`, optionally substitutable in `hit-spark` and `fire` if a custom shader is overkill.
3
+ Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `vfx-magic-glow`, optionally substitutable in `vfx-hit-spark` and `vfx-fire` if a custom shader is overkill.
4
4
 
5
5
  `BaseMaterial3D` is abstract — `BaseMaterial3D.new()` is a parse error ("Native class
6
6
  "BaseMaterial3D" cannot be constructed as it is abstract"). Instantiate
@@ -27,8 +27,8 @@ bm.emission = Color(R, G, B) # usually same as albedo for single-color
27
27
 
28
28
  ## When to use this vs a custom shader
29
29
 
30
- - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free Godot-managed billboard math.
31
- - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all verified present in 4.6) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
30
+ - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free engine-managed billboard math.
31
+ - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all present on the shipped engine) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
32
32
  - **Use a custom `ShaderMaterial`** when you need per-fragment shape masks (muzzle flash star burst), noise-distorted UVs (fire, smoke), or anything that varies *within* the quad. Those are what `StandardMaterial3D` genuinely can't express.
33
33
  - If a custom shader does need the particle age, note that the age lives in `INSTANCE_CUSTOM.y` (normalized by `INSTANCE_CUSTOM.w`, the lifetime), that `INSTANCE_CUSTOM.x` is the rotation angle — not the age — and that `INSTANCE_CUSTOM` is **vertex-stage only**. Pass it to `fragment()` through a `varying`.
34
34
 
@@ -11,20 +11,20 @@ paths: ["**/*.tscn", "**/*.gd", "**/*.gdshader", "addons/vfx/**"]
11
11
 
12
12
  # lightning — Procedural Jagged Bolt
13
13
 
14
- A lightning bolt is a noisy line from A to B, drawn for ~150 ms with a glow shader, sparks at both endpoints, and camera shake on cast. The recipe builds the jagged path in GDScript (midpoint displacement on a polyline), feeds the verts into an `ImmediateMesh`, applies a `ShaderMaterial` for additive bloom + flicker, spawns `hit-spark` particles at each endpoint, and calls `CameraShake.add_trauma(0.6)` for the impact. Used for shock spells, tesla coils, weapon discharges, electric enemies.
14
+ A lightning bolt is a noisy line from A to B, drawn for ~150 ms with a glow shader, sparks at both endpoints, and camera shake on cast. The recipe builds the jagged path in GDScript (midpoint displacement on a polyline), feeds the verts into an `ImmediateMesh`, applies a `ShaderMaterial` for additive bloom + flicker, spawns `vfx-hit-spark` particles at each endpoint, and calls `CameraShake.add_trauma(0.6)` for the impact. Used for shock spells, tesla coils, weapon discharges, electric enemies.
15
15
 
16
16
  ## When to use
17
17
 
18
18
  - "Cast a lightning bolt from the wizard's hand to the enemy."
19
19
  - "Chain lightning from one enemy to the next." (call `cast_lightning` per segment)
20
20
  - "Tesla coil firing at the player every 2 seconds."
21
- - "Energy weapon laser." (use the `laser-beam` variant)
21
+ - "Energy weapon laser." (use the `plasma-laser` variant)
22
22
  - "Lightning strike from the sky."
23
23
  - The user wants a *short, dramatic* energy connection between two points.
24
24
 
25
25
  ## When NOT to use
26
26
 
27
- - The user wants a continuous beam that holds (e.g., laser sniper holding the trigger) — use the same shader on a `MeshInstance3D` cylinder with continuous emission, not the `ImmediateMesh` one-shot pattern. (See variants for `held-beam`.)
27
+ - The user wants a continuous beam that holds (e.g., laser sniper holding the trigger) — use the same shader on a `MeshInstance3D` cylinder with continuous emission, not the `ImmediateMesh` one-shot pattern. (See the `plasma-laser` variant.)
28
28
  - The user wants ambient electricity *on* an object (Frankenstein arcs) — use a custom shader on the mesh with screen-space arcs; this recipe is for two-point bolts.
29
29
  - The user wants a 2D lightning effect on UI — `canvas_item` shader, not this.
30
30
  - The user wants a tracer line for a bullet — use a simple `ImmediateMesh`
@@ -369,7 +369,7 @@ trauma_amount = 0.0 # no shake on a held beam
369
369
 
370
370
  - One bolt at `SEGMENTS = 18`: 19 path points × 2 verts = 38 verts for the trunk, plus 2 × (`SEGMENTS / 3` + 1) = 14 verts per forked branch. One draw call, freed after 150 ms. Effectively free.
371
371
  - Chain lightning with 5 segments stays in the same negligible band — that is an order-of-magnitude expectation, not a measurement.
372
- - Endpoint sparks (instantiated `hit-spark` scenes) are the bigger cost — 64 particles × 2 = 128 particles per cast. Throttle for storms (see edge cases).
372
+ - Endpoint sparks (instantiated `vfx-hit-spark` scenes) are the bigger cost — 64 particles × 2 = 128 particles per cast. Throttle for storms (see edge cases).
373
373
  - The shader's flicker uses `floor(TIME * flicker_rate)`, so it ages with `TIME` not particle time — flicker is consistent across all bolts in flight.
374
374
 
375
375
  ## Edge cases
@@ -378,7 +378,7 @@ trauma_amount = 0.0 # no shake on a held beam
378
378
  - **Bolt passes through a wall.** Visual only — the bolt shader doesn't depth test. If the user wants the bolt to be occluded by walls, set `depth_draw_opaque` and let the depth buffer cull it (loses the additive bloom in front of geometry).
379
379
  - **Bolt origin and target at the same point.** Falloff goes to zero; `_generate_path` returns a degenerate strip. Add a guard: if `(to - from).length() < 0.01`, skip.
380
380
  - **Underwater bolt.** Tint blue-green, drop `emission_boost` to 5.0; underwater bloom is muted.
381
- - **First-person caster (player's hand).** The bolt starts inside the player's view and reads as a flash. Use a `held-beam` variant or shorten `LIFETIME` to 0.08.
381
+ - **First-person caster (player's hand).** The bolt starts inside the player's view and reads as a flash. Use the `plasma-laser` variant or shorten `LIFETIME` to 0.08.
382
382
  - **No `CameraShake` autoload registered.** `get_node_or_null("/root/CameraShake")` returns null and the `if cs` check skips the call; the bolt fires without shake. Suggest `_building-blocks/trauma-shake-snippet.md` to wire it.
383
383
 
384
384
  ## Fallback (no MCP)
@@ -1,6 +1,6 @@
1
1
  # Additive Billboard Particles — Canonical Material Settings
2
2
 
3
- Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `magic-glow`, optionally substitutable in `hit-spark` and `fire` if a custom shader is overkill.
3
+ Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `vfx-magic-glow`, optionally substitutable in `vfx-hit-spark` and `vfx-fire` if a custom shader is overkill.
4
4
 
5
5
  `BaseMaterial3D` is abstract — `BaseMaterial3D.new()` is a parse error ("Native class
6
6
  "BaseMaterial3D" cannot be constructed as it is abstract"). Instantiate
@@ -27,8 +27,8 @@ bm.emission = Color(R, G, B) # usually same as albedo for single-color
27
27
 
28
28
  ## When to use this vs a custom shader
29
29
 
30
- - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free Godot-managed billboard math.
31
- - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all verified present in 4.6) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
30
+ - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free engine-managed billboard math.
31
+ - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all present on the shipped engine) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
32
32
  - **Use a custom `ShaderMaterial`** when you need per-fragment shape masks (muzzle flash star burst), noise-distorted UVs (fire, smoke), or anything that varies *within* the quad. Those are what `StandardMaterial3D` genuinely can't express.
33
33
  - If a custom shader does need the particle age, note that the age lives in `INSTANCE_CUSTOM.y` (normalized by `INSTANCE_CUSTOM.w`, the lifetime), that `INSTANCE_CUSTOM.x` is the rotation angle — not the age — and that `INSTANCE_CUSTOM` is **vertex-stage only**. Pass it to `fragment()` through a `varying`.
34
34
 
@@ -1,6 +1,6 @@
1
1
  # Trauma Camera Shake — Reusable Snippet
2
2
 
3
- Variant of the canonical "trauma model" shake (see `visual-effects/game-feel/SKILL.md` for the full game-feel discipline). Lightning and explosion recipes call `add_trauma()` to chain visual impact with screen-level reaction.
3
+ Variant of the canonical "trauma model" shake (the `game-feel` skill has the full game-feel discipline). Lightning and explosion recipes call `add_trauma()` to chain visual impact with screen-level reaction.
4
4
 
5
5
  ## Setup (autoload script)
6
6
 
@@ -15,18 +15,24 @@ var max_offset: Vector3 = Vector3(0.4, 0.4, 0.0)
15
15
  var max_yaw: float = 0.05
16
16
  var max_pitch: float = 0.05
17
17
  var camera: Camera3D
18
+ var _rot_offset := Vector2.ZERO # shake rotation applied last frame
18
19
 
19
20
  func _process(delta: float) -> void:
20
21
  if camera == null:
21
22
  camera = get_viewport().get_camera_3d()
22
23
  if camera == null:
23
24
  return
25
+ # Undo last frame's shake first, so the camera never drifts.
26
+ camera.rotation.x -= _rot_offset.x
27
+ camera.rotation.y -= _rot_offset.y
28
+ _rot_offset = Vector2.ZERO
24
29
  if trauma > 0.0:
25
30
  var s := trauma * trauma # perceived intensity grows quadratically
26
31
  camera.h_offset = max_offset.x * s * (randf() * 2.0 - 1.0)
27
32
  camera.v_offset = max_offset.y * s * (randf() * 2.0 - 1.0)
28
- camera.rotation.x += max_pitch * s * (randf() * 2.0 - 1.0) * 0.1
29
- camera.rotation.y += max_yaw * s * (randf() * 2.0 - 1.0) * 0.1
33
+ _rot_offset = Vector2(max_pitch * s * (randf() * 2.0 - 1.0), max_yaw * s * (randf() * 2.0 - 1.0))
34
+ camera.rotation.x += _rot_offset.x
35
+ camera.rotation.y += _rot_offset.y
30
36
  trauma = max(0.0, trauma - trauma_decay * delta)
31
37
  else:
32
38
  camera.h_offset = 0.0
@@ -21,13 +21,13 @@ Three layered cues that together read as "magical": a pulsing `OmniLight3D` (sin
21
21
  - "Wisp / fairy / firefly companion."
22
22
  - "The summoning circle is active."
23
23
  - "Quest item glows so the player notices it."
24
- - Pre-charge phase before casting `lightning` or `muzzle-flash` (charge-up beam).
24
+ - Pre-charge phase before casting `vfx-lightning` or `vfx-muzzle-flash` (charge-up beam).
25
25
 
26
26
  ## When NOT to use
27
27
 
28
28
  - The user wants a static, non-animated glow — just enable emission on the mesh's material; this recipe is overkill.
29
- - The user wants flames, not a glow — use `fire` (or `magic-fire` variant of `fire`).
30
- - The user wants a beam shooting out, not an aura — use `lightning` with the `plasma-laser` variant.
29
+ - The user wants flames, not a glow — use `vfx-fire` (or `magic-fire` variant of `vfx-fire`).
30
+ - The user wants a beam shooting out, not an aura — use `vfx-lightning` with the `plasma-laser` variant.
31
31
  - The user wants a screen-space bloom on the whole scene — that's `WorldEnvironment.glow_*`, not a per-object recipe.
32
32
  - The user wants a 2D glow on a UI sprite — use `canvas_item` shader with a radial gradient, not this 3D recipe.
33
33
 
@@ -415,7 +415,7 @@ manually in Summer Engine:
415
415
 
416
416
  After firing this recipe, suggest:
417
417
 
418
- - `vfx-lightning` — perfect pre-cast charge-up. Use the `charge-up` variant and ramp `set_intensity(0→1)` then call `Lightning.cast_lightning`.
418
+ - `vfx-lightning` — pre-cast charge-up. Use this skill's `charge-up` variant, ramp `set_intensity(0→1)` then call `Lightning.cast_lightning`.
419
419
  - `vfx-dissolve` — pair `summon-arrival` (materialize_object) with the `summoning-circle` variant.
420
420
  - `vfx-fire` (the `magic-fire` variant) — for items that should glow AND flame.
421
421
  - `game-feel` — slight time-dilation when picking up a pulsing quest item adds weight.
@@ -1,6 +1,6 @@
1
1
  # Additive Billboard Particles — Canonical Material Settings
2
2
 
3
- Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `magic-glow`, optionally substitutable in `hit-spark` and `fire` if a custom shader is overkill.
3
+ Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `vfx-magic-glow`, optionally substitutable in `vfx-hit-spark` and `vfx-fire` if a custom shader is overkill.
4
4
 
5
5
  `BaseMaterial3D` is abstract — `BaseMaterial3D.new()` is a parse error ("Native class
6
6
  "BaseMaterial3D" cannot be constructed as it is abstract"). Instantiate
@@ -27,8 +27,8 @@ bm.emission = Color(R, G, B) # usually same as albedo for single-color
27
27
 
28
28
  ## When to use this vs a custom shader
29
29
 
30
- - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free Godot-managed billboard math.
31
- - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all verified present in 4.6) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
30
+ - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free engine-managed billboard math.
31
+ - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all present on the shipped engine) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
32
32
  - **Use a custom `ShaderMaterial`** when you need per-fragment shape masks (muzzle flash star burst), noise-distorted UVs (fire, smoke), or anything that varies *within* the quad. Those are what `StandardMaterial3D` genuinely can't express.
33
33
  - If a custom shader does need the particle age, note that the age lives in `INSTANCE_CUSTOM.y` (normalized by `INSTANCE_CUSTOM.w`, the lifetime), that `INSTANCE_CUSTOM.x` is the rotation angle — not the age — and that `INSTANCE_CUSTOM` is **vertex-stage only**. Pass it to `fragment()` through a `varying`.
34
34
 
@@ -11,7 +11,7 @@ paths: ["**/*.tscn", "**/*.gd", "**/*.gdshader", "addons/vfx/**"]
11
11
 
12
12
  # muzzle-flash — One-Shot Star-Burst Flare
13
13
 
14
- A muzzle flash is on screen for 60–100 ms. Long enough to read, too short to animate. The recipe: a single billboarded quad with a star-burst gradient shader, fired by `restart()` on a weapon's `fired` signal, plus an `OmniLight3D` snapping on for 60 ms to light the room. Optional: a tiny GPUParticles3D one-shot for sparks. Doom Eternal does this. Half-Life 2 did this. Every shooter does this.
14
+ A muzzle flash is on screen for 60–100 ms. Long enough to read, too short to animate. The recipe: a single billboarded quad with a star-burst gradient shader, fired by `restart()` on a weapon's `fired` signal, plus an `OmniLight3D` snapping on for 60 ms to light the room. Optional: a tiny GPUParticles3D one-shot for sparks. Most shooters use this pattern.
15
15
 
16
16
  ## When to use
17
17
 
@@ -23,12 +23,12 @@ A muzzle flash is on screen for 60–100 ms. Long enough to read, too short to a
23
23
 
24
24
  ## When NOT to use
25
25
 
26
- - The user wants a *continuous* flame (flamethrower) — use `fire`, not muzzle-flash.
27
- - The user wants the impact spark on the wall the bullet hit — that's `hit-spark`.
26
+ - The user wants a *continuous* flame (flamethrower) — use `vfx-fire`, not muzzle-flash.
27
+ - The user wants the impact spark on the wall the bullet hit — that's `vfx-hit-spark`.
28
28
  - The user wants a tracer line from barrel to target — use an `ImmediateMesh`
29
29
  recipe, not this. The current Summer build has no `Line3D`
30
30
  (`ClassDB.class_exists("Line3D")` is `false`).
31
- - The user wants a slow-glowing spell charge-up — use `magic-glow` for the buildup, then this for the release frame.
31
+ - The user wants a slow-glowing spell charge-up — use `vfx-magic-glow` for the buildup, then this for the release frame.
32
32
 
33
33
  ## Recipe
34
34
 
@@ -377,7 +377,7 @@ After firing this recipe, suggest:
377
377
 
378
378
  - `vfx-hit-spark` — pair on the bullet impact end.
379
379
  - `vfx-smoke` — for a small puff at the barrel after the flash for high-caliber weapons.
380
- - `game-feel` — recoil camera kick + screen shake (`CameraShake.add_trauma(0.15)`) on every shot makes the flash feel 5× more powerful.
380
+ - `game-feel` — recoil camera kick + screen shake (`CameraShake.add_trauma(0.15)`) on every shot makes the flash land much harder.
381
381
  - `sound-effect` — generate `9mm pistol shot, sharp crack, indoor, short tail, 400ms` and play in the same `fire()`.
382
382
 
383
383
  ## See also
@@ -1,6 +1,6 @@
1
1
  # Additive Billboard Particles — Canonical Material Settings
2
2
 
3
- Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `magic-glow`, optionally substitutable in `hit-spark` and `fire` if a custom shader is overkill.
3
+ Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `vfx-magic-glow`, optionally substitutable in `vfx-hit-spark` and `vfx-fire` if a custom shader is overkill.
4
4
 
5
5
  `BaseMaterial3D` is abstract — `BaseMaterial3D.new()` is a parse error ("Native class
6
6
  "BaseMaterial3D" cannot be constructed as it is abstract"). Instantiate
@@ -27,8 +27,8 @@ bm.emission = Color(R, G, B) # usually same as albedo for single-color
27
27
 
28
28
  ## When to use this vs a custom shader
29
29
 
30
- - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free Godot-managed billboard math.
31
- - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all verified present in 4.6) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
30
+ - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free engine-managed billboard math.
31
+ - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all present on the shipped engine) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
32
32
  - **Use a custom `ShaderMaterial`** when you need per-fragment shape masks (muzzle flash star burst), noise-distorted UVs (fire, smoke), or anything that varies *within* the quad. Those are what `StandardMaterial3D` genuinely can't express.
33
33
  - If a custom shader does need the particle age, note that the age lives in `INSTANCE_CUSTOM.y` (normalized by `INSTANCE_CUSTOM.w`, the lifetime), that `INSTANCE_CUSTOM.x` is the rotation angle — not the age — and that `INSTANCE_CUSTOM` is **vertex-stage only**. Pass it to `fragment()` through a `varying`.
34
34
 
@@ -1,6 +1,6 @@
1
1
  # Trauma Camera Shake — Reusable Snippet
2
2
 
3
- Variant of the canonical "trauma model" shake (see `visual-effects/game-feel/SKILL.md` for the full game-feel discipline). Lightning and explosion recipes call `add_trauma()` to chain visual impact with screen-level reaction.
3
+ Variant of the canonical "trauma model" shake (the `game-feel` skill has the full game-feel discipline). Lightning and explosion recipes call `add_trauma()` to chain visual impact with screen-level reaction.
4
4
 
5
5
  ## Setup (autoload script)
6
6
 
@@ -15,18 +15,24 @@ var max_offset: Vector3 = Vector3(0.4, 0.4, 0.0)
15
15
  var max_yaw: float = 0.05
16
16
  var max_pitch: float = 0.05
17
17
  var camera: Camera3D
18
+ var _rot_offset := Vector2.ZERO # shake rotation applied last frame
18
19
 
19
20
  func _process(delta: float) -> void:
20
21
  if camera == null:
21
22
  camera = get_viewport().get_camera_3d()
22
23
  if camera == null:
23
24
  return
25
+ # Undo last frame's shake first, so the camera never drifts.
26
+ camera.rotation.x -= _rot_offset.x
27
+ camera.rotation.y -= _rot_offset.y
28
+ _rot_offset = Vector2.ZERO
24
29
  if trauma > 0.0:
25
30
  var s := trauma * trauma # perceived intensity grows quadratically
26
31
  camera.h_offset = max_offset.x * s * (randf() * 2.0 - 1.0)
27
32
  camera.v_offset = max_offset.y * s * (randf() * 2.0 - 1.0)
28
- camera.rotation.x += max_pitch * s * (randf() * 2.0 - 1.0) * 0.1
29
- camera.rotation.y += max_yaw * s * (randf() * 2.0 - 1.0) * 0.1
33
+ _rot_offset = Vector2(max_pitch * s * (randf() * 2.0 - 1.0), max_yaw * s * (randf() * 2.0 - 1.0))
34
+ camera.rotation.x += _rot_offset.x
35
+ camera.rotation.y += _rot_offset.y
30
36
  trauma = max(0.0, trauma - trauma_decay * delta)
31
37
  else:
32
38
  camera.h_offset = 0.0
@@ -11,7 +11,7 @@ paths: ["**/*.tscn", "**/*.gd", "**/*.gdshader", "addons/vfx/**"]
11
11
 
12
12
  # smoke — Soft Particle Smoke Plume
13
13
 
14
- Smoke is the same particle pattern as fire — billboard quads emitted from a small disc, drifting upward — except the shader is dim, soft, low-emission, and tinted by depth instead of glowing. Slower spawn rate, longer lifetime, larger end scale. Pair it with `fire` for any campfire/torch/explosion. Used everywhere: chimney smoke, smoldering wreckage, smoke trails behind rockets, steam from vents, fog clouds.
14
+ Smoke is the same particle pattern as fire — billboard quads emitted from a small disc, drifting upward — except the shader is dim, soft, low-emission, and tinted by depth instead of glowing. Slower spawn rate, longer lifetime, larger end scale. Pair it with `vfx-fire` for any campfire/torch/explosion. Used everywhere: chimney smoke, smoldering wreckage, smoke trails behind rockets, steam from vents, fog clouds.
15
15
 
16
16
  ## When to use
17
17
 
@@ -21,12 +21,12 @@ Smoke is the same particle pattern as fire — billboard quads emitted from a sm
21
21
  - "Steam from the vent."
22
22
  - "Smoke from the smoldering wreckage."
23
23
  - "Fog cloud at the cave entrance."
24
- - After spawning `fire`, smoke almost always belongs above it.
24
+ - After spawning `vfx-fire`, smoke almost always belongs above it.
25
25
 
26
26
  ## When NOT to use
27
27
 
28
- - The user wants flames, not smoke — use `fire`.
29
- - The user wants a giant ground-hugging fog volume — use a `FogVolume` node with the `WorldEnvironment.volumetric_fog` shader, not a particle system. Particles don't scale to room-size fog.
28
+ - The user wants flames, not smoke — use `vfx-fire`.
29
+ - The user wants a giant ground-hugging fog volume — use a `FogVolume` node with volumetric fog enabled in the `WorldEnvironment`, not a particle system. Particles don't scale to room-size fog.
30
30
  - The user wants a 2D smoke effect — `canvas_item` shader, not this.
31
31
  - The user wants the smoke to physically interact with the player (pushed by movement) — particles are visual; use a `FogVolume` + script that follows the player.
32
32
  - The user wants thick black bonfire smoke that completely occludes — bump density way up, but consider a `FogVolume` for genuine visual occlusion.
@@ -334,7 +334,7 @@ color_old = Color(0.55, 0.55, 0.55)
334
334
 
335
335
  ### black-fire-smoke
336
336
 
337
- Burning oil / tires. Pair with `fire` set to `bonfire`.
337
+ Burning oil / tires. Pair with `vfx-fire` set to `bonfire`.
338
338
 
339
339
  ```
340
340
  particle_count = 96
@@ -24,9 +24,9 @@ Concentric expanding rings on a water surface, normal-distorted so the ripple ac
24
24
 
25
25
  ## When NOT to use
26
26
 
27
- - The user wants the *whole* water surface to wave (Gerstner / FFT ocean) — that's a separate `ocean-water` recipe; this is impact ripples on top.
27
+ - The user wants the *whole* water surface to wave (Gerstner / FFT ocean) — that needs an ocean wave shader; this recipe adds impact ripples on top.
28
28
  - The user wants a 2D top-down ripple effect on a UI map — use `canvas_item` shader, not this `spatial` one.
29
- - The user wants splash particles flying upward on impact — pair this with `hit-spark` (recolor blue) for the droplets; this only handles the ring on the surface.
29
+ - The user wants splash particles flying upward on impact — pair this with `vfx-hit-spark` (recolor blue) for the droplets; this only handles the ring on the surface.
30
30
  - The user wants the ripple to physically displace floating objects — this is visual only. Use `Area3D` impulses for the simulation side.
31
31
 
32
32
  ## Recipe
@@ -1,6 +1,6 @@
1
1
  # Additive Billboard Particles — Canonical Material Settings
2
2
 
3
- Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `magic-glow`, optionally substitutable in `hit-spark` and `fire` if a custom shader is overkill.
3
+ Reusable material configuration for additive particle billboards (motes, sparks, glow, ash). Used by `vfx-magic-glow`, optionally substitutable in `vfx-hit-spark` and `vfx-fire` if a custom shader is overkill.
4
4
 
5
5
  `BaseMaterial3D` is abstract — `BaseMaterial3D.new()` is a parse error ("Native class
6
6
  "BaseMaterial3D" cannot be constructed as it is abstract"). Instantiate
@@ -27,8 +27,8 @@ bm.emission = Color(R, G, B) # usually same as albedo for single-color
27
27
 
28
28
  ## When to use this vs a custom shader
29
29
 
30
- - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free Godot-managed billboard math.
31
- - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all verified present in 4.6) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
30
+ - **Use this `StandardMaterial3D` config** when the effect is just a tinted soft-circle mote (magic glow, sparkles, dust). Less code, faster iteration, free engine-managed billboard math.
31
+ - **Per-particle color over age does NOT need a custom shader.** `ParticleProcessMaterial` has `color_ramp`, `color_initial_ramp`, `alpha_curve` and `emission_curve` (all present on the shipped engine) — those drive the particle's `COLOR` from age and feed straight into a plain `StandardMaterial3D`. Reach for a ramp before reaching for a shader.
32
32
  - **Use a custom `ShaderMaterial`** when you need per-fragment shape masks (muzzle flash star burst), noise-distorted UVs (fire, smoke), or anything that varies *within* the quad. Those are what `StandardMaterial3D` genuinely can't express.
33
33
  - If a custom shader does need the particle age, note that the age lives in `INSTANCE_CUSTOM.y` (normalized by `INSTANCE_CUSTOM.w`, the lifetime), that `INSTANCE_CUSTOM.x` is the rotation angle — not the age — and that `INSTANCE_CUSTOM` is **vertex-stage only**. Pass it to `fragment()` through a `varying`.
34
34
 
@@ -24,7 +24,7 @@ Then it generates one line (or a multi-turn dialogue) with the right stability /
24
24
 
25
25
  ## When NOT to use
26
26
 
27
- - Non-verbal vocal SFX (grunt, scream) → `audio/sound-effect` with prompt `male grunt of pain, mid-thirties, sharp, 400ms`.
27
+ - Non-verbal vocal SFX (grunt, scream) → `sound-effect` with prompt `male grunt of pain, mid-thirties, sharp, 400ms`.
28
28
  - Pre-recorded voice from a real actor — import the .mp3 / .wav with `summer_import_from_url` and skip TTS.
29
29
 
30
30
  ## Steps
@@ -146,7 +146,7 @@ For a single line, the prompt is just the text. Punctuation and formatting matte
146
146
 
147
147
  - **Periods** = clear pauses (~300ms). Use them.
148
148
  - **Commas** = short pauses (~100ms).
149
- - **Em dashes** = sharp cut. (Note: avoid em dashes in user-facing UI copy per project standard, but they're fine in voice prompts as a delivery cue.)
149
+ - **Em dashes** = sharp cut.
150
150
  - **All-caps word** = stress: `You SHALL not pass.`
151
151
  - **Ellipsis** = trailing pause: `I... I don't know what to say.`
152
152
  - **Parenthetical stage direction is ignored** — `(angrily)` is read as the word "angrily". Use stability/style instead.
@@ -230,7 +230,7 @@ Excited young hero: 18-28, high energy, mid-high pitch
230
230
  Cold villain: 30-50, neutral/theatrical, low-mid, slow with sharp consonants
231
231
  Mischievous trickster: theatrical, light, fast cadence
232
232
  Calm scholar: 30-50, neutral, mid, even cadence
233
- Scared / breathy: high stability=0.25, style=0.5
233
+ Scared / breathy: stability=0.25, style=0.5
234
234
  Robotic AI: stability=1.0, style=0.0
235
235
  Narrator cinematic: mid-deep, neutral/theatrical, even, very stable
236
236
  Narrator intimate: warmer mid pitch, lower stability for breath
@@ -250,9 +250,9 @@ Narrator intimate: warmer mid pitch, lower stability for breath
250
250
 
251
251
  ## Edge cases
252
252
 
253
- - **Line longer than ~1000 characters.** ElevenLabs caps per-call. Split at sentence boundaries, generate each, concatenate with `AudioStreamPlayer.queue` or chained `finished` signals.
253
+ - **Line longer than ~1000 characters.** ElevenLabs caps per-call. Split at sentence boundaries, generate each, and play them in order by chaining the player's `finished` signal.
254
254
  - **Mispronunciation of a fictional word.** Spell it phonetically: `Caelthorne` → `KEL-thorn` or `KAYL-thorn`. Or use SSML if the model supports it.
255
- - **Voice drifts in long lines.** Increase `similarity_boost` toward 0.9; or split.
255
+ - **Voice drifts in long lines.** Increase `similarityBoost` toward 0.9; or split.
256
256
  - **Need a non-English line.** `eleven_multilingual_v2` supports 29 languages. Just write in the target language; the same voice id works.
257
257
  - **User wants the line shorter on regen.** Edit the text first; don't try to compress with `speed` past 1.15 (artifacts).
258
258
  - **NPC bark variants.** Generate 3–5 variants of the same intent (`"They're at the gate!"`, `"Enemy approaching!"`, `"Look out!"`) and pick at random in code so the bark doesn't repeat.
@@ -266,10 +266,10 @@ Print the call (text, voice id, params, target path). User runs via the Summer d
266
266
  > Line `hodge_hold_the_line.mp3` wired to `NPC/VoiceLine` on the `Voice` bus. Cast bible updated. Next:
267
267
  > - Generate 3 bark variants of the same intent so the NPC doesn't sound like a recording.
268
268
  > - For the upcoming gate scene, run `/voice-line` with `text_to_dialogue` for the multi-turn exchange.
269
- > - Set up music ducking on the `Music` bus when `Voice` is active (one Tween or a `BusEffect Compressor` sidechained to `Voice`).
269
+ > - Set up music ducking on the `Music` bus when `Voice` is active (one Tween, or an `AudioEffectCompressor` on `Music` with `sidechain` set to `Voice`).
270
270
 
271
271
  ## See also
272
272
 
273
- - `audio/audio-direction` — Voice bus and ducking rules
274
- - `audio/sound-effect` — non-verbal vocal SFX (grunt, scream)
275
- - `audio/adaptive-music` — ducking integration
273
+ - `audio-direction` — Voice bus and ducking rules
274
+ - `sound-effect` — non-verbal vocal SFX (grunt, scream)
275
+ - `adaptive-music` — ducking integration
@@ -24,6 +24,7 @@ related:
24
24
  - skill/art-direction
25
25
  - skill/tune-performance
26
26
  - skill/ui-basics
27
+ - skill/compatibility-renderer-traps
27
28
  source: official
28
29
  license: MIT
29
30
  status: preview
@@ -17,7 +17,7 @@ Input is a candidate global position and global Euler rotation. The subject's cu
17
17
 
18
18
  Interpretation:
19
19
 
20
- - Physics overlap counts are lower bounds because Godot exposes no broadphase-completeness bit.
20
+ - Physics overlap counts are lower bounds because the physics server exposes no broadphase-completeness bit.
21
21
  - Any known obstruction makes `fits: false`.
22
22
  - Zero known physics overlaps can still yield `fits: null`; never coerce it to success.
23
23
  - `grounded`, signed `floorGap`, and support evidence are independent of overlap certainty. Claim physics-grounded only when `floorEvidence` is `physics` and `supportQueryComplete` is true; otherwise label the evidence approximate or incomplete.
@@ -42,7 +42,7 @@ This is one-dimensional arrangement evidence. It does not prove clearance on the
42
42
 
43
43
  ## `summer_navigation_probe`
44
44
 
45
- Iteration 0 is unready; iteration 1 and later can be queried. Layer-filtered snapped endpoints and the reported snap distances define what Godot actually tested. `ready: false` means unknown, not unreachable.
45
+ Iteration 0 is unready; iteration 1 and later can be queried. Layer-filtered snapped endpoints and the reported snap distances define what the engine actually tested. `ready: false` means unknown, not unreachable.
46
46
 
47
47
  Require both a reachable path and a small endpoint snap distance appropriate to the authored target.
48
48
  Probe every independent destination; one reachable subject does not validate the
@@ -66,9 +66,9 @@ This structure informs the task decomposition. Each task should produce self-con
66
66
  ### Task N: [Component Name]
67
67
 
68
68
  **Files:**
69
- - Create: `exact/path/to/file.py`
70
- - Modify: `exact/path/to/existing.py:123-145`
71
- - Test: `tests/exact/path/to/test.py`
69
+ - Create: `exact/path/to/file.gd`
70
+ - Modify: `exact/path/to/existing.gd:123-145`
71
+ - Test: `tests/exact/path/to/test_file.gd`
72
72
 
73
73
  - [ ] **Step 1: Write the failing test**
74
74
 
@@ -103,7 +103,7 @@ Expected: PASS
103
103
  - [ ] **Step 5: Commit**
104
104
 
105
105
  ```bash
106
- git add tests/path/test.py src/path/file.py
106
+ git add tests/unit/test_health.gd scripts/health.gd
107
107
  git commit -m "feat: add specific feature"
108
108
  ```
109
109
  ````
@@ -104,7 +104,7 @@ skills/
104
104
 
105
105
  ```markdown
106
106
  ---
107
- name: Skill-Name-With-Hyphens
107
+ name: skill-name-with-hyphens
108
108
  description: Use when [specific triggering conditions and symptoms]
109
109
  ---
110
110
 
@@ -260,7 +260,7 @@ You: Searching...
260
260
 
261
261
  **Verification:**
262
262
  ```bash
263
- wc -w skills/path/SKILL.md
263
+ wc -w library/skills/<slug>/SKILL.md
264
264
  # getting-started workflows: aim for <150 each
265
265
  # Other frequently-loaded: aim for <200 total
266
266
  ```
@@ -287,7 +287,7 @@ Use skill name only, with explicit requirement markers:
287
287
 
288
288
  **Check the skill exists before you point at it.** The registry of shipped skills is `registry/generated/skills-registry.json` (generated from `library/skills/`); `summer skills list` prints it. A `REQUIRED SUB-SKILL` pointing at a skill that was never shipped is worse than no cross-reference: the reader stops and looks for something that does not exist.
289
289
 
290
- **Why no @ links:** `@` syntax force-loads files immediately, consuming 200k+ context before you need them.
290
+ **Why no @ links:** `@` syntax force-loads files immediately and spends context before you need them.
291
291
 
292
292
  ## Flowchart Usage
293
293
 
@@ -549,7 +549,7 @@ Run same scenarios WITH skill. Agent should now comply.
549
549
 
550
550
  Agent found new rationalization? Add explicit counter. Re-test until bulletproof.
551
551
 
552
- **Testing methodology:** See @testing-skills-with-subagents.md for the complete testing methodology:
552
+ **Testing methodology:** See `testing-skills-with-subagents.md` in this directory for the complete testing methodology:
553
553
  - How to write pressure scenarios
554
554
  - Pressure types (time, sunk cost, authority, exhaustion)
555
555
  - Plugging holes systematically
@@ -633,10 +633,10 @@ Deploying untested skills = deploying untested code. It's a violation of quality
633
633
  How future Claude finds your skill:
634
634
 
635
635
  1. **Encounters problem** ("tests are flaky")
636
- 3. **Finds SKILL** (description matches)
637
- 4. **Scans overview** (is this relevant?)
638
- 5. **Reads patterns** (quick reference table)
639
- 6. **Loads example** (only when implementing)
636
+ 2. **Finds SKILL** (description matches)
637
+ 3. **Scans overview** (is this relevant?)
638
+ 4. **Reads patterns** (quick reference table)
639
+ 5. **Loads example** (only when implementing)
640
640
 
641
641
  **Optimize for this flow** - put searchable terms early and often.
642
642
 
@@ -0,0 +1,73 @@
1
+ id: tool/capture-gameplay
2
+ kind: tool
3
+ version: 1.0.0
4
+ summary: Capture real gameplay frames (PNG, HUD included) in Summer Engine's offscreen verify instance, without a running editor, e.g. store screenshots.
5
+ use_when:
6
+ - '"take gameplay screenshots for my store page"'
7
+ - '"I need screenshots but the editor is not open"'
8
+ - '"capture a 1920x1080 frame of my game"'
9
+ - collecting real gameplay screenshots for summer_store_set_art desktop.screenshots or mobile.screenshots
10
+ do_not_use_when:
11
+ - the editor is open and the game is running — tool/screenshot with target game shows the live game
12
+ - key art, covers or icons — those are generated art, not gameplay frames
13
+ - checking an interaction with inputs and assertions — RunVerification through tool/batch
14
+ facets:
15
+ lifecycle:
16
+ - launch
17
+ - build
18
+ domains:
19
+ - creator
20
+ - headless
21
+ compatibility:
22
+ engine: ">=4.6"
23
+ source: official
24
+ license: MIT
25
+ status: preview
26
+ aliases:
27
+ - summer_capture_gameplay
28
+ implementation:
29
+ module: src/core/capabilities/capture-gameplay.ts
30
+ export: captureGameplay
31
+ surfaces:
32
+ mcp:
33
+ tool_name: summer_capture_gameplay
34
+ remote: true
35
+ input_schema:
36
+ type: object
37
+ properties:
38
+ project:
39
+ type: string
40
+ description: Project folder with project.godot. Defaults to the MCP's bound project, then the working directory.
41
+ scene:
42
+ type: string
43
+ description: Scene to start (res://... or uid://...). Default is the project's main scene, often a title menu; pass the gameplay scene for gameplay frames.
44
+ resolution:
45
+ type: string
46
+ description: Window size WIDTHxHEIGHT (default 1920x1080; 1080x1920 for portrait).
47
+ frames:
48
+ type: integer
49
+ minimum: 1
50
+ maximum: 10
51
+ description: Frames to save (default 1).
52
+ waitSeconds:
53
+ type: number
54
+ minimum: 0
55
+ maximum: 120
56
+ description: Seconds the game runs before the first frame (default 3).
57
+ intervalSeconds:
58
+ type: number
59
+ minimum: 0.1
60
+ maximum: 60
61
+ description: Seconds between frames (default 1).
62
+ out:
63
+ type: string
64
+ description: Output folder. Defaults to <project>/.summer/captures/<time>/ (ignored by git).
65
+ additionalProperties: false
66
+ authority:
67
+ filesystem: true
68
+ editor_mutation: false
69
+ network: false
70
+ credentials: false
71
+ publish: false
72
+ evidence_checks:
73
+ - none
@@ -1,12 +1,12 @@
1
1
  id: tool/creator-publish
2
2
  kind: tool
3
3
  version: 1.1.0
4
- summary: "Deprecated: publishes a .pck to the legacy Summercraft API. Use summer_export_game, then summer_publish_build, to upload to summer.games."
4
+ summary: "Deprecated: publishes a .pck to the legacy creator API. Use summer_export_game, then summer_publish_build, to upload to summer.games."
5
5
  use_when:
6
- - releasing a user-approved build to a Summercraft channel
7
- - '"ship this exported build to the live channel"'
8
- - '"release version 1.2.0 of my game"'
6
+ - an old project that still publishes a .pck to the legacy Summercraft creator channel with an sc_ creator token
7
+ - a ~/.summer/config.json that names a legacy creator projectId and channel
9
8
  do_not_use_when:
9
+ - releasing a version on summer.games — summer_publish_build, then summer_store_submit (the owner approves)
10
10
  - uploading to summer.games — summer_export_game, then summer_publish_build
11
11
  - the user has not approved the exact version, digest, and channel
12
12
  - the game is not exported yet — export the .pck first (skill/export-and-ship)