summer-engine 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/.claude-plugin/plugin.json +2 -1
  2. package/.codex-plugin/plugin.json +3 -2
  3. package/.cursor-plugin/plugin.json +2 -1
  4. package/.opencode/INSTALL.md +1 -1
  5. package/.opencode/plugins/summer.js +1 -1
  6. package/AGENTS.md +4 -4
  7. package/CHANGELOG.md +10 -0
  8. package/GEMINI.md +5 -4
  9. package/README.md +58 -19
  10. package/assets/autopilot/README.md +51 -0
  11. package/assets/autopilot/autopilot.gd +222 -0
  12. package/assets/autopilot/probe_base.gd +262 -0
  13. package/assets/autopilot/run.sh +78 -0
  14. package/commands/gameskill.md +11 -2
  15. package/dist/bin/summer.js +8 -0
  16. package/dist/commands/config.d.ts +2 -0
  17. package/dist/commands/config.js +53 -0
  18. package/dist/commands/create.d.ts +1 -0
  19. package/dist/commands/create.js +38 -6
  20. package/dist/commands/list.js +1 -1
  21. package/dist/commands/login.d.ts +19 -0
  22. package/dist/commands/login.js +123 -36
  23. package/dist/commands/logout.js +3 -16
  24. package/dist/commands/logs.d.ts +2 -0
  25. package/dist/commands/logs.js +19 -0
  26. package/dist/commands/mcp.js +7 -2
  27. package/dist/commands/open.js +1 -1
  28. package/dist/commands/publish.d.ts +2 -0
  29. package/dist/commands/publish.js +20 -0
  30. package/dist/commands/releases.d.ts +2 -0
  31. package/dist/commands/releases.js +20 -0
  32. package/dist/commands/run.js +1 -1
  33. package/dist/lib/api-client.d.ts +4 -2
  34. package/dist/lib/api-client.js +28 -4
  35. package/dist/lib/auth.d.ts +40 -12
  36. package/dist/lib/auth.js +173 -37
  37. package/dist/lib/cloud/engine-bridge.d.ts +17 -4
  38. package/dist/lib/cloud/engine-bridge.js +32 -6
  39. package/dist/lib/config.d.ts +20 -0
  40. package/dist/lib/config.js +142 -0
  41. package/dist/lib/creator.d.ts +93 -0
  42. package/dist/lib/creator.js +393 -0
  43. package/dist/lib/engine.d.ts +35 -2
  44. package/dist/lib/engine.js +240 -6
  45. package/dist/lib/public-surface-paths.d.ts +13 -0
  46. package/dist/lib/public-surface-paths.js +42 -0
  47. package/dist/lib/skills-registry.d.ts +8 -0
  48. package/dist/lib/skills-registry.js +9 -0
  49. package/dist/lib/store.d.ts +14 -0
  50. package/dist/lib/store.js +145 -0
  51. package/dist/lib/summer-compatibility.d.ts +6 -0
  52. package/dist/lib/summer-compatibility.js +22 -0
  53. package/dist/mcp/server.d.ts +8 -1
  54. package/dist/mcp/server.js +25 -4
  55. package/dist/mcp/tools/creator-tools.d.ts +2 -0
  56. package/dist/mcp/tools/creator-tools.js +105 -0
  57. package/dist/mcp/tools/generate-tools.js +16 -6
  58. package/dist/mcp/tools/project-tools.js +12 -7
  59. package/dist/mcp/tools/scene-tools.js +6 -6
  60. package/dist/mcp/tools/visual-tools.js +4 -3
  61. package/hooks/pre-commit-doctor.sh +0 -0
  62. package/hooks/run-hook.cmd +0 -0
  63. package/hooks/session-start.sh +5 -5
  64. package/package.json +3 -1
  65. package/references/collaborative-protocol.md +50 -0
  66. package/references/gd-style.md +121 -0
  67. package/references/godot-version.md +51 -0
  68. package/references/mcp-tools-reference.md +199 -0
  69. package/references/public-surface-language.md +30 -0
  70. package/references/summer-folder.md +90 -0
  71. package/references/template-registry.md +73 -0
  72. package/skills/2d-assets/character-portrait/SKILL.md +17 -12
  73. package/skills/2d-assets/concept-art/SKILL.md +10 -9
  74. package/skills/2d-assets/pixel-art/SKILL.md +36 -20
  75. package/skills/2d-assets/skybox-panorama/SKILL.md +32 -37
  76. package/skills/2d-assets/sprite-sheet/SKILL.md +40 -35
  77. package/skills/2d-assets/tileable-texture/SKILL.md +28 -22
  78. package/skills/2d-assets/ui-graphics/SKILL.md +46 -32
  79. package/skills/2d-assets/use-widget-asset/SKILL.md +8 -6
  80. package/skills/3d-assets/character-model/SKILL.md +34 -19
  81. package/skills/3d-assets/environment-kit/SKILL.md +11 -5
  82. package/skills/3d-assets/organic-model/SKILL.md +8 -5
  83. package/skills/3d-assets/prop-model/SKILL.md +9 -3
  84. package/skills/3d-assets/vehicle-model/SKILL.md +32 -19
  85. package/skills/README.md +1 -1
  86. package/skills/ai-and-npcs/design-npc/SKILL.md +31 -13
  87. package/skills/animation/animation-tree/SKILL.md +39 -15
  88. package/skills/animation/facial-and-lipsync/SKILL.md +25 -8
  89. package/skills/animation/generate-motion/SKILL.md +47 -15
  90. package/skills/animation/procedural-animation/SKILL.md +31 -13
  91. package/skills/animation/retarget/SKILL.md +127 -79
  92. package/skills/audio/adaptive-music/SKILL.md +24 -20
  93. package/skills/audio/ambient-bed/SKILL.md +22 -16
  94. package/skills/audio/audio-direction/SKILL.md +15 -10
  95. package/skills/audio/music-track/SKILL.md +18 -12
  96. package/skills/audio/sound-effect/SKILL.md +17 -12
  97. package/skills/audio/voice-line/SKILL.md +42 -42
  98. package/skills/character-controllers/fps-controller/SKILL.md +26 -16
  99. package/skills/debugging/debug/SKILL.md +52 -20
  100. package/skills/deployment/export-and-ship/SKILL.md +105 -38
  101. package/skills/deployment/remote-deploy/SKILL.md +56 -23
  102. package/skills/gameplay-mechanics/auto-fire-targeting/SKILL.md +26 -1
  103. package/skills/gameplay-mechanics/design-mechanic/SKILL.md +23 -15
  104. package/skills/level-design/design-level/SKILL.md +22 -8
  105. package/skills/level-design/scene-to-level/SKILL.md +13 -7
  106. package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +8 -8
  107. package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +2 -7
  108. package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +26 -18
  109. package/skills/performance/tune-performance/SKILL.md +51 -32
  110. package/skills/rendering-and-lighting/3d-lighting/SKILL.md +34 -5
  111. package/skills/rendering-and-lighting/art-direction/SKILL.md +6 -8
  112. package/skills/scene-and-project/brainstorm-game/SKILL.md +3 -5
  113. package/skills/scene-and-project/make-game/SKILL.md +2 -1
  114. package/skills/scene-and-project/play/SKILL.md +10 -4
  115. package/skills/scene-and-project/scene-composition/SKILL.md +21 -8
  116. package/skills/scene-and-project/summer-cloud/SKILL.md +1 -1
  117. package/skills/ui-and-ux/ui-basics/SKILL.md +16 -7
  118. package/skills/video/animated-loop/SKILL.md +63 -39
  119. package/skills/video/cinematic-cutscene/SKILL.md +66 -30
  120. package/skills/video/trailer-shot/SKILL.md +30 -21
  121. package/skills/visual-effects/_building-blocks/additive-billboard-particles.md +25 -16
  122. package/skills/visual-effects/_building-blocks/trauma-shake-snippet.md +5 -3
  123. package/skills/visual-effects/game-feel/SKILL.md +51 -33
  124. package/skills/visual-effects/recipes/dissolve/SKILL.md +51 -9
  125. package/skills/visual-effects/recipes/fire/SKILL.md +136 -49
  126. package/skills/visual-effects/recipes/hit-spark/SKILL.md +45 -8
  127. package/skills/visual-effects/recipes/lightning/SKILL.md +59 -27
  128. package/skills/visual-effects/recipes/magic-glow/SKILL.md +59 -26
  129. package/skills/visual-effects/recipes/muzzle-flash/SKILL.md +68 -25
  130. package/skills/visual-effects/recipes/smoke/SKILL.md +89 -28
  131. package/skills/visual-effects/recipes/water-ripple/SKILL.md +83 -23
  132. package/skills/workflow/brainstorming/SKILL.md +1 -1
  133. package/skills/workflow/brainstorming/scripts/start-server.sh +0 -0
  134. package/skills/workflow/brainstorming/scripts/stop-server.sh +0 -0
  135. package/skills/workflow/debugging-game-feel/SKILL.md +29 -9
  136. package/skills/workflow/diagnosing-perf-regressions/SKILL.md +46 -21
  137. package/skills/workflow/gameskill/SKILL.md +11 -2
  138. package/skills/workflow/headless-scripting/SKILL.md +407 -0
  139. package/skills/workflow/investigating-bugs/SKILL.md +4 -2
  140. package/skills/workflow/investigating-bugs/find-polluter.sh +0 -0
  141. package/skills/workflow/mcpupdate/SKILL.md +3 -3
  142. package/skills/workflow/playtesting-a-feature/SKILL.md +94 -21
  143. package/skills/workflow/skill-create/SKILL.md +7 -7
  144. package/skills/workflow/skill-test/SKILL.md +3 -3
  145. package/skills/workflow/using-summer/SKILL.md +12 -2
  146. package/skills/workflow/verification-before-completion/SKILL.md +2 -0
  147. package/skills/workflow/writing-plans/SKILL.md +7 -7
  148. package/skills/workflow/writing-skills/SKILL.md +7 -5
  149. package/skills/workflow/writing-skills/render-graphs.js +0 -0
  150. package/skills/workflow/writing-skills/testing-skills-with-subagents.md +1 -1
@@ -11,7 +11,9 @@ paths: ["assets/**", "ui/**", "art/ui/**"]
11
11
 
12
12
  # ui-graphics — Icons, Buttons, Panels, HUD
13
13
 
14
- This skill generates flat, game-UI-style graphics: icons (skill / item / status), buttons (idle / hover / pressed states), panels and frames (NinePatch-friendly), HUD widgets (health frames, minimaps, badges). Output is **transparent PNG** by default and wires via Godot's `TextureRect`, `NinePatchRect`, or `AtlasTexture`.
14
+ This skill generates flat game-UI graphics: icons, button states, panels,
15
+ frames, and HUD widgets. Output is **transparent PNG** by default and wires
16
+ through Summer Engine `TextureRect`, `NinePatchRect`, or `AtlasTexture` nodes.
15
17
 
16
18
  UI graphics succeed or fail on **two specific things**: a clean transparent background (no checkerboard residue) and a consistent visual language across the set (all icons share line weight, color treatment, lighting). This skill encodes both.
17
19
 
@@ -52,18 +54,20 @@ Every icon / button / panel re-uses this anchor verbatim. Skipping this step pro
52
54
  ### 2. Search before generating
53
55
 
54
56
  ```
55
- summer_search_assets(query="<subject> icon", filter={ kind: "image" })
57
+ summer_search_assets(query="<subject> icon", assetType="2d_image", source="all")
56
58
  ```
57
59
 
58
60
  ### 3. Pick the right pattern (icon vs button vs panel)
59
61
 
60
- | Asset class | Image size | Wiring node | Notes |
62
+ `summer_generate_image` has no size or aspect argument — every MCP image comes back at the server's 1:1 default. Square suits icons, panels, and badges; for wide assets (buttons, HUD bar frames) describe the proportions in the prompt and crop after, or generate in the Summer dashboard where aspect ratio is exposed.
63
+
64
+ | Asset class | Framing | Wiring node | Notes |
61
65
  |---|---|---|---|
62
- | Icon (ability, item, status) | `square_hd` | `TextureRect` (or `AtlasTexture` if part of an icon sheet) | Centered subject, generous padding |
63
- | Button (idle / hover / pressed) | `landscape_4_3` | `Button` with custom theme OR `TextureButton` | Generate 3 variants of the same shape |
64
- | Panel / frame (NinePatch-friendly) | `square_hd` | `NinePatchRect` | Border + center MUST be visually separable for 9-slicing |
65
- | HUD bar frame | `landscape_16_9` | `NinePatchRect` over `ProgressBar` | Frame only — bar fill is a separate gradient texture |
66
- | Badge / emblem | `square_hd` | `TextureRect` | Symmetric, centered, no text |
66
+ | Icon (ability, item, status) | square (default) | `TextureRect` (or `AtlasTexture` if part of an icon sheet) | Centered subject, generous padding |
67
+ | Button (idle / hover / pressed) | wide — prompt for it, crop after | `Button` with custom theme OR `TextureButton` | Generate 3 variants of the same shape |
68
+ | Panel / frame (NinePatch-friendly) | square (default) | `NinePatchRect` | Border + center MUST be visually separable for 9-slicing |
69
+ | HUD bar frame | wide — prompt for it, crop after | `NinePatchRect` over `ProgressBar` | Frame only — bar fill is a separate gradient texture |
70
+ | Badge / emblem | square (default) | `TextureRect` | Symmetric, centered, no text |
67
71
 
68
72
  ### 4. Build the prompt — subject + anchor + transparent
69
73
 
@@ -73,20 +77,22 @@ Pattern:
73
77
  <asset class> of <subject>, game UI, <anchor style>, flat design, clean edges, transparent background, centered, isolated
74
78
  ```
75
79
 
76
- `transparent background` and `isolated` are the load-bearing words. Without them, you get a square card with a textured background that defeats the purpose.
80
+ `isolated` is load-bearing. For the background, **do not rely on the prompt** — pass `options.removeBackground: true`, which runs a real background-removal pass after generation and returns a PNG with true alpha. That is the single highest-value argument in this skill, and it is the actual fix for the checkerboard failure listed below: models asked for a "transparent background" in text frequently paint the checkerboard.
77
81
 
78
82
  ### 5. Generate
79
83
 
80
84
  **Icon example:**
81
85
  ```
