summer-engine 1.3.1 → 1.4.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 +59 -0
- package/.codex-plugin/plugin.json +38 -0
- package/.cursor-plugin/plugin.json +42 -0
- package/.mcp.json +8 -0
- package/.opencode/plugins/summer.js +49 -0
- package/CHANGELOG.md +67 -0
- package/README.md +13 -0
- package/dist/lib/skills-registry.d.ts +80 -0
- package/dist/lib/skills-registry.js +172 -0
- package/gemini-extension.json +21 -0
- package/hooks/hooks-cursor.json +21 -0
- package/hooks/hooks.json +31 -0
- package/hooks/pre-commit-doctor.sh +123 -0
- package/hooks/run-hook.cmd +23 -0
- package/hooks/session-start.sh +120 -0
- package/marketplace.json +24 -0
- package/package.json +13 -3
- package/skills/_meta/skill-test/SKILL.md +1 -1
- package/skills/_shared/summer-folder.md +44 -0
- package/skills/_tests/specs/art-direction.md +115 -0
- package/skills/_tests/specs/audio-direction.md +123 -0
- package/skills/_tests/specs/brainstorm-game.md +99 -0
- package/skills/_tests/specs/design-level.md +113 -0
- package/skills/_tests/specs/design-mechanic.md +112 -0
- package/skills/_tests/specs/design-npc.md +112 -0
- package/skills/_tests/specs/export-and-ship.md +114 -0
- package/skills/_tests/specs/fps-controller.md +5 -5
- package/skills/_tests/specs/peer-to-peer-multiplayer.md +99 -0
- package/skills/_tests/specs/setup-multiplayer.md +106 -0
- package/skills/_tests/specs/tune-performance.md +104 -0
- package/skills/_tests/specs/vfx.md +98 -0
- package/skills/ai-and-npcs/design-npc/SKILL.md +343 -0
- package/skills/asset-pipeline/asset-strategy/SKILL.md +8 -0
- package/skills/audio/audio-direction/SKILL.md +258 -0
- package/skills/catalog.yaml +82 -0
- package/skills/character-controllers/fps-controller/SKILL.md +27 -0
- package/skills/deployment/export-and-ship/SKILL.md +300 -0
- package/skills/gameplay-mechanics/design-mechanic/SKILL.md +265 -0
- package/skills/level-design/design-level/SKILL.md +266 -0
- package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +378 -0
- package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +328 -0
- package/skills/performance/tune-performance/SKILL.md +219 -0
- package/skills/rendering-and-lighting/3d-lighting/SKILL.md +20 -0
- package/skills/rendering-and-lighting/art-direction/SKILL.md +284 -0
- package/skills/scene-and-project/brainstorm-game/SKILL.md +210 -0
- package/skills/scene-and-project/make-game/SKILL.md +10 -0
- package/skills/scene-and-project/scene-composition/SKILL.md +8 -0
- package/skills/ui-and-ux/ui-basics/SKILL.md +28 -0
- package/skills/visual-effects/vfx/SKILL.md +280 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-mechanic
|
|
3
|
+
description: Use when designing one specific game mechanic in detail — input, response, feedback, failure modes, depth, tunables. Outputs a design doc and a scaffolding-ready node-graph sketch + GDScript stub. Trigger on "design a mechanic", "how should X work", "design the parry", "design the dash", "design the inventory", "the loop is broken".
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: gameplay-mechanics
|
|
7
|
+
user-invocable: true
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_get_scene_tree summer_inspect_node summer_add_node summer_set_prop summer_input_map_bind summer_save_scene summer_get_script_errors
|
|
9
|
+
paths: ["**/*.gd", "**/*.tscn", ".summer/**"]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# /design-mechanic — Design One Mechanic in Detail
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
A "mechanic" is a verb the player performs that produces a meaningful response from the world. Not a system. Not a feature. A verb with feedback. This skill walks the five layers of a real mechanic: **input → response → feedback → failure modes → depth** — then drops a node-graph sketch + GDScript stub into the project so the next session can implement it.
|
|
17
|
+
|
|
18
|
+
**Core principle:** a mechanic is only as good as its weakest feedback layer. A perfect parry with no audio cue is broken. A great audio cue with floaty input is broken. Walk all five layers before scaffolding.
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
|
|
22
|
+
### 1. Pin which mechanic
|
|
23
|
+
|
|
24
|
+
Ask exactly one question and wait:
|
|
25
|
+
|
|
26
|
+
> Which mechanic? (e.g., "double-jump", "parry", "stamina-dash", "pickup", "lock-on", "crafting-recipe-craft").
|
|
27
|
+
|
|
28
|
+
If the user gives a system name ("inventory", "combat"), push back:
|
|
29
|
+
|
|
30
|
+
> Inventory is a system, not a mechanic. The mechanics inside it are: pickup, equip, drop, use, swap. Which one?
|
|
31
|
+
|
|
32
|
+
### 2. Read context if available
|
|
33
|
+
|
|
34
|
+
If `.summer/GameSoul.md` exists, read it. The mechanic should fit the game brief, not exist in isolation.
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Read .summer/GameSoul.md
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Quote the relevant constraint back at the user:
|
|
41
|
+
|
|
42
|
+
> Brief says core loop is "see obstacle, attempt, fail, learn, retry". A double-jump only matters if it changes which obstacles are reachable. Confirm that's what we're solving.
|
|
43
|
+
|
|
44
|
+
### 3. Walk the five layers — one at a time
|
|
45
|
+
|
|
46
|
+
**Layer 1: Input.** Exactly what does the player press, hold, release, time?
|
|
47
|
+
|
|
48
|
+
State a candidate, ask for refinement:
|
|
49
|
+
|
|
50
|
+
> Input candidate: tap Space mid-air. Or: hold-and-release for variable height? Or: requires direction + Space? Pick one.
|
|
51
|
+
|
|
52
|
+
**Layer 2: Response.** What changes in the world the moment the input fires?
|
|
53
|
+
|
|
54
|
+
State the deltas. For double-jump:
|
|
55
|
+
|
|
56
|
+
> Response: vertical velocity set to (jump_velocity * 0.85). `_can_double_jump` flag flips false. Visual rig plays "jump_2" anim. Audio cue. Particle burst at feet.
|
|
57
|
+
|
|
58
|
+
**Layer 3: Feedback** — and this is where most amateur designs collapse. Three sub-channels, all required:
|
|
59
|
+
|
|
60
|
+
| Channel | Question to answer | Bad example | Good example |
|
|
61
|
+
|---|---|---|---|
|
|
62
|
+
| Visual | Can a player who can't hear tell it worked? | "It just jumps." | "GPUParticles3D burst at feet, 0.1s slow-mo on apex, after-image trail behind." |
|
|
63
|
+
| Audio | Can a player who can't see tell it worked? | "Plays jump.wav." | "Layered: short whoosh on input, ambient pitch-up while airborne, soft thud on second jump start." |
|
|
64
|
+
| Mechanical | Does the input feel different from a single-jump? | "Same jump, just twice." | "Second jump has tighter air control, slightly lower height, different particle color." |
|
|
65
|
+
|
|
66
|
+
Force the user to answer all three. If they hand-wave one, name it:
|
|
67
|
+
|
|
68
|
+
> You named visual and audio. Mechanical-feel is missing — what makes the second jump feel different from the first beyond just being a second one?
|
|
69
|
+
|
|
70
|
+
**Layer 4: Failure modes.** What happens when the input fires but conditions aren't met?
|
|
71
|
+
|
|
72
|
+
For double-jump:
|
|
73
|
+
|
|
74
|
+
- Already used? → no input registered? Or denied with a UI shake? Or a small audio cue?
|
|
75
|
+
- During wall-slide? → does it count as airborne or grounded?
|
|
76
|
+
- During cutscene? → is input gated entirely?
|
|
77
|
+
- Spammed input? → buffered or ignored?
|
|
78
|
+
|
|
79
|
+
State the rules, ask:
|
|
80
|
+
|
|
81
|
+
> Failure rules: (a) already-used → silent ignore. (b) during wall-slide → counts as airborne, can double-jump off wall. (c) cutscene → input fully gated. (d) spam → input buffer of 0.1s. OK?
|
|
82
|
+
|
|
83
|
+
**Layer 5: Depth.** What makes this mechanic interesting after 5 minutes of play?
|
|
84
|
+
|
|
85
|
+
This is the hardest layer. State the depth-vector explicitly:
|
|
86
|
+
|
|
87
|
+
> Depth: double-jump becomes interesting when level design forces a *choice* — jump now to clear obstacle A, or save it to escape enemy B coming at you. Without that choice, it's just a longer jump. The level-design implication: every double-jump gap should pair with a near-future threat that also wants the resource.
|
|
88
|
+
|
|
89
|
+
If the user can't articulate depth, the mechanic might not be needed. Say it:
|
|
90
|
+
|
|
91
|
+
> If the only purpose is "can reach higher platforms", that's just a higher-jumping single-jump. Either change the input shape (give it a cost), or cut it.
|
|
92
|
+
|
|
93
|
+
### 4. List the tunables
|
|
94
|
+
|
|
95
|
+
Every mechanic has 3-7 numbers a designer will tweak. Name them. For double-jump:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
@export var double_jump_velocity: float = 4.0 # vertical speed of second jump
|
|
99
|
+
@export var double_jump_air_control: float = 0.7 # multiplier vs ground control
|
|
100
|
+
@export var input_buffer_time: float = 0.1 # window to register early input
|
|
101
|
+
@export var ground_grace_period: float = 0.05 # coyote time before lockout
|
|
102
|
+
@export var slow_mo_on_apex: float = 0.0 # 0 = off, 0.05 = brief
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
These become `@export` vars in the stub. The user tunes in the inspector, no recompile.
|
|
106
|
+
|
|
107
|
+
### 5. Sketch the node graph
|
|
108
|
+
|
|
109
|
+
Describe what nodes the mechanic touches in the existing scene. Don't add yet — sketch first.
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
World/Player (CharacterBody3D) # existing
|
|
113
|
+
├── CollisionShape3D # existing
|
|
114
|
+
├── Camera3D # existing
|
|
115
|
+
├── DoubleJumpFX (GPUParticles3D) # NEW — particles on second jump
|
|
116
|
+
├── JumpAudio (AudioStreamPlayer3D) # NEW — input + apex cues
|
|
117
|
+
└── (script: player_controller.gd, modify) # MODIFY — add _can_double_jump state
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Show this to the user. Ask:
|
|
121
|
+
|
|
122
|
+
> Node-graph plan above. May I add `DoubleJumpFX` and `JumpAudio` to `./World/Player`, and modify `player_controller.gd` to add the double-jump logic?
|
|
123
|
+
|
|
124
|
+
### 6. Scaffold via MCP
|
|
125
|
+
|
|
126
|
+
**Preferred (Summer MCP):**
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
summer_get_scene_tree # confirm Player exists where expected
|
|
130
|
+
summer_add_node(parent="./World/Player", type="GPUParticles3D", name="DoubleJumpFX")
|
|
131
|
+
summer_set_prop("./World/Player/DoubleJumpFX", "emitting", "false")
|
|
132
|
+
summer_add_node(parent="./World/Player", type="AudioStreamPlayer3D", name="JumpAudio")
|
|
133
|
+
summer_input_map_bind(name="jump", events=[{type:"key", key:"Space"}]) # idempotent
|
|
134
|
+
summer_save_scene
|
|
135
|
+
summer_get_script_errors
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Fallback (no MCP):** Print the `.tscn` snippet for the user to paste:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
[node name="DoubleJumpFX" type="GPUParticles3D" parent="Player"]
|
|
142
|
+
emitting = false
|
|
143
|
+
amount = 16
|
|
144
|
+
lifetime = 0.4
|
|
145
|
+
|
|
146
|
+
[node name="JumpAudio" type="AudioStreamPlayer3D" parent="Player"]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 7. Write the GDScript stub
|
|
150
|
+
|
|
151
|
+
Stub only — implementation is the next session. Use `_shared/gd-style.md` conventions. For double-jump:
|
|
152
|
+
|
|
153
|
+
```gdscript
|
|
154
|
+
class_name PlayerController
|
|
155
|
+
extends CharacterBody3D
|
|
156
|
+
|
|
157
|
+
# Tunables
|
|
158
|
+
@export var jump_velocity: float = 4.5
|
|
159
|
+
@export var double_jump_velocity: float = 4.0
|
|
160
|
+
@export var double_jump_air_control: float = 0.7
|
|
161
|
+
@export var input_buffer_time: float = 0.1
|
|
162
|
+
|
|
163
|
+
# State
|
|
164
|
+
var _can_double_jump: bool = false
|
|
165
|
+
var _input_buffer_t: float = 0.0
|
|
166
|
+
|
|
167
|
+
@onready var fx: GPUParticles3D = $DoubleJumpFX
|
|
168
|
+
@onready var audio: AudioStreamPlayer3D = $JumpAudio
|
|
169
|
+
|
|
170
|
+
signal jumped
|
|
171
|
+
signal double_jumped
|
|
172
|
+
|
|
173
|
+
func _physics_process(delta: float) -> void:
|
|
174
|
+
_input_buffer_t = max(0.0, _input_buffer_t - delta)
|
|
175
|
+
|
|
176
|
+
if Input.is_action_just_pressed("jump"):
|
|
177
|
+
_input_buffer_t = input_buffer_time
|
|
178
|
+
|
|
179
|
+
if _input_buffer_t > 0.0:
|
|
180
|
+
if is_on_floor():
|
|
181
|
+
velocity.y = jump_velocity
|
|
182
|
+
_can_double_jump = true
|
|
183
|
+
_input_buffer_t = 0.0
|
|
184
|
+
jumped.emit()
|
|
185
|
+
elif _can_double_jump:
|
|
186
|
+
velocity.y = double_jump_velocity
|
|
187
|
+
_can_double_jump = false
|
|
188
|
+
_input_buffer_t = 0.0
|
|
189
|
+
fx.emitting = true
|
|
190
|
+
audio.play()
|
|
191
|
+
double_jumped.emit()
|
|
192
|
+
|
|
193
|
+
move_and_slide()
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Ask:
|
|
197
|
+
|
|
198
|
+
> May I write `scripts/player_controller.gd` (or merge into the existing script if one is attached)?
|
|
199
|
+
|
|
200
|
+
### 8. Save the design doc
|
|
201
|
+
|
|
202
|
+
Always write the design doc — it's the artifact the next session reads. Path: `.summer/mechanics/<mechanic-name>.md`.
|
|
203
|
+
|
|
204
|
+
```markdown
|
|
205
|
+
# Mechanic: Double-Jump
|
|
206
|
+
|
|
207
|
+
**Input:** Tap Space mid-air. Buffered 0.1s before ground.
|
|
208
|
+
**Response:** velocity.y = double_jump_velocity. `_can_double_jump` flag false.
|
|
209
|
+
**Feedback:**
|
|
210
|
+
- Visual: GPUParticles3D burst, 0.1s slow-mo on apex
|
|
211
|
+
- Audio: short whoosh on input
|
|
212
|
+
- Mechanical: 70% air control on second jump
|
|
213
|
+
**Failure modes:**
|
|
214
|
+
- Already used → silent ignore
|
|
215
|
+
- During wall-slide → counts as airborne
|
|
216
|
+
- Cutscene → input gated
|
|
217
|
+
- Spam → buffered (0.1s window)
|
|
218
|
+
**Depth:**
|
|
219
|
+
- Resource the player chooses when to spend
|
|
220
|
+
- Level design pairs every gap with a near-future threat
|
|
221
|
+
**Tunables:** see @export vars in player_controller.gd
|
|
222
|
+
**Open questions:** <list any the user couldn't answer>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Ask:
|
|
226
|
+
|
|
227
|
+
> May I create `.summer/mechanics/double-jump.md` with this design doc?
|
|
228
|
+
|
|
229
|
+
## Common mistakes
|
|
230
|
+
|
|
231
|
+
| Mistake | Fix |
|
|
232
|
+
|---|---|
|
|
233
|
+
| Designing the system, not the verb | "Combat" is a system. "Parry" is a mechanic. Pick the verb. |
|
|
234
|
+
| Skipping mechanical-feel in feedback | Visual + audio alone produce hollow mechanics. Mechanical difference is required. |
|
|
235
|
+
| No failure modes | Players spam, edge into states you didn't plan for, and find the hole. Plan the failure cases up front. |
|
|
236
|
+
| Hand-wave depth | "Players will use it strategically" is not depth. Name the choice the player makes. |
|
|
237
|
+
| Tunables hard-coded as `const` | Use `@export` so designers tune in the inspector. |
|
|
238
|
+
| Adding the mechanic without the FX/audio nodes | Without nodes for feedback, the mechanic ships feeling cheap. Scaffold the nodes alongside the script. |
|
|
239
|
+
| Setting `position` for movement instead of `velocity` | Physics objects use `velocity` in `_physics_process`. See `_shared/gd-style.md`. |
|
|
240
|
+
| Calling SetResourceProperty on inline sub_resources | Silent fail. See `_shared/mcp-tools-reference.md` § Trap. |
|
|
241
|
+
|
|
242
|
+
## Collaborative protocol
|
|
243
|
+
|
|
244
|
+
This skill writes scene nodes and one or more files (`.gd`, `.summer/mechanics/<name>.md`). Group writes into one ask per phase. See `_shared/collaborative-protocol.md`.
|
|
245
|
+
|
|
246
|
+
## Want a working starter?
|
|
247
|
+
|
|
248
|
+
For full character mechanics in a runnable starter:
|
|
249
|
+
|
|
250
|
+
- FPS variant → `template-id: template-3d-fps` (https://github.com/SummerEngine/FPS-template-Summer-Engine)
|
|
251
|
+
- Platformer → `template-id: template-3d-platformer` (TBD)
|
|
252
|
+
|
|
253
|
+
This skill is a workflow that designs and scaffolds — the templates are runnable bases the mechanic plugs into.
|
|
254
|
+
|
|
255
|
+
## See also
|
|
256
|
+
|
|
257
|
+
- `_shared/collaborative-protocol.md`
|
|
258
|
+
- `_shared/mcp-tools-reference.md`
|
|
259
|
+
- `_shared/gd-style.md` — GDScript conventions
|
|
260
|
+
- `_shared/godot-version.md` — Godot 4.5 API notes
|
|
261
|
+
- `scene-and-project/brainstorm-game/SKILL.md` — produces `.summer/GameSoul.md` this skill reads
|
|
262
|
+
- `level-design/design-level/SKILL.md` — design the levels that exercise the mechanic
|
|
263
|
+
- `character-controllers/fps-controller/SKILL.md` — FPS movement scaffolding
|
|
264
|
+
- `scripting-patterns/state-machine-patterns/SKILL.md` — state machines for complex mechanics
|
|
265
|
+
- `audio/audio-direction/SKILL.md` — defines the SFX vocabulary the mechanic draws from
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-level
|
|
3
|
+
description: Use when designing a single level — layout, pacing, encounters, secrets, reward gating. Outputs a level design doc and a concrete node-tree skeleton for `summer_create_scene`. Trigger on "design a level", "design level 1", "tutorial level", "boss arena", "design the encounter", "make a level layout".
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: level-design
|
|
7
|
+
user-invocable: true
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_get_scene_tree summer_create_scene summer_open_scene summer_add_node summer_set_prop summer_save_scene summer_get_script_errors
|
|
9
|
+
paths: ["**/*.tscn", "**/*.gd", ".summer/**", "levels/**"]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# /design-level — Design One Level
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
A level is a controlled sequence of player experiences in physical space. Layout, pacing, encounters, secrets, and reward gating must work together — a "fun layout" with a flat pacing curve still feels boring. This skill walks the six design beats of a single level and drops a node-tree skeleton ready for `summer_create_scene`.
|
|
17
|
+
|
|
18
|
+
**Core principle:** A level has a *pacing curve* and a *teaching arc*. If you can't draw the tension graph and name what the player learned by the end, the level isn't designed yet.
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
|
|
22
|
+
### 1. Pin the level type
|
|
23
|
+
|
|
24
|
+
Ask exactly one question:
|
|
25
|
+
|
|
26
|
+
> What kind of level? Pick one: tutorial / hub / combat encounter / boss / exploration / puzzle / stealth / platforming-challenge / mixed.
|
|
27
|
+
|
|
28
|
+
Each type has different beats. Don't blend types in v1 — a "boss room with stealth and puzzles" is three levels poorly squeezed into one.
|
|
29
|
+
|
|
30
|
+
### 2. Read context
|
|
31
|
+
|
|
32
|
+
If `.summer/GameSoul.md` exists, read it. The level must serve the brief's core loop and the three mechanics.
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
Read .summer/GameSoul.md
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If `.summer/mechanics/` exists, list the mechanics. Quote them back:
|
|
39
|
+
|
|
40
|
+
> Brief says mechanics are: dash, parry, double-jump. This level should *exercise* at least one and ideally combine two.
|
|
41
|
+
|
|
42
|
+
### 3. Define the teaching / experience goal
|
|
43
|
+
|
|
44
|
+
Ask plain:
|
|
45
|
+
|
|
46
|
+
> What does the player know by the end of this level that they didn't at the start?
|
|
47
|
+
|
|
48
|
+
Tutorial-level answer: "How to dash." Combat-encounter answer: "That parrying converts damage to mana, and that big enemies need parry, not dodge." Exploration answer: "That this region's secrets are hidden behind double-jumpable gaps."
|
|
49
|
+
|
|
50
|
+
If the user can't answer, the level has no purpose. Say it:
|
|
51
|
+
|
|
52
|
+
> If there's no answer to that question, the level is filler. Either give it a teaching goal, give it a *failure-state* goal (the player must die here to progress), or merge it into the next level.
|
|
53
|
+
|
|
54
|
+
### 4. Sketch the pacing curve
|
|
55
|
+
|
|
56
|
+
Draw it as text. Five beats, intensity 0-10:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Intro Build Peak Release Hook
|
|
60
|
+
2 → 5 → 8 → 3 → 6
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
For a 5-minute encounter level:
|
|
64
|
+
|
|
65
|
+
| Beat | Duration | Intensity | Player feels | Designer plants |
|
|
66
|
+
|---|---|---|---|---|
|
|
67
|
+
| Intro | 30s | 2 | Calm, oriented | Visual landmark for the goal direction |
|
|
68
|
+
| Build | 90s | 5 | Tension rising, small pressure | First weak enemy / first puzzle clue |
|
|
69
|
+
| Peak | 60s | 8 | Stakes high, mistakes hurt | Main encounter / hardest fight |
|
|
70
|
+
| Release | 60s | 3 | Catharsis, loot | Reward + breath room |
|
|
71
|
+
| Hook | 30s | 6 | Curiosity for next | Visible-but-locked secret or path |
|
|
72
|
+
|
|
73
|
+
Show the curve. Ask:
|
|
74
|
+
|
|
75
|
+
> Pacing above. Does the peak land where you want, or does the level need a second wave?
|
|
76
|
+
|
|
77
|
+
### 5. List encounters and secrets
|
|
78
|
+
|
|
79
|
+
Encounters = explicit player tests (combat, puzzle, platforming). Secrets = optional rewards that respect the pacing curve.
|
|
80
|
+
|
|
81
|
+
State them flat. For a combat encounter level:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Encounters (in player-traversal order):
|
|
85
|
+
1. E1 — Tutorial enemy (1 weak grunt) at 0:30, in the open atrium. Teaches the basic attack.
|
|
86
|
+
2. E2 — Forced parry (mid-tier enemy with telegraphed wind-up) at 1:30, in a corridor with no dodge room. Teaches parry.
|
|
87
|
+
3. E3 — Mixed wave (2 grunts + 1 parry-required) at 3:00, in the peak arena. Tests both.
|
|
88
|
+
4. E4 — Mini-boss at 4:00 in the chamber. Combines.
|
|
89
|
+
|
|
90
|
+
Secrets (3 total — one per beat after intro):
|
|
91
|
+
- S1 (build beat): Behind a breakable wall in the corridor, holds 50 currency. Teaches "walls can break".
|
|
92
|
+
- S2 (peak beat): Visible from the arena, accessible only via parrying off an enemy. Rewards mastery.
|
|
93
|
+
- S3 (hook beat): Locked door, key in a future level. Plants curiosity for next level.
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 6. Define reward gating
|
|
97
|
+
|
|
98
|
+
What's behind which gate? Levels feel cheap when they hand out rewards without respecting the difficulty curve.
|
|
99
|
+
|
|
100
|
+
| Reward | Gate | Why |
|
|
101
|
+
|---|---|---|
|
|
102
|
+
| Heal pickup | After E2 | Player just learned parry; reward + safety net before the peak |
|
|
103
|
+
| New ability unlock | After mini-boss | Mastery-pinned; player demonstrates parry before getting upgrade |
|
|
104
|
+
| Currency cache | Behind S1 (breakable wall) | Optional; rewards observation |
|
|
105
|
+
| Story note | At the calm intro | Free; orients the player to the level's narrative |
|
|
106
|
+
|
|
107
|
+
Ask:
|
|
108
|
+
|
|
109
|
+
> Reward gating above. Anything missing or mis-placed?
|
|
110
|
+
|
|
111
|
+
### 7. Define the layout primitives
|
|
112
|
+
|
|
113
|
+
Every level is built from a small vocabulary of spaces. Name them. Most levels need 4-6 distinct spaces, no more.
|
|
114
|
+
|
|
115
|
+
For a combat-encounter level:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
Spaces (node-tree skeleton):
|
|
119
|
+
World (Node3D)
|
|
120
|
+
├── Geometry (Node3D)
|
|
121
|
+
│ ├── IntroAtrium (Node3D) # open, calm, well-lit
|
|
122
|
+
│ ├── Corridor (Node3D) # tight, forces parry
|
|
123
|
+
│ ├── PeakArena (Node3D) # large, multiple cover, exit visible
|
|
124
|
+
│ └── BossChamber (Node3D) # contained, single exit, dramatic lighting
|
|
125
|
+
├── Spawns (Node3D)
|
|
126
|
+
│ ├── PlayerSpawn (Node3D) # marker
|
|
127
|
+
│ ├── E1_Spawn (Node3D)
|
|
128
|
+
│ ├── E2_Spawn (Node3D)
|
|
129
|
+
│ ├── E3_Wave_Spawns (Node3D)
|
|
130
|
+
│ └── MiniBoss_Spawn (Node3D)
|
|
131
|
+
├── Triggers (Node3D)
|
|
132
|
+
│ ├── E2_GateTrigger (Area3D) # locks door behind player on entry
|
|
133
|
+
│ ├── PeakWaveTrigger (Area3D)
|
|
134
|
+
│ └── BossDoorTrigger (Area3D)
|
|
135
|
+
├── Pickups (Node3D)
|
|
136
|
+
│ ├── HealAfterE2 (Node3D)
|
|
137
|
+
│ └── CurrencyS1 (Node3D)
|
|
138
|
+
├── Secrets (Node3D)
|
|
139
|
+
│ ├── S1_BreakableWall (StaticBody3D)
|
|
140
|
+
│ ├── S2_ParryLedge (StaticBody3D)
|
|
141
|
+
│ └── S3_LockedDoor (StaticBody3D)
|
|
142
|
+
└── Lighting (Node3D) # WorldEnvironment + DirectionalLight3D
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Show the skeleton. Ask:
|
|
146
|
+
|
|
147
|
+
> Tree above. May I create the level scene `levels/<level-name>.tscn` with this skeleton?
|
|
148
|
+
|
|
149
|
+
### 8. Scaffold via MCP
|
|
150
|
+
|
|
151
|
+
**Preferred (Summer MCP):**
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
summer_create_scene(path="res://levels/level_01.tscn", root_type="Node3D", root_name="World")
|
|
155
|
+
summer_add_node(parent="./World", type="Node3D", name="Geometry")
|
|
156
|
+
summer_add_node(parent="./World/Geometry", type="Node3D", name="IntroAtrium")
|
|
157
|
+
summer_add_node(parent="./World/Geometry", type="Node3D", name="Corridor")
|
|
158
|
+
summer_add_node(parent="./World/Geometry", type="Node3D", name="PeakArena")
|
|
159
|
+
summer_add_node(parent="./World/Geometry", type="Node3D", name="BossChamber")
|
|
160
|
+
summer_add_node(parent="./World", type="Node3D", name="Spawns")
|
|
161
|
+
summer_add_node(parent="./World/Spawns", type="Node3D", name="PlayerSpawn")
|
|
162
|
+
summer_add_node(parent="./World/Spawns", type="Node3D", name="E1_Spawn")
|
|
163
|
+
# ... and so on
|
|
164
|
+
summer_add_node(parent="./World", type="Node3D", name="Triggers")
|
|
165
|
+
summer_add_node(parent="./World/Triggers", type="Area3D", name="E2_GateTrigger")
|
|
166
|
+
# ... etc.
|
|
167
|
+
summer_add_node(parent="./World", type="Node3D", name="Lighting")
|
|
168
|
+
summer_add_node(parent="./World/Lighting", type="WorldEnvironment", name="WorldEnvironment")
|
|
169
|
+
summer_add_node(parent="./World/Lighting", type="DirectionalLight3D", name="Sun")
|
|
170
|
+
summer_save_scene
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
This is a **skeleton, not playable geometry**. Markers and Area3Ds, no meshes, no enemy scripts. Implementation in subsequent sessions / templates.
|
|
174
|
+
|
|
175
|
+
**Fallback (no MCP):** Print the `.tscn` file contents for the user to save manually.
|
|
176
|
+
|
|
177
|
+
### 9. Save the level design doc
|
|
178
|
+
|
|
179
|
+
Always write the design doc — it's the artifact that drives implementation. Path: `.summer/levels/<level-name>.md`.
|
|
180
|
+
|
|
181
|
+
```markdown
|
|
182
|
+
# Level: <Name>
|
|
183
|
+
|
|
184
|
+
**Type:** combat encounter
|
|
185
|
+
**Duration target:** 5 min
|
|
186
|
+
**Teaching goal:** Player learns parry and that parrying mid-tier enemies is required, not optional.
|
|
187
|
+
|
|
188
|
+
**Pacing curve:** 2 → 5 → 8 → 3 → 6
|
|
189
|
+
**Beats:** Intro (30s) | Build (90s) | Peak (60s) | Release (60s) | Hook (30s)
|
|
190
|
+
|
|
191
|
+
## Encounters
|
|
192
|
+
- E1 — Tutorial grunt @ 0:30 (IntroAtrium)
|
|
193
|
+
- E2 — Forced parry @ 1:30 (Corridor)
|
|
194
|
+
- E3 — Mixed wave @ 3:00 (PeakArena)
|
|
195
|
+
- E4 — Mini-boss @ 4:00 (BossChamber)
|
|
196
|
+
|
|
197
|
+
## Secrets
|
|
198
|
+
- S1 — Breakable wall (Corridor) → 50 currency
|
|
199
|
+
- S2 — Parry-ledge (PeakArena) → cosmetic
|
|
200
|
+
- S3 — Locked door (BossChamber) → next level
|
|
201
|
+
|
|
202
|
+
## Reward Gating
|
|
203
|
+
- Heal pickup after E2
|
|
204
|
+
- Ability unlock after mini-boss
|
|
205
|
+
|
|
206
|
+
## Spaces
|
|
207
|
+
1. IntroAtrium — open, calm
|
|
208
|
+
2. Corridor — tight, forces parry
|
|
209
|
+
3. PeakArena — large with cover
|
|
210
|
+
4. BossChamber — contained, dramatic
|
|
211
|
+
|
|
212
|
+
## Open questions
|
|
213
|
+
<list anything the user couldn't answer>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Ask:
|
|
217
|
+
|
|
218
|
+
> May I create `.summer/levels/<level-name>.md` with this design doc?
|
|
219
|
+
|
|
220
|
+
### 10. Route to the next step
|
|
221
|
+
|
|
222
|
+
End with:
|
|
223
|
+
|
|
224
|
+
> Skeleton + design doc saved. Next:
|
|
225
|
+
> - `/summer:design-mechanic` to design any mechanics this level requires that aren't designed yet.
|
|
226
|
+
> - `/summer:design-npc` to design the enemies (E1-E4) in detail.
|
|
227
|
+
> - `/summer:art-direction` if the visual style isn't pinned yet.
|
|
228
|
+
> - Or open `levels/<level-name>.tscn` and start blocking out geometry.
|
|
229
|
+
|
|
230
|
+
## Common mistakes
|
|
231
|
+
|
|
232
|
+
| Mistake | Fix |
|
|
233
|
+
|---|---|
|
|
234
|
+
| No teaching goal | Every level teaches something or fails. State it explicitly. |
|
|
235
|
+
| Flat pacing curve | If intensity stays at 5 the whole time, you have a hallway, not a level. |
|
|
236
|
+
| Too many spaces | 4-6 distinct spaces max. More fragments the player's mental map. |
|
|
237
|
+
| Encounters not tied to mechanics | E2 should *require* parry, not just allow it. Forced use teaches; optional use doesn't. |
|
|
238
|
+
| Secrets ignore the pacing curve | Don't put a major secret in the calm intro — players aren't curious yet. |
|
|
239
|
+
| Reward gating too generous | Free heals before the peak deflate the peak. Gate them after the test. |
|
|
240
|
+
| Blending level types | Stealth + puzzle + boss in one level = three half-baked levels. Pick one. |
|
|
241
|
+
| Building geometry before the skeleton | Skeleton-first lets you iterate on layout cheaply. Geometry comes after the design is locked. |
|
|
242
|
+
| Calling SetResourceProperty on inline sub_resources | Silent fail. See `_shared/mcp-tools-reference.md` § Trap. |
|
|
243
|
+
|
|
244
|
+
## Collaborative protocol
|
|
245
|
+
|
|
246
|
+
This skill creates a new scene file (`.tscn`) and a design doc (`.md`). Group writes per phase. Always ask before `summer_create_scene`. See `_shared/collaborative-protocol.md`.
|
|
247
|
+
|
|
248
|
+
## Want a working starter?
|
|
249
|
+
|
|
250
|
+
This is a workflow that produces a skeleton scene. For runnable level examples, see:
|
|
251
|
+
|
|
252
|
+
- `template-id: template-3d-fps` (https://github.com/SummerEngine/FPS-template-Summer-Engine) ships a sample arena.
|
|
253
|
+
- `template-id: template-3d-platformer` (TBD) for jump-based level samples.
|
|
254
|
+
|
|
255
|
+
The skeleton this skill produces is meant to be filled in via `/summer:design-mechanic`, gridmap blockout, or a template merge.
|
|
256
|
+
|
|
257
|
+
## See also
|
|
258
|
+
|
|
259
|
+
- `_shared/collaborative-protocol.md`
|
|
260
|
+
- `_shared/mcp-tools-reference.md`
|
|
261
|
+
- `_shared/godot-version.md` — Godot 4.5 API notes
|
|
262
|
+
- `scene-and-project/brainstorm-game/SKILL.md` — produces `.summer/GameSoul.md`
|
|
263
|
+
- `gameplay-mechanics/design-mechanic/SKILL.md` — designs the verbs the level exercises
|
|
264
|
+
- `ai-and-npcs/design-npc/SKILL.md` — designs the enemies the encounters reference
|
|
265
|
+
- `rendering-and-lighting/3d-lighting/SKILL.md` — sets the lighting in `WorldEnvironment` + lights
|
|
266
|
+
- `rendering-and-lighting/art-direction/SKILL.md` — defines the visual style the level expresses
|