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.
- package/.claude-plugin/plugin.json +2 -1
- package/.codex-plugin/plugin.json +3 -2
- package/.cursor-plugin/plugin.json +2 -1
- package/.opencode/INSTALL.md +1 -1
- package/.opencode/plugins/summer.js +1 -1
- package/AGENTS.md +4 -4
- package/CHANGELOG.md +10 -0
- package/GEMINI.md +5 -4
- package/README.md +58 -19
- package/assets/autopilot/README.md +51 -0
- package/assets/autopilot/autopilot.gd +222 -0
- package/assets/autopilot/probe_base.gd +262 -0
- package/assets/autopilot/run.sh +78 -0
- package/commands/gameskill.md +11 -2
- package/dist/bin/summer.js +8 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +53 -0
- package/dist/commands/create.d.ts +1 -0
- package/dist/commands/create.js +38 -6
- package/dist/commands/list.js +1 -1
- package/dist/commands/login.d.ts +19 -0
- package/dist/commands/login.js +123 -36
- package/dist/commands/logout.js +3 -16
- package/dist/commands/logs.d.ts +2 -0
- package/dist/commands/logs.js +19 -0
- package/dist/commands/mcp.js +7 -2
- package/dist/commands/open.js +1 -1
- package/dist/commands/publish.d.ts +2 -0
- package/dist/commands/publish.js +20 -0
- package/dist/commands/releases.d.ts +2 -0
- package/dist/commands/releases.js +20 -0
- package/dist/commands/run.js +1 -1
- package/dist/lib/api-client.d.ts +4 -2
- package/dist/lib/api-client.js +28 -4
- package/dist/lib/auth.d.ts +40 -12
- package/dist/lib/auth.js +173 -37
- package/dist/lib/cloud/engine-bridge.d.ts +17 -4
- package/dist/lib/cloud/engine-bridge.js +32 -6
- package/dist/lib/config.d.ts +20 -0
- package/dist/lib/config.js +142 -0
- package/dist/lib/creator.d.ts +93 -0
- package/dist/lib/creator.js +393 -0
- package/dist/lib/engine.d.ts +35 -2
- package/dist/lib/engine.js +240 -6
- package/dist/lib/public-surface-paths.d.ts +13 -0
- package/dist/lib/public-surface-paths.js +42 -0
- package/dist/lib/skills-registry.d.ts +8 -0
- package/dist/lib/skills-registry.js +9 -0
- package/dist/lib/store.d.ts +14 -0
- package/dist/lib/store.js +145 -0
- package/dist/lib/summer-compatibility.d.ts +6 -0
- package/dist/lib/summer-compatibility.js +22 -0
- package/dist/mcp/server.d.ts +8 -1
- package/dist/mcp/server.js +25 -4
- package/dist/mcp/tools/creator-tools.d.ts +2 -0
- package/dist/mcp/tools/creator-tools.js +105 -0
- package/dist/mcp/tools/generate-tools.js +16 -6
- package/dist/mcp/tools/project-tools.js +12 -7
- package/dist/mcp/tools/scene-tools.js +6 -6
- package/dist/mcp/tools/visual-tools.js +4 -3
- package/hooks/pre-commit-doctor.sh +0 -0
- package/hooks/run-hook.cmd +0 -0
- package/hooks/session-start.sh +5 -5
- package/package.json +3 -1
- package/references/collaborative-protocol.md +50 -0
- package/references/gd-style.md +121 -0
- package/references/godot-version.md +51 -0
- package/references/mcp-tools-reference.md +199 -0
- package/references/public-surface-language.md +30 -0
- package/references/summer-folder.md +90 -0
- package/references/template-registry.md +73 -0
- package/skills/2d-assets/character-portrait/SKILL.md +17 -12
- package/skills/2d-assets/concept-art/SKILL.md +10 -9
- package/skills/2d-assets/pixel-art/SKILL.md +36 -20
- package/skills/2d-assets/skybox-panorama/SKILL.md +32 -37
- package/skills/2d-assets/sprite-sheet/SKILL.md +40 -35
- package/skills/2d-assets/tileable-texture/SKILL.md +28 -22
- package/skills/2d-assets/ui-graphics/SKILL.md +46 -32
- package/skills/2d-assets/use-widget-asset/SKILL.md +8 -6
- package/skills/3d-assets/character-model/SKILL.md +34 -19
- package/skills/3d-assets/environment-kit/SKILL.md +11 -5
- package/skills/3d-assets/organic-model/SKILL.md +8 -5
- package/skills/3d-assets/prop-model/SKILL.md +9 -3
- package/skills/3d-assets/vehicle-model/SKILL.md +32 -19
- package/skills/README.md +1 -1
- package/skills/ai-and-npcs/design-npc/SKILL.md +31 -13
- package/skills/animation/animation-tree/SKILL.md +39 -15
- package/skills/animation/facial-and-lipsync/SKILL.md +25 -8
- package/skills/animation/generate-motion/SKILL.md +47 -15
- package/skills/animation/procedural-animation/SKILL.md +31 -13
- package/skills/animation/retarget/SKILL.md +127 -79
- package/skills/audio/adaptive-music/SKILL.md +24 -20
- package/skills/audio/ambient-bed/SKILL.md +22 -16
- package/skills/audio/audio-direction/SKILL.md +15 -10
- package/skills/audio/music-track/SKILL.md +18 -12
- package/skills/audio/sound-effect/SKILL.md +17 -12
- package/skills/audio/voice-line/SKILL.md +42 -42
- package/skills/character-controllers/fps-controller/SKILL.md +26 -16
- package/skills/debugging/debug/SKILL.md +52 -20
- package/skills/deployment/export-and-ship/SKILL.md +105 -38
- package/skills/deployment/remote-deploy/SKILL.md +56 -23
- package/skills/gameplay-mechanics/auto-fire-targeting/SKILL.md +26 -1
- package/skills/gameplay-mechanics/design-mechanic/SKILL.md +23 -15
- package/skills/level-design/design-level/SKILL.md +22 -8
- package/skills/level-design/scene-to-level/SKILL.md +13 -7
- package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +8 -8
- package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +2 -7
- package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +26 -18
- package/skills/performance/tune-performance/SKILL.md +51 -32
- package/skills/rendering-and-lighting/3d-lighting/SKILL.md +34 -5
- package/skills/rendering-and-lighting/art-direction/SKILL.md +6 -8
- package/skills/scene-and-project/brainstorm-game/SKILL.md +3 -5
- package/skills/scene-and-project/make-game/SKILL.md +2 -1
- package/skills/scene-and-project/play/SKILL.md +10 -4
- package/skills/scene-and-project/scene-composition/SKILL.md +21 -8
- package/skills/scene-and-project/summer-cloud/SKILL.md +1 -1
- package/skills/ui-and-ux/ui-basics/SKILL.md +16 -7
- package/skills/video/animated-loop/SKILL.md +63 -39
- package/skills/video/cinematic-cutscene/SKILL.md +66 -30
- package/skills/video/trailer-shot/SKILL.md +30 -21
- package/skills/visual-effects/_building-blocks/additive-billboard-particles.md +25 -16
- package/skills/visual-effects/_building-blocks/trauma-shake-snippet.md +5 -3
- package/skills/visual-effects/game-feel/SKILL.md +51 -33
- package/skills/visual-effects/recipes/dissolve/SKILL.md +51 -9
- package/skills/visual-effects/recipes/fire/SKILL.md +136 -49
- package/skills/visual-effects/recipes/hit-spark/SKILL.md +45 -8
- package/skills/visual-effects/recipes/lightning/SKILL.md +59 -27
- package/skills/visual-effects/recipes/magic-glow/SKILL.md +59 -26
- package/skills/visual-effects/recipes/muzzle-flash/SKILL.md +68 -25
- package/skills/visual-effects/recipes/smoke/SKILL.md +89 -28
- package/skills/visual-effects/recipes/water-ripple/SKILL.md +83 -23
- package/skills/workflow/brainstorming/SKILL.md +1 -1
- package/skills/workflow/brainstorming/scripts/start-server.sh +0 -0
- package/skills/workflow/brainstorming/scripts/stop-server.sh +0 -0
- package/skills/workflow/debugging-game-feel/SKILL.md +29 -9
- package/skills/workflow/diagnosing-perf-regressions/SKILL.md +46 -21
- package/skills/workflow/gameskill/SKILL.md +11 -2
- package/skills/workflow/headless-scripting/SKILL.md +407 -0
- package/skills/workflow/investigating-bugs/SKILL.md +4 -2
- package/skills/workflow/investigating-bugs/find-polluter.sh +0 -0
- package/skills/workflow/mcpupdate/SKILL.md +3 -3
- package/skills/workflow/playtesting-a-feature/SKILL.md +94 -21
- package/skills/workflow/skill-create/SKILL.md +7 -7
- package/skills/workflow/skill-test/SKILL.md +3 -3
- package/skills/workflow/using-summer/SKILL.md +12 -2
- package/skills/workflow/verification-before-completion/SKILL.md +2 -0
- package/skills/workflow/writing-plans/SKILL.md +7 -7
- package/skills/workflow/writing-skills/SKILL.md +7 -5
- package/skills/workflow/writing-skills/render-graphs.js +0 -0
- package/skills/workflow/writing-skills/testing-skills-with-subagents.md +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: host-authoritative-state
|
|
3
|
-
description: Use when designing the state layer of a multiplayer
|
|
3
|
+
description: Use when designing the state layer of a multiplayer Summer game: deciding what the host owns, how clients request changes, and how the host validates and broadcasts. Pairs with `/peer-to-peer-multiplayer`. Trigger on "host authority", "authoritative state", "state ownership", "MP cheating", "client validation", "RPC patterns".
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: multiplayer-and-networking
|
|
@@ -134,7 +134,7 @@ func _broadcast_score(peer: int, value: int) -> void:
|
|
|
134
134
|
score_updated.emit(peer, value)
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
- `authority` = only host can call this.
|
|
137
|
+
- `authority` = only the host can call this. Summer Engine drops other calls.
|
|
138
138
|
- `call_remote` = doesn't run on the caller. Host already wrote the dictionary; no need to re-run locally.
|
|
139
139
|
- `reliable` = state must arrive. Lost packets retry.
|
|
140
140
|
- **Bug if wrong:** if you mark this `any_peer`, a client can fake a score broadcast → desync.
|
|
@@ -151,7 +151,8 @@ func _client_request_use_item(item_id: String) -> void:
|
|
|
151
151
|
```
|
|
152
152
|
|
|
153
153
|
- `any_peer` = any client can call.
|
|
154
|
-
- First line is **always** `if not NetworkManager.is_host: return`.
|
|
154
|
+
- First line is **always** `if not NetworkManager.is_host: return`. Summer
|
|
155
|
+
Engine already routes correctly; this also guards against misconfiguration.
|
|
155
156
|
- `multiplayer.get_remote_sender_id()` is trustworthy — clients can't lie about who sent the request.
|
|
156
157
|
- **Bug if wrong:** missing the `is_host` guard means peers process each other's requests and corrupt local state.
|
|
157
158
|
|
|
@@ -284,7 +285,9 @@ Use flavor 4 (`rpc_id`) so only the joining peer gets the replay. Broadcasting t
|
|
|
284
285
|
|
|
285
286
|
## Anti-pattern: the "synced var" temptation
|
|
286
287
|
|
|
287
|
-
|
|
288
|
+
Summer Engine ships a `MultiplayerSynchronizer` node that automatically
|
|
289
|
+
replicates a list of properties across the network. It is tempting because it
|
|
290
|
+
removes RPC boilerplate. **It is wrong for anything game-logic-relevant.**
|
|
288
291
|
|
|
289
292
|
`MultiplayerSynchronizer`:
|
|
290
293
|
- Has no validation hook. Writes go through unconditionally.
|
|
@@ -321,12 +324,9 @@ This skill writes new autoload files (one per Manager). Always ask before each:
|
|
|
321
324
|
|
|
322
325
|
Don't bulk-create five Managers in one shot. Walk one Manager end-to-end (data → mutators → requests → broadcasts → lifecycle) so the user can verify the shape, then repeat for the next domain.
|
|
323
326
|
|
|
324
|
-
After each Manager file lands, call `summer_get_script_errors` to confirm clean compile.
|
|
327
|
+
After each Manager file lands, call `summer_get_script_errors` to confirm clean compile.
|
|
325
328
|
|
|
326
329
|
## See also
|
|
327
330
|
|
|
328
331
|
- [`peer-to-peer-multiplayer`](../peer-to-peer-multiplayer/SKILL.md) — the four-layer architecture overview. Read this first if you haven't.
|
|
329
332
|
- [`setup-multiplayer`](../setup-multiplayer/SKILL.md) — lighter intro that just gets a session running. Use that one if the user just wants two players to see each other.
|
|
330
|
-
- [`references/godot-version.md`](../../references/godot-version.md) — Godot 4.5 multiplayer API stability notes.
|
|
331
|
-
- [`references/gd-style.md`](../../references/gd-style.md) — typed-GDScript conventions used in the examples above.
|
|
332
|
-
- [`references/mcp-tools-reference.md`](../../references/mcp-tools-reference.md) — `summer_get_script_errors` for compile verification.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: peer-to-peer-multiplayer
|
|
3
|
-
description: Use when starting a multiplayer
|
|
3
|
+
description: Use when starting a multiplayer Summer game from scratch with peer-to-peer host authority. Build the network architecture top-down so authoritative state, routing rules, and real-time rendering are not bolted on later. Use before writing game logic, not after. Trigger on "multiplayer", "peer-to-peer", "p2p", "co-op", "host", "multiplayer architecture", "add multiplayer".
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: multiplayer-and-networking
|
|
@@ -42,7 +42,7 @@ If P2P is right, continue. Otherwise, stop and route to the right skill.
|
|
|
42
42
|
|
|
43
43
|
A single autoload that owns the network. Nothing else in the game touches `MultiplayerAPI` directly.
|
|
44
44
|
|
|
45
|
-
May I create `autoloads/network_manager.gd` and register it as a
|
|
45
|
+
May I create `autoloads/network_manager.gd` and register it as a Summer Engine autoload?
|
|
46
46
|
|
|
47
47
|
```gdscript
|
|
48
48
|
class_name NetworkManager
|
|
@@ -361,8 +361,6 @@ This skill writes multiple new files (`autoloads/network_manager.gd`, `autoloads
|
|
|
361
361
|
|
|
362
362
|
Don't apply all four layers in one shot — checkpoint after each layer so the user can verify before adding the next.
|
|
363
363
|
|
|
364
|
-
See [`references/collaborative-protocol.md`](../../references/collaborative-protocol.md).
|
|
365
|
-
|
|
366
364
|
## Want a working starter?
|
|
367
365
|
|
|
368
366
|
No template ships with this exact architecture yet — it's deliberately built fresh for each project because the State Layer's authority decisions are game-specific (a stealth game's "visibility" and a shooter's "ammo count" both want host authority but for different reasons). Run this skill from scratch.
|
|
@@ -371,8 +369,5 @@ When the `template-co-op-3d` template ships in the registry, this skill will ref
|
|
|
371
369
|
|
|
372
370
|
## See also
|
|
373
371
|
|
|
374
|
-
- [`references/godot-version.md`](../../references/godot-version.md) — Godot 4.5 multiplayer API stability notes
|
|
375
|
-
- [`references/mcp-tools-reference.md`](../../references/mcp-tools-reference.md) — `summer_project_setting` for autoload registration
|
|
376
|
-
- [`references/gd-style.md`](../../references/gd-style.md) — typed-GDScript conventions
|
|
377
372
|
- [`host-authoritative-state`](../host-authoritative-state/SKILL.md) — deeper dive on JUST the state ownership decision matrix
|
|
378
373
|
- [`setup-multiplayer`](../setup-multiplayer/SKILL.md) — lighter intro that just gets a session running (use that one if the user just wants 2 players to see each other; use this one if they want to ship a real game)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: setup-multiplayer
|
|
3
|
-
description: Use when the user wants to add multiplayer to an existing
|
|
3
|
+
description: Use when the user wants to add multiplayer to an existing Summer game: co-op LAN, co-op online, competitive PvP, or a lobby. Start with Summer Engine's high-level MultiplayerAPI plus MultiplayerSpawner and MultiplayerSynchronizer; use custom networking only with a justified reason. Walks peer authority, RPC patterns, replication, and irreversible architecture decisions. It does not claim that managed matchmaking or hosting is live. Trigger on "multiplayer", "co-op", "PvP", "online", "netcode", "rollback", "MultiplayerAPI", "host migration", "matchmaking".
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: multiplayer-and-networking
|
|
@@ -13,7 +13,10 @@ paths: ["**/*.gd", "**/*.tscn", "**/*.tres", "project.godot"]
|
|
|
13
13
|
|
|
14
14
|
## Overview
|
|
15
15
|
|
|
16
|
-
Multiplayer is a one-way door. Pick the wrong authority model and refactoring
|
|
16
|
+
Multiplayer is a one-way door. Pick the wrong authority model and refactoring
|
|
17
|
+
later is brutal. Start with **Summer Engine's high-level MultiplayerAPI +
|
|
18
|
+
MultiplayerSpawner + MultiplayerSynchronizer + ENet**. Do not roll custom
|
|
19
|
+
networking without a measured reason.
|
|
17
20
|
|
|
18
21
|
**Core principle:** the architecture decision (peer authority vs server authority) is harder than the code. Lock it before touching a single RPC.
|
|
19
22
|
|
|
@@ -48,7 +51,9 @@ State the choice explicitly:
|
|
|
48
51
|
|
|
49
52
|
### 3. Pick the transport
|
|
50
53
|
|
|
51
|
-
Almost always: **ENetMultiplayerPeer**. It
|
|
54
|
+
Almost always: **ENetMultiplayerPeer**. It is UDP with reliability layers and
|
|
55
|
+
ships with Summer Engine. Validate the actual game topology and player count;
|
|
56
|
+
this is local netcode, not managed hosting or matchmaking.
|
|
52
57
|
|
|
53
58
|
When to switch:
|
|
54
59
|
- **WebSocketMultiplayerPeer**: if you need the game to run in the browser (HTML5 export). ENet doesn't work in browsers.
|
|
@@ -163,7 +168,7 @@ func _spawn_player(peer_id: int) -> void:
|
|
|
163
168
|
Register as autoload in `project.godot`:
|
|
164
169
|
|
|
165
170
|
```
|
|
166
|
-
summer_project_setting(
|
|
171
|
+
summer_project_setting(key="autoload/Network", value="*res://scripts/network.gd")
|
|
167
172
|
```
|
|
168
173
|
|
|
169
174
|
#### b) Player scene with MultiplayerSynchronizer
|
|
@@ -179,10 +184,14 @@ Player (CharacterBody3D)
|
|
|
179
184
|
```
|
|
180
185
|
|
|
181
186
|
```
|
|
182
|
-
summer_add_node(parent="./World/Players/Player", type="MultiplayerSynchronizer", name="Sync")
|
|
187
|
+
summer_add_node(scenePath="res://scenes/player.tscn", parent="./World/Players/Player", type="MultiplayerSynchronizer", name="Sync")
|
|
183
188
|
```
|
|
184
189
|
|
|
185
|
-
|
|
190
|
+
`scenePath` is required on `summer_add_node`, `summer_set_prop`,
|
|
191
|
+
`summer_connect_signal` and `summer_save_scene`; it names the exact `res://`
|
|
192
|
+
scene to mutate and does not default to the open tab.
|
|
193
|
+
|
|
194
|
+
Configure the synchronizer to replicate `position`, `rotation.y`, `health`. A standalone `SceneReplicationConfig.tres` is worth it here because the same config is shared by every player instance — not because embedded sub_resources fail (they don't):
|
|
186
195
|
|
|
187
196
|
```gdscript
|
|
188
197
|
# scripts/player_net.gd
|
|
@@ -259,15 +268,17 @@ Defer to a specialist skill, but flag the basics:
|
|
|
259
268
|
|
|
260
269
|
- For projectiles: spawn locally on owner's machine at fire time, replicate the spawn event with a timestamp. Other peers fast-forward the projectile by their RTT.
|
|
261
270
|
- For hit detection: server-authoritative + simple latency tolerance (host accepts hits within ~100ms past server time).
|
|
262
|
-
- For movement: client-side prediction
|
|
271
|
+
- For movement: client-side prediction plus server reconciliation is the
|
|
272
|
+
standard model. Summer Engine does not provide this game-specific layer; you
|
|
273
|
+
write it. Competitive PvP requires specialist lag-compensation work.
|
|
263
274
|
|
|
264
275
|
### 8. Save and verify
|
|
265
276
|
|
|
266
277
|
```
|
|
267
|
-
summer_save_scene
|
|
268
|
-
summer_get_script_errors
|
|
278
|
+
summer_save_scene(scenePath="res://scenes/player.tscn")
|
|
279
|
+
summer_get_script_errors(path="res://scripts/player_net.gd") # one file per call; path required
|
|
269
280
|
summer_play
|
|
270
|
-
# user tests by running two instances locally (
|
|
281
|
+
# user tests by running two instances locally (Debug → Customize Run Instances → 2)
|
|
271
282
|
summer_stop
|
|
272
283
|
```
|
|
273
284
|
|
|
@@ -286,7 +297,7 @@ Test checklist:
|
|
|
286
297
|
| Replicate every property | Replicate position, rotation, health, that's it | Bandwidth + bug surface |
|
|
287
298
|
| Run physics on every peer for every player | Physics on owner only, others receive transform | Otherwise jitter and divergence |
|
|
288
299
|
| Trust the client | Validate `get_remote_sender_id()` in every `any_peer` RPC | Cheaters route through the wrong RPC |
|
|
289
|
-
|
|
|
300
|
+
| Copy-pasting a `SceneReplicationConfig` per player scene | One standalone `.tres`, referenced everywhere | Replication config must match on every peer; duplicated copies drift |
|
|
290
301
|
| Roll custom transport | ENet (or WebSocket for browser) | You will hit edge cases ENet already solved |
|
|
291
302
|
| Skip authority check in damage RPC | `if not multiplayer.is_server(): return` at the top of damage handlers | Otherwise damage applied N times |
|
|
292
303
|
| Spawn players on every peer | MultiplayerSpawner — host spawns, clients receive | Otherwise N copies of each player |
|
|
@@ -298,27 +309,24 @@ Test checklist:
|
|
|
298
309
|
- **"Let's also have rollback netcode for our co-op shooter."** Rollback is a 6-month project on its own. Use it for fighting games and lock-step RTS, not co-op.
|
|
299
310
|
- **NAT punchthrough on day one.** Use Steam Networking or a relay; don't write punchthrough yourself for v1.
|
|
300
311
|
- **Dedicated servers without a deploy story.** If you can't redeploy in < 5 min, the dedicated path isn't ready.
|
|
301
|
-
- **Custom serialization.**
|
|
312
|
+
- **Custom serialization.** Summer Engine's variant serialization is fine. Do
|
|
313
|
+
not write your own packing until you measure bandwidth.
|
|
302
314
|
- **Host migration in v1.** It's a feature, not a primitive. Ship without it; add later if churn data demands.
|
|
303
315
|
|
|
304
316
|
## Collaborative protocol
|
|
305
317
|
|
|
306
|
-
This skill rewires the project at the architectural level. Always ask before each block of changes. Group writes — "I'm about to add the autoload + 2 scenes + 3 scripts + InputMap entries. OK?".
|
|
318
|
+
This skill rewires the project at the architectural level. Always ask before each block of changes. Group writes — "I'm about to add the autoload + 2 scenes + 3 scripts + InputMap entries. OK?".
|
|
307
319
|
|
|
308
320
|
## Want a working starter?
|
|
309
321
|
|
|
310
322
|
For a known-good multiplayer scaffold (host + join UI, ENet transport, MultiplayerSpawner, replicated player), point users at:
|
|
311
323
|
|
|
312
|
-
→ **template-id**:
|
|
324
|
+
→ **template-id**: none ships today. Run `summer list templates` for the live list rather than naming one from memory.
|
|
313
325
|
|
|
314
326
|
For now: this skill produces the scaffold inline. When the template lands, link from here.
|
|
315
327
|
|
|
316
328
|
## See also
|
|
317
329
|
|
|
318
|
-
- `references/mcp-tools-reference.md` — full MCP tool list (project-setting, autoload registration)
|
|
319
|
-
- `references/godot-version.md` — `MultiplayerAPI` is medium-churn; `SceneReplicationConfig` settled in 4.0+
|
|
320
|
-
- `references/collaborative-protocol.md` — "May I write" pattern
|
|
321
|
-
- `references/gd-style.md` — typed GDScript conventions
|
|
322
330
|
- `multiplayer-and-networking/multiplayerapi-basics/SKILL.md` — deeper MultiplayerAPI patterns
|
|
323
331
|
- `multiplayer-and-networking/client-server-pattern/SKILL.md` — dedicated server architecture
|
|
324
332
|
- `multiplayer-and-networking/peer-replication/SKILL.md` — synchronizer config patterns
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: performance
|
|
7
7
|
user-invocable: true
|
|
8
|
-
allowed-tools: Read Grep Glob Edit summer_get_diagnostics summer_get_console summer_get_scene_tree summer_inspect_node summer_inspect_resource summer_play summer_stop summer_is_running summer_clear_console summer_set_prop summer_project_setting
|
|
8
|
+
allowed-tools: Read Grep Glob Edit summer_get_diagnostics summer_get_console summer_get_scene_tree summer_inspect_node summer_inspect_resource summer_play summer_stop summer_is_running summer_clear_console summer_set_prop summer_add_node summer_save_scene summer_batch summer_screenshot summer_project_setting
|
|
9
9
|
paths: ["**/*.gd", "**/*.tscn", "**/*.tres", "project.godot"]
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -37,27 +37,45 @@ Wait. The answer narrows the fix domain by 5x:
|
|
|
37
37
|
|
|
38
38
|
Don't guess. Read the engine's actual numbers.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
**`summer_get_diagnostics` is NOT a profiler.** It returns counts of console errors, debugger errors, debugger warnings and script errors — nothing else. It carries no FPS, no frame time, no draw calls, no body counts. Never quote a performance number you claim came from it.
|
|
41
|
+
|
|
42
|
+
**Preferred (Summer MCP): measure inside a verification probe.** `RunVerification` spawns a hidden, disposable game instance with a real renderer, runs your GDScript probe, and dies without touching the user's editor. `Performance.get_monitor(...)` inside that probe returns the real numbers.
|
|
41
43
|
|
|
42
44
|
```
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
summer_batch ops:[{
|
|
46
|
+
"op": "RunVerification",
|
|
47
|
+
"probe_source": "<probe below>",
|
|
48
|
+
"max_seconds": 20
|
|
49
|
+
}]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```gdscript
|
|
53
|
+
extends SummerProbeBase
|
|
54
|
+
func _ready() -> void:
|
|
55
|
+
await super._ready()
|
|
56
|
+
await get_tree().process_frame
|
|
57
|
+
await get_tree().create_timer(3.0).timeout # let it settle, then sample
|
|
58
|
+
report("fps", Performance.get_monitor(Performance.TIME_FPS))
|
|
59
|
+
report("process_ms", Performance.get_monitor(Performance.TIME_PROCESS) * 1000.0)
|
|
60
|
+
report("physics_ms", Performance.get_monitor(Performance.TIME_PHYSICS_PROCESS) * 1000.0)
|
|
61
|
+
report("draw_calls", Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME))
|
|
62
|
+
report("objects", Performance.get_monitor(Performance.RENDER_TOTAL_OBJECTS_IN_FRAME))
|
|
63
|
+
report("primitives", Performance.get_monitor(Performance.RENDER_TOTAL_PRIMITIVES_IN_FRAME))
|
|
64
|
+
report("video_mem", Performance.get_monitor(Performance.RENDER_VIDEO_MEM_USED))
|
|
65
|
+
report("bodies_3d", Performance.get_monitor(Performance.PHYSICS_3D_ACTIVE_OBJECTS))
|
|
66
|
+
report("bodies_2d", Performance.get_monitor(Performance.PHYSICS_2D_ACTIVE_OBJECTS))
|
|
67
|
+
report("objects_total", Performance.get_monitor(Performance.OBJECT_COUNT))
|
|
68
|
+
save_frame("baseline")
|
|
69
|
+
finish()
|
|
49
70
|
```
|
|
50
71
|
|
|
51
|
-
`
|
|
72
|
+
Write the returned numbers down before fixing anything. Drive the probe to the slow state first (`press()` / `key()` to spawn the enemies, walk into the bad room) — measuring the main menu tells you nothing.
|
|
52
73
|
|
|
53
|
-
-
|
|
54
|
-
- Frame time (ms) — anything over 16.67 ms = below 60 fps
|
|
55
|
-
- Draw calls per frame
|
|
56
|
-
- Active physics bodies
|
|
57
|
-
- Active GPUParticles instances
|
|
58
|
-
- Script time vs. physics time vs. render time
|
|
74
|
+
**Let it settle for at least a second before sampling.** `TIME_FPS` is a per-second average, so a probe that reports at 0.5 s returns exactly `1.0` and looks like a catastrophic stall. An `fps` of exactly `1.0` almost always means you sampled too early, not that the game runs at 1 fps.
|
|
59
75
|
|
|
60
|
-
**
|
|
76
|
+
**Never profile with `--headless`.** A headless instance has no renderer: `RENDER_TOTAL_DRAW_CALLS_IN_FRAME` and `RENDER_TOTAL_OBJECTS_IN_FRAME` read `0.0`, and the FPS figure is an uncapped loop rate, not the game's framerate. The verify instance is windowed-offscreen precisely so the numbers are real.
|
|
77
|
+
|
|
78
|
+
**Genuine fallback (engine not running at all):** ask the user to enable Godot's built-in monitor (`Debug → Monitor`, or in-game with `Performance.get_monitor`) and paste numbers. At minimum: FPS, frame time, draw calls, physics active objects.
|
|
61
79
|
|
|
62
80
|
### 3. Identify the dominant cost
|
|
63
81
|
|
|
@@ -73,7 +91,7 @@ Decision tree:
|
|
|
73
91
|
|
|
74
92
|
### 4a. Rendering hotspot
|
|
75
93
|
|
|
76
|
-
Common Godot 4.
|
|
94
|
+
Common Godot 4.x rendering costs, ordered by frequency:
|
|
77
95
|
|
|
78
96
|
| Pattern | Symptom | Fix |
|
|
79
97
|
|---|---|---|
|
|
@@ -91,6 +109,8 @@ summer_inspect_node "./World/Enemy"
|
|
|
91
109
|
summer_inspect_resource "./World/Enemy" # for mesh/material/shape details
|
|
92
110
|
```
|
|
93
111
|
|
|
112
|
+
**Bakes you cannot run for the user.** `LightmapGI` bake and the `OccluderInstance3D` bake are editor-process operations — `LightmapGI.bake()` is not exposed to scripting at all, and there is no MCP op for either. You can add and configure the nodes, but the bake itself is a button the user presses in the editor. Say so explicitly rather than reporting the optimization as applied. Navmesh baking, collision-shape generation from meshes, and `ImporterMesh.generate_lods` are all scriptable and remain yours to do.
|
|
113
|
+
|
|
94
114
|
### 4b. Physics hotspot
|
|
95
115
|
|
|
96
116
|
Top patterns:
|
|
@@ -165,13 +185,12 @@ After the user approves:
|
|
|
165
185
|
```
|
|
166
186
|
# apply the fix (Edit / summer_add_node / summer_set_prop / etc)
|
|
167
187
|
summer_save_scene
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
# user reproduces the same scenario
|
|
171
|
-
summer_get_diagnostics
|
|
172
|
-
summer_stop
|
|
188
|
+
# re-run the SAME probe from step 2 — same scene, same settle time, same drive sequence
|
|
189
|
+
summer_batch ops:[{"op": "RunVerification", "probe_source": "<same probe>", "max_seconds": 20}]
|
|
173
190
|
```
|
|
174
191
|
|
|
192
|
+
Re-running the identical probe is the whole point: same instance type, same warm-up, same sample point, so the delta is attributable to the fix and not to how the run was taken.
|
|
193
|
+
|
|
175
194
|
Compare: was the metric movement at least 50% of what was promised? If yes, ship it. If no, the hypothesis was wrong — go back to step 3 with the new numbers.
|
|
176
195
|
|
|
177
196
|
> Before: 14.2 ms render / 22 fps. After: 4.1 ms render / 58 fps. Shipped.
|
|
@@ -180,7 +199,9 @@ Compare: was the metric movement at least 50% of what was promised? If yes, ship
|
|
|
180
199
|
|
|
181
200
|
| Don't | Do | Why |
|
|
182
201
|
|---|---|---|
|
|
183
|
-
| Optimize without baseline metrics | Always
|
|
202
|
+
| Optimize without baseline metrics | Always run the measurement probe before and after | "Felt faster" is not a measurement |
|
|
203
|
+
| Quote FPS or draw calls from `summer_get_diagnostics` | It returns error/warning counts only — get numbers from `Performance.get_monitor` in a probe | Reporting a metric the tool never returned is fabrication |
|
|
204
|
+
| Profile with `--headless` | Use the windowed-offscreen verify instance | Headless has no renderer: draw calls read 0 and FPS is a meaningless loop rate |
|
|
184
205
|
| Fix the second-biggest cost | Fix the biggest first, re-measure, re-prioritize | Amdahl's law — the small win evaporates next to the big one |
|
|
185
206
|
| Bundle 5 fixes into one PR | One fix at a time, verify each | Bundles hide regressions. Hard to attribute the win or the loss. |
|
|
186
207
|
| `_process` for everything | 10 Hz timer for AI / distance checks / range polls | 60 Hz AI is wasted CPU |
|
|
@@ -200,7 +221,7 @@ Compare: was the metric movement at least 50% of what was promised? If yes, ship
|
|
|
200
221
|
|
|
201
222
|
## Collaborative protocol
|
|
202
223
|
|
|
203
|
-
This skill makes scene/resource/code changes. Always ask before each fix is applied. See
|
|
224
|
+
This skill makes scene/resource/code changes. Always ask before each fix is applied. See `../../../references/collaborative-protocol.md`.
|
|
204
225
|
|
|
205
226
|
## Want a working starter?
|
|
206
227
|
|
|
@@ -208,12 +229,10 @@ No template — this is a workflow. Performance tuning is project-specific by de
|
|
|
208
229
|
|
|
209
230
|
## See also
|
|
210
231
|
|
|
211
|
-
-
|
|
212
|
-
-
|
|
213
|
-
-
|
|
214
|
-
-
|
|
215
|
-
- `performance/profiling-godot/SKILL.md` — deeper Godot profiler usage
|
|
216
|
-
- `performance/draw-call-batching/SKILL.md` — MultiMeshInstance3D patterns
|
|
217
|
-
- `performance/lod-and-culling/SKILL.md` — LOD setup
|
|
232
|
+
- `../../../references/mcp-tools-reference.md` — full MCP tool list
|
|
233
|
+
- `../../../references/godot-version.md` — renderer API churn notes (Compositor, RenderSceneBuffers)
|
|
234
|
+
- `../../../references/collaborative-protocol.md` — "May I write" pattern
|
|
235
|
+
- `../../../references/gd-style.md` — GDScript conventions (avoid bare types, use `:=`)
|
|
218
236
|
- `debugging/debug/SKILL.md` — bug triage (related but different)
|
|
219
|
-
- `
|
|
237
|
+
- `workflow/diagnosing-perf-regressions/SKILL.md` — when it *got* slow rather than always was
|
|
238
|
+
- `rendering-and-lighting/3d-lighting/SKILL.md` — light setup and bake decisions
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: 3d-lighting
|
|
3
|
-
description: Use when setting up lighting in a 3D scene — adding lights, configuring WorldEnvironment, sky, or shadows. Covers DirectionalLight3D
|
|
3
|
+
description: Use when setting up lighting in a Summer Engine 3D scene — adding lights, configuring WorldEnvironment, sky, or shadows. Covers DirectionalLight3D versus Omni versus Spot, shadow tuning, ambient and sky-driven lighting, and the current Summer rendering conventions. Trigger on "lighting", "shadows", "WorldEnvironment", "sun", "ambient", "sky", "light".
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: rendering-and-lighting
|
|
@@ -25,9 +25,13 @@ Set up lighting and environment for 3D scenes. Follow these patterns for outdoor
|
|
|
25
25
|
|
|
26
26
|
### 1. Directional Light (Sun)
|
|
27
27
|
|
|
28
|
+
Every tool below also takes a **required** `scenePath` (the exact `res://` scene
|
|
29
|
+
to mutate — get it from `summer_get_project_context`). It is elided in these
|
|
30
|
+
snippets for readability; a real call without it is rejected by the tool schema.
|
|
31
|
+
|
|
28
32
|
```
|
|
29
|
-
summer_add_node(parent="./World", type="DirectionalLight3D", name="Sun")
|
|
30
|
-
summer_set_prop(path="./World/Sun", key="rotation_degrees", value="Vector3(-45, 30, 0)")
|
|
33
|
+
summer_add_node(scenePath="res://main.tscn", parent="./World", type="DirectionalLight3D", name="Sun")
|
|
34
|
+
summer_set_prop(scenePath="res://main.tscn", path="./World/Sun", key="rotation_degrees", value="Vector3(-45, 30, 0)")
|
|
31
35
|
summer_set_prop(path="./World/Sun", key="light_energy", value="1.0")
|
|
32
36
|
summer_set_prop(path="./World/Sun", key="shadow_enabled", value="true")
|
|
33
37
|
summer_set_prop(path="./World/Sun", key="light_color", value="Color(1, 0.95, 0.9, 1)")
|
|
@@ -43,7 +47,7 @@ summer_set_prop(path="./World/WorldEnvironment", key="environment", value="Envir
|
|
|
43
47
|
```
|
|
44
48
|
|
|
45
49
|
Then configure the Environment's sub-properties. The Environment resource has:
|
|
46
|
-
- `background_mode` — 2 for sky, 1 for color, 3 for canvas
|
|
50
|
+
- `background_mode` — 2 for sky, 1 for color, 3 for canvas (`Environment.BG_SKY` = 2, `BG_COLOR` = 1, `BG_CANVAS` = 3; default is 0, `BG_CLEAR_COLOR`)
|
|
47
51
|
- `sky` — Sky resource (ProceduralSkyMaterial or PhysicalSkyMaterial)
|
|
48
52
|
- `ambient_light_source` — AMBIENT_SOURCE_SKY or AMBIENT_SOURCE_COLOR
|
|
49
53
|
- `ambient_light_color`
|
|
@@ -103,6 +107,31 @@ Always use `Color(r, g, b, a)` with values 0.0–1.0:
|
|
|
103
107
|
- Orange (torch): `Color(1, 0.6, 0.2, 1)`
|
|
104
108
|
- Green (alien): `Color(0.5, 1, 0.5, 1)`
|
|
105
109
|
|
|
110
|
+
## Baked lighting — what you can and cannot do from here
|
|
111
|
+
|
|
112
|
+
Real-time lighting (everything above) is fully scriptable. Baking is not, and the
|
|
113
|
+
split is worth stating before you promise a user a bake.
|
|
114
|
+
|
|
115
|
+
| Approach | Callable from MCP / a script? |
|
|
116
|
+
|---|---|
|
|
117
|
+
| DirectionalLight3D / Omni / Spot with `shadow_enabled` | Yes |
|
|
118
|
+
| `WorldEnvironment` + `Environment` (sky, ambient, tonemap, glow, SSAO, SSR) | Yes |
|
|
119
|
+
| `SDFGI` real-time GI | Yes — `Environment.sdfgi_enabled = true`, no bake step at all |
|
|
120
|
+
| `VoxelGI` | Yes — `VoxelGI.bake()` **is** bound to script (`ClassDB.class_has_method("VoxelGI", "bake")` is true) |
|
|
121
|
+
| **`LightmapGI` bake** | **No.** `LightmapGI` exposes only its `set_*` / `get_*` configuration methods — there is no `bake` in its method list on this build. It runs from the editor's Bake Lightmaps button only. |
|
|
122
|
+
| **`OccluderInstance3D` occlusion bake** | **No.** `bake_single_node` is not script-callable either. Editor-only. |
|
|
123
|
+
|
|
124
|
+
So when the user asks for baked lighting: add and configure the `LightmapGI`
|
|
125
|
+
node and set the meshes' `gi_mode`, then tell them plainly that the bake itself
|
|
126
|
+
is a button they press in the editor and that you cannot trigger it. Do not claim
|
|
127
|
+
a bake happened. If they want GI without a manual step, steer to `SDFGI`
|
|
128
|
+
(`Environment.sdfgi_enabled`, no bake) or `VoxelGI` (whose `bake()` you can call).
|
|
129
|
+
|
|
130
|
+
Note the related trap: `Engine.has_singleton("EditorInterface")` returns **true**
|
|
131
|
+
even in a headless non-editor process, so it is not a valid capability probe.
|
|
132
|
+
`ClassDB.can_instantiate("EditorScript")` returns false outside the editor and is
|
|
133
|
+
the reliable check.
|
|
134
|
+
|
|
106
135
|
## Fallback (no MCP — edit `.tscn` directly)
|
|
107
136
|
|
|
108
137
|
If Summer MCP isn't connected, append the lighting block to your scene file:
|
|
@@ -121,4 +150,4 @@ Then create `Environment` and `Sky` resources via the inspector or load from `.t
|
|
|
121
150
|
|
|
122
151
|
## Collaborative protocol
|
|
123
152
|
|
|
124
|
-
This skill mutates the scene (adds lights + WorldEnvironment + tunes Environment sub-properties). Always ask before applying: "May I add a DirectionalLight3D Sun with shadows + a WorldEnvironment with a procedural sky?".
|
|
153
|
+
This skill mutates the scene (adds lights + WorldEnvironment + tunes Environment sub-properties). Always ask before applying: "May I add a DirectionalLight3D Sun with shadows + a WorldEnvironment with a procedural sky?".
|
|
@@ -113,7 +113,7 @@ Ask:
|
|
|
113
113
|
|
|
114
114
|
### 6. Write the lighting plan
|
|
115
115
|
|
|
116
|
-
State the plan in one block. For
|
|
116
|
+
State the plan in one block. For the current Summer Engine rendering stack:
|
|
117
117
|
|
|
118
118
|
```
|
|
119
119
|
Sun: DirectionalLight3D, color #fff2d9, energy 0.9, angle ~30° (warm low-angle)
|
|
@@ -133,7 +133,8 @@ NEVER: full-bright modulation, no soft falloff
|
|
|
133
133
|
|
|
134
134
|
### 7. Define post-processing rules
|
|
135
135
|
|
|
136
|
-
|
|
136
|
+
Summer Engine post stack: Glow, SDFGI, SSAO, SSR, Adjustments, Color Correction
|
|
137
|
+
(LUT). State opinions, not options.
|
|
137
138
|
|
|
138
139
|
```
|
|
139
140
|
Glow: ON, threshold 0.9, intensity 0.5 (soft bloom on highlights only)
|
|
@@ -168,7 +169,7 @@ This is the contract. Five do's, five don'ts. Specific, enforceable.
|
|
|
168
169
|
- No chromatic aberration / lens flare / motion blur — they're cheap and date-fast.
|
|
169
170
|
```
|
|
170
171
|
|
|
171
|
-
### 9. Apply
|
|
172
|
+
### 9. Apply Summer project-level settings
|
|
172
173
|
|
|
173
174
|
Some art-direction calls translate to `project.godot` settings. Apply them.
|
|
174
175
|
|
|
@@ -261,11 +262,11 @@ End with:
|
|
|
261
262
|
| Procedural skybox without angle | Mid-day sun + uniform fog reads generic. Always angle the sun. |
|
|
262
263
|
| Skipping the lighting plan | Lighting *is* art direction in 3D. Without a plan, every level looks different. |
|
|
263
264
|
| Adopting "AAA realism" at vertical-slice scope | Asset cost is brutal solo. Stylized always wins. |
|
|
264
|
-
| Calling SetResourceProperty
|
|
265
|
+
| Calling SetResourceProperty before the property holds a resource | Explicit `resource is null` error, not a silent drop. Assign the resource first (`summer_set_prop key="environment" value="Environment"`), then set its sub-properties. Scene-embedded sub_resources are fully supported targets. |
|
|
265
266
|
|
|
266
267
|
## Collaborative protocol
|
|
267
268
|
|
|
268
|
-
This skill writes one design doc (`.summer/art-bible.md`) and may modify `project.godot` settings + the main scene's `WorldEnvironment`. Always ask.
|
|
269
|
+
This skill writes one design doc (`.summer/art-bible.md`) and may modify `project.godot` settings + the main scene's `WorldEnvironment`. Always ask.
|
|
269
270
|
|
|
270
271
|
## Want a working starter?
|
|
271
272
|
|
|
@@ -273,9 +274,6 @@ No template — this is a workflow that produces the bible the rest of the proje
|
|
|
273
274
|
|
|
274
275
|
## See also
|
|
275
276
|
|
|
276
|
-
- `references/collaborative-protocol.md`
|
|
277
|
-
- `references/godot-version.md` — Godot 4.5 rendering API notes (Compositor moved in 4.4 / 4.5)
|
|
278
|
-
- `references/mcp-tools-reference.md`
|
|
279
277
|
- `scene-and-project/brainstorm-game/SKILL.md` — produces the brief that anchors the bible
|
|
280
278
|
- `audio/audio-direction/SKILL.md` — the sonic counterpart
|
|
281
279
|
- `rendering-and-lighting/3d-lighting/SKILL.md` — implements the lighting plan
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: scene-and-project
|
|
7
7
|
user-invocable: true
|
|
8
|
-
allowed-tools: Read Grep Glob Write Edit summer_get_project_context summer_get_scene_tree
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_get_project_context summer_get_scene_tree summer_read_file summer_write_file
|
|
9
9
|
paths: [".summer/**", "project.godot", "**/*.md"]
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -193,16 +193,14 @@ Don't auto-pick. Let them decide.
|
|
|
193
193
|
|
|
194
194
|
## Collaborative protocol
|
|
195
195
|
|
|
196
|
-
This skill writes one file (`.summer/GameSoul.md`). Always ask before writing. Always show the brief inline before saving so the user can react.
|
|
196
|
+
This skill writes one file (`.summer/GameSoul.md`). Always ask before writing. Always show the brief inline before saving so the user can react.
|
|
197
197
|
|
|
198
198
|
## Want a working starter?
|
|
199
199
|
|
|
200
|
-
No template — this is a workflow that produces the brief that drives template selection later. Once `.summer/GameSoul.md` exists, `/summer:make-game`
|
|
200
|
+
No template — this is a workflow that produces the brief that drives template selection later. Once `.summer/GameSoul.md` exists, `/summer:make-game` reads it and `summer list templates` shows what's actually available to match against.
|
|
201
201
|
|
|
202
202
|
## See also
|
|
203
203
|
|
|
204
|
-
- `references/collaborative-protocol.md` — "May I write?" pattern
|
|
205
|
-
- `references/template-registry.md` — templates the brief will be matched against later
|
|
206
204
|
- `gameplay-mechanics/design-mechanic/SKILL.md` — design the core loop in detail
|
|
207
205
|
- `level-design/design-level/SKILL.md` — sketch level 1
|
|
208
206
|
- `rendering-and-lighting/art-direction/SKILL.md` — turn the one-phrase look into a full bible
|
|
@@ -198,7 +198,8 @@ Use `summer:asset-strategy` to decide whether to generate assets, search the lib
|
|
|
198
198
|
Skill: summer:vfx
|
|
199
199
|
```
|
|
200
200
|
|
|
201
|
-
Walks the canonical
|
|
201
|
+
Walks the canonical Summer Engine game-feel stack: hit flash, trauma camera
|
|
202
|
+
shake, and audio ducking wired so a single hit fires all three.
|
|
202
203
|
|
|
203
204
|
```
|
|
204
205
|
Skill: summer:tune-performance
|
|
@@ -34,10 +34,16 @@ If not running, continue.
|
|
|
34
34
|
|
|
35
35
|
Cheapest call. If the script won't compile, play will fail with a noisy error — better to surface that clearly first.
|
|
36
36
|
|
|
37
|
+
`summer_get_script_errors` checks **one** file and `path` is required — there is
|
|
38
|
+
no project-wide form. Call it on the scripts you just touched:
|
|
39
|
+
|
|
37
40
|
```
|
|
38
|
-
summer_get_script_errors
|
|
41
|
+
summer_get_script_errors(path="res://scripts/player.gd")
|
|
39
42
|
```
|
|
40
43
|
|
|
44
|
+
If you don't know which scripts changed, use `summer_get_diagnostics` instead —
|
|
45
|
+
it takes no arguments and reports editor + runtime counts across the project.
|
|
46
|
+
|
|
41
47
|
If errors found:
|
|
42
48
|
> Won't run yet — there's a script error: `<one-line summary>`. Want me to /debug it?
|
|
43
49
|
|
|
@@ -85,7 +91,7 @@ Leave the game running. The user wants to play it. Stop only on explicit ask.
|
|
|
85
91
|
|---|---|
|
|
86
92
|
| User says "play" with no context | Steps 1–5 above |
|
|
87
93
|
| User says "play and watch it for me" | After step 5, set a timer / poll `summer_get_debugger_errors` every few seconds for the duration the user specifies |
|
|
88
|
-
| User says "play the boss fight scene" |
|
|
94
|
+
| User says "play the boss fight scene" | Pass it directly: `summer_play(scene="res://scenes/boss_fight.tscn")`. `summer_open_scene(path=...)` needs a full `res://` path too — never a bare relative one |
|
|
89
95
|
| Game is already running and user says "play" again | Step 1's check covers it — ask before restarting |
|
|
90
96
|
|
|
91
97
|
## Anti-patterns
|
|
@@ -100,9 +106,9 @@ This skill mutates engine state (clearing console, starting play). It's a read-s
|
|
|
100
106
|
|
|
101
107
|
## Want a working starter?
|
|
102
108
|
|
|
103
|
-
No template
|
|
109
|
+
No template. Works against any Summer project that has a main scene set in the
|
|
110
|
+
technical `project.godot` file.
|
|
104
111
|
|
|
105
112
|
## See also
|
|
106
113
|
|
|
107
|
-
- `references/mcp-tools-reference.md` — full tool list
|
|
108
114
|
- `debugging/debug/SKILL.md` — what to do when /play surfaces an error
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scene-composition
|
|
3
|
-
description: Use when building or organizing
|
|
3
|
+
description: Use when building or organizing Summer Engine scenes: node hierarchy conventions, when to extract sub-scenes, reusable prefab patterns, and instance-versus-add-node decisions. Trigger on "scene", "sub-scene", "instance", "prefab", "node hierarchy", "scene structure", "PackedScene".
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: scene-and-project
|
|
@@ -80,8 +80,8 @@ Use `./` for paths relative to the scene root:
|
|
|
80
80
|
|
|
81
81
|
1. Build the hierarchy in the main scene
|
|
82
82
|
2. Select the root of what you want to extract
|
|
83
|
-
3. Save as scene: `summer_save_scene(path="res://scenes/player.tscn")`.
|
|
84
|
-
4. In the main scene, add it with `summer_instantiate_scene(parent="./World", scene="res://scenes/player.tscn", name="Player")`
|
|
83
|
+
3. Save as scene: `summer_save_scene(scenePath="res://scenes/source.tscn", path="res://scenes/player.tscn")`. `scenePath` names the scene being saved and is **required**; `path` is the optional save-as target. There is no "current scene" default.
|
|
84
|
+
4. In the main scene, add it with `summer_instantiate_scene(scenePath="res://main.tscn", parent="./World", scene="res://scenes/player.tscn", name="Player")`
|
|
85
85
|
|
|
86
86
|
**Practical approach:** Create reusable scenes (player.tscn, enemy.tscn) as separate scene files, then instantiate them into levels.
|
|
87
87
|
|
|
@@ -97,9 +97,9 @@ Use `./` for paths relative to the scene root:
|
|
|
97
97
|
|
|
98
98
|
## Save Conventions
|
|
99
99
|
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
100
|
+
- The mutation tools (`summer_add_node`, `summer_set_prop`, ...) already append one save per call, so a standalone `summer_save_scene` is only for a save-as or an explicit extra flush
|
|
101
|
+
- Save-as: `summer_save_scene(scenePath="res://main.tscn", path="res://scenes/level1.tscn")`
|
|
102
|
+
- Plain save: `summer_save_scene(scenePath="res://main.tscn")` — `scenePath` is required in both forms
|
|
103
103
|
|
|
104
104
|
## Common Mistakes
|
|
105
105
|
|
|
@@ -110,7 +110,20 @@ Use `./` for paths relative to the scene root:
|
|
|
110
110
|
|
|
111
111
|
## Fallback
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
MCP is the preferred path, not a requirement. Hand-written `.tscn` text loads and
|
|
114
|
+
instantiates fine — including `[ext_resource]` lines with **no `uid=` field**,
|
|
115
|
+
which the engine resolves by path (verified by loading such a scene on the
|
|
116
|
+
shipped 4.6.1 build). Format version 3 is current for Godot 4.
|
|
117
|
+
|
|
118
|
+
What actually goes wrong when you hand-write scenes is mundane and checkable:
|
|
119
|
+
a `SubResource("id")` with no matching `[sub_resource id="id"]` block, a
|
|
120
|
+
`parent=` path naming a node that isn't declared above it, or an
|
|
121
|
+
`[ext_resource path=...]` pointing at a file that hasn't been imported yet
|
|
122
|
+
(`--headless --import`, or `summer_import_from_url`, before it will load).
|
|
123
|
+
|
|
124
|
+
So: use MCP when it's connected because the ops are undoable as one step and the
|
|
125
|
+
engine validates paths for you. When it isn't, write the `.tscn` and then open it
|
|
126
|
+
once to confirm it loads. Do not tell the user it's impossible.
|
|
114
127
|
|
|
115
128
|
## Trap — Cross-scene transform leak when copying a scene as a template
|
|
116
129
|
|
|
@@ -143,4 +156,4 @@ Don't skip the player mask update. If you only move foliage to layer 9 without a
|
|
|
143
156
|
|
|
144
157
|
## Collaborative protocol
|
|
145
158
|
|
|
146
|
-
This skill creates and mutates scene files. Always ask before applying: "May I create `res://scenes/player.tscn` and instantiate it under `./World`?".
|
|
159
|
+
This skill creates and mutates scene files. Always ask before applying: "May I create `res://scenes/player.tscn` and instantiate it under `./World`?".
|
|
@@ -89,4 +89,4 @@ If the MCP tools are unavailable, run the `summer cloud ...` CLI commands direct
|
|
|
89
89
|
|
|
90
90
|
## Collaborative protocol
|
|
91
91
|
|
|
92
|
-
Push and pull move bytes and can replace files. Always run `summer cloud status` and say what will move before you push or pull: "Push will upload 4 files and delete 0. OK to push?" For any gated deletion, state the exact count and get explicit confirmation before setting `confirmDeletes`.
|
|
92
|
+
Push and pull move bytes and can replace files. Always run `summer cloud status` and say what will move before you push or pull: "Push will upload 4 files and delete 0. OK to push?" For any gated deletion, state the exact count and get explicit confirmation before setting `confirmDeletes`.
|