82
86
  summer_generate_image(
83
- prompt="ability icon for a fire spell, glowing flame in cupped hand, game UI, flat design with subtle gradient and soft inner shadow, 2px deep navy outline, gold and parchment palette, rounded square frame, transparent background, centered, isolated",
87
+ prompt="ability icon for a fire spell, glowing flame in cupped hand, game UI, flat design with subtle gradient and soft inner shadow, 2px deep navy outline, gold and parchment palette, rounded square frame, centered, isolated on a plain background. Not photorealistic, no 3D render, no scene background, not busy, no multiple objects.",
84
88
  model="nano-banana-2",
85
89
  style="none",
86
- options={ image_size: "square_hd", negative_prompt: "photorealistic, 3D render, scene background, busy, multiple objects" }
90
+ options={ removeBackground: true }
87
91
  )
88
92
  ```
89
93
 
94
+ `image_size` and `negative_prompt` do not exist on this tool and are dropped without an error — the negations have to live in the prompt text, and the size is fixed. `removeBackground` is the one `options` key here that does real work.
95
+
90
96
  **Button (3 states in 3 calls):**
91
97
  ```
92
98
  summer_generate_image(prompt="<subject>, idle state, ...")
@@ -114,22 +120,25 @@ Verify in the import dock: `Mipmaps: off` (UI shouldn't mipmap), `Filter: Linear
114
120
 
115
121
  ### 7. Wire into the scene
116
122
 
123
+ Every scene-mutating tool takes an explicit `scenePath`, node paths are relative to that scene's root (`./`) rather than absolute `/root/...` runtime paths, and the property argument is named `key`, not `property`.
124
+
117
125
  **Icon as TextureRect:**
118
126
  ```
119
- summer_add_node(parentPath="/root/UI/AbilityBar", type="TextureRect", name="FireSpellIcon")
120
- summer_set_prop(path="/root/UI/AbilityBar/FireSpellIcon", property="texture", value="res://ui/icons/fire_spell.png")
121
- summer_set_prop(path="/root/UI/AbilityBar/FireSpellIcon", property="expand_mode", value=1) # KEEP_SIZE → 1 = STRETCH
122
- summer_set_prop(path="/root/UI/AbilityBar/FireSpellIcon", property="stretch_mode", value=5) # KEEP_ASPECT_CENTERED
127
+ summer_add_node(scenePath="res://ui/hud.tscn", parent="./AbilityBar", type="TextureRect", name="FireSpellIcon")
128
+ summer_set_prop(scenePath="res://ui/hud.tscn", path="./AbilityBar/FireSpellIcon", key="texture", value="res://ui/icons/fire_spell.png")
129
+ summer_set_prop(scenePath="res://ui/hud.tscn", path="./AbilityBar/FireSpellIcon", key="expand_mode", value=1) # EXPAND_IGNORE_SIZE
130
+ summer_set_prop(scenePath="res://ui/hud.tscn", path="./AbilityBar/FireSpellIcon", key="stretch_mode", value=5) # STRETCH_KEEP_ASPECT_CENTERED
123
131
  ```
124
132
 
125
133
  **Panel as NinePatchRect:**
126
134
  ```
127
- summer_add_node(parentPath="/root/UI", type="NinePatchRect", name="InventoryPanel")
128
- summer_set_prop(path="/root/UI/InventoryPanel", property="texture", value="res://ui/panels/parchment.png")
129
- summer_set_prop(path="/root/UI/InventoryPanel", property="patch_margin_left", value=24)
130
- summer_set_prop(path="/root/UI/InventoryPanel", property="patch_margin_right", value=24)
131
- summer_set_prop(path="/root/UI/InventoryPanel", property="patch_margin_top", value=24)
132
- summer_set_prop(path="/root/UI/InventoryPanel", property="patch_margin_bottom", value=24)
135
+ summer_add_node(scenePath="res://ui/hud.tscn", parent=".", type="NinePatchRect", name="InventoryPanel")
136
+ summer_set_prop(scenePath="res://ui/hud.tscn", path="./InventoryPanel", key="texture", value="res://ui/panels/parchment.png")
137
+ summer_set_prop(scenePath="res://ui/hud.tscn", path="./InventoryPanel", key="patch_margin_left", value=24)
138
+ summer_set_prop(scenePath="res://ui/hud.tscn", path="./InventoryPanel", key="patch_margin_right", value=24)
139
+ summer_set_prop(scenePath="res://ui/hud.tscn", path="./InventoryPanel", key="patch_margin_top", value=24)
140
+ summer_set_prop(scenePath="res://ui/hud.tscn", path="./InventoryPanel", key="patch_margin_bottom", value=24)
141
+ summer_save_scene(scenePath="res://ui/hud.tscn")
133
142
  ```
134
143
 
135
144
  Tune patch margins to match the actual border width in the generated texture. Open the texture in the editor's NinePatch preview to verify.
@@ -155,26 +164,30 @@ If you generate a 4×4 grid of icons in one image, each icon becomes an `AtlasTe
155
164
  | Bad | Failure mode |
156
165
  |---|---|
157
166
  | `cool button` | No subject, no anchor. Returns a generic button on a card background. |
158
- | `transparent button with icon` (no negative prompt) | Model often renders a checkerboard "transparent" pattern as the actual fill. Add `no checkerboard pattern` to negative. |
167
+ | `transparent button with icon` | Model often renders a checkerboard "transparent" pattern as the actual fill. There is no negative-prompt argument to counter it — drop the word "transparent" from the prompt entirely and pass `options.removeBackground: true` instead. |
159
168
  | `8 ability icons in one image` | Inconsistent style across the 8. Generate one at a time with the same anchor. |
160
169
  | `realistic 3D rendered button` | Conflicts with flat-UI. Stay flat. |
161
- | `button with the word "Play"` on it | Models render text badly. Add text in Godot via a `Label` over the button, not in the texture. |
170
+ | `button with the word "Play"` on it | Models render text badly. Add text in Summer Engine via a `Label` over the button, not in the texture. |
162
171
 
163
172
  ## Anti-patterns
164
173
 
165
174
  - **Skipping the anchor.** A 12-icon ability bar with no anchor looks like 12 unrelated games. Define the anchor on icon #1.
166
- - **Letting the model render text.** Diffusion models can't render reliable text. Always overlay text in Godot via a `Label` node. The button texture is the frame; the label is the word.
167
- - **Forgetting `transparent background` in the prompt.** Default is opaque. Without the keyword, you import an icon with a 200×200 white square around the actual icon.
168
- - **Using `style: "realistic"` for UI.** UI is flat. `style: "none"` lets the prompt's "flat design" land cleanly.
175
+ - **Letting the model render text.** Diffusion models cannot render reliable
176
+ text. Always overlay text in Summer Engine with a `Label` node. The button
177
+ texture is the frame; the label is the word.
178
+ - **Forgetting `options.removeBackground: true`.** Default is opaque. Prompting for "transparent background" instead is what produces the painted-checkerboard failure below — the option runs a real alpha pass and does not.
179
+ - **Expecting `style` to do the work.** Only `cartoon` and `anime` append anything; `realistic` and `none` append nothing, and any other value is coerced to `none`. `style: "none"` is right for UI, but "flat design" has to be in the prompt regardless.
169
180
  - **NinePatch with no border-vs-center distinction.** The 9-slice scaling smears the border into the center.
170
181
  - **Mipmaps on UI.** UI textures shouldn't mipmap — they're displayed at 1:1 or near it. Mipmaps waste memory and blur sharp edges.
171
182
 
172
183
  ## Edge cases
173
184
 
174
- - **User wants the same icon at multiple sizes (32, 64, 128).** Generate once at high res. Godot's `TextureRect` with `STRETCH_KEEP_ASPECT_CENTERED` scales it down cleanly. Don't generate three sizes.
185
+ - **User wants the same icon at multiple sizes (32, 64, 128).** Generate once
186
+ at high resolution. Summer Engine's `TextureRect` with
187
+ `STRETCH_KEEP_ASPECT_CENTERED` scales it down cleanly.
175
188
  - **User wants pixel-style UI.** Route to `summer:2d-assets/pixel-art` — different prompt pattern, different filter, different anchor.
176
189
  - **User wants animated UI (spinning loading icon).** Generate the static frame here. Animate via `AnimationPlayer` rotating the `TextureRect`, not as a sprite sheet.
177
- - **Transparency comes back as a checkerboard pattern in the image.** The model rendered the checkerboard literally. Regenerate with `no checkerboard pattern, true alpha transparency` in the negative prompt.
190
+ - **Transparency comes back as a checkerboard pattern in the image.** The model rendered the checkerboard literally because the prompt asked for transparency. Remove every mention of transparency from the prompt, generate on a plain background, and pass `options.removeBackground: true` to cut the alpha server-side.
178
191
  - **Icons need to read at very small size (16-24px in a packed bar).** Bias prompts toward bold silhouette + minimal interior detail. Ornate detail is invisible at 16px and adds noise.
179
192
 
180
193
  ## Fallback (no MCP)
@@ -183,10 +196,10 @@ Print the call:
183
196
 
184
197
  ```
185
198
  summer_generate_image(
186
- prompt="<asset + anchor + transparent>",
199
+ prompt="<asset + anchor>, isolated on a plain background. No scene background, not photorealistic, no 3D, not busy.",
187
200
  model="nano-banana-2",
188
201
  style="none",
189
- options={ image_size: "square_hd", negative_prompt: "scene background, photorealistic, 3D, busy" }
202
+ options={ removeBackground: true }
190
203
  )
191
204
  ```
192
205
 
@@ -198,7 +211,8 @@ After the UI graphic is wired:
198
211
 
199
212
  - **More icons in the same set** → re-invoke this skill with the same anchor.
200
213
  - **Button states (hover/pressed)** → re-invoke for each state.
201
- - **Theme assembly (combining icons + panels into a Godot Theme resource)** → `summer:scene-composition` for the Theme resource wiring.
214
+ - **Theme assembly (combining icons + panels into a Summer Engine Theme
215
+ resource)** → `summer:scene-composition` for the resource wiring.
202
216
  - **Pixel-art UI** → `summer:2d-assets/pixel-art`.
203
217
  - **Dialogue UI with portraits** → `summer:2d-assets/character-portrait` for the portrait, then back here for the surrounding panel.
204
218
 
@@ -207,4 +221,4 @@ After the UI graphic is wired:
207
221
  - `summer:2d-assets/character-portrait` — for in-UI character images.
208
222
  - `summer:2d-assets/pixel-art` — pixel-style UI.
209
223
  - `summer:scene-composition` — Theme and Control hierarchy.
210
- - `references/mcp-tools-reference.md` — `summer_generate_image` schema.
224
+ - `../../../references/mcp-tools-reference.md` — `summer_generate_image` schema.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-widget-asset
3
- description: Use when consuming a widget slice (panel, button, slider, progress bar, or toggle pair) from a `create-asset-sheet` pack into a Godot scene. The pack's metadata.sliceMeta carries 9-slice margins, fill rects, and on/off pair links per slice — this skill explains how to wire those into NinePatchRect / TextureProgressBar / TextureRect so the asset behaves like a real UI control instead of a static texture.
3
+ description: Use when consuming a widget slice (panel, button, slider, progress bar, or toggle pair) from a `create-asset-sheet` pack in a Summer Engine scene. The pack's metadata.sliceMeta carries 9-slice margins, fill rects, and on/off pair links per slice. This skill explains how to wire those into NinePatchRect, TextureProgressBar, or TextureRect so the asset behaves like a real UI control instead of a static texture.
4
4
  license: MIT
5
5
  compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
6
  category: 2d-assets
@@ -9,9 +9,9 @@ allowed-tools: Read Grep Glob Write Edit summer_add_node summer_set_prop summer_
9
9
  paths: ["assets/**", "art/**", "ui/**", "scenes/**"]
10
10
  ---
11
11
 
12
- # use-widget-asset — Wire a sliced widget into a real Godot control
12
+ # use-widget-asset — Wire a sliced widget into a Summer Engine control
13
13
 
14
- When the `create-asset-sheet` wizard sees a stretchable UI element (a panel, a slider, a progress bar, a toggle), it returns more than a flat PNG. It returns geometry: **9-slice frame margins** for stretchable rectangles, and a **fill rect** for value-driven widgets. It also pairs ON/OFF toggle slices via `pairWith`. This skill is the runtime side: how to read that metadata and wire the asset into the right Godot node.
14
+ When the `create-asset-sheet` wizard sees a stretchable UI element (a panel, a slider, a progress bar, a toggle), it returns more than a flat PNG. It returns geometry: **9-slice frame margins** for stretchable rectangles, and a **fill rect** for value-driven widgets. It also pairs ON/OFF toggle slices via `pairWith`. This skill is the runtime side: how to read that metadata and wire the asset into the right Summer Engine node.
15
15
 
16
16
  If a slice has no widget metadata, treat it as a static texture (`TextureRect`) and skip this skill.
17
17
 
@@ -57,7 +57,7 @@ metadata.sliceMeta: { "0": { category, widget?, pairWith?, parentSliceIndex? }
57
57
  }
58
58
  ```
59
59
 
60
- Margins and rect are **percentages of the SLICE's own pixel dimensions** (not the source sheet). Convert to pixels with `Math.round(pct * sliceWidth / 100)` before applying to a Godot node.
60
+ Margins and rect are **percentages of the SLICE's own pixel dimensions** (not the source sheet). Convert to pixels with `Math.round(pct * sliceWidth / 100)` before applying to a Summer Engine node.
61
61
 
62
62
  ## Decision tree
63
63
 
@@ -132,7 +132,9 @@ Set `value` from 0 to 100 to drive the bar.
132
132
 
133
133
  ### 3. Slider — HSlider with TextureRect overlays
134
134
 
135
- `Slider` in Godot is a behavioral node (drag input + value range); it doesn't ship visuals on its own. Combine it with two `TextureRect`s underneath: one for the track (the slice texture, optionally as NinePatchRect for stretch) and one for the knob (a separate small slice cut from the slider's `fillRect` end).
135
+ `Slider` in Summer Engine is a behavioral node (drag input + value range); it
136
+ does not ship visuals on its own. Combine it with two `TextureRect`s underneath:
137
+ one for the track and one for the knob.
136
138
 
