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,99 @@
|
|
|
1
|
+
# Skill Spec: /brainstorm-game
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Empty Godot 4.5 / Summer Engine project, `project.godot` exists, no `.summer/` folder yet.
|
|
6
|
+
- Summer MCP available.
|
|
7
|
+
- Host file tools available (Read, Write, Edit).
|
|
8
|
+
|
|
9
|
+
## Case 1: Happy Path — fresh idea, full brainstorm
|
|
10
|
+
|
|
11
|
+
**Input:** "I want to make a game but I don't know what."
|
|
12
|
+
|
|
13
|
+
**Expected behavior:**
|
|
14
|
+
|
|
15
|
+
1. Skill asks the one opening question: "One sentence — what kind of game do you want to make?"
|
|
16
|
+
2. (Simulated user reply: "Something like Hades, but cozy.")
|
|
17
|
+
3. Skill recognizes Action-Combat anchor + cozy modifier, picks Action-Combat branch, but flags the tension: "Hades is tense, cozy is calm — let's pin which side wins."
|
|
18
|
+
4. Skill walks: core loop candidate → user refinement → three mechanics (push back if user lists more) → one-phrase art direction → scope (recommend vertical slice).
|
|
19
|
+
5. Skill drafts the 1-page brief inline, shows it to the user.
|
|
20
|
+
6. Skill asks: "May I create `.summer/GameSoul.md` with this brief?"
|
|
21
|
+
7. On yes, calls `Write .summer/GameSoul.md`.
|
|
22
|
+
8. Skill ends with the routing question pointing to `/summer:design-mechanic` or similar.
|
|
23
|
+
|
|
24
|
+
**Assertions:**
|
|
25
|
+
|
|
26
|
+
- [ ] Skill asks ONLY the opening question first, no menu of options.
|
|
27
|
+
- [ ] Skill picks ONE branch, not multiple; doesn't ask 6 questions in parallel.
|
|
28
|
+
- [ ] Skill enforces the three-mechanic limit (pushes back if user lists more).
|
|
29
|
+
- [ ] Brief includes all 8 fields: Pitch, Core loop, Three mechanics, Art direction, Scope, Win condition, "One thing this is NOT", Inspirations, Parked for later.
|
|
30
|
+
- [ ] Skill asks "May I create `.summer/GameSoul.md`?" before writing.
|
|
31
|
+
- [ ] Brief is shown inline before being written so the user can react.
|
|
32
|
+
- [ ] Skill ends with a routing question to a next `/summer:` step.
|
|
33
|
+
- [ ] Skill defaults to "vertical slice" scope when the user is unsure.
|
|
34
|
+
|
|
35
|
+
## Case 2: Failure Path — `.summer/GameSoul.md` already exists
|
|
36
|
+
|
|
37
|
+
**Fixture:** Same as Case 1, except `.summer/GameSoul.md` already exists with a previous game's brief.
|
|
38
|
+
|
|
39
|
+
**Input:** "I want to brainstorm a new game."
|
|
40
|
+
|
|
41
|
+
**Expected behavior:**
|
|
42
|
+
|
|
43
|
+
- Skill reads the existing `.summer/GameSoul.md` first via `Read`.
|
|
44
|
+
- Skill walks the brainstorm normally.
|
|
45
|
+
- Before writing, skill detects the file exists and asks: "`.summer/GameSoul.md` already exists. May I overwrite it, or merge into a 'Revision 2' section below the existing brief?"
|
|
46
|
+
- Does NOT silently overwrite.
|
|
47
|
+
|
|
48
|
+
**Assertions:**
|
|
49
|
+
|
|
50
|
+
- [ ] Skill reads existing `.summer/GameSoul.md` before drafting the new brief.
|
|
51
|
+
- [ ] Skill shows the user what would change before writing.
|
|
52
|
+
- [ ] Skill explicitly offers overwrite vs. merge — does not default-pick.
|
|
53
|
+
- [ ] No `Write` call happens until the user answers.
|
|
54
|
+
|
|
55
|
+
## Case 3: Edge Case — user pitches a multiplayer 4-player co-op horror RPG with crafting
|
|
56
|
+
|
|
57
|
+
**Fixture:** Same as Case 1.
|
|
58
|
+
|
|
59
|
+
**Input:** "I want a 4-player online co-op horror RPG with crafting, base-building, dialogue trees, and procedural worlds, kind of like Valheim meets Phasmophobia meets Disco Elysium."
|
|
60
|
+
|
|
61
|
+
**Expected behavior:**
|
|
62
|
+
|
|
63
|
+
- Skill catches the multiplayer flag (4-player co-op = scope explosion) and surfaces it explicitly: "Multiplayer is its own scope category — it roughly 3x's everything. Confirm: is multiplayer non-negotiable, or could a great single-player version land first and multiplayer come later?"
|
|
64
|
+
- Skill enforces the three-mechanic constraint hard. Names which mechanics from the user's pitch are content vs. mechanics, e.g.: "crafting + base-building are systems, not mechanics; dialogue is a mechanic if choices change outcomes."
|
|
65
|
+
- Skill states a sanity-check concern: "Procedural worlds + horror + RPG depth + multiplayer at vertical-slice scope is unrealistic. Suggest scoping to one of those four pillars."
|
|
66
|
+
- Skill does NOT just write the brief with all five things in it.
|
|
67
|
+
- Skill asks the user to pick the cut.
|
|
68
|
+
|
|
69
|
+
**Assertions:**
|
|
70
|
+
|
|
71
|
+
- [ ] Skill flags multiplayer explicitly and asks about negotiability before continuing.
|
|
72
|
+
- [ ] Skill distinguishes "system/feature" from "mechanic" out loud.
|
|
73
|
+
- [ ] Skill names a scope concern instead of writing the brief verbatim from the pitch.
|
|
74
|
+
- [ ] Skill never writes a brief with more than three mechanics.
|
|
75
|
+
- [ ] Skill offers a clear cut, not a vague "scope down" platitude.
|
|
76
|
+
|
|
77
|
+
## Case 4: No Summer MCP / no host file write — fallback path
|
|
78
|
+
|
|
79
|
+
**Fixture:** Same as Case 1, except the host has no file-write tool (read-only agent in a constrained environment).
|
|
80
|
+
|
|
81
|
+
**Input:** "Help me brainstorm a game."
|
|
82
|
+
|
|
83
|
+
**Expected behavior:**
|
|
84
|
+
|
|
85
|
+
- Skill detects no write tool is available.
|
|
86
|
+
- Walks the brainstorm normally.
|
|
87
|
+
- Instead of asking "May I create `.summer/GameSoul.md`?", prints the full brief to the user with explicit save instruction: "Save this as `.summer/GameSoul.md` in your project root. Every Summer skill reads it."
|
|
88
|
+
- Still ends with the routing question.
|
|
89
|
+
|
|
90
|
+
**Assertions:**
|
|
91
|
+
|
|
92
|
+
- [ ] Skill does NOT call a file-write tool that doesn't exist.
|
|
93
|
+
- [ ] Skill prints the brief inline as a self-contained block.
|
|
94
|
+
- [ ] Skill includes the explicit save instruction with the canonical path.
|
|
95
|
+
- [ ] Skill still asks the user the brainstorm questions and the routing question.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
This spec runs via `/skill-test brainstorm-game spec` (see `_meta/skill-test/SKILL.md`).
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Skill Spec: /design-level
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project, main scene already has a `World/Player` (CharacterBody3D) with FPS controller wired.
|
|
6
|
+
- `.summer/GameSoul.md` exists; brief: "Action-combat game, three mechanics: dash, parry, double-jump. Vertical slice scope."
|
|
7
|
+
- `.summer/mechanics/parry.md` exists.
|
|
8
|
+
- No `levels/` folder yet.
|
|
9
|
+
- Summer MCP available.
|
|
10
|
+
|
|
11
|
+
## Case 1: Happy Path — design level 1, a combat encounter
|
|
12
|
+
|
|
13
|
+
**Input:** "Design level 1, a 5-minute combat encounter that teaches parry."
|
|
14
|
+
|
|
15
|
+
**Expected MCP tool sequence (in order):**
|
|
16
|
+
|
|
17
|
+
1. `Read .summer/GameSoul.md` — anchor to the brief
|
|
18
|
+
2. (Optional: `Read .summer/mechanics/parry.md` — anchor to the mechanic being taught)
|
|
19
|
+
3. (Skill walks: type → teaching goal → pacing curve (5 beats with intensity numbers) → encounters list → secrets list → reward gating → spaces list)
|
|
20
|
+
4. (Skill shows the node-tree skeleton inline)
|
|
21
|
+
5. (Skill asks: "May I create `levels/level_01.tscn` with this skeleton?")
|
|
22
|
+
6. `summer_create_scene(path="res://levels/level_01.tscn", root_type="Node3D", root_name="World")`
|
|
23
|
+
7. `summer_add_node(parent="./World", type="Node3D", name="Geometry")` and children
|
|
24
|
+
8. `summer_add_node(parent="./World", type="Node3D", name="Spawns")` and children
|
|
25
|
+
9. `summer_add_node(parent="./World", type="Node3D", name="Triggers")` and Area3D children
|
|
26
|
+
10. `summer_add_node(parent="./World", type="Node3D", name="Pickups")`
|
|
27
|
+
11. `summer_add_node(parent="./World", type="Node3D", name="Secrets")`
|
|
28
|
+
12. `summer_add_node(parent="./World", type="Node3D", name="Lighting")` with WorldEnvironment + DirectionalLight3D
|
|
29
|
+
13. `summer_save_scene`
|
|
30
|
+
14. (Skill asks: "May I create `.summer/levels/level_01.md` with the design doc?")
|
|
31
|
+
15. `Write .summer/levels/level_01.md`
|
|
32
|
+
16. `summer_get_script_errors`
|
|
33
|
+
|
|
34
|
+
**Assertions:**
|
|
35
|
+
|
|
36
|
+
- [ ] Skill reads `.summer/GameSoul.md` to anchor.
|
|
37
|
+
- [ ] Skill reads the relevant `.summer/mechanics/<name>.md` if the level teaches an existing mechanic.
|
|
38
|
+
- [ ] Skill states a concrete teaching goal — not a vague "fun encounter".
|
|
39
|
+
- [ ] Skill draws a 5-beat pacing curve with intensity numbers (Intro / Build / Peak / Release / Hook).
|
|
40
|
+
- [ ] Skill lists 4 encounters with timing + space mapping.
|
|
41
|
+
- [ ] Skill lists 3 secrets with which beat each lives in.
|
|
42
|
+
- [ ] Skill lists reward gating, gates rewards behind tests.
|
|
43
|
+
- [ ] Skill enforces 4-6 distinct spaces (does not produce 12 micro-rooms).
|
|
44
|
+
- [ ] Skill asks "May I create ..." before `summer_create_scene`.
|
|
45
|
+
- [ ] Skeleton is markers + Area3Ds, NOT meshes / enemy scripts (those come later).
|
|
46
|
+
- [ ] Skill writes the design doc to `.summer/levels/<name>.md`.
|
|
47
|
+
- [ ] Skill never calls `summer_set_resource_property` on an inline sub_resource.
|
|
48
|
+
- [ ] Final step is `summer_save_scene` then `summer_get_script_errors`.
|
|
49
|
+
|
|
50
|
+
## Case 2: Failure Path — user blends three level types
|
|
51
|
+
|
|
52
|
+
**Fixture:** Same as Case 1.
|
|
53
|
+
|
|
54
|
+
**Input:** "Design a stealth level with a puzzle in the middle and a boss at the end."
|
|
55
|
+
|
|
56
|
+
**Expected behavior:**
|
|
57
|
+
|
|
58
|
+
- Skill recognizes blended types: stealth + puzzle + boss.
|
|
59
|
+
- Skill pushes back: "That's three level types. Pick one as the primary; the other two become flavor or get split into sequential levels."
|
|
60
|
+
- Skill names the trade-off: "Stealth + boss in the same level kills both — stealth wants tension that releases at the encounter, boss wants tension that builds *to* the encounter. They're opposite shapes."
|
|
61
|
+
- Skill does NOT silently pick one or design all three at once.
|
|
62
|
+
|
|
63
|
+
**Assertions:**
|
|
64
|
+
|
|
65
|
+
- [ ] Skill identifies the blend explicitly.
|
|
66
|
+
- [ ] Skill explains the design tension between the blended types.
|
|
67
|
+
- [ ] Skill asks the user to pick one primary type before designing.
|
|
68
|
+
- [ ] No `summer_create_scene` call until user picks.
|
|
69
|
+
|
|
70
|
+
## Case 3: Edge Case — no `.summer/GameSoul.md` exists
|
|
71
|
+
|
|
72
|
+
**Fixture:** Same as Case 1, but `.summer/GameSoul.md` does NOT exist.
|
|
73
|
+
|
|
74
|
+
**Input:** "Design level 1 of my game."
|
|
75
|
+
|
|
76
|
+
**Expected behavior:**
|
|
77
|
+
|
|
78
|
+
- Skill detects no brief exists.
|
|
79
|
+
- Skill suggests: "No `.summer/GameSoul.md` yet — without a brief, this level has no game to serve. Run `/summer:brainstorm-game` first, or give me the core loop + mechanics inline so I can anchor the design."
|
|
80
|
+
- Skill does NOT design a generic level in a vacuum.
|
|
81
|
+
|
|
82
|
+
**Assertions:**
|
|
83
|
+
|
|
84
|
+
- [ ] Skill checks for `.summer/GameSoul.md` early (before designing).
|
|
85
|
+
- [ ] Skill explicitly recommends `/summer:brainstorm-game` if absent.
|
|
86
|
+
- [ ] Skill offers the inline-anchor alternative as a fallback.
|
|
87
|
+
- [ ] No design happens without anchoring information.
|
|
88
|
+
|
|
89
|
+
## Case 4: No Summer MCP — file-edit fallback
|
|
90
|
+
|
|
91
|
+
**Fixture:** Same as Case 1, but Summer MCP is unavailable.
|
|
92
|
+
|
|
93
|
+
**Input:** "Design level 1 — a 5-minute combat encounter."
|
|
94
|
+
|
|
95
|
+
**Expected behavior:**
|
|
96
|
+
|
|
97
|
+
- Skill detects no MCP.
|
|
98
|
+
- Walks the design beats normally.
|
|
99
|
+
- Instead of `summer_create_scene` + `summer_add_node`, prints the full `.tscn` file contents for the user to save manually at `levels/level_01.tscn`.
|
|
100
|
+
- Generated `.tscn` is syntactically valid Godot 4 scene format with the marker/Area3D skeleton (no meshes).
|
|
101
|
+
- Still writes the design doc to `.summer/levels/level_01.md` via host `Write`.
|
|
102
|
+
- Asks "May I write ..." before each file write.
|
|
103
|
+
|
|
104
|
+
**Assertions:**
|
|
105
|
+
|
|
106
|
+
- [ ] Skill identifies that MCP is unavailable; does not blindly call `summer_*`.
|
|
107
|
+
- [ ] Generated `.tscn` is parseable Godot 4 scene file.
|
|
108
|
+
- [ ] Skeleton in the `.tscn` matches the spaces / spawns / triggers structure from the design doc.
|
|
109
|
+
- [ ] Skill still writes `.summer/levels/<name>.md`.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
This spec runs via `/skill-test design-level spec` (see `_meta/skill-test/SKILL.md`).
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Skill Spec: /design-mechanic
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project with `World/Player` (CharacterBody3D + CollisionShape3D + Camera3D) already in the main scene.
|
|
6
|
+
- A `scripts/player_controller.gd` exists with single-jump logic.
|
|
7
|
+
- `.summer/GameSoul.md` exists, brief says: "core loop is precise platforming, three mechanics: dash, double-jump, parry".
|
|
8
|
+
- Summer MCP available.
|
|
9
|
+
|
|
10
|
+
## Case 1: Happy Path — design double-jump
|
|
11
|
+
|
|
12
|
+
**Input:** "Design the double-jump mechanic."
|
|
13
|
+
|
|
14
|
+
**Expected MCP tool sequence (in order):**
|
|
15
|
+
|
|
16
|
+
1. (Skill asks one clarifying question if any — e.g., "Tap or hold-and-release?" — and waits.)
|
|
17
|
+
2. `Read .summer/GameSoul.md` — anchor to the brief
|
|
18
|
+
3. (Skill walks the five layers: input, response, feedback (visual/audio/mechanical), failure modes, depth)
|
|
19
|
+
4. (Skill names tunables as `@export` vars)
|
|
20
|
+
5. (Skill sketches the node-graph plan and asks "May I add `DoubleJumpFX` and `JumpAudio` to `./World/Player`?")
|
|
21
|
+
6. `summer_get_scene_tree` — confirm Player exists
|
|
22
|
+
7. `summer_add_node(parent="./World/Player", type="GPUParticles3D", name="DoubleJumpFX")`
|
|
23
|
+
8. `summer_set_prop("./World/Player/DoubleJumpFX", "emitting", "false")`
|
|
24
|
+
9. `summer_add_node(parent="./World/Player", type="AudioStreamPlayer3D", name="JumpAudio")`
|
|
25
|
+
10. `summer_input_map_bind(name="jump", events=[{type:"key", key:"Space"}])` (idempotent)
|
|
26
|
+
11. (Skill asks "May I modify `scripts/player_controller.gd` to add double-jump logic?")
|
|
27
|
+
12. `Edit scripts/player_controller.gd` — merge double-jump logic
|
|
28
|
+
13. (Skill asks "May I create `.summer/mechanics/double-jump.md` with the design doc?")
|
|
29
|
+
14. `Write .summer/mechanics/double-jump.md`
|
|
30
|
+
15. `summer_save_scene`
|
|
31
|
+
16. `summer_get_script_errors`
|
|
32
|
+
|
|
33
|
+
**Assertions:**
|
|
34
|
+
|
|
35
|
+
- [ ] Skill reads `.summer/GameSoul.md` to anchor the design to the brief.
|
|
36
|
+
- [ ] Skill walks all five layers (input, response, feedback, failure modes, depth) before scaffolding.
|
|
37
|
+
- [ ] Skill enforces all THREE feedback channels (visual, audio, mechanical) — pushes back if user only names two.
|
|
38
|
+
- [ ] Skill lists 3-7 tunables as `@export` vars (not `const`).
|
|
39
|
+
- [ ] Skill asks "May I add ..." before scene mutations.
|
|
40
|
+
- [ ] Skill asks "May I modify ..." before script edits.
|
|
41
|
+
- [ ] Skill writes the design doc to `.summer/mechanics/<name>.md`.
|
|
42
|
+
- [ ] Skill never calls `summer_set_resource_property` on an inline sub_resource (silent-fail trap).
|
|
43
|
+
- [ ] Generated GDScript uses typed vars, `@export`, `class_name`, `@onready`, signals (matches `_shared/gd-style.md`).
|
|
44
|
+
- [ ] Final step is `summer_save_scene` then `summer_get_script_errors`.
|
|
45
|
+
|
|
46
|
+
## Case 2: Failure Path — user names a system, not a mechanic
|
|
47
|
+
|
|
48
|
+
**Fixture:** Same as Case 1.
|
|
49
|
+
|
|
50
|
+
**Input:** "Design the inventory."
|
|
51
|
+
|
|
52
|
+
**Expected behavior:**
|
|
53
|
+
|
|
54
|
+
- Skill recognizes "inventory" is a system, not a mechanic.
|
|
55
|
+
- Skill pushes back: "Inventory is a system. The mechanics inside it are pickup, equip, drop, use, swap. Which one?"
|
|
56
|
+
- Does NOT start designing a generic "inventory mechanic".
|
|
57
|
+
- Waits for the user to pick a verb.
|
|
58
|
+
|
|
59
|
+
**Assertions:**
|
|
60
|
+
|
|
61
|
+
- [ ] Skill explicitly distinguishes system vs. mechanic.
|
|
62
|
+
- [ ] Skill asks the user to pick a verb before walking the five layers.
|
|
63
|
+
- [ ] No scene mutations or file writes happen until the user picks.
|
|
64
|
+
|
|
65
|
+
## Case 3: Edge Case — user can't articulate depth
|
|
66
|
+
|
|
67
|
+
**Fixture:** Same as Case 1.
|
|
68
|
+
|
|
69
|
+
**Input:** "Design the double-jump."
|
|
70
|
+
|
|
71
|
+
**During step 3, on Layer 5 (depth):**
|
|
72
|
+
|
|
73
|
+
User says: "Players will use it strategically."
|
|
74
|
+
|
|
75
|
+
**Expected behavior:**
|
|
76
|
+
|
|
77
|
+
- Skill rejects the hand-wave: "That's not depth — name the choice the player makes."
|
|
78
|
+
- Skill offers a concrete frame: "Depth = the resource is finite or has a cost, and level design forces a choice between using it now or saving it. If neither is true, this is just a higher-jumping single-jump."
|
|
79
|
+
- Skill asks the user to either (a) name the cost / choice, or (b) cut the mechanic.
|
|
80
|
+
- Skill does NOT scaffold a depth-less mechanic.
|
|
81
|
+
|
|
82
|
+
**Assertions:**
|
|
83
|
+
|
|
84
|
+
- [ ] Skill does not accept "strategically" / "for skilled play" / "it's interesting" as depth.
|
|
85
|
+
- [ ] Skill names a concrete depth-vector (cost, resource, choice).
|
|
86
|
+
- [ ] Skill explicitly offers "cut the mechanic" as a valid outcome.
|
|
87
|
+
- [ ] No scaffolding happens until depth is articulated.
|
|
88
|
+
|
|
89
|
+
## Case 4: No Summer MCP — file-edit fallback
|
|
90
|
+
|
|
91
|
+
**Fixture:** Same as Case 1, but Summer MCP is unavailable (engine not connected).
|
|
92
|
+
|
|
93
|
+
**Input:** "Design the double-jump mechanic."
|
|
94
|
+
|
|
95
|
+
**Expected behavior:**
|
|
96
|
+
|
|
97
|
+
- Skill detects no MCP and falls back to file edits.
|
|
98
|
+
- Walks the five layers normally.
|
|
99
|
+
- Instead of `summer_add_node`, prints the `.tscn` snippet for `DoubleJumpFX` and `JumpAudio` nodes for the user to paste into the scene file (or asks the user which `.tscn` to edit).
|
|
100
|
+
- Asks before each file write.
|
|
101
|
+
- Still writes the GDScript stub via `Edit` and the design doc via `Write`.
|
|
102
|
+
|
|
103
|
+
**Assertions:**
|
|
104
|
+
|
|
105
|
+
- [ ] Skill identifies that MCP is unavailable; does not blindly call `summer_*` tools.
|
|
106
|
+
- [ ] Generated `.tscn` snippet is syntactically valid Godot 4 scene format.
|
|
107
|
+
- [ ] Skill still asks "May I write ..." before each file write.
|
|
108
|
+
- [ ] Skill still produces both the GDScript stub AND the design doc at `.summer/mechanics/<name>.md`.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
This spec runs via `/skill-test design-mechanic spec` (see `_meta/skill-test/SKILL.md`).
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Skill Spec: /design-npc
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project, main scene with `World/Player` (CharacterBody3D in `player` group) and an empty `World/Enemies` parent.
|
|
6
|
+
- Summer MCP tools available.
|
|
7
|
+
- Host file tools available (Read, Edit, Write).
|
|
8
|
+
|
|
9
|
+
## Case 1: Happy Path — basic patrol-and-chase enemy
|
|
10
|
+
|
|
11
|
+
**Input:** "Add a basic enemy that chases the player when it sees them."
|
|
12
|
+
|
|
13
|
+
**Expected MCP tool sequence (in order):**
|
|
14
|
+
|
|
15
|
+
1. (Skill asks the archetype question and waits.)
|
|
16
|
+
2. User confirms "basic enemy".
|
|
17
|
+
3. `summer_get_scene_tree`
|
|
18
|
+
4. `summer_inspect_node "./World/Player"` — confirms it's in `player` group
|
|
19
|
+
5. (Skill proposes the bundle: scene tree + script + states + telegraph + loot hook + "May I create?")
|
|
20
|
+
6. After user OK:
|
|
21
|
+
- `summer_add_node(parent="./World/Enemies", type="CharacterBody3D", name="Enemy")`
|
|
22
|
+
- `summer_add_node(parent="./World/Enemies/Enemy", type="CollisionShape3D", name="Body")`
|
|
23
|
+
- `summer_add_node(parent="./World/Enemies/Enemy", type="MeshInstance3D", name="Mesh")`
|
|
24
|
+
- `summer_add_node(parent="./World/Enemies/Enemy", type="Area3D", name="Vision")`
|
|
25
|
+
- `summer_add_node(parent="./World/Enemies/Enemy/Vision", type="CollisionShape3D", name="VisionShape")`
|
|
26
|
+
- `summer_add_node(parent="./World/Enemies/Enemy", type="RayCast3D", name="Sight")`
|
|
27
|
+
- (Vision SphereShape3D saved as standalone `.tres`, NOT inline)
|
|
28
|
+
- `summer_set_prop` on Sight: `enabled = true`
|
|
29
|
+
- `Write scripts/enemy_ai.gd`
|
|
30
|
+
- `summer_connect_signal(from="./World/Enemies/Enemy/Vision", signal="body_entered", to="./World/Enemies/Enemy", method="_on_body_entered")`
|
|
31
|
+
- `summer_save_scene`
|
|
32
|
+
- `summer_get_script_errors`
|
|
33
|
+
|
|
34
|
+
**Assertions:**
|
|
35
|
+
|
|
36
|
+
- [ ] Skill asks the archetype question before any tool call.
|
|
37
|
+
- [ ] Scene has BOTH a Vision Area3D AND a Sight RayCast3D (the two-step perception pattern).
|
|
38
|
+
- [ ] Vision shape is saved as a standalone `.tres`, NOT inline sub_resource (silent-fail trap).
|
|
39
|
+
- [ ] Script defines an `enum State` with at least 4 states (idle / alert / attack / dead).
|
|
40
|
+
- [ ] Script has an attack `telegraph` parameter in 0.3–0.7 sec range.
|
|
41
|
+
- [ ] Script emits a `died` signal.
|
|
42
|
+
- [ ] Script uses `distance_squared_to` (NOT `distance_to`) for range comparisons.
|
|
43
|
+
- [ ] Script uses typed GDScript per `_shared/gd-style.md`.
|
|
44
|
+
- [ ] Skill asks "May I create / write …" before each user-visible mutation.
|
|
45
|
+
- [ ] Final step is `summer_save_scene` then `summer_get_script_errors`.
|
|
46
|
+
|
|
47
|
+
## Case 2: Failure Path — wave-mob archetype but user asks for full FSM
|
|
48
|
+
|
|
49
|
+
**Fixture:** User wants 100+ enemies on screen at once.
|
|
50
|
+
|
|
51
|
+
**Input:** "Spawn 100 enemies that chase the player. Each one should perceive, decide, telegraph attacks, and drop loot."
|
|
52
|
+
|
|
53
|
+
**Expected behavior:**
|
|
54
|
+
|
|
55
|
+
- Skill recognizes the scale conflict.
|
|
56
|
+
- Says: "100 enemies with full FSM + LOS perception will eat your frame budget. For wave mobs at this scale, the right archetype is the wave-mob (2 states, no LOS, direct line to player). Want me to build that instead?"
|
|
57
|
+
- Does NOT silently build 100 expensive enemies.
|
|
58
|
+
- Offers the trade-off explicitly.
|
|
59
|
+
|
|
60
|
+
**Assertions:**
|
|
61
|
+
|
|
62
|
+
- [ ] Skill names the performance trade-off, not just "this is hard".
|
|
63
|
+
- [ ] Skill points to the wave-mob archetype as the right answer.
|
|
64
|
+
- [ ] Skill does NOT proceed without confirmation.
|
|
65
|
+
- [ ] Skill never starts spawning 100 expensive nodes.
|
|
66
|
+
|
|
67
|
+
## Case 3: Edge Case — boss with phases
|
|
68
|
+
|
|
69
|
+
**Fixture:** Same as Case 1.
|
|
70
|
+
|
|
71
|
+
**Input:** "Design a 3-phase boss for the dungeon room."
|
|
72
|
+
|
|
73
|
+
**Expected behavior:**
|
|
74
|
+
|
|
75
|
+
- Skill picks the **boss** archetype (different complexity budget).
|
|
76
|
+
- Calls out: "Boss complexity (6–10 states, scripted phases) is at the threshold where a behavior tree might pay off, but I recommend a hand-coded FSM with phase enum first since you're a single dev."
|
|
77
|
+
- Walks the four pillars but at boss scale: more tells per state, telegraph 0.5–0.7 sec, distinct mechanics per phase (cap at 4–6 total mechanics).
|
|
78
|
+
- Defers to `ai-and-npcs/boss-patterns/SKILL.md` for the deeper phase-transition patterns.
|
|
79
|
+
- Does NOT just scale up the basic-enemy stub.
|
|
80
|
+
|
|
81
|
+
**Assertions:**
|
|
82
|
+
|
|
83
|
+
- [ ] Skill recognizes "boss" requires a different design.
|
|
84
|
+
- [ ] Skill caps at 4–6 distinct mechanics across phases.
|
|
85
|
+
- [ ] Skill mentions phase enum as the FSM extension.
|
|
86
|
+
- [ ] Skill defers to boss-patterns for deeper detail rather than trying to one-shot it.
|
|
87
|
+
|
|
88
|
+
## Case 4: No Summer MCP — fallback path
|
|
89
|
+
|
|
90
|
+
**Fixture:** Same as Case 1, but Summer MCP unavailable.
|
|
91
|
+
|
|
92
|
+
**Input:** "Add a basic enemy that chases the player."
|
|
93
|
+
|
|
94
|
+
**Expected behavior:**
|
|
95
|
+
|
|
96
|
+
- Skill detects MCP unavailable.
|
|
97
|
+
- Asks user to paste the existing scene tree (or the relevant `.tscn` snippet) so node paths are right.
|
|
98
|
+
- Generates a `.tscn` snippet (Enemy + Vision + Sight + Mesh + CollisionShape) with valid Godot 4 scene syntax.
|
|
99
|
+
- Writes `scripts/enemy_ai.gd` directly.
|
|
100
|
+
- Provides manual editor instructions for connecting the `body_entered` signal (or a connection block in the `.tscn`).
|
|
101
|
+
- Still asks "May I write …" before each file write.
|
|
102
|
+
|
|
103
|
+
**Assertions:**
|
|
104
|
+
|
|
105
|
+
- [ ] Skill does not blindly call `summer_*` tools and fail.
|
|
106
|
+
- [ ] Generated `.tscn` is valid Godot 4 syntax (parseable).
|
|
107
|
+
- [ ] Generated GDScript has the same FSM structure (states / telegraph / died signal).
|
|
108
|
+
- [ ] Skill still asks "May I" on writes.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
This spec runs via `/skill-test design-npc spec` (see `_meta/skill-test/SKILL.md`).
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Skill Spec: /export-and-ship
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project, complete game with main scene set, no script errors, basic icon at `icon.png` (256×256).
|
|
6
|
+
- Existing `export_presets.cfg` with Windows/Mac/Linux presets, all `debug = true` (development defaults).
|
|
7
|
+
- No `LICENSE` file at repo root.
|
|
8
|
+
- No `attribution.md`.
|
|
9
|
+
- Two CC-BY 4.0 assets imported from public sources (used in scene).
|
|
10
|
+
- Summer MCP tools available.
|
|
11
|
+
|
|
12
|
+
## Case 1: Happy Path — Steam (Windows + Mac + Linux)
|
|
13
|
+
|
|
14
|
+
**Input:** "I'm ready to ship to Steam. Build me Windows, Mac, and Linux releases."
|
|
15
|
+
|
|
16
|
+
**Expected MCP tool sequence (in order):**
|
|
17
|
+
|
|
18
|
+
1. (Skill asks the destination question and waits — confirms Steam, Win/Mac/Linux.)
|
|
19
|
+
2. Pre-flight:
|
|
20
|
+
- `summer_get_diagnostics` — clean
|
|
21
|
+
- `summer_get_console` — clean
|
|
22
|
+
- Read `project.godot` — main scene set, no version, no name
|
|
23
|
+
- Read `LICENSE` — does not exist
|
|
24
|
+
- Read `attribution.md` — does not exist
|
|
25
|
+
- Read `export_presets.cfg` — `debug = true` on all presets
|
|
26
|
+
- Grep for hardcoded paths
|
|
27
|
+
3. (Skill lists the pre-flight failures: missing LICENSE, missing attribution.md, missing version, missing game name, debug=true on release presets, missing Steam-required assets like trailer + capsules.)
|
|
28
|
+
4. Skill asks: "Pre-flight failed on N items: <list>. Want me to walk these one by one?"
|
|
29
|
+
5. (Does NOT proceed to build.)
|
|
30
|
+
|
|
31
|
+
**Assertions:**
|
|
32
|
+
|
|
33
|
+
- [ ] Skill asks the destination question first.
|
|
34
|
+
- [ ] Skill runs the FULL pre-flight checklist before any build.
|
|
35
|
+
- [ ] Skill detects missing LICENSE and missing `attribution.md`.
|
|
36
|
+
- [ ] Skill detects `debug = true` and flags it as a blocker for release.
|
|
37
|
+
- [ ] Skill detects missing Steam-specific assets (capsules, trailer) and lists them.
|
|
38
|
+
- [ ] Skill does NOT produce a build until the user fixes the blockers OR explicitly waives them.
|
|
39
|
+
- [ ] Skill never auto-uploads to Steam Pipe — only points at the upload command.
|
|
40
|
+
|
|
41
|
+
## Case 2: Failure Path — pre-flight passes, but iOS targeted without Apple Developer setup
|
|
42
|
+
|
|
43
|
+
**Fixture:** Project is clean (LICENSE present, no script errors, version + name set).
|
|
44
|
+
|
|
45
|
+
**Input:** "Ship to iOS App Store."
|
|
46
|
+
|
|
47
|
+
**Expected behavior:**
|
|
48
|
+
|
|
49
|
+
- Skill runs pre-flight — clean.
|
|
50
|
+
- Skill walks iOS-specific requirements: 1024×1024 icon, screenshots at 6.5" iPhone resolution, App Store description, privacy policy URL, support URL, bundle ID, Apple Developer cert + provisioning profile.
|
|
51
|
+
- Skill asks: "iOS submission requires (a) Apple Developer account ($99/yr), (b) Bundle ID configured in Apple Developer portal, (c) distribution certificate + provisioning profile, (d) macOS machine with Xcode for the final archive step. Do you have these set up? If not, those are the prerequisites — I can help with the build config but not the Apple Developer side."
|
|
52
|
+
- Does NOT silently produce an unsigned `.ipa` that can't be submitted.
|
|
53
|
+
|
|
54
|
+
**Assertions:**
|
|
55
|
+
|
|
56
|
+
- [ ] Skill names the iOS prerequisites that aren't satisfiable from inside Godot.
|
|
57
|
+
- [ ] Skill names the bundle-ID convention (`com.<org>.<game>`).
|
|
58
|
+
- [ ] Skill mentions TestFlight before App Store review.
|
|
59
|
+
- [ ] Skill does NOT pretend to do code signing it can't actually do.
|
|
60
|
+
- [ ] Skill names AAB-vs-APK if the user mistakenly says "Android APK" (different ticket but related anti-pattern).
|
|
61
|
+
|
|
62
|
+
## Case 3: Edge Case — multi-platform, web HTML5 included
|
|
63
|
+
|
|
64
|
+
**Fixture:** Same as Case 1 but post-fix (LICENSE added, attribution.md added, presets `debug = false`, version = "1.0.0", screenshots ready, trailer recorded).
|
|
65
|
+
|
|
66
|
+
**Input:** "Ship to Steam + itch + web."
|
|
67
|
+
|
|
68
|
+
**Expected behavior:**
|
|
69
|
+
|
|
70
|
+
- Pre-flight clean.
|
|
71
|
+
- Skill walks each platform's requirements separately.
|
|
72
|
+
- For web: explicitly flags the multiplayer transport (ENet doesn't work in browser), the audio autoplay block (Chrome blocks until first user click), and the file-size matters trap.
|
|
73
|
+
- Web export preset configured: encryption disabled, no JS eval, GLES3 fallback to GLES2 on if old browsers targeted.
|
|
74
|
+
- Skill asks: "May I produce 5 builds (Win + Mac + Linux + itch packages + web)?"
|
|
75
|
+
- Produces builds via `godot --headless --export-release` invocations after user OK.
|
|
76
|
+
- Verifies each build size and lists post-build warnings (e.g. "Web build is 180 MB — consider stripping unused textures").
|
|
77
|
+
- Points at upload commands for each: `steamcmd`, `butler push`, manual itch web upload.
|
|
78
|
+
|
|
79
|
+
**Assertions:**
|
|
80
|
+
|
|
81
|
+
- [ ] Skill walks per-platform requirements separately, NOT a generic checklist.
|
|
82
|
+
- [ ] For web: skill flags the autoplay + multiplayer + file-size traps explicitly.
|
|
83
|
+
- [ ] Skill produces builds in correct order (build, then verify, then point at upload — never auto-upload).
|
|
84
|
+
- [ ] Skill provides per-platform upload commands (steamcmd / butler / etc).
|
|
85
|
+
- [ ] Skill does NOT execute uploads itself.
|
|
86
|
+
|
|
87
|
+
## Case 4: No Summer MCP — fallback path
|
|
88
|
+
|
|
89
|
+
**Fixture:** Same as Case 1, MCP unavailable.
|
|
90
|
+
|
|
91
|
+
**Input:** "I want to ship to Steam."
|
|
92
|
+
|
|
93
|
+
**Expected behavior:**
|
|
94
|
+
|
|
95
|
+
- Skill detects MCP unavailable.
|
|
96
|
+
- Asks user to confirm via the editor: main scene set, no errors in Output panel, no errors in Debugger panel.
|
|
97
|
+
- Asks user to paste contents of `project.godot` and `export_presets.cfg`.
|
|
98
|
+
- Walks the pre-flight checklist by reasoning over the pasted text.
|
|
99
|
+
- Provides per-platform asset list and config recommendations.
|
|
100
|
+
- Provides build commands the user can run manually (`godot --headless --export-release ...`).
|
|
101
|
+
- Provides upload commands the user can run manually (`steamcmd ...`).
|
|
102
|
+
- Still applies "May I write" before any file edit (e.g. `LICENSE` creation).
|
|
103
|
+
|
|
104
|
+
**Assertions:**
|
|
105
|
+
|
|
106
|
+
- [ ] Skill does not blindly call `summer_*` tools and fail.
|
|
107
|
+
- [ ] Skill asks for the specific files it needs (project.godot, export_presets.cfg).
|
|
108
|
+
- [ ] Skill still runs the full pre-flight check via reading.
|
|
109
|
+
- [ ] Skill names the same blockers (LICENSE, debug=true, missing trailer).
|
|
110
|
+
- [ ] Skill asks "May I write" before creating LICENSE / attribution.md / etc.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
This spec runs via `/skill-test export-and-ship spec` (see `_meta/skill-test/SKILL.md`).
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
5. `summer_set_prop("./World/Player/Collision", "shape", "CapsuleShape3D")` (creates standalone, NOT inline sub-resource)
|
|
21
21
|
6. `summer_set_resource_property("./World/Player/Collision", "shape.height", "1.8")` (only after the shape is standalone)
|
|
22
22
|
7. `summer_set_prop("./World/Player/Camera", "position", "Vector3(0, 1.6, 0)")`
|
|
23
|
-
8. `summer_input_map_bind("move_forward", "key:W")`
|
|
24
|
-
9. `summer_input_map_bind("move_back", "key:S")`
|
|
25
|
-
10. `summer_input_map_bind("move_left", "key:A")`
|
|
26
|
-
11. `summer_input_map_bind("move_right", "key:D")`
|
|
27
|
-
12. `summer_input_map_bind("jump", "key:Space")`
|
|
23
|
+
8. `summer_input_map_bind(name="move_forward", events=[{type:"key", key:"W"}])`
|
|
24
|
+
9. `summer_input_map_bind(name="move_back", events=[{type:"key", key:"S"}])`
|
|
25
|
+
10. `summer_input_map_bind(name="move_left", events=[{type:"key", key:"A"}])`
|
|
26
|
+
11. `summer_input_map_bind(name="move_right", events=[{type:"key", key:"D"}])`
|
|
27
|
+
12. `summer_input_map_bind(name="jump", events=[{type:"key", key:"Space"}])`
|
|
28
28
|
13. (User-side write) `Write` script file `scripts/player_controller.gd` after the agent asks "May I attach the controller script to ./World/Player?"
|
|
29
29
|
14. `summer_save_scene`
|
|
30
30
|
15. `summer_get_script_errors`
|