summer-engine 3.4.0 → 3.5.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +5 -1
- package/.codex-plugin/plugin.json +5 -1
- package/.cursor-plugin/plugin.json +5 -1
- package/.factory-plugin/plugin.json +5 -1
- package/.opencode/INSTALL.md +8 -8
- package/.opencode/plugins/summer.js +2 -2
- package/AGENTS.md +7 -7
- package/CHANGELOG.md +37 -0
- package/GEMINI.md +1 -1
- package/NOTICE +1 -1
- package/README.md +35 -35
- package/assets/autopilot/run.sh +2 -2
- package/assets/navigation/web-routes.json +1 -1
- package/commands/gameskill.md +2 -2
- package/commands/summer.md +25 -25
- package/dist/cli/commands/open.d.ts +1 -1
- package/dist/cli/commands/run.d.ts +1 -1
- package/dist/cli/commands/run.js +1 -1
- package/dist/cli/commands/setup.js +24 -4
- package/dist/cli/commands/skills.js +2 -2
- package/dist/core/api-client.d.ts +5 -6
- package/dist/core/api-client.js +12 -15
- package/dist/core/auth.js +2 -2
- package/dist/core/capabilities/asset-import.d.ts +0 -1
- package/dist/core/capabilities/camera-view.d.ts +1 -1
- package/dist/core/capabilities/camera-view.js +2 -2
- package/dist/core/capabilities/capture-gameplay.d.ts +72 -7
- package/dist/core/capabilities/capture-gameplay.js +386 -25
- package/dist/core/capabilities/connect-signal.d.ts +1 -2
- package/dist/core/capabilities/connect-signal.js +1 -2
- package/dist/core/capabilities/console-read.d.ts +2 -2
- package/dist/core/capabilities/console-read.js +2 -2
- package/dist/core/capabilities/engine-receipt.d.ts +5 -7
- package/dist/core/capabilities/engine-receipt.js +7 -9
- package/dist/core/capabilities/export-engine-version.d.ts +7 -0
- package/dist/core/capabilities/export-engine-version.js +9 -0
- package/dist/core/capabilities/export-game.d.ts +4 -0
- package/dist/core/capabilities/export-game.js +53 -10
- package/dist/core/capabilities/export-presets.d.ts +1 -1
- package/dist/core/capabilities/export-presets.js +1 -1
- package/dist/core/capabilities/fabricate-mesh.d.ts +2 -3
- package/dist/core/capabilities/fabricate-mesh.js +2 -3
- package/dist/core/capabilities/frame-quality.d.ts +4 -4
- package/dist/core/capabilities/frame-quality.js +4 -4
- package/dist/core/capabilities/grep.d.ts +1 -1
- package/dist/core/capabilities/grep.js +1 -1
- package/dist/core/capabilities/image-generation.d.ts +12 -2
- package/dist/core/capabilities/image-generation.js +31 -2
- package/dist/core/capabilities/navigation/open.d.ts +1 -1
- package/dist/core/capabilities/navigation/open.js +1 -1
- package/dist/core/capabilities/navigation/render-product-map.js +1 -1
- package/dist/core/capabilities/navigation/targets.js +2 -2
- package/dist/core/capabilities/placement-batch.d.ts +1 -1
- package/dist/core/capabilities/placement-batch.js +2 -2
- package/dist/core/capabilities/play-determinism.d.ts +1 -1
- package/dist/core/capabilities/play-determinism.js +1 -1
- package/dist/core/capabilities/publish-build.d.ts +1 -1
- package/dist/core/capabilities/publish-build.js +21 -9
- package/dist/core/capabilities/publish-download.d.ts +1 -2
- package/dist/core/capabilities/publish-download.js +2 -3
- package/dist/core/capabilities/replace-node.d.ts +1 -3
- package/dist/core/capabilities/replace-node.js +1 -3
- package/dist/core/capabilities/runtime-control.d.ts +5 -7
- package/dist/core/capabilities/runtime-control.js +7 -9
- package/dist/core/capabilities/scene-batch.d.ts +1 -1
- package/dist/core/capabilities/scene-batch.js +1 -1
- package/dist/core/capabilities/scene-kind.js +1 -1
- package/dist/core/capabilities/scene-readback.d.ts +3 -4
- package/dist/core/capabilities/scene-readback.js +3 -4
- package/dist/core/capabilities/scene-script.d.ts +2 -2
- package/dist/core/capabilities/scene-script.js +2 -2
- package/dist/core/capabilities/seeing/shot-store.d.ts +1 -1
- package/dist/core/capabilities/seeing/shot-store.js +1 -1
- package/dist/core/capabilities/summer-bundle.d.ts +11 -3
- package/dist/core/capabilities/summer-bundle.js +21 -3
- package/dist/core/capabilities/surface-snap.d.ts +1 -1
- package/dist/core/capabilities/surface-snap.js +1 -1
- package/dist/core/capabilities/tool-dispatch.js +14 -3
- package/dist/core/capabilities/ui-control.d.ts +1 -2
- package/dist/core/capabilities/ui-control.js +1 -2
- package/dist/core/capabilities/world-snapshot.d.ts +1 -1
- package/dist/core/capabilities/world-snapshot.js +1 -1
- package/dist/core/capability-skew.d.ts +2 -3
- package/dist/core/capability-skew.js +4 -5
- package/dist/core/feedback/client.js +1 -1
- package/dist/core/launch-posture.d.ts +3 -3
- package/dist/core/launch-posture.js +3 -3
- package/dist/core/library-read.d.ts +7 -0
- package/dist/core/library-read.js +60 -9
- package/dist/core/library-search.d.ts +2 -0
- package/dist/core/templates.d.ts +1 -2
- package/dist/core/templates.js +1 -2
- package/dist/installer/agent-config.d.ts +25 -0
- package/dist/installer/agent-config.js +114 -3
- package/dist/installer/agent-table.d.ts +12 -0
- package/dist/installer/agent-table.js +9 -0
- package/dist/mcp/server.d.ts +2 -2
- package/dist/mcp/server.js +2 -2
- package/dist/mcp/tools/creator-tools.js +33 -4
- package/dist/mcp/tools/debug-tools.js +1 -1
- package/dist/mcp/tools/generate-tools.js +18 -37
- package/dist/mcp/tools/library-tools.d.ts +2 -1
- package/dist/mcp/tools/library-tools.js +1 -0
- package/dist/mcp/tools/navigation-tools.d.ts +1 -1
- package/dist/mcp/tools/navigation-tools.js +1 -1
- package/dist/mcp/tools/spatial-tools.js +1 -1
- package/dist/mcp/tools/visual-tools.js +2 -2
- package/dist/mcp/tools/with-engine.d.ts +1 -2
- package/dist/mcp/tools/with-engine.js +1 -2
- package/gemini-extension.json +5 -1
- package/hooks/session-start.sh +2 -2
- package/integrations/README.md +70 -76
- package/integrations/claude/README.md +0 -3
- package/integrations/codex/README.md +1 -2
- package/integrations/copilot-jetbrains/README.md +1 -1
- package/integrations/cursor/README.md +1 -2
- package/integrations/factory/README.md +15 -11
- package/integrations/mistral-vibe/README.md +1 -1
- package/integrations/opencode/README.md +1 -1
- package/integrations/roo-code/README.md +1 -1
- package/integrations/rovo-dev/README.md +1 -1
- package/integrations/trae/README.md +1 -1
- package/integrations/windsurf/README.md +3 -3
- package/library/references/collaborative-protocol/collaborative-protocol.md +5 -5
- package/library/references/gd-style/gd-style.md +4 -6
- package/library/references/godot-version/godot-version.md +3 -3
- package/library/references/headless-routing/headless-routing.md +2 -2
- package/library/references/mcp-fresh-chat-playbook/mcp-fresh-chat-playbook.md +2 -2
- package/library/references/mcp-tools-reference/mcp-tools-reference.md +16 -15
- package/library/references/product-map/product-map.md +1 -1
- package/library/references/public-surface-language/public-surface-language.md +1 -1
- package/library/references/summer-folder/summer-folder.md +1 -1
- package/library/skills/3d-lighting/SKILL.md +4 -4
- package/library/skills/README.md +16 -6
- package/library/skills/adaptive-music/SKILL.md +7 -7
- package/library/skills/ai-characters-in-games/SKILL.md +1 -1
- package/library/skills/ambient-bed/SKILL.md +12 -14
- package/library/skills/animated-loop/SKILL.md +42 -42
- package/library/skills/animation-tree/SKILL.md +6 -6
- package/library/skills/art-direction/SKILL.md +8 -11
- package/library/skills/asset-strategy/SKILL.md +3 -3
- package/library/skills/audio-direction/SKILL.md +8 -10
- package/library/skills/auto-fire-targeting/SKILL.md +4 -3
- package/library/skills/bounded-engine-runs/SKILL.md +6 -7
- package/library/skills/brainstorm-game/SKILL.md +5 -5
- package/library/skills/brainstorming/SKILL.md +9 -15
- package/library/skills/celeste-momentum-platforming/SKILL.md +8 -13
- package/library/skills/celeste-momentum-platforming/resource.yaml +1 -1
- package/library/skills/character-animation-wiring/SKILL.md +2 -2
- package/library/skills/character-model/SKILL.md +15 -26
- package/library/skills/character-movement/SKILL.md +1 -1
- package/library/skills/character-movement/references/movement-3d.md +1 -1
- package/library/skills/character-portrait/SKILL.md +4 -4
- package/library/skills/cinematic-cutscene/SKILL.md +38 -38
- package/library/skills/combat-basics/SKILL.md +1 -1
- package/library/skills/compatibility-renderer-traps/SKILL.md +2 -2
- package/library/skills/concept-art/SKILL.md +3 -3
- package/library/skills/create-asset-sheet/SKILL.md +12 -31
- package/library/skills/debug/SKILL.md +5 -4
- package/library/skills/debugging-game-feel/SKILL.md +1 -4
- package/library/skills/debugging-game-feel/resource.yaml +1 -1
- package/library/skills/design-level/SKILL.md +5 -5
- package/library/skills/design-mechanic/SKILL.md +6 -6
- package/library/skills/design-npc/SKILL.md +8 -15
- package/library/skills/diagnosing-perf-regressions/SKILL.md +5 -10
- package/library/skills/dispatching-parallel-agents/SKILL.md +1 -19
- package/library/skills/environment-kit/SKILL.md +5 -5
- package/library/skills/export-and-ship/SKILL.md +24 -25
- package/library/skills/export-and-ship/resource.yaml +2 -1
- package/library/skills/fabricating-assets/SKILL.md +1 -1
- package/library/skills/facial-and-lipsync/SKILL.md +5 -5
- package/library/skills/fps-controller/SKILL.md +17 -16
- package/library/skills/fps-controller/resource.yaml +0 -2
- package/library/skills/game-feel/SKILL.md +6 -7
- package/library/skills/gameskill/SKILL.md +3 -3
- package/library/skills/gdscript-patterns/SKILL.md +3 -3
- package/library/skills/generate-motion/SKILL.md +5 -22
- package/library/skills/godogen-visual-proof-game-generation/SKILL.md +72 -90
- package/library/skills/godogen-visual-proof-game-generation/resource.yaml +0 -1
- package/library/skills/grow-analytics/SKILL.md +21 -0
- package/library/skills/grow-analytics/resource.yaml +27 -0
- package/library/skills/headless-scripting/SKILL.md +8 -8
- package/library/skills/instantiate-asset-pack/SKILL.md +7 -3
- package/library/skills/investigating-bugs/SKILL.md +3 -11
- package/library/skills/investigating-bugs/condition-based-waiting.md +0 -10
- package/library/skills/investigating-bugs/root-cause-tracing.md +0 -8
- package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +15 -15
- package/library/skills/lumera-single-image-scene-reconstruction/resource.yaml +0 -1
- package/library/skills/make-game/SKILL.md +3 -5
- package/library/skills/make-game/references/2d-platformer.md +1 -1
- package/library/skills/multiplayer-project/SKILL.md +1 -1
- package/library/skills/multiplayer-testing/SKILL.md +4 -4
- package/library/skills/music-track/SKILL.md +40 -38
- package/library/skills/new-project/SKILL.md +4 -6
- package/library/skills/organic-model/SKILL.md +9 -9
- package/library/skills/pixel-art/SKILL.md +6 -6
- package/library/skills/play/SKILL.md +3 -4
- package/library/skills/playtesting-a-feature/SKILL.md +4 -6
- package/library/skills/procedural-animation/SKILL.md +10 -11
- package/library/skills/prop-model/SKILL.md +4 -4
- package/library/skills/psx-retro-rendering/SKILL.md +20 -20
- package/library/skills/psx-retro-rendering/resource.yaml +2 -3
- package/library/skills/publish-your-game/SKILL.md +21 -0
- package/library/skills/publish-your-game/resource.yaml +29 -0
- package/library/skills/realtime-wet-surfaces/SKILL.md +15 -15
- package/library/skills/realtime-wet-surfaces/resource.yaml +1 -2
- package/library/skills/remote-deploy/SKILL.md +20 -21
- package/library/skills/retarget/SKILL.md +19 -23
- package/library/skills/running-in-the-cloud/SKILL.md +5 -5
- package/library/skills/scene-composition/SKILL.md +5 -5
- package/library/skills/scene-hierarchy-design/SKILL.md +3 -3
- package/library/skills/scene-hierarchy-design/resource.yaml +0 -1
- package/library/skills/scene-scripting/SKILL.md +3 -3
- package/library/skills/scene-to-level/SKILL.md +28 -31
- package/library/skills/skill-create/SKILL.md +1 -1
- package/library/skills/skill-improve/SKILL.md +9 -9
- package/library/skills/skill-test/SKILL.md +10 -10
- package/library/skills/skintokens-auto-rigging/SKILL.md +18 -18
- package/library/skills/skintokens-auto-rigging/resource.yaml +3 -3
- package/library/skills/skybox-panorama/SKILL.md +8 -9
- package/library/skills/sound-effect/SKILL.md +19 -19
- package/library/skills/spatial-placement/SKILL.md +2 -2
- package/library/skills/spatial-placement/references/kit-placement-tools.md +12 -22
- package/library/skills/sprite-sheet/SKILL.md +10 -10
- package/library/skills/store-art/SKILL.md +23 -0
- package/library/skills/store-art/resource.yaml +30 -0
- package/library/skills/store-listing/SKILL.md +21 -0
- package/library/skills/store-listing/resource.yaml +25 -0
- package/library/skills/summer-analytics/SKILL.md +3 -3
- package/library/skills/summer-analytics/resource.yaml +1 -0
- package/library/skills/summer-friends/SKILL.md +10 -10
- package/library/skills/summer-leaderboards/SKILL.md +6 -6
- package/library/skills/summer-match-results/SKILL.md +13 -13
- package/library/skills/summer-matchmaking/SKILL.md +11 -11
- package/library/skills/summer-parties/SKILL.md +9 -9
- package/library/skills/summer-player-data/SKILL.md +12 -12
- package/library/skills/summer-store/SKILL.md +6 -6
- package/library/skills/summer-world-chat/SKILL.md +9 -9
- package/library/skills/summer-world-saves/SKILL.md +7 -7
- package/library/skills/text-to-motion/rigging-for-text-motion.md +1 -1
- package/library/skills/tileable-texture/SKILL.md +1 -1
- package/library/skills/trailer-shot/SKILL.md +36 -36
- package/library/skills/tune-performance/SKILL.md +13 -13
- package/library/skills/tune-performance/resource.yaml +1 -1
- package/library/skills/ui-graphics/SKILL.md +7 -7
- package/library/skills/use-widget-asset/SKILL.md +7 -7
- package/library/skills/using-summer/SKILL.md +5 -7
- package/library/skills/vehicle-model/SKILL.md +6 -7
- package/library/skills/vehicle-model/resource.yaml +2 -2
- package/library/skills/verification-before-completion/SKILL.md +5 -6
- package/library/skills/vfx-dissolve/SKILL.md +4 -4
- package/library/skills/vfx-fire/SKILL.md +6 -6
- package/library/skills/vfx-fire/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/vfx-hit-spark/SKILL.md +4 -4
- package/library/skills/vfx-hit-spark/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/vfx-lightning/SKILL.md +5 -5
- package/library/skills/vfx-lightning/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/vfx-lightning/_building-blocks/trauma-shake-snippet.md +9 -3
- package/library/skills/vfx-magic-glow/SKILL.md +4 -4
- package/library/skills/vfx-magic-glow/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/vfx-muzzle-flash/SKILL.md +5 -5
- package/library/skills/vfx-muzzle-flash/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/vfx-muzzle-flash/_building-blocks/trauma-shake-snippet.md +9 -3
- package/library/skills/vfx-smoke/SKILL.md +5 -5
- package/library/skills/vfx-water-ripple/SKILL.md +2 -2
- package/library/skills/vfx-water-ripple/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/voice-line/SKILL.md +9 -9
- package/library/skills/world-building-3d/references/spatial-tools.md +2 -2
- package/library/skills/writing-plans/SKILL.md +4 -4
- package/library/skills/writing-skills/SKILL.md +8 -8
- package/library/tools/capture-gameplay/resource.yaml +66 -1
- package/library/tools/creator-publish/resource.yaml +4 -4
- package/library/tools/creator-releases/resource.yaml +5 -5
- package/library/tools/export-game/resource.yaml +3 -0
- package/library/tools/generate-image/resource.yaml +4 -2
- package/library/tools/publish-build/resource.yaml +5 -1
- package/package.json +1 -1
- package/registry/generated/counts.json +2 -2
- package/registry/generated/gemini-extension.json +5 -1
- package/registry/generated/index.json +280 -137
- package/registry/generated/marketplace.claude.json +1 -1
- package/registry/generated/plugin.claude.json +5 -1
- package/registry/generated/plugin.codex.json +5 -1
- package/registry/generated/plugin.cursor.json +5 -1
- package/registry/generated/plugin.factory.json +5 -1
- package/registry/generated/skills-index.md +16 -6
- package/registry/generated/skills-registry.json +57 -5
- package/registry/schemas/domains.json +1 -1
- package/registry/schemas/skill.schema.json +5 -0
|
@@ -108,12 +108,12 @@ extends TextureProgressBar
|
|
|
108
108
|
|
|
109
109
|
func _ready():
|
|
110
110
|
var tex = load(slice_url)
|
|
111
|
-
# The base / "under" texture is the same image —
|
|
111
|
+
# The base / "under" texture is the same image — the bar masks it
|
|
112
112
|
# to whatever value 0-100 we set.
|
|
113
113
|
texture_under = tex
|
|
114
114
|
texture_progress = tex
|
|
115
115
|
fill_mode = TextureProgressBar.FILL_LEFT_TO_RIGHT if orientation == "horizontal" else TextureProgressBar.FILL_TOP_TO_BOTTOM
|
|
116
|
-
# The fill rect tells
|
|
116
|
+
# The fill rect tells the bar which sub-region of the texture is the
|
|
117
117
|
# bar fill (vs the frame). Texture_progress_offset + stretch_margin_*
|
|
118
118
|
# form the inset.
|
|
119
119
|
var sw = tex.get_width()
|
|
@@ -160,7 +160,7 @@ In the pack, find the pair: `sliceMeta[currentIndex].pairWith` gives the other s
|
|
|
160
160
|
|
|
161
161
|
## Cut-offs and re-renders
|
|
162
162
|
|
|
163
|
-
If the detected `frameMargins` are obviously wrong (the dashed overlay in the wizard's lightbox shows the center area clipping into a corner ornament), the user should hit **Recreate (HD)** on that slice.
|
|
163
|
+
If the detected `frameMargins` are obviously wrong (the dashed overlay in the wizard's lightbox shows the center area clipping into a corner ornament), the user should hit **Recreate (HD)** on that slice. It regenerates cleanly — but the *margins themselves* don't get re-detected after upscale. Margins live on the original detection. The user can also manually edit them in code via the `patch_margin_*` properties after instantiating.
|
|
164
164
|
|
|
165
165
|
## Composite panels with sub-elements
|
|
166
166
|
|
|
@@ -171,16 +171,16 @@ When a slice has `parentSliceIndex` set, it came from a **Break-down** pass —
|
|
|
171
171
|
|
|
172
172
|
Pick based on whether your game needs the panel to stretch as one unit or whether each control needs independent interaction.
|
|
173
173
|
|
|
174
|
-
See **Composite Panels (Sliced Further)** below for the
|
|
174
|
+
See **Composite Panels (Sliced Further)** below for the fields the wizard emits (`isComposite`, `zOrder`) and the consume recipe.
|
|
175
175
|
|
|
176
176
|
## Composite Panels (Sliced Further)
|
|
177
177
|
|
|
178
|
-
The wizard's Break-down pass
|
|
178
|
+
The wizard's Break-down pass adds per-slice fields the runtime must understand:
|
|
179
179
|
|
|
180
180
|
| Field | Type | Meaning |
|
|
181
181
|
|---|---|---|
|
|
182
182
|
| `isComposite` | boolean | True on the **parent** slice — the flat preview image of the assembled panel. NOT a runtime asset. Filter it out on import unless the caller explicitly wants the preview thumbnail. |
|
|
183
|
-
| `zOrder` | number | Back-to-front paint order on children. Lower = behind.
|
|
183
|
+
| `zOrder` | number | Back-to-front paint order on children. Lower = behind. Maps to `CanvasItem.z_index`. |
|
|
184
184
|
| `parentSliceIndex` | number | Set on each child, points at the composite parent. Used to group children. |
|
|
185
185
|
|
|
186
186
|
The table above lists every field this skill reads; treat any other field in the pack manifest as opaque.
|
|
@@ -201,7 +201,7 @@ For the full instantiation flow (op JSON, examples), use `instantiate-asset-pack
|
|
|
201
201
|
|
|
202
202
|
### Legacy compatibility
|
|
203
203
|
|
|
204
|
-
Older packs
|
|
204
|
+
Older packs use different field names. Always fall back:
|
|
205
205
|
|
|
206
206
|
```
|
|
207
207
|
const zOrder = slice.zOrder ?? slice.layerIndex ?? packFileIndex;
|
|
@@ -36,14 +36,12 @@ If `CLAUDE.md` says "skip the brainstorm, just build it" and a skill says "alway
|
|
|
36
36
|
Two layers:
|
|
37
37
|
|
|
38
38
|
- **Skills** — discipline guides that fire on specific situations: brainstorming a game, designing a mechanic, building an FPS controller, debugging a crash, shipping a build. Each one is a SKILL.md you load via the Skill tool.
|
|
39
|
-
- **MCP tools** — `summer_*` tools that talk to the running Summer Engine on `localhost:6550`. Scene mutation (`summer_add_node`, `summer_set_prop`), inspection (`summer_get_scene_tree`, `summer_inspect_node`), play/diagnostics (`summer_play`, `summer_get_diagnostics`), asset import/generation (`summer_import_from_url`, `summer_generate_3d`), and
|
|
39
|
+
- **MCP tools** — `summer_*` tools that talk to the running Summer Engine on `localhost:6550`. Scene mutation (`summer_add_node`, `summer_set_prop`), inspection (`summer_get_scene_tree`, `summer_inspect_node`), play/diagnostics (`summer_play`, `summer_get_diagnostics`), asset import/generation (`summer_import_from_url`, `summer_generate_3d`), and the rest of the `summer_*` set.
|
|
40
40
|
|
|
41
41
|
**Scripting language:** The user is making a Summer game with the Summer SDK.
|
|
42
|
-
GDScript is the default creator language. Summer
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
string rather than turning that base into the product identity. You can write
|
|
46
|
-
game code in either:
|
|
42
|
+
GDScript is the default creator language. Summer Engine follows its upstream
|
|
43
|
+
technical base continuously, so confirm version-sensitive behavior from the
|
|
44
|
+
engine's own version string. You can write game code in either:
|
|
47
45
|
|
|
48
46
|
- **GDScript** (`.gd`) — the default. Best supported by Summer skills (see `gdscript-patterns`). Use this unless the user has explicitly chosen C#.
|
|
49
47
|
- **C#** (`.cs`) — supported by the shipped Mono build. The GDScript
|
|
@@ -150,7 +148,7 @@ Run `summer doctor` early in a fresh Summer session when setup, MCP tools, slash
|
|
|
150
148
|
npx clear-npx-cache && npx -y summer-engine@latest setup <agent> --yes --force
|
|
151
149
|
```
|
|
152
150
|
|
|
153
|
-
Use the dist-tag `summer doctor` recommends: `@latest` normally, `@next` (with `--channel next`) when this CLI was installed from the soaking release, otherwise the MCP server silently drops back to the older `latest`. Use the real agent slug from doctor or the current environment (`claude-code`, `codex`, `cursor`, `
|
|
151
|
+
Use the dist-tag `summer doctor` recommends: `@latest` normally, `@next` (with `--channel next`) when this CLI was installed from the soaking release, otherwise the MCP server silently drops back to the older `latest`. Use the real agent slug from doctor or the current environment (`claude-code`, `codex`, `cursor`, `antigravity`, `github-copilot`, `vscode-copilot`, `opencode`, etc.).
|
|
154
152
|
|
|
155
153
|
Why this exact command matters:
|
|
156
154
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vehicle-model
|
|
3
|
-
description: "Generate a hard-surface vehicle — car, spaceship, mech, boat, tank — static mesh with optional detail-texture pass, wired as
|
|
3
|
+
description: "Generate a hard-surface vehicle — car, spaceship, mech, boat, tank — static mesh with optional detail-texture pass, wired as VehicleBody3D or MeshInstance3D."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: 3d-assets
|
|
@@ -101,7 +101,7 @@ Nothing in the prompt text "triggers" multi-view. The phrase `front and 3/4 side
|
|
|
101
101
|
|
|
102
102
|
### 4. Confirm and call
|
|
103
103
|
|
|
104
|
-
> About to generate `red_race_car` via `hunyuan`, target ~25k tris, multi-angle ref.
|
|
104
|
+
> About to generate `red_race_car` via `hunyuan`, target ~25k tris, multi-angle ref. Uses credits, ~90s. OK?
|
|
105
105
|
|
|
106
106
|
```
|
|
107
107
|
summer_generate_3d(
|
|
@@ -145,7 +145,7 @@ This re-textures the existing mesh with sharper detail — panel lines, decals,
|
|
|
145
145
|
| Use case | Parent type | Notes |
|
|
146
146
|
|---|---|---|
|
|
147
147
|
| Player-driven (car, bike, hover) | `VehicleBody3D` (wheeled) or `RigidBody3D` (free physics) | Add `VehicleWheel3D` children for wheeled vehicles |
|
|
148
|
-
| Player-driven (spaceship, mech) | `RigidBody3D` or `CharacterBody3D` | Custom thrust / walk code
|
|
148
|
+
| Player-driven (spaceship, mech) | `RigidBody3D` or `CharacterBody3D` | Custom thrust / walk code (`character-movement` for walkers) |
|
|
149
149
|
| Background scenery (parked, flyby) | `MeshInstance3D` under a `Node3D` | No physics, no collision needed for distant traffic |
|
|
150
150
|
| Background traffic (moving but not interactive) | `Node3D` + `AnimationPlayer` driving the position | Cheap, no physics overhead |
|
|
151
151
|
|
|
@@ -161,7 +161,7 @@ summer_set_resource_property(scenePath="res://main.tscn", nodePath="./World/Race
|
|
|
161
161
|
summer_save_scene(scenePath="res://main.tscn")
|
|
162
162
|
```
|
|
163
163
|
|
|
164
|
-
A `.glb` cannot be assigned to `MeshInstance3D.mesh` — an imported `.glb` is a scene, not a `Mesh` (`ResourceLoader.get_recognized_extensions_for_type("Mesh")` on the shipped
|
|
164
|
+
A `.glb` cannot be assigned to `MeshInstance3D.mesh` — an imported `.glb` is a scene, not a `Mesh` (`ResourceLoader.get_recognized_extensions_for_type("Mesh")` on the shipped engine returns `["tres", "mesh", "res"]`, no `glb`). Instantiate it. Assigning a bare class name like `"BoxShape3D"` to a resource property auto-instantiates it, which is how you get a shape you can then size.
|
|
165
165
|
|
|
166
166
|
Every scene-mutating tool takes an explicit `scenePath`; node paths are relative to that scene's root (`./`); `summer_set_prop`'s property argument is `key`; and `summer_set_resource_property` needs all five of `scenePath`, `nodePath`, `resourceProperty`, `subProperty`, `value`.
|
|
167
167
|
|
|
@@ -185,7 +185,7 @@ summer_save_scene(scenePath="res://main.tscn")
|
|
|
185
185
|
## Edge cases
|
|
186
186
|
|
|
187
187
|
- **Tracked vehicle (tank).** AI mesh-gen handles the hull but the tracks come back as a fused ring. Generate the hull only, then add tracks as a separate `prop-model` (or use a tiled texture on a torus). For animation, scroll the track texture's UV.
|
|
188
|
-
- **Articulated vehicle (mech with shoulders, hips, knees).** The mesh is one piece — joints aren't separated. For animated mechs, treat as a humanoid: generate as `character-model` with the rig pass, then animate
|
|
188
|
+
- **Articulated vehicle (mech with shoulders, hips, knees).** The mesh is one piece — joints aren't separated. For animated mechs, treat as a humanoid: generate as `character-model` with the rig pass, then animate with `text-to-motion` (prompt "walks heavily").
|
|
189
189
|
- **Vehicle with rotor (helicopter, drone).** Generate without rotor, then add the rotor as a separate `prop-model` and parent it. Spin via code in `_process`.
|
|
190
190
|
- **Open-top vehicle (convertible, jeep).** Specify "open top, no roof" — defaults often add a roof.
|
|
191
191
|
- **The user wants the cockpit interior visible.** Generate exterior here, then a separate `prop-model` for the interior, and switch meshes when the camera enters first-person view.
|
|
@@ -202,7 +202,7 @@ summer_save_scene(scenePath="res://main.tscn")
|
|
|
202
202
|
After the vehicle is wired:
|
|
203
203
|
|
|
204
204
|
> `race_car.glb` placed at `./World/RaceCar` as a VehicleBody3D. Next:
|
|
205
|
-
> - **Vehicle controls:** WASD steering / accel —
|
|
205
|
+
> - **Vehicle controls:** WASD steering / accel — write them with `engine_force`, `steering`, and `brake` on VehicleBody3D.
|
|
206
206
|
> - **Driver character:** generate via `character-model` and parent to the seat position.
|
|
207
207
|
> - **Engine sound + tire screech:** `sound-effect` for one-shots, `ambient-bed` for the engine loop.
|
|
208
208
|
> - **Particles:** exhaust smoke, dust trail, sparks on collision — `vfx-smoke` / `vfx-hit-spark` or built-in GPUParticles3D.
|
|
@@ -212,5 +212,4 @@ After the vehicle is wired:
|
|
|
212
212
|
- `character-model` — for the driver/pilot.
|
|
213
213
|
- `prop-model` — for separable parts (rotors, decals as decals, modular kit pieces).
|
|
214
214
|
- `asset-strategy` — meta-router.
|
|
215
|
-
- `fps-controller` — for player-driven vehicle input wiring.
|
|
216
215
|
- `../../references/mcp-tools-reference/mcp-tools-reference.md` — `summer_generate_3d` schema, including `kind: "texture"` for the secondary detail pass.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
id: skill/vehicle-model
|
|
2
2
|
kind: skill
|
|
3
3
|
version: 1.0.3
|
|
4
|
-
summary: Generate a hard-surface vehicle — car, spaceship, mech, boat, tank — static mesh with optional detail-texture pass, wired as
|
|
4
|
+
summary: Generate a hard-surface vehicle — car, spaceship, mech, boat, tank — static mesh with optional detail-texture pass, wired as VehicleBody3D or MeshInstance3D.
|
|
5
5
|
use_when:
|
|
6
6
|
- generating a hard-surface vehicle — car, motorcycle, spaceship, hover bike, boat, mech, tank, helicopter
|
|
7
|
-
- a racing, flying, or combat game needs a hard-surface vehicle mesh as a
|
|
7
|
+
- a racing, flying, or combat game needs a hard-surface vehicle mesh as a VehicleBody3D or MeshInstance3D
|
|
8
8
|
facets:
|
|
9
9
|
lifecycle:
|
|
10
10
|
- build
|
|
@@ -109,12 +109,11 @@ Bad: Trust agent report
|
|
|
109
109
|
|
|
110
110
|
## Why This Matters
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
-
|
|
114
|
-
- Undefined functions
|
|
115
|
-
- Missing requirements
|
|
116
|
-
- Time
|
|
117
|
-
- Violates: "Honesty is a core value. If you lie, you'll be replaced."
|
|
112
|
+
False completion claims cost trust and time:
|
|
113
|
+
- The user stops believing your reports.
|
|
114
|
+
- Undefined functions ship and crash.
|
|
115
|
+
- Missing requirements ship as incomplete features.
|
|
116
|
+
- Time goes to redirecting and rework.
|
|
118
117
|
|
|
119
118
|
## When To Apply
|
|
120
119
|
|
|
@@ -25,8 +25,8 @@ The dissolve shader samples 3D noise per fragment and clips pixels whose noise v
|
|
|
25
25
|
|
|
26
26
|
## When NOT to use
|
|
27
27
|
|
|
28
|
-
- The user wants *fire* on the object that doesn't consume it — use `fire`, not dissolve. Dissolve makes the mesh disappear; fire just sits on top.
|
|
29
|
-
- The user wants a particle-driven ash cloud as the object disappears — pair this with `smoke` (recolor to ash gray) spawned at the dissolving mesh's bounds.
|
|
28
|
+
- The user wants *fire* on the object that doesn't consume it — use `vfx-fire`, not dissolve. Dissolve makes the mesh disappear; fire just sits on top.
|
|
29
|
+
- The user wants a particle-driven ash cloud as the object disappears — pair this with `vfx-smoke` (recolor to ash gray) spawned at the dissolving mesh's bounds.
|
|
30
30
|
- The user wants a fade-out via alpha (cheap, no shader) — set `transparency = TRANSPARENCY_ALPHA` and tween `albedo_color.a` to 0. Dissolve is better but more expensive.
|
|
31
31
|
- The user wants the *world* to dissolve in for a level transition — that's a screen-space post-process, not this per-mesh recipe.
|
|
32
32
|
- The character has skinned mesh + multiple materials — this works but you have to override every material slot. Confirm with user; consider a fade-out instead.
|
|
@@ -307,7 +307,7 @@ noise_scale = 3.0
|
|
|
307
307
|
|
|
308
308
|
### thanos-snap
|
|
309
309
|
|
|
310
|
-
Fast, fine grain, blue edge for the cosmic feel. Pair with `smoke` in pale gray for ash particles rising.
|
|
310
|
+
Fast, fine grain, blue edge for the cosmic feel. Pair with `vfx-smoke` in pale gray for ash particles rising.
|
|
311
311
|
|
|
312
312
|
```
|
|
313
313
|
duration = 0.8
|
|
@@ -319,7 +319,7 @@ noise_scale = 8.0
|
|
|
319
319
|
|
|
320
320
|
### holy-banish
|
|
321
321
|
|
|
322
|
-
Slow, white edge, big halo. Add `magic-glow` underneath for a beam of light.
|
|
322
|
+
Slow, white edge, big halo. Add `vfx-magic-glow` underneath for a beam of light.
|
|
323
323
|
|
|
324
324
|
```
|
|
325
325
|
duration = 2.5
|
|
@@ -19,14 +19,14 @@ Fire in games is almost never a video clip and never an AI-generated sprite. It'
|
|
|
19
19
|
- "Make a campfire / bonfire / hearth flame."
|
|
20
20
|
- "Light the brazier."
|
|
21
21
|
- "I need a candle flame on this candlestick."
|
|
22
|
-
- "The dragon needs a flame breath" (use this for the persistent emitter; pair with a one-shot `muzzle-flash` for the burst).
|
|
22
|
+
- "The dragon needs a flame breath" (use this for the persistent emitter; pair with a one-shot `vfx-muzzle-flash` for the burst).
|
|
23
23
|
- The player set something on fire and you need a continuous, physically-anchored flame.
|
|
24
24
|
|
|
25
25
|
## When NOT to use
|
|
26
26
|
|
|
27
|
-
- The user wants an object to *burn away* (mesh disintegrating with a fire edge) — route to `dissolve`. Fire is a separate effect; pair them.
|
|
28
|
-
- The user wants smoke without flame — go straight to `smoke`. (Most fires want a smoke trail above; spawn this recipe and add `smoke` on top.)
|
|
29
|
-
- The user wants a one-frame muzzle flash from a gun — that's `muzzle-flash`, not fire.
|
|
27
|
+
- The user wants an object to *burn away* (mesh disintegrating with a fire edge) — route to `vfx-dissolve`. Fire is a separate effect; pair them.
|
|
28
|
+
- The user wants smoke without flame — go straight to `vfx-smoke`. (Most fires want a smoke trail above; spawn this recipe and add `vfx-smoke` on top.)
|
|
29
|
+
- The user wants a one-frame muzzle flash from a gun — that's `vfx-muzzle-flash`, not fire.
|
|
30
30
|
- The user wants 2D fire on a UI element — use `canvas_item` shader; this recipe is `spatial`/`particles`.
|
|
31
31
|
- The user wants stylized magic flame (blue, purple, ethereal) — use this recipe and load the `magic-fire` variant in the cookbook below.
|
|
32
32
|
|
|
@@ -397,7 +397,7 @@ OmniLight3D: light_energy = 1.6, omni_range = 6.0
|
|
|
397
397
|
|
|
398
398
|
### bonfire
|
|
399
399
|
|
|
400
|
-
Wide, tall, hungry. Pair with `smoke` directly above.
|
|
400
|
+
Wide, tall, hungry. Pair with `vfx-smoke` directly above.
|
|
401
401
|
|
|
402
402
|
```
|
|
403
403
|
particle_count = 256
|
|
@@ -442,7 +442,7 @@ OmniLight3D: light_color = Color(0.40, 0.65, 1.0), light_energy = 2.4
|
|
|
442
442
|
## Anti-patterns
|
|
443
443
|
|
|
444
444
|
- **Spatial-only shader on the visual quad.** It still works, but you forgot `blend_add` + `unshaded` and the flame looks like a flat orange triangle in shadow. Always: `render_mode unshaded, blend_add, depth_draw_never;`.
|
|
445
|
-
- **Looping a one-shot emitter.** `one_shot = false` for fire (continuous). One-shot is for `muzzle-flash` and `hit-spark`.
|
|
445
|
+
- **Looping a one-shot emitter.** `one_shot = false` for fire (continuous). One-shot is for `vfx-muzzle-flash` and `vfx-hit-spark`.
|
|
446
446
|
- **Missing `cull_disabled`.** Particles billboard toward camera; if you cull backfaces, the flame disappears at certain angles.
|
|
447
447
|
- **`depth_draw_opaque` on the visual material.** You'll z-fight with anything inside the flame (the torch handle). Use `depth_draw_never`.
|
|
448
448
|
- **OmniLight3D parented under the GPUParticles3D.** The particles emit in local space; the light moves with them. Sibling, not child.
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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
|
-
|
|
29
|
-
camera.rotation.
|
|
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` —
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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
|
-
|
|
29
|
-
camera.rotation.
|
|
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
|
|
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
|
|
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
|