137
139
  Simplest wiring: NinePatchRect for the track using `frameMargins`, an HSlider on top with `flat = true` and `theme_override_styles/grabber_area = null`, and a child `TextureRect` for the knob positioned via `slider.ratio`.
138
140
 
@@ -181,7 +183,7 @@ The wizard's Break-down pass produces two new per-slice fields the runtime must
181
183
  | `zOrder` | number | Back-to-front paint order on children. Lower = behind. Matches Godot `z_index`, Unity `sortingOrder`, CSS `z-index`. |
182
184
  | `parentSliceIndex` | number | Set on each child, points at the composite parent. Used to group children. |
183
185
 
184
- The full schema lives at `publicsummerengine/public/knowledge/asset_pack_schema.json`. Read it once if you need to know every field.
186
+ The full schema is the zod definition at `publicsummerengine/src/lib/asset-packs/schema.ts` (`SliceMetaSchema`, `PACK_SCHEMA_VERSION`, and the legacy-migration helper). Read it once if you need to know every field.
185
187
 
186
188
  ### Consume recipe
187
189
 
@@ -19,7 +19,7 @@ The whole flow:
19
19
  1. T-pose reference image → summer_generate_image (~$0.05, ~10s)
20
20
  2. Un-rigged 3D mesh → summer_generate_3d(image-to-3d) (~$0.50, ~60s)
