summer-engine 2.3.0 → 2.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 +20 -5
- package/.codex-plugin/plugin.json +15 -5
- package/.cursor-plugin/plugin.json +15 -5
- package/.factory-plugin/plugin.json +2 -2
- package/.opencode/INSTALL.md +1 -1
- package/CHANGELOG.md +27 -6
- package/CLAUDE.md +2 -2
- package/GEMINI.md +2 -3
- package/README.md +51 -30
- package/_persona/summer/SKILL.md +5 -6
- package/commands/gameskill.md +103 -0
- package/dist/bin/summer.js +12 -4
- package/dist/commands/create.js +2 -0
- package/dist/commands/doctor.js +71 -1
- package/dist/commands/install.d.ts +17 -0
- package/dist/commands/install.js +63 -4
- package/dist/commands/memory.d.ts +14 -0
- package/dist/commands/memory.js +196 -0
- package/dist/commands/setup.js +8 -2
- package/dist/commands/skills.js +90 -6
- package/dist/commands/status.js +3 -0
- package/dist/lib/agent-config.d.ts +2 -2
- package/dist/lib/agent-config.js +134 -7
- package/dist/lib/api-client.d.ts +13 -0
- package/dist/lib/api-client.js +63 -26
- package/dist/lib/async-op-lifecycle.d.ts +60 -0
- package/dist/lib/async-op-lifecycle.js +83 -0
- package/dist/lib/project-memory.d.ts +33 -0
- package/dist/lib/project-memory.js +220 -0
- package/dist/lib/skills-registry.d.ts +134 -61
- package/dist/lib/skills-registry.js +102 -4
- package/dist/lib/version-check.d.ts +106 -0
- package/dist/lib/version-check.js +338 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.js +81 -0
- package/dist/mcp/tools/debug-tools.js +32 -2
- package/dist/mcp/tools/project-tools.js +18 -6
- package/dist/mcp/tools/with-engine.d.ts +14 -0
- package/dist/mcp/tools/with-engine.js +52 -7
- package/gemini-extension.json +2 -2
- package/hooks/pre-commit-doctor.sh +0 -0
- package/hooks/run-hook.cmd +0 -0
- package/hooks/session-start.sh +0 -0
- package/package.json +6 -4
- package/skills/2d-assets/character-portrait/SKILL.md +1 -1
- package/skills/2d-assets/concept-art/SKILL.md +1 -1
- package/skills/2d-assets/create-asset-sheet/SKILL.md +163 -0
- package/skills/2d-assets/instantiate-asset-pack/SKILL.md +245 -0
- package/skills/2d-assets/pixel-art/SKILL.md +1 -1
- package/skills/2d-assets/skybox-panorama/SKILL.md +1 -1
- package/skills/2d-assets/sprite-sheet/SKILL.md +1 -1
- package/skills/2d-assets/tileable-texture/SKILL.md +1 -1
- package/skills/2d-assets/ui-graphics/SKILL.md +1 -1
- package/skills/2d-assets/use-widget-asset/SKILL.md +217 -0
- package/skills/3d-assets/character-model/SKILL.md +1 -1
- package/skills/3d-assets/organic-model/SKILL.md +1 -1
- package/skills/3d-assets/prop-model/SKILL.md +1 -1
- package/skills/3d-assets/vehicle-model/SKILL.md +1 -1
- package/skills/README.md +37 -30
- package/skills/ai-and-npcs/design-npc/SKILL.md +6 -6
- package/skills/animation/animation-tree/SKILL.md +2 -2
- package/skills/animation/facial-and-lipsync/SKILL.md +1 -1
- package/skills/animation/generate-motion/SKILL.md +1 -1
- package/skills/animation/procedural-animation/SKILL.md +2 -2
- package/skills/audio/adaptive-music/SKILL.md +1 -1
- package/skills/audio/audio-direction/SKILL.md +5 -5
- package/skills/audio/sound-effect/SKILL.md +2 -2
- package/skills/audio/voice-line/SKILL.md +25 -3
- package/skills/character-controllers/fps-controller/SKILL.md +5 -5
- package/skills/debugging/debug/SKILL.md +39 -1
- package/skills/deployment/export-and-ship/SKILL.md +4 -4
- package/skills/gameplay-mechanics/auto-fire-targeting/SKILL.md +170 -0
- package/skills/gameplay-mechanics/design-mechanic/SKILL.md +8 -8
- package/skills/level-design/design-level/SKILL.md +5 -5
- package/skills/level-design/scene-to-level/SKILL.md +125 -0
- package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +4 -4
- package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +4 -4
- package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +7 -7
- package/skills/performance/tune-performance/SKILL.md +5 -5
- package/skills/rendering-and-lighting/3d-lighting/SKILL.md +1 -1
- package/skills/rendering-and-lighting/art-direction/SKILL.md +5 -5
- package/skills/scene-and-project/brainstorm-game/SKILL.md +4 -4
- package/skills/scene-and-project/play/SKILL.md +1 -1
- package/skills/scene-and-project/scene-composition/SKILL.md +30 -1
- package/skills/scripting-patterns/gdscript-patterns/SKILL.md +53 -0
- package/skills/ui-and-ux/ui-basics/SKILL.md +1 -1
- package/skills/video/animated-loop/SKILL.md +1 -1
- package/skills/video/cinematic-cutscene/SKILL.md +1 -1
- package/skills/video/trailer-shot/SKILL.md +1 -1
- package/skills/visual-effects/game-feel/SKILL.md +6 -6
- package/skills/workflow/brainstorming/SKILL.md +164 -0
- package/skills/workflow/brainstorming/scripts/frame-template.html +214 -0
- package/skills/workflow/brainstorming/scripts/helper.js +88 -0
- package/skills/workflow/brainstorming/scripts/server.cjs +354 -0
- package/skills/workflow/brainstorming/scripts/start-server.sh +148 -0
- package/skills/workflow/brainstorming/scripts/stop-server.sh +56 -0
- package/skills/workflow/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/skills/workflow/brainstorming/visual-companion.md +287 -0
- package/skills/workflow/debugging-game-feel/SKILL.md +174 -0
- package/skills/workflow/diagnosing-perf-regressions/SKILL.md +190 -0
- package/skills/workflow/dispatching-parallel-agents/SKILL.md +182 -0
- package/skills/workflow/gameskill/SKILL.md +111 -0
- package/skills/workflow/investigating-bugs/CREATION-LOG.md +119 -0
- package/skills/workflow/investigating-bugs/SKILL.md +296 -0
- package/skills/workflow/investigating-bugs/condition-based-waiting-example.ts +158 -0
- package/skills/workflow/investigating-bugs/condition-based-waiting.md +115 -0
- package/skills/workflow/investigating-bugs/defense-in-depth.md +122 -0
- package/skills/workflow/investigating-bugs/find-polluter.sh +63 -0
- package/skills/workflow/investigating-bugs/root-cause-tracing.md +169 -0
- package/skills/workflow/investigating-bugs/test-academic.md +14 -0
- package/skills/workflow/investigating-bugs/test-pressure-1.md +58 -0
- package/skills/workflow/investigating-bugs/test-pressure-2.md +68 -0
- package/skills/workflow/investigating-bugs/test-pressure-3.md +69 -0
- package/skills/workflow/playtesting-a-feature/SKILL.md +173 -0
- package/skills/{_meta → workflow}/skill-create/SKILL.md +32 -22
- package/skills/{_meta → workflow}/skill-improve/SKILL.md +9 -10
- package/skills/{_meta → workflow}/skill-test/SKILL.md +12 -12
- package/skills/{_meta → workflow}/using-summer/SKILL.md +5 -2
- package/skills/workflow/verification-before-completion/SKILL.md +139 -0
- package/skills/workflow/writing-plans/SKILL.md +152 -0
- package/skills/workflow/writing-plans/plan-document-reviewer-prompt.md +49 -0
- package/skills/workflow/writing-skills/SKILL.md +655 -0
- package/skills/workflow/writing-skills/anthropic-best-practices.md +1150 -0
- package/skills/workflow/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/skills/workflow/writing-skills/graphviz-conventions.dot +172 -0
- package/skills/workflow/writing-skills/persuasion-principles.md +187 -0
- package/skills/workflow/writing-skills/render-graphs.js +168 -0
- package/skills/workflow/writing-skills/testing-skills-with-subagents.md +384 -0
- package/dist/commands/assets.d.ts +0 -2
- package/dist/commands/assets.js +0 -189
- package/dist/commands/debug.d.ts +0 -2
- package/dist/commands/debug.js +0 -127
- package/dist/commands/doctor.test.d.ts +0 -1
- package/dist/commands/doctor.test.js +0 -29
- package/dist/commands/project.d.ts +0 -2
- package/dist/commands/project.js +0 -170
- package/dist/commands/scene.d.ts +0 -2
- package/dist/commands/scene.js +0 -290
- package/dist/lib/agent-config.test.d.ts +0 -1
- package/dist/lib/agent-config.test.js +0 -80
- package/dist/lib/format.test.d.ts +0 -1
- package/dist/lib/format.test.js +0 -36
- package/dist/lib/plugin-manifests.test.d.ts +0 -1
- package/dist/lib/plugin-manifests.test.js +0 -134
- package/dist/lib/with-engine.d.ts +0 -14
- package/dist/lib/with-engine.js +0 -109
- package/skills/_shared/collaborative-protocol.md +0 -50
- package/skills/_shared/gd-style.md +0 -121
- package/skills/_shared/godot-version.md +0 -32
- package/skills/_shared/mcp-tools-reference.md +0 -133
- package/skills/_shared/summer-folder.md +0 -44
- package/skills/_shared/template-registry.md +0 -40
- package/skills/_tests/runner.md +0 -90
- package/skills/_tests/specs/3d-lighting.md +0 -19
- package/skills/_tests/specs/art-direction.md +0 -115
- package/skills/_tests/specs/asset-strategy.md +0 -19
- package/skills/_tests/specs/audio-direction.md +0 -123
- package/skills/_tests/specs/brainstorm-game.md +0 -99
- package/skills/_tests/specs/debug.md +0 -94
- package/skills/_tests/specs/design-level.md +0 -113
- package/skills/_tests/specs/design-mechanic.md +0 -112
- package/skills/_tests/specs/design-npc.md +0 -143
- package/skills/_tests/specs/export-and-ship.md +0 -114
- package/skills/_tests/specs/fps-controller.md +0 -113
- package/skills/_tests/specs/gdscript-patterns.md +0 -19
- package/skills/_tests/specs/host-authoritative-state.md +0 -104
- package/skills/_tests/specs/make-game.md +0 -19
- package/skills/_tests/specs/peer-to-peer-multiplayer.md +0 -99
- package/skills/_tests/specs/play.md +0 -88
- package/skills/_tests/specs/scene-composition.md +0 -19
- package/skills/_tests/specs/setup-multiplayer.md +0 -106
- package/skills/_tests/specs/tune-performance.md +0 -104
- package/skills/_tests/specs/ui-basics.md +0 -19
- package/skills/_tests/specs/vfx.md +0 -116
- package/skills/catalog.yaml +0 -991
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: instantiate-asset-pack
|
|
3
|
+
description: Use when the user wants to import or spawn an entire asset pack (the multi-slice ArtAsset produced by `create-asset-sheet`) into the current scene — not a single slice, the whole pack. Reads the pack's per-slice metadata (zOrder, isComposite, parentSliceIndex, widget, bbox), groups composites, sorts children by paint order, and emits the Sprite2D / Node2D / NinePatchRect ops to lay it out correctly. Trigger on "import the X pack", "spawn the UI from pack Y", "bring in that asset sheet", "add the panel from the pack".
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: 2d-assets
|
|
7
|
+
user-invocable: true
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_add_node summer_set_prop summer_set_resource_property summer_inspect_node summer_get_scene_tree summer_import_from_url
|
|
9
|
+
paths: ["assets/**", "art/**", "ui/**", "scenes/**"]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# instantiate-asset-pack — Instantiate Asset Pack into Scene
|
|
13
|
+
|
|
14
|
+
A pack ArtAsset (produced by `summer:2d-assets/create-asset-sheet`) is a bundle of cropped slice PNGs with per-slice metadata. This skill is the runtime side: given a pack, lay its slices into the current scene as a correctly-grouped, correctly-layered set of nodes.
|
|
15
|
+
|
|
16
|
+
For wiring individual widget slices (9-slice panels, progress bars, toggles), this skill delegates to `summer:2d-assets/use-widget-asset`. This skill handles the pack-level layout: grouping composites, paint order, spatial offset, naming.
|
|
17
|
+
|
|
18
|
+
## When to use
|
|
19
|
+
|
|
20
|
+
- "Import the dungeon UI pack."
|
|
21
|
+
- "Spawn the settings panel from that asset sheet I just made."
|
|
22
|
+
- "Bring the whole biome pack into this scene."
|
|
23
|
+
- "Add the card frame composite from pack X."
|
|
24
|
+
- User has a pack ArtAsset in their library and wants it placed in the scene, not just imported as files.
|
|
25
|
+
|
|
26
|
+
## When NOT to use
|
|
27
|
+
|
|
28
|
+
- User wants a single slice → import it directly as a `Sprite2D` (or `summer:2d-assets/use-widget-asset` if it's a UI widget).
|
|
29
|
+
- User wants to **generate** a new pack → `summer:2d-assets/create-asset-sheet`.
|
|
30
|
+
- User wants to apply a slice as a material/texture on a 3D mesh → not the pack flow; see `asset_pipeline.json`.
|
|
31
|
+
|
|
32
|
+
## Pack JSON shape
|
|
33
|
+
|
|
34
|
+
Full schema: `publicsummerengine/public/knowledge/asset_pack_schema.json`.
|
|
35
|
+
|
|
36
|
+
The per-slice fields this skill cares about:
|
|
37
|
+
|
|
38
|
+
| Field | Used for |
|
|
39
|
+
|---|---|
|
|
40
|
+
| `name` | Node name |
|
|
41
|
+
| `url` | Texture path (after `summer_import_from_url`) |
|
|
42
|
+
| `bbox` | Spatial offset of composite children relative to parent |
|
|
43
|
+
| `zOrder` | `z_index` on the Sprite2D; sort children by this ascending |
|
|
44
|
+
| `isComposite` | Filter out parent slices (flat previews, not runtime assets) |
|
|
45
|
+
| `parentSliceIndex` | Group children to their composite parent |
|
|
46
|
+
| `pairWith` | Toggle ON/OFF pair link |
|
|
47
|
+
| `widget` | Wrap in NinePatchRect / TextureProgressBar via `use-widget-asset` |
|
|
48
|
+
| `category` | Decide wrapper type — `ui` → Control tree, else Node2D/Sprite2D |
|
|
49
|
+
|
|
50
|
+
Legacy fallback: `slice.zOrder ?? slice.layerIndex ?? packFileIndex`, `slice.isComposite ?? slice.isReference ?? false`. `packFileIndex` is the iteration counter when looping `packFiles[]`, not a stored field.
|
|
51
|
+
|
|
52
|
+
## Standalone child slice
|
|
53
|
+
|
|
54
|
+
A standalone slice has no `parentSliceIndex` and isn't a composite parent. Spawn as a single `Sprite2D`:
|
|
55
|
+
|
|
56
|
+
1. Import the slice URL via `summer_import_from_url` to get a `res://` path.
|
|
57
|
+
2. `summer_add_node` — type `Sprite2D`, name `slice.name`.
|
|
58
|
+
3. `summer_set_prop` — `texture = res://...`.
|
|
59
|
+
4. If `slice.zOrder` is set, `summer_set_prop` — `z_index = slice.zOrder`.
|
|
60
|
+
|
|
61
|
+
If the slice has a `widget` field, hand off to `summer:2d-assets/use-widget-asset` after step 1.
|
|
62
|
+
|
|
63
|
+
## Composite parent + children
|
|
64
|
+
|
|
65
|
+
A composite parent (`isComposite: true`) is the flat preview the wizard made of the assembled panel. **Do not spawn it.** Its children — slices whose `parentSliceIndex` points back at it — are the real runtime assets.
|
|
66
|
+
|
|
67
|
+
Recipe:
|
|
68
|
+
|
|
69
|
+
1. **Skip the parent.** Filter out `isComposite: true` slices unless the user asked for the flat preview.
|
|
70
|
+
2. **Group children.** Collect every slice whose `parentSliceIndex` matches this parent's index.
|
|
71
|
+
3. **Sort children by `zOrder` ascending.** Lower zOrder renders behind. Use the legacy fallback chain.
|
|
72
|
+
4. **Spawn a `Node2D` parent** named after the composite parent's `name` (e.g. `settings_panel`).
|
|
73
|
+
5. **For each child, in sorted order:**
|
|
74
|
+
- Import `child.url` → `res://` path.
|
|
75
|
+
- `summer_add_node` `Sprite2D` under the Node2D, name = `child.name`.
|
|
76
|
+
- `summer_set_prop` — `texture = res://...`.
|
|
77
|
+
- `summer_set_prop` — `z_index = child.zOrder`.
|
|
78
|
+
- `summer_set_prop` — `position = Vector2(child.bbox.x - parent.bbox.x, child.bbox.y - parent.bbox.y)`.
|
|
79
|
+
6. **Apply widget post-processing** to any child with a `widget` field — see next section.
|
|
80
|
+
|
|
81
|
+
## Widget post-processing
|
|
82
|
+
|
|
83
|
+
When a child slice has `widget.kind` set, the bare Sprite2D is not the right node. Replace or wrap it per the widget mapping:
|
|
84
|
+
|
|
85
|
+
| widget.kind | Node | Mapping |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| `panel`, `button` | `NinePatchRect` | `frameMargins[0..3]` → `patch_margin_left/top/right/bottom` |
|
|
88
|
+
| `progress_bar` | `TextureProgressBar` | `fillRect` → `stretch_margin_*`; `orientation` → `fill_mode` |
|
|
89
|
+
| `slider` | `HSlider`/`VSlider` + `NinePatchRect` track | track uses `frameMargins`; slider sits on top |
|
|
90
|
+
| `toggle` | `TextureRect` | Swap `texture` between this slice and `packFiles[pairWith].url` |
|
|
91
|
+
|
|
92
|
+
Delegate the actual wiring (percentage-to-pixel conversion, node-specific props) to `summer:2d-assets/use-widget-asset`. This skill places the node; that skill configures the geometry.
|
|
93
|
+
|
|
94
|
+
## Naming convention
|
|
95
|
+
|
|
96
|
+
- `slice.name` is canonical. The wizard's classifier produces snake_case names (`play_button`, `health_bar_fill`, `settings_panel`). Use as the node name verbatim.
|
|
97
|
+
- If the user said "name them with prefix X" (e.g. "prefix everything with `hud_`"), prepend: `hud_play_button`.
|
|
98
|
+
- Composite parent's `name` becomes the `Node2D` wrapper name.
|
|
99
|
+
- If a name collides with an existing node in the scene, suffix `_1`, `_2`, etc. Do not silently overwrite.
|
|
100
|
+
|
|
101
|
+
## Examples
|
|
102
|
+
|
|
103
|
+
### Example 1 — Standalone slice import
|
|
104
|
+
|
|
105
|
+
Pack has one non-composite slice, `crate_wooden`, no widget metadata. Place it at scene origin:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"ops": [
|
|
110
|
+
{
|
|
111
|
+
"op": "AddNode",
|
|
112
|
+
"parent": ".",
|
|
113
|
+
"type": "Sprite2D",
|
|
114
|
+
"name": "crate_wooden"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"op": "SetProp",
|
|
118
|
+
"path": "./crate_wooden",
|
|
119
|
+
"key": "texture",
|
|
120
|
+
"value": "res://assets/images/crate_wooden.png"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"op": "SetProp",
|
|
124
|
+
"path": "./crate_wooden",
|
|
125
|
+
"key": "position",
|
|
126
|
+
"value": "Vector2(0, 0)"
|
|
127
|
+
},
|
|
128
|
+
{ "op": "SaveScene" }
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Example 2 — Composite panel with three children
|
|
134
|
+
|
|
135
|
+
Pack has a composite parent `settings_panel` (filtered out) plus three children:
|
|
136
|
+
|
|
137
|
+
- `panel_bg` — zOrder 0, bbox offset (0, 0), widget.kind = `panel`, frameMargins present
|
|
138
|
+
- `apply_button` — zOrder 1, bbox offset (40, 120), widget.kind = `button`, frameMargins present
|
|
139
|
+
- `close_icon` — zOrder 2, bbox offset (220, 8), no widget
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
{
|
|
143
|
+
"ops": [
|
|
144
|
+
{
|
|
145
|
+
"op": "AddNode",
|
|
146
|
+
"parent": ".",
|
|
147
|
+
"type": "Node2D",
|
|
148
|
+
"name": "settings_panel"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"op": "AddNode",
|
|
152
|
+
"parent": "./settings_panel",
|
|
153
|
+
"type": "NinePatchRect",
|
|
154
|
+
"name": "panel_bg"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"op": "SetProp",
|
|
158
|
+
"path": "./settings_panel/panel_bg",
|
|
159
|
+
"key": "texture",
|
|
160
|
+
"value": "res://assets/images/panel_bg.png"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"op": "SetProp",
|
|
164
|
+
"path": "./settings_panel/panel_bg",
|
|
165
|
+
"key": "z_index",
|
|
166
|
+
"value": 0
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"op": "SetProp",
|
|
170
|
+
"path": "./settings_panel/panel_bg",
|
|
171
|
+
"key": "position",
|
|
172
|
+
"value": "Vector2(0, 0)"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"op": "AddNode",
|
|
176
|
+
"parent": "./settings_panel",
|
|
177
|
+
"type": "NinePatchRect",
|
|
178
|
+
"name": "apply_button"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"op": "SetProp",
|
|
182
|
+
"path": "./settings_panel/apply_button",
|
|
183
|
+
"key": "texture",
|
|
184
|
+
"value": "res://assets/images/apply_button.png"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"op": "SetProp",
|
|
188
|
+
"path": "./settings_panel/apply_button",
|
|
189
|
+
"key": "z_index",
|
|
190
|
+
"value": 1
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"op": "SetProp",
|
|
194
|
+
"path": "./settings_panel/apply_button",
|
|
195
|
+
"key": "position",
|
|
196
|
+
"value": "Vector2(40, 120)"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"op": "AddNode",
|
|
200
|
+
"parent": "./settings_panel",
|
|
201
|
+
"type": "Sprite2D",
|
|
202
|
+
"name": "close_icon"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"op": "SetProp",
|
|
206
|
+
"path": "./settings_panel/close_icon",
|
|
207
|
+
"key": "texture",
|
|
208
|
+
"value": "res://assets/images/close_icon.png"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"op": "SetProp",
|
|
212
|
+
"path": "./settings_panel/close_icon",
|
|
213
|
+
"key": "z_index",
|
|
214
|
+
"value": 2
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"op": "SetProp",
|
|
218
|
+
"path": "./settings_panel/close_icon",
|
|
219
|
+
"key": "position",
|
|
220
|
+
"value": "Vector2(220, 8)"
|
|
221
|
+
},
|
|
222
|
+
{ "op": "SaveScene" }
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
After this, hand `panel_bg` and `apply_button` to `summer:2d-assets/use-widget-asset` to set `patch_margin_*` from their `widget.frameMargins`.
|
|
228
|
+
|
|
229
|
+
Note the ops format: `position` is the **Godot string** `"Vector2(0, 0)"`, not a JSON object. `z_index` is a bare integer. This is the format Summer Engine expects — see the publicsummerengine CLAUDE.md.
|
|
230
|
+
|
|
231
|
+
## Failure modes
|
|
232
|
+
|
|
233
|
+
- **Old pack with no `zOrder`.** Fall back to `slice.zOrder ?? slice.layerIndex ?? packFileIndex`. `packFileIndex` is the iteration counter when looping `packFiles[]` (not a persisted field). If even `layerIndex` is missing (very old pack), iteration order is the only signal — accept it.
|
|
234
|
+
- **Old pack with no `isComposite`.** Fall back to `slice.isComposite ?? slice.isReference ?? false`. If both are missing on every slice, treat the whole pack as standalone — no compositing, every slice spawns at origin as its own Sprite2D.
|
|
235
|
+
- **Composite parent with no children in the pack.** The composite preview is the only thing the user has — render the parent as a regular Sprite2D (do not filter it out in this case).
|
|
236
|
+
- **Child references a parent that's missing.** Treat the child as standalone. Spawn at `Vector2(0, 0)` with its own `zOrder`.
|
|
237
|
+
- **Widget with no `frameMargins`.** The vision detector said `kind: 'panel'` but didn't emit margins. Render as `TextureRect` (or `Sprite2D` if outside a Control tree) and skip 9-slice. Do not invent margins.
|
|
238
|
+
- **Name collision in scene.** Suffix `_1`, `_2`, etc. Never overwrite an existing node.
|
|
239
|
+
- **Slice URL fails to import.** `summer_import_from_url` returns an error — skip that slice, log a warning, continue with the rest. Do not abort the whole pack.
|
|
240
|
+
|
|
241
|
+
## Related skills
|
|
242
|
+
|
|
243
|
+
- `summer:2d-assets/create-asset-sheet` — production side; how the pack was made.
|
|
244
|
+
- `summer:2d-assets/use-widget-asset` — wiring an individual widget slice (NinePatchRect, TextureProgressBar geometry).
|
|
245
|
+
- `asset_pipeline.json` — broader find-or-generate -> import -> apply flow.
|
|
@@ -177,4 +177,4 @@ After the asset is wired:
|
|
|
177
177
|
- `summer:2d-assets/sprite-sheet` — animated pixel frames.
|
|
178
178
|
- `summer:2d-assets/character-portrait` — high-res counterpart.
|
|
179
179
|
- `summer:asset-pipeline/asset-strategy` — meta-router.
|
|
180
|
-
- `
|
|
180
|
+
- `references/mcp-tools-reference.md` — `summer_generate_image` schema.
|
|
@@ -204,4 +204,4 @@ After the sky is wired:
|
|
|
204
204
|
- `summer:2d-assets/tileable-texture` — ground/floor counterpart.
|
|
205
205
|
- `summer:scene-composition` — WorldEnvironment placement and configuration.
|
|
206
206
|
- `summer:asset-pipeline/asset-strategy` — meta-router.
|
|
207
|
-
- `
|
|
207
|
+
- `references/mcp-tools-reference.md` — `summer_generate_image` schema.
|
|
@@ -236,4 +236,4 @@ After the animation is wired:
|
|
|
236
236
|
- `summer:2d-assets/character-portrait` — base portrait for higher-res characters.
|
|
237
237
|
- `summer:animation/generate-motion` — 3D-skeletal counterpart.
|
|
238
238
|
- `summer:audio/sound-effect` — frame-synced SFX.
|
|
239
|
-
- `
|
|
239
|
+
- `references/mcp-tools-reference.md` — `summer_generate_image` schema.
|
|
@@ -202,4 +202,4 @@ After the texture is wired:
|
|
|
202
202
|
- `summer:asset-pipeline/asset-strategy` — meta-router and 3D pipeline.
|
|
203
203
|
- `summer:2d-assets/skybox-panorama` — sky/environment counterpart.
|
|
204
204
|
- `summer:scene-composition` — applying textures to CSG and MeshInstance3D.
|
|
205
|
-
- `
|
|
205
|
+
- `references/mcp-tools-reference.md` — `summer_generate_image` schema.
|
|
@@ -207,4 +207,4 @@ After the UI graphic is wired:
|
|
|
207
207
|
- `summer:2d-assets/character-portrait` — for in-UI character images.
|
|
208
208
|
- `summer:2d-assets/pixel-art` — pixel-style UI.
|
|
209
209
|
- `summer:scene-composition` — Theme and Control hierarchy.
|
|
210
|
-
- `
|
|
210
|
+
- `references/mcp-tools-reference.md` — `summer_generate_image` schema.
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
---
|
|
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.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: 2d-assets
|
|
7
|
+
user-invocable: true
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_add_node summer_set_prop summer_set_resource_property summer_inspect_node summer_get_scene_tree
|
|
9
|
+
paths: ["assets/**", "art/**", "ui/**", "scenes/**"]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# use-widget-asset — Wire a sliced widget into a real Godot control
|
|
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.
|
|
15
|
+
|
|
16
|
+
If a slice has no widget metadata, treat it as a static texture (`TextureRect`) and skip this skill.
|
|
17
|
+
|
|
18
|
+
## Shape support (read first)
|
|
19
|
+
|
|
20
|
+
The single rule that governs everything below:
|
|
21
|
+
|
|
22
|
+
> **9-slice for any AABB-fitting stretchable widget. Static texture for everything else.**
|
|
23
|
+
|
|
24
|
+
Concrete:
|
|
25
|
+
|
|
26
|
+
| Shape | Approach | Why |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| Rectangle (panel, button, bar, frame) | `NinePatchRect` with `frameMargins` | 4 corners stay fixed, 4 edges stretch on one axis, center stretches both. Standard 9-slice. |
|
|
29
|
+
| Rounded rectangle | `NinePatchRect` with `frameMargins` | Corner radii live inside the fixed corner cells. Identical to plain rectangle. |
|
|
30
|
+
| Circle / ellipse (round button, gem) | Static `TextureRect`, scale uniformly | No edge to stretch — the shape has no "interior to grow." |
|
|
31
|
+
| Diamond / hexagon (badge) | Either ship at multiple sizes OR static texture, scale uniformly | 9-slice would distort the angled corners. SDF would solve it but is overkill for this pipeline. |
|
|
32
|
+
| Diagonal banner | `NinePatchRect`, accept some distortion | Slopes sit in the fixed corner cells; horizontal middle stretches. Looks fine if not stretched aggressively. |
|
|
33
|
+
| Organic shape (scroll, ribbon, painted sash) | Static `TextureRect` | Not stretchable in any direction. Regenerate at the target size if you need a different one. |
|
|
34
|
+
|
|
35
|
+
The wizard's vision detector only emits `widget` metadata for the 5 kinds it knows how to slice (slider, progress_bar, toggle, panel, button). Anything else lands as a static `category: ui` slice with no `widget` field — fall through to "render as TextureRect" and skip the rest of this skill.
|
|
36
|
+
|
|
37
|
+
## What the pack hands you
|
|
38
|
+
|
|
39
|
+
The wizard saves the pack as a single ArtAsset with:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
isPack: true
|
|
43
|
+
packFiles: [{ url, name, type: "image/png" }, ...]
|
|
44
|
+
metadata.sliceBboxes: { "0": {x,y,w,h}, "1": ... } // source-sheet coords
|
|
45
|
+
metadata.sliceMeta: { "0": { category, widget?, pairWith?, parentSliceIndex? }, ... }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`widget` looks like:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
{
|
|
52
|
+
kind: "slider" | "progress_bar" | "toggle" | "panel" | "button",
|
|
53
|
+
frameMargins: [leftPct, topPct, rightPct, bottomPct], // optional
|
|
54
|
+
fillRect: [xPct, yPct, wPct, hPct], // optional
|
|
55
|
+
orientation: "horizontal" | "vertical", // optional
|
|
56
|
+
pairCandidate: boolean // optional
|
|
57
|
+
}
|
|
58
|
+
```
|
|
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.
|
|
61
|
+
|
|
62
|
+
## Decision tree
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
kind?
|
|
66
|
+
├─ "panel" or "button"
|
|
67
|
+
│ └─ NinePatchRect, set patch_margin_* from frameMargins
|
|
68
|
+
├─ "slider"
|
|
69
|
+
│ └─ HSlider/VSlider with two TextureRects underneath: track + fill
|
|
70
|
+
├─ "progress_bar"
|
|
71
|
+
│ └─ TextureProgressBar with texture_under = 9-slice frame,
|
|
72
|
+
│ texture_progress = cropped fill region
|
|
73
|
+
└─ "toggle"
|
|
74
|
+
└─ TextureRect that swaps texture between on/off via pairWith
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Recipes
|
|
78
|
+
|
|
79
|
+
### 1. Panel — NinePatchRect
|
|
80
|
+
|
|
81
|
+
```gdscript
|
|
82
|
+
extends NinePatchRect
|
|
83
|
+
|
|
84
|
+
@export var slice_url: String
|
|
85
|
+
@export var frame_margins: Array # [L, T, R, B] in percentage
|
|
86
|
+
@export var slice_size: Vector2 # the slice's pixel dimensions
|
|
87
|
+
|
|
88
|
+
func _ready():
|
|
89
|
+
texture = load(slice_url)
|
|
90
|
+
var w = slice_size.x
|
|
91
|
+
var h = slice_size.y
|
|
92
|
+
patch_margin_left = int(round(frame_margins[0] * w / 100.0))
|
|
93
|
+
patch_margin_top = int(round(frame_margins[1] * h / 100.0))
|
|
94
|
+
patch_margin_right = int(round(frame_margins[2] * w / 100.0))
|
|
95
|
+
patch_margin_bottom = int(round(frame_margins[3] * h / 100.0))
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
When the NinePatchRect is sized larger than the source, corners stay fixed, edges stretch on one axis, center stretches both. This is exactly the behavior the wizard's widget detection assumes.
|
|
99
|
+
|
|
100
|
+
### 2. Progress bar — TextureProgressBar (fill_mode = FILL_LEFT_TO_RIGHT)
|
|
101
|
+
|
|
102
|
+
```gdscript
|
|
103
|
+
extends TextureProgressBar
|
|
104
|
+
|
|
105
|
+
@export var slice_url: String # The full bar (frame + fill at 100%)
|
|
106
|
+
@export var fill_rect: Array # [x, y, w, h] in percentage
|
|
107
|
+
@export var orientation: String = "horizontal"
|
|
108
|
+
|
|
109
|
+
func _ready():
|
|
110
|
+
var tex = load(slice_url)
|
|
111
|
+
# The base / "under" texture is the same image — Godot will mask it
|
|
112
|
+
# to whatever value 0-100 we set.
|
|
113
|
+
texture_under = tex
|
|
114
|
+
texture_progress = tex
|
|
115
|
+
fill_mode = TextureProgressBar.FILL_LEFT_TO_RIGHT if orientation == "horizontal" else TextureProgressBar.FILL_TOP_TO_BOTTOM
|
|
116
|
+
# The fill rect tells Godot which sub-region of the texture is the
|
|
117
|
+
# bar fill (vs the frame). Texture_progress_offset + stretch_margin_*
|
|
118
|
+
# form the inset.
|
|
119
|
+
var sw = tex.get_width()
|
|
120
|
+
var sh = tex.get_height()
|
|
121
|
+
var fx = int(round(fill_rect[0] * sw / 100.0))
|
|
122
|
+
var fy = int(round(fill_rect[1] * sh / 100.0))
|
|
123
|
+
var fw = int(round(fill_rect[2] * sw / 100.0))
|
|
124
|
+
var fh = int(round(fill_rect[3] * sh / 100.0))
|
|
125
|
+
stretch_margin_left = fx
|
|
126
|
+
stretch_margin_top = fy
|
|
127
|
+
stretch_margin_right = sw - (fx + fw)
|
|
128
|
+
stretch_margin_bottom = sh - (fy + fh)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Set `value` from 0 to 100 to drive the bar.
|
|
132
|
+
|
|
133
|
+
### 3. Slider — HSlider with TextureRect overlays
|
|
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).
|
|
136
|
+
|
|
137
|
+
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
|
+
|
|
139
|
+
### 4. Toggle — TextureRect that swaps texture via pairWith
|
|
140
|
+
|
|
141
|
+
```gdscript
|
|
142
|
+
extends TextureRect
|
|
143
|
+
|
|
144
|
+
@export var on_url: String # The slice with name ending in "_on"
|
|
145
|
+
@export var off_url: String # The pair's URL (sliceMeta.pairWith)
|
|
146
|
+
|
|
147
|
+
var _state := false
|
|
148
|
+
|
|
149
|
+
func set_state(on: bool) -> void:
|
|
150
|
+
_state = on
|
|
151
|
+
texture = load(on_url if on else off_url)
|
|
152
|
+
|
|
153
|
+
func _ready():
|
|
154
|
+
texture = load(off_url)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
In the pack, find the pair: `sliceMeta[currentIndex].pairWith` gives the other slice's index; look it up in `packFiles[pairIndex].url`.
|
|
158
|
+
|
|
159
|
+
## Cut-offs and re-renders
|
|
160
|
+
|
|
161
|
+
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. FLUX will regenerate it 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.
|
|
162
|
+
|
|
163
|
+
## Composite panels with sub-elements
|
|
164
|
+
|
|
165
|
+
When a slice has `parentSliceIndex` set, it came from a **Break-down** pass — the parent is a composite (settings panel, card frame) and this slice is one of its sub-elements (Apply button, slider, toggle). Use either:
|
|
166
|
+
|
|
167
|
+
- The whole parent as a single `NinePatchRect` for the frame, OR
|
|
168
|
+
- Instantiate each sub-element individually positioned where the original panel had them (the parent's `sliceBboxes[parentSliceIndex]` gives the source-sheet rect; each sub-slice's relative position within it is recoverable from its own bbox).
|
|
169
|
+
|
|
170
|
+
Pick based on whether your game needs the panel to stretch as one unit or whether each control needs independent interaction.
|
|
171
|
+
|
|
172
|
+
See **Composite Panels (Sliced Further)** below for the canonical fields the wizard now emits (`isComposite`, `zOrder`) and the consume recipe.
|
|
173
|
+
|
|
174
|
+
## Composite Panels (Sliced Further)
|
|
175
|
+
|
|
176
|
+
The wizard's Break-down pass produces two new per-slice fields the runtime must understand:
|
|
177
|
+
|
|
178
|
+
| Field | Type | Meaning |
|
|
179
|
+
|---|---|---|
|
|
180
|
+
| `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. |
|
|
181
|
+
| `zOrder` | number | Back-to-front paint order on children. Lower = behind. Matches Godot `z_index`, Unity `sortingOrder`, CSS `z-index`. |
|
|
182
|
+
| `parentSliceIndex` | number | Set on each child, points at the composite parent. Used to group children. |
|
|
183
|
+
|
|
184
|
+
The full schema lives at `publicsummerengine/public/knowledge/asset_pack_schema.json`. Read it once if you need to know every field.
|
|
185
|
+
|
|
186
|
+
### Consume recipe
|
|
187
|
+
|
|
188
|
+
1. **Filter out composite parents.** Drop any slice with `isComposite: true` unless the caller specifically asked for the flat preview.
|
|
189
|
+
2. **Group by `parentSliceIndex`.** Slices that share a `parentSliceIndex` belong to the same composite group. Slices without it are standalone.
|
|
190
|
+
3. **Sort each group by `zOrder` ascending.** Lower values render behind higher values. This determines paint order.
|
|
191
|
+
4. **Spawn `Node2D` parent + `Sprite2D` children.** Name the parent after the original composite parent's slice name. For each child:
|
|
192
|
+
- `name = child.name`
|
|
193
|
+
- `texture = imported res:// path`
|
|
194
|
+
- `z_index = child.zOrder`
|
|
195
|
+
- `position = Vector2(child.bbox.x - parent.bbox.x, child.bbox.y - parent.bbox.y)` — offset relative to the parent's source-sheet rect.
|
|
196
|
+
5. **Apply widget post-processing.** If any child has a `widget` field, wrap or replace its `Sprite2D` with the appropriate Control node per the recipes above (panel → `NinePatchRect`, progress_bar → `TextureProgressBar`, etc.).
|
|
197
|
+
|
|
198
|
+
For the full instantiation flow (op JSON, examples), use `summer:2d-assets/instantiate-asset-pack`.
|
|
199
|
+
|
|
200
|
+
### Legacy compatibility
|
|
201
|
+
|
|
202
|
+
Older packs (saved before the rename) used different field names. Always fall back:
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
const zOrder = slice.zOrder ?? slice.layerIndex ?? packFileIndex;
|
|
206
|
+
const isComposite = slice.isComposite ?? slice.isReference ?? false;
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
`packFileIndex` is the slice's iteration position in `packFiles[]` (the loop counter, not a persisted field). On packs with no `zOrder` and no `layerIndex` at all, iteration order is the only signal you get — accept it and move on.
|
|
210
|
+
|
|
211
|
+
Check `metadata.schemaVersion` on the pack: `null` (or absent) = legacy, `1` = current. New packs from the wizard always set it.
|
|
212
|
+
|
|
213
|
+
## What this skill does NOT cover
|
|
214
|
+
|
|
215
|
+
- Auto-tiling terrain (Wang / 47-tile). Different format entirely — see `summer:2d-assets/tileable-texture`.
|
|
216
|
+
- Animated UI (button press-down sprites, hover glow). The wizard captures static frames; for animation see `summer:2d-assets/sprite-sheet`.
|
|
217
|
+
- Non-AABB widgets in the 9-slice path. See the **Shape support** table at the top — for circles, hexagons, organic shapes, fall through to `TextureRect` and skip 9-slice entirely.
|
|
@@ -222,4 +222,4 @@ After the rigged character is wired:
|
|
|
222
222
|
- `summer:asset-pipeline/asset-strategy` — meta-router; this skill is the canonical drill-down of its "Image-to-3D for characters" path.
|
|
223
223
|
- `summer:3d-assets/prop-model` — for non-character props.
|
|
224
224
|
- `summer:scene-composition` — for the CharacterBody3D + Mesh + Collider parent pattern.
|
|
225
|
-
- `
|
|
225
|
+
- `references/mcp-tools-reference.md` — full parameter schemas for `summer_generate_3d`, `summer_generate_image`, and `summer_generate_motion`.
|
|
@@ -189,4 +189,4 @@ After the organic models are scattered:
|
|
|
189
189
|
- `summer:3d-assets/environment-kit` — pair with this skill: kit pieces give the architecture, organic gives the natural softness.
|
|
190
190
|
- `summer:asset-pipeline/asset-strategy` — meta-router; ground textures and skyboxes go to Pipeline 2 / panoramic gen.
|
|
191
191
|
- `summer:scene-composition` — MultiMeshInstance3D scatter pattern.
|
|
192
|
-
- `
|
|
192
|
+
- `references/mcp-tools-reference.md` — `summer_generate_3d` schema.
|
|
@@ -130,4 +130,4 @@ After the prop is wired:
|
|
|
130
130
|
- `summer:asset-pipeline/asset-strategy` — the meta-router that decides between this skill and Pipeline 2 (textures).
|
|
131
131
|
- `summer:3d-assets/character-model` — for humanoids.
|
|
132
132
|
- `summer:3d-assets/environment-kit` — for style-locked sets.
|
|
133
|
-
- `
|
|
133
|
+
- `references/mcp-tools-reference.md` — `summer_generate_3d` parameter schema.
|
|
@@ -199,4 +199,4 @@ After the vehicle is wired:
|
|
|
199
199
|
- `summer:3d-assets/prop-model` — for separable parts (rotors, decals as decals, modular kit pieces).
|
|
200
200
|
- `summer:asset-pipeline/asset-strategy` — meta-router.
|
|
201
201
|
- `summer:character-controllers` — for player-driven vehicle input wiring.
|
|
202
|
-
- `
|
|
202
|
+
- `references/mcp-tools-reference.md` — `summer_generate_3d` schema, including `kind: "texture"` for the secondary detail pass.
|
package/skills/README.md
CHANGED
|
@@ -7,32 +7,45 @@ When an agent is asked to make a game in Summer Engine, this is what it reads to
|
|
|
7
7
|
## Layout
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
|
|
11
|
-
├──
|
|
12
|
-
├──
|
|
13
|
-
├── _shared/ # cross-skill references every skill can link
|
|
10
|
+
summer-cli/
|
|
11
|
+
├── .claude-plugin/plugin.json # the registry (skills: array). Sibling Codex/Cursor manifests mirror it.
|
|
12
|
+
├── references/ # cross-skill shared docs (sibling of skills/)
|
|
14
13
|
│ ├── godot-version.md
|
|
15
14
|
│ ├── mcp-tools-reference.md
|
|
16
15
|
│ ├── collaborative-protocol.md
|
|
17
16
|
│ ├── template-registry.md
|
|
17
|
+
│ ├── summer-folder.md
|
|
18
18
|
│ └── gd-style.md
|
|
19
|
-
├──
|
|
20
|
-
│ ├── skill-test
|
|
21
|
-
│
|
|
22
|
-
|
|
23
|
-
├──
|
|
24
|
-
|
|
25
|
-
│
|
|
26
|
-
|
|
27
|
-
├──
|
|
28
|
-
├──
|
|
29
|
-
├──
|
|
30
|
-
|
|
19
|
+
├── tests/
|
|
20
|
+
│ ├── runner.md # how /skill-test works
|
|
21
|
+
│ └── specs/ # behavioral specs per skill
|
|
22
|
+
└── skills/
|
|
23
|
+
├── README.md # this file
|
|
24
|
+
├── workflow/ # process skills (brainstorming, debugging, planning, etc.)
|
|
25
|
+
│ ├── using-summer/
|
|
26
|
+
│ ├── skill-create/
|
|
27
|
+
│ ├── skill-improve/
|
|
28
|
+
│ ├── skill-test/
|
|
29
|
+
│ ├── brainstorming/
|
|
30
|
+
│ ├── investigating-bugs/
|
|
31
|
+
│ ├── verification-before-completion/
|
|
32
|
+
│ ├── writing-plans/
|
|
33
|
+
│ ├── dispatching-parallel-agents/
|
|
34
|
+
│ ├── writing-skills/
|
|
35
|
+
│ ├── playtesting-a-feature/
|
|
36
|
+
│ ├── debugging-game-feel/
|
|
37
|
+
│ └── diagnosing-perf-regressions/
|
|
38
|
+
└── <category>/<skill>/ # gamedev domain skills
|
|
39
|
+
├── SKILL.md # < 500 lines, frontmatter + body
|
|
40
|
+
├── reference.md # optional, loaded on demand
|
|
41
|
+
└── examples/ # optional, working snippets
|
|
31
42
|
```
|
|
32
43
|
|
|
33
|
-
## Categories (
|
|
44
|
+
## Categories (21)
|
|
34
45
|
|
|
35
|
-
`character-controllers`, `gameplay-mechanics`, `scripting-patterns`, `scene-and-project`, `rendering-and-lighting`, `shaders`, `visual-effects`, `post-processing`, `animation`, `audio`, `physics`, `multiplayer-and-networking`, `ai-and-npcs`, `level-design`, `performance`, `ui-and-ux`, `asset-pipeline`, `input-and-controls`, `debugging`, `deployment`.
|
|
46
|
+
`workflow` (process discipline) plus 20 gamedev domains: `character-controllers`, `gameplay-mechanics`, `scripting-patterns`, `scene-and-project`, `rendering-and-lighting`, `shaders`, `visual-effects`, `post-processing`, `animation`, `audio`, `physics`, `multiplayer-and-networking`, `ai-and-npcs`, `level-design`, `performance`, `ui-and-ux`, `asset-pipeline`, `input-and-controls`, `debugging`, `deployment`.
|
|
47
|
+
|
|
48
|
+
Folder structure is for humans only — Claude resolves skills as `summer:<skill-name>` regardless of category nesting.
|
|
36
49
|
|
|
37
50
|
## Standard
|
|
38
51
|
|
|
@@ -45,7 +58,7 @@ description: <when-to-use, key trigger phrases first>
|
|
|
45
58
|
license: MIT
|
|
46
59
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
47
60
|
category: <one of the 20>
|
|
48
|
-
template-id: <optional, resolved against
|
|
61
|
+
template-id: <optional, resolved against references/template-registry.md>
|
|
49
62
|
allowed-tools: Read Grep summer_add_node summer_set_prop ...
|
|
50
63
|
paths: ["**/*.gd", "**/*.tscn"]
|
|
51
64
|
---
|
|
@@ -57,7 +70,7 @@ Cross-portable. Cursor / Codex / Windsurf understand the same SKILL.md.
|
|
|
57
70
|
|
|
58
71
|
1. **SKILL.md ≤ 500 lines.** Push detail into `references/`. Progressive disclosure.
|
|
59
72
|
2. **MCP-preferred + file-edit-fallback.** Every code-touching skill must show both paths so the skill works without Summer MCP installed.
|
|
60
|
-
3. **Collaborative protocol.** "May I write…?" before any user-visible mutation. See `
|
|
73
|
+
3. **Collaborative protocol.** "May I write…?" before any user-visible mutation. See `references/collaborative-protocol.md`.
|
|
61
74
|
4. **Template cross-link.** When a working starter exists, link via `template-id` and the section "Want a working starter?".
|
|
62
75
|
5. **Test spec.** Every non-`_meta` skill ships `tests/spec.md` with at least one Test Case.
|
|
63
76
|
|
|
@@ -67,7 +80,7 @@ Cross-portable. Cursor / Codex / Windsurf understand the same SKILL.md.
|
|
|
67
80
|
/skill-create
|
|
68
81
|
```
|
|
69
82
|
|
|
70
|
-
(See `
|
|
83
|
+
(See `workflow/skill-create/SKILL.md`.)
|
|
71
84
|
|
|
72
85
|
## Testing
|
|
73
86
|
|
|
@@ -78,17 +91,11 @@ Cross-portable. Cursor / Codex / Windsurf understand the same SKILL.md.
|
|
|
78
91
|
/skill-improve <name> # parallel-eval harness for iteration
|
|
79
92
|
```
|
|
80
93
|
|
|
81
|
-
(See `
|
|
82
|
-
|
|
83
|
-
## Roadmap
|
|
84
|
-
|
|
85
|
-
Status legend in `catalog.yaml`:
|
|
94
|
+
(See `workflow/skill-test/SKILL.md` and `tests/runner.md`.)
|
|
86
95
|
|
|
87
|
-
|
|
88
|
-
- **NEXT** — next wave, in active development.
|
|
89
|
-
- **LATER** — on roadmap.
|
|
96
|
+
## What ships today
|
|
90
97
|
|
|
91
|
-
|
|
98
|
+
The `skills:` array in `.claude-plugin/plugin.json` is the registry — what ships, ships there. New skills are added via `/skill-create` (see `workflow/skill-create/SKILL.md`).
|
|
92
99
|
|
|
93
100
|
## See also
|
|
94
101
|
|