21
21
  3. ── USER REVIEW GATE ──
22
- 4. Rigged .glb → summer_generate_3d(image-to-3d, rig: true) (~$1.00, ~90s)
22
+ 4. Rigged .glb → summer_generate_3d(image-to-3d, rig=true) (~$1.00, ~90s)
23
23
  5. Import → editor RESTART → wire as CharacterBody3D / Node3D
24
24
  6. Hand off to summer:animation/generate-motion for clips
25
25
  ```
@@ -133,10 +133,13 @@ If the user wants changes, loop back to step 1 or 2. Do NOT silently run the rig
133
133
  summer_generate_3d({
134
134
  kind: "image-to-3d",
135
135
  imageUrl: "<image url from step 1>",
136
- options: { rig: true, polyTarget: 12000 } // polyTarget is best-effort; backend may use options.target_polycount
136
+ rig: true,
137
+ options: { target_polycount: 12000 }
137
138
  })
138
139
  ```
139
140
 
141
+ `rig` is a **top-level boolean argument** on `summer_generate_3d` (the tool also merges it into `options.rig`, so `options: { rig: true }` works too). There is no `polyTarget` — the polycount key is `target_polycount` inside `options`, exactly as in step 2. Related top-level arguments worth knowing here: `riggingHeightMeters` for character height, and `animationNames` / `actionIds` to have the shared animated-character pipeline produce clips in the same job instead of a separate `summer_generate_motion` pass.
142
+
140
143
  Returns a job whose result includes `assetId`, `fileUrl`, and `rigAssetId`.
141
144
  If you ran with `wait: false`, poll via `summer_check_job(jobId)`. The
142
145
  `rigAssetId` is the handle `summer:animation/generate-motion` needs — store it.
@@ -154,11 +157,11 @@ summer_import_asset_by_id(
154
157
 
155
158
  ### 5. ⚠️ Restart the editor
156
159
 
157
- **Known Godot 4.5 gotcha:** after importing a rigged `.glb`, the `Skeleton3D` node appears stale in the scene dock — bones are missing, `skeleton.get_bone_count()` returns 0, and `AnimationPlayer` libraries fail to bind. The fix:
160
+ **Known gotcha:** after importing a rigged `.glb`, the `Skeleton3D` node appears stale in the scene dock — bones are missing, `skeleton.get_bone_count()` returns 0, and `AnimationPlayer` libraries fail to bind. The fix:
158
161
 
159
162
  > The rigged mesh is imported. Please restart the Summer Engine editor (close and reopen) so the Skeleton3D rebuilds correctly. Without the restart, animations will fail to bind.
160
163
 
161
- There is no programmatic workaround as of Godot 4.5.x. Tell the user, wait, then continue.
164
+ No programmatic workaround is known. Tell the user, wait, then continue.
162
165
 
163
166
  ### 6. Wire as CharacterBody3D or Node3D — pick the right parent
164
167
 
@@ -169,25 +172,33 @@ There is no programmatic workaround as of Godot 4.5.x. Tell the user, wait, then
169
172
  | Pure-visual character (background extra, dialogue head) | `Node3D` | Same as above |
170
173
  | Ragdoll-on-death enemy | `CharacterBody3D` while alive, swap to `RigidBody3D` skeleton on death | Two-mode rig; see `summer:animation/procedural-animation` |
171
174
 
175
+ Four things the call shapes below encode:
176
+
177
+ - **Every scene-mutating tool takes an explicit `scenePath`** and the scene need not be the active editor tab.
178
+ - **Node paths are relative to that scene's root (`./`)**, not absolute `/root/...` runtime paths.
179
+ - **`summer_set_prop`'s property argument is named `key`**, not `property`.
180
+ - **A `.glb` is instantiated, not assigned.** There is no `scene` property on `Node3D`, and an imported `.glb` is a scene rather than a `Mesh` — on the shipped 4.6.1 binary `ResourceLoader.get_recognized_extensions_for_type("Mesh")` returns `["tres", "mesh", "res"]`, with no `glb`. Use `summer_instantiate_scene`.
181
+
172
182
  **CharacterBody3D wiring (player / enemy):**
173
183
 
174
184
  ```
175
- summer_add_node(parent="./World", type="CharacterBody3D", name="Knight")
176
- summer_set_prop(path="./World/Knight", property="position", value="Vector3(0, 0, 0)")
177
- summer_add_node(parent="./World/Knight", type="Node3D", name="Mesh")
178
- # Instantiate the imported scene as a child of the Mesh node
179
- summer_set_prop(path="./World/Knight/Mesh", property="scene", value="res://assets/characters/knight.glb")
180
- summer_add_node(parent="./World/Knight", type="CollisionShape3D", name="Collider")
181
- # Add a CapsuleShape3D resource (height ~1.7m, radius ~0.4m) to the collider
182
- summer_save_scene
185
+ summer_add_node(scenePath="res://main.tscn", parent="./World", type="CharacterBody3D", name="Knight")
186
+ summer_set_prop(scenePath="res://main.tscn", path="./World/Knight", key="position", value="Vector3(0, 0, 0)")
187
+ summer_instantiate_scene(scenePath="res://main.tscn", parent="./World/Knight", scene="res://assets/characters/knight.glb", name="Mesh")
188
+ summer_add_node(scenePath="res://main.tscn", parent="./World/Knight", type="CollisionShape3D", name="Collider")
189
+ summer_set_prop(scenePath="res://main.tscn", path="./World/Knight/Collider", key="shape", value="CapsuleShape3D")
190
+ summer_set_resource_property(scenePath="res://main.tscn", nodePath="./World/Knight/Collider", resourceProperty="shape", subProperty="height", value=1.7)
191
+ summer_set_resource_property(scenePath="res://main.tscn", nodePath="./World/Knight/Collider", resourceProperty="shape", subProperty="radius", value=0.4)
192
+ summer_save_scene(scenePath="res://main.tscn")
183
193
  ```
184
194
 
195
+ Assigning a bare class name like `"CapsuleShape3D"` to a resource property auto-instantiates it, which is how you get a shape you can then size. `summer_set_resource_property` needs all five of `scenePath`, `nodePath`, `resourceProperty`, `subProperty`, `value`.
196
+
185
197
  **Node3D wiring (cinematic NPC):**
186
198
 
187
199
  ```
188
- summer_add_node(parent="./World/Tavern", type="Node3D", name="OldWizard")
189
- summer_set_prop(path="./World/Tavern/OldWizard", property="scene", value="res://assets/characters/wizard.glb")
190
- summer_save_scene
200
+ summer_instantiate_scene(scenePath="res://main.tscn", parent="./World/Tavern", scene="res://assets/characters/wizard.glb", name="OldWizard")
201
+ summer_save_scene(scenePath="res://main.tscn")
191
202
  ```
192
203
 
193
204
  The imported `.glb` includes its own `Skeleton3D` and `AnimationPlayer` (empty library). The animation skill writes into that AnimationPlayer.
@@ -196,7 +207,11 @@ The imported `.glb` includes its own `Skeleton3D` and `AnimationPlayer` (empty l
196
207
 
197
208
  > Knight is wired at `./World/Knight` with a Meshy-rigged skeleton. `rigAssetId` saved.
198
209
  >
199
- > Next: `summer:animation/generate-motion` to add idle / walk / run / attack clips. Example call: `summer_generate_motion(rigAssetId: "<saved id>", backend: "meshy-library", motionName: "walk")`. The animation skill uses Meshy's curated mocap library (~70 standard motions). Custom prompt-driven motion is on the roadmap; for one-off signature moves not on the curated list, fall back to hand-authoring in the Godot editor or importing from Mixamo.
210
+ > Next: `summer:animation/generate-motion` to add idle / walk / run / attack
211
+ > clips. Example call: `summer_generate_motion(rigAssetId: "<saved id>",
212
+ > backend: "meshy-library", motionName: "walk")`. Custom prompt-driven motion
213
+ > is not shipped; hand-author one-off moves in Summer Engine or import a
214
+ > licensed clip.
200
215
 
201
216
  ## Anti-patterns
202
217
 
@@ -221,9 +236,9 @@ The imported `.glb` includes its own `Skeleton3D` and `AnimationPlayer` (empty l
221
236
  1. Generate the T-pose reference at the Summer dashboard (or any image gen — Midjourney, nano-banana web, DALL-E).
222
237
  2. Upload to Meshy at meshy.ai → Image to 3D → enable rigging.
223
238
  3. Download the `.glb`.
224
- 4. Drop into `res://assets/characters/` — Godot's import dock picks it up.
239
+ 4. Drop into `res://assets/characters/`; Summer Engine's Import dock picks it up.
225
240
  5. Restart the editor.
226
- 6. Wire as CharacterBody3D / Node3D in the Godot editor manually.
241
+ 6. Wire as CharacterBody3D / Node3D in Summer Engine manually.
227
242
 
228
243
  The output is identical to the MCP path — same Meshy skeleton, same compatibility with `summer:animation/generate-motion` (which has its own dashboard fallback).
229
244
 
@@ -244,4 +259,4 @@ After the rigged character is wired:
244
259
  - `summer:asset-pipeline/asset-strategy` — meta-router; this skill is the canonical drill-down of its "Image-to-3D for characters" path.
245
260
  - `summer:3d-assets/prop-model` — for non-character props.
246
261
  - `summer:scene-composition` — for the CharacterBody3D + Mesh + Collider parent pattern.
247
- - `references/mcp-tools-reference.md` — full parameter schemas for `summer_generate_3d`, `summer_generate_image`, and `summer_generate_motion`.
262
+ - `../../../references/mcp-tools-reference.md` — full parameter schemas for `summer_generate_3d`, `summer_generate_image`, and `summer_generate_motion`.
@@ -113,13 +113,18 @@ Polycount targets per kit piece: walls/floors 800–1500 tris (placed dozens of
113
113
  Don't dump the kit into the level scene. Make a `kit_dungeon.tscn` that holds one of every piece, labelled, positioned next to each other on the snap grid. The level designer instantiates from there.
114
114
 
115
115
  ```
116
- summer_add_node(parent="./KitRoot", type="Node3D", name="Wall")
117
- summer_set_prop(path="./KitRoot/Wall", property="scene", value="res://assets/kits/dungeon/wall.glb")
118
- summer_set_prop(path="./KitRoot/Wall", property="position", value="Vector3(0, 0, 0)")
116
+ summer_instantiate_scene(scenePath="res://assets/kits/dungeon/kit_dungeon.tscn", parent="./KitRoot", scene="res://assets/kits/dungeon/wall.glb", name="Wall")
117
+ summer_set_prop(scenePath="res://assets/kits/dungeon/kit_dungeon.tscn", path="./KitRoot/Wall", key="position", value="Vector3(0, 0, 0)")
119
118
  # ...repeat for floor, pillar, door, corner, arch with positions Vector3(2,0,0), Vector3(4,0,0), ...
120
- summer_save_scene
119
+ summer_save_scene(scenePath="res://assets/kits/dungeon/kit_dungeon.tscn")
121
120
  ```
122
121
 
122
+ Three things the shape of those calls encodes:
123
+
124
+ - **A `.glb` is instantiated, not assigned.** There is no `scene` property on `Node3D`, and an imported `.glb` is a scene, not a `Mesh` — `ResourceLoader.get_recognized_extensions_for_type("Mesh")` on the shipped 4.6.1 binary returns `["tres", "mesh", "res"]`, with no `glb`. Use `summer_instantiate_scene`, which adds the model as a child in one op.
125
+ - **Every scene-mutating tool takes an explicit `scenePath`**, and node paths are relative to that scene's root (`./`).
126
+ - **`summer_set_prop`'s property argument is named `key`**, not `property`.
127
+
123
128
  ### 5. Verify scale and pivots
124
129
 
125
130
  ```
@@ -149,7 +154,8 @@ Check the AABB. If the wall is 1.85m tall when you asked for 3m, scale it in the
149
154
  1. Run each prompt at the Summer dashboard (or Hunyuan / Trellis web UIs), keeping the locked suffix.
150
155
  2. Download each `.glb`.
151
156
  3. Drop into `res://assets/kits/<kit-name>/`.
152
- 4. Build the kit-display scene manually in Godot — one of each piece, snapped to grid.
157
+ 4. Build the kit-display scene manually in Summer Engine, with one of each piece
158
+ snapped to the grid.
153
159
  5. Hand to the level designer.
154
160
 
155
161
  ## Handoff
@@ -129,11 +129,14 @@ Then scatter all five with random rotation. Five unique meshes + rotation = look
129
129
  **Hero tree:**
130
130
 
131
131
  ```
132
- summer_add_node(parent="./World/Forest", type="MeshInstance3D", name="HeroOak")
133
- summer_set_prop(path="./World/Forest/HeroOak", property="mesh", value="res://assets/organic/oak_tree.glb")
134
- summer_save_scene
132
+ summer_instantiate_scene(scenePath="res://main.tscn", parent="./World/Forest", scene="res://assets/organic/oak_tree.glb", name="HeroOak")
133
+ summer_save_scene(scenePath="res://main.tscn")
135
134
  ```
136
135
 
136
+ A `.glb` cannot be assigned to `MeshInstance3D.mesh`. An imported `.glb` is a scene, not a `Mesh` — on the shipped 4.6.1 binary `ResourceLoader.get_recognized_extensions_for_type("Mesh")` returns `["tres", "mesh", "res"]`, with no `glb`. `summer_instantiate_scene` adds it as a child in one op. (For the `MultiMeshInstance3D` path below you do need a real `Mesh`: pull it out of the instantiated scene's `MeshInstance3D` in script, or save it as a `.tres`.)
137
+
138
+ Every scene-mutating tool takes an explicit `scenePath`; node paths are relative to that scene's root (`./`).
139
+
137
140
  **Forest scatter (MultiMesh):** create a `MultiMeshInstance3D`, assign a `MultiMesh` resource referencing the tree mesh, set `instance_count` to e.g. 100, and populate `set_instance_transform()` from a script with random positions + rotations. See `summer:scene-composition` for the scatter pattern.
138
141
 
139
142
  ### 6. LOD and billboards
@@ -169,7 +172,7 @@ For a 200-tree forest, ~10 close trees are real meshes, 190 are billboards. Fram
169
172
 
170
173
  1. Run prompts at the Summer dashboard or any 3D-gen web playground (Hunyuan, Trellis, Meshy).
171
174
  2. Download `.glb` files into `res://assets/organic/`.
172
- 3. Build scatter scenes manually in Godot.
175
+ 3. Build scatter scenes manually in Summer Engine.
173
176
 
174
177
  For totally free / offline alternatives: **Quaternius** (free stylized organics), **AmbientCG** (rocks + textures), **Sketchfab** free filter, **Polyhaven** (HDRIs + scans).
175
178
 
@@ -190,4 +193,4 @@ After the organic models are scattered:
190
193
  - `summer:3d-assets/environment-kit` — pair with this skill: kit pieces give the architecture, organic gives the natural softness.
191
194
  - `summer:asset-pipeline/asset-strategy` — meta-router; ground textures and skyboxes go to Pipeline 2 / panoramic gen.
192
195
  - `summer:scene-composition` — MultiMeshInstance3D scatter pattern.
193
- - `references/mcp-tools-reference.md` — `summer_generate_3d` schema.
196
+ - `../../../references/mcp-tools-reference.md` — `summer_generate_3d` schema.
@@ -94,11 +94,14 @@ summer_import_asset_by_id(
94
94
  assetId="<assetId>",
95
95
  path="res://assets/models/viking_axe.glb",
96
96
  parent="./World/Props",
97
+ scenePath="res://main.tscn",
97
98
  name="VikingAxe"
98
99
  )
99
- summer_save_scene
100
+ summer_save_scene(scenePath="res://main.tscn")
100
101
  ```
101
102
 
103
+ `scenePath` is **required whenever `parent` is set** — it names the exact scene that receives the model, and the scene does not have to be the active editor tab. Omitting it fails the import with a `pass the exact scenePath when parent is set` hint. `summer_save_scene` likewise takes an explicit `scenePath`; there is no bare form.
104
+
102
105
  For interactive props (chest the player opens, lantern the player picks up),
103
106
  wrap the instantiated model in a `StaticBody3D` (or `RigidBody3D` for physics
104
107
  props) with a `CollisionShape3D` sibling — see `summer:scene-composition` for
@@ -122,7 +125,10 @@ the parent-shape pattern.
122
125
 
123
126
  ## Fallback (no MCP)
124
127
 
125
- The user can run the same prompt at the Summer dashboard (or directly via the Hunyuan / Trellis web UIs), download the `.glb`, drop it into `res://assets/models/`, and Godot's import dock will pick it up. Then add a MeshInstance3D manually in the Godot editor and assign the mesh.
128
+ The user can run the same prompt in the Summer dashboard or a supported
129
+ provider UI, download the `.glb`, and drop it into `res://assets/models/`.
130
+ Summer Engine's Import dock will pick it up. Then add a MeshInstance3D and
131
+ assign the mesh.
126
132
 
127
133
  ## Handoff
128
134
 
@@ -138,4 +144,4 @@ After the prop is wired:
138
144
  - `summer:asset-pipeline/asset-strategy` — the meta-router that decides between this skill and Pipeline 2 (textures).
139
145
  - `summer:3d-assets/character-model` — for humanoids.
140
146
  - `summer:3d-assets/environment-kit` — for style-locked sets.
141
- - `references/mcp-tools-reference.md` — `summer_generate_3d` parameter schema.
147
+ - `../../../references/mcp-tools-reference.md` — `summer_generate_3d` parameter schema.
@@ -43,17 +43,26 @@ Vehicles benefit more from polycount than props — flat panels need edge densit
43
43
 
44
44
  ## Multi-angle reference — the single biggest quality lever
45
45
 
46
- Vehicles are highly view-dependent. A front-only reference produces a mesh with great front detail and a melted rear. The fix: generate a **front + 3/4 side composite reference** before the 3D pass.
46
+ Vehicles are highly view-dependent. A front-only reference produces a mesh with great front detail and a melted rear. There are two ways to give the mesher more than one angle, and they are not the same thing:
47
+
48
+ **(a) A real multi-image request — prefer this.** `summer_generate_3d` takes an `imageUrls` array of up to four views. These are passed through as separate views, not fused into one picture.
47
49
 
48
50
  ```
49
- summer_generate_image(
50
- prompt="A sleek red sports car, front view AND 3/4 rear-side view side by side, two angles in one image, white background, studio lighting, clean references for 3D modeling, isolated, no scenery."
51
+ summer_generate_3d(
52
+ kind="image-to-3d",
53
+ imageUrls=["<front url>", "<3/4 rear-side url>", "<profile url>"],
54
+ model="hunyuan",
55
+ options={ target_polycount: 25000 }
51
56
  )
52
57
  ```
53
58
 
54
- Most image models will produce a two-view composite. Then feed it to image-to-3D:
59
+ **(b) A composite reference image**, when you only have one slot to work with:
55
60
 
56
61
  ```
62
+ summer_generate_image(
63
+ prompt="A sleek red sports car, front view AND 3/4 rear-side view side by side, two angles in one image, white background, studio lighting, clean references for 3D modeling, isolated, no scenery."
64
+ )
65
+
57
66
  summer_generate_3d(
58
67
  kind="image-to-3d",
59
68
  imageUrl="<composite reference url>",
@@ -62,7 +71,7 @@ summer_generate_3d(
62
71
  )
63
72
  ```
64
73
 
65
- If the user has reference images already (concept art, photos), prefer those — composite them into a single image first if they aren't already.
74
+ If the user has reference images already (concept art, photos), pass them straight to `imageUrls` — do not composite them down into one image first; that throws away the multi-view path.
66
75
 
67
76
  ## Steps
68
77
 
@@ -88,7 +97,7 @@ Pattern: `<vehicle type> + <silhouette / era / style> + <materials> + <surface s
88
97
  | Mech | `A 4 meter tall bipedal combat mech, blocky armored torso, articulated arms with rifle and missile pod, thick legs with hydraulic pistons, painted olive drab with hazard stripes. Front and 3/4 side views. Game asset, hard-surface stylized, white background, isolated vehicle.` |
89
98
  | Background sedan | `A generic 90s civilian sedan, four doors, beige paint, slightly worn. Front and 3/4 side views. Game asset, low-detail stylized, white background, isolated vehicle.` |
90
99
 
91
- The phrase `front and 3/4 side views` is what triggers the multi-angle composite reference internally.
100
+ Nothing in the prompt text "triggers" multi-view. The phrase `front and 3/4 side views` only shapes what the *image* model draws; the 3D tool has no prompt-sniffing and sees whatever pixels you hand it. Multi-view comes from the `imageUrls` array, nothing else.
92
101
 
93
102
  ### 4. Confirm and call
94
103
 
@@ -135,7 +144,7 @@ This re-textures the existing mesh with sharper detail — panel lines, decals,
135
144
 
136
145
  | Use case | Parent type | Notes |
137
146
  |---|---|---|
138
- | Player-driven (car, bike, hover) | `VehicleBody3D` (Godot 4.5 wheeled) or `RigidBody3D` (free physics) | Add `VehicleWheel3D` children for wheeled vehicles |
147
+ | Player-driven (car, bike, hover) | `VehicleBody3D` (wheeled) or `RigidBody3D` (free physics) | Add `VehicleWheel3D` children for wheeled vehicles |
139
148
  | Player-driven (spaceship, mech) | `RigidBody3D` or `CharacterBody3D` | Custom thrust / walk code, see `summer:character-controllers` |
140
149
  | Background scenery (parked, flyby) | `MeshInstance3D` under a `Node3D` | No physics, no collision needed for distant traffic |
141
150
  | Background traffic (moving but not interactive) | `Node3D` + `AnimationPlayer` driving the position | Cheap, no physics overhead |
@@ -143,26 +152,30 @@ This re-textures the existing mesh with sharper detail — panel lines, decals,
143
152
  **Player car wiring:**
144
153
 
145
154
  ```
146
- summer_add_node(parent="./World", type="VehicleBody3D", name="RaceCar")
147
- summer_add_node(parent="./World/RaceCar", type="MeshInstance3D", name="Body")
148
- summer_set_prop(path="./World/RaceCar/Body", property="mesh", value="res://assets/vehicles/race_car.glb")
149
- summer_add_node(parent="./World/RaceCar", type="CollisionShape3D", name="Collider")
150
- # Add a BoxShape3D resource matched to the AABB
155
+ summer_add_node(scenePath="res://main.tscn", parent="./World", type="VehicleBody3D", name="RaceCar")
156
+ summer_instantiate_scene(scenePath="res://main.tscn", parent="./World/RaceCar", scene="res://assets/vehicles/race_car.glb", name="Body")
157
+ summer_add_node(scenePath="res://main.tscn", parent="./World/RaceCar", type="CollisionShape3D", name="Collider")
158
+ summer_set_prop(scenePath="res://main.tscn", path="./World/RaceCar/Collider", key="shape", value="BoxShape3D")
159
+ summer_set_resource_property(scenePath="res://main.tscn", nodePath="./World/RaceCar/Collider", resourceProperty="shape", subProperty="size", value="Vector3(4.5, 1.1, 1.9)")
151
160
  # Add VehicleWheel3D children at each wheel position
152
- summer_save_scene
161
+ summer_save_scene(scenePath="res://main.tscn")
153
162
  ```
154
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 4.6.1 binary 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
+
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
+
155
168
  **Background scenery wiring:**
156
169
 
157
170
  ```
158
- summer_add_node(parent="./World/Street", type="MeshInstance3D", name="ParkedSedan")
159
- summer_set_prop(path="./World/Street/ParkedSedan", property="mesh", value="res://assets/vehicles/sedan.glb")
160
- summer_save_scene
171
+ summer_instantiate_scene(scenePath="res://main.tscn", parent="./World/Street", scene="res://assets/vehicles/sedan.glb", name="ParkedSedan")
172
+ summer_save_scene(scenePath="res://main.tscn")
161
173
  ```
162
174
 
163
175
  ## Anti-patterns
164
176
 
165
- - **Single-angle reference for a hero vehicle.** Front-only → melted rear. Always go multi-angle for anything the player gets close to.
177
+ - **Single-angle reference for a hero vehicle.** Front-only → melted rear. Pass an `imageUrls` array (up to four views) for anything the player gets close to.
178
+ - **Expecting the prompt to request multi-view.** It cannot. `imageUrls` is the only multi-view mechanism.
166
179
  - **Flat-shaded prompt for hard surfaces.** "Smooth shading", "rounded edges" → loses the panel-line crispness that defines vehicles. Prefer "hard-surface", "panel-lined", "crisp edges".
167
180
  - **Skipping symmetry callouts.** Vehicles are bilaterally symmetric — without `symmetric, mirrored` you get one headlight bigger than the other 30% of the time.
168
181
  - **Asking the mesh pass to invent decals / liveries.** It can't — the mesh has the silhouette but the decals get geometry-baked weirdly. Use the texture pass for liveries.
@@ -182,7 +195,7 @@ summer_save_scene
182
195
  1. Generate the multi-angle reference at the Summer dashboard (or Midjourney / nano-banana web).
183
196
  2. Upload to Hunyuan or Trellis web playground → image-to-3D → download `.glb`.
184
197
  3. Drop into `res://assets/vehicles/`.
185
- 4. Wire as VehicleBody3D / MeshInstance3D in the Godot editor manually.
198
+ 4. Wire as VehicleBody3D / MeshInstance3D in Summer Engine manually.
186
199
 
187
200
  ## Handoff
188
201
 
@@ -200,4 +213,4 @@ After the vehicle is wired:
200
213
  - `summer:3d-assets/prop-model` — for separable parts (rotors, decals as decals, modular kit pieces).
201
214
  - `summer:asset-pipeline/asset-strategy` — meta-router.
202
215
  - `summer:character-controllers` — for player-driven vehicle input wiring.
203
- - `references/mcp-tools-reference.md` — `summer_generate_3d` schema, including `kind: "texture"` for the secondary detail pass.
216
+ - `../../../references/mcp-tools-reference.md` — `summer_generate_3d` schema, including `kind: "texture"` for the secondary detail pass.
package/skills/README.md CHANGED
@@ -70,7 +70,7 @@ Cross-portable. Cursor / Codex / Windsurf understand the same SKILL.md.
70
70
 
71
71
  1. **SKILL.md ≤ 500 lines.** Push detail into `references/`. Progressive disclosure.
72
72
  2. **MCP-preferred + file-edit-fallback.** Every code-touching skill must show both paths so the skill works without Summer MCP installed.
73
- 3. **Collaborative protocol.** "May I write…?" before any user-visible mutation. See `references/collaborative-protocol.md`.
73
+ 3. **Collaborative protocol.** "May I write…?" before any user-visible mutation. See `../references/collaborative-protocol.md`.
74
74
  4. **Template cross-link.** When a working starter exists, link via `template-id` and the section "Want a working starter?".
75
75
  5. **Test spec.** Every non-`_meta` skill ships `tests/spec.md` with at least one Test Case.
76
76