summer-engine 1.3.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/.claude-plugin/plugin.json +59 -0
  2. package/.codex-plugin/plugin.json +38 -0
  3. package/.cursor-plugin/plugin.json +42 -0
  4. package/.mcp.json +8 -0
  5. package/.opencode/plugins/summer.js +49 -0
  6. package/README.md +13 -0
  7. package/dist/lib/skills-registry.d.ts +96 -0
  8. package/dist/lib/skills-registry.js +205 -0
  9. package/gemini-extension.json +21 -0
  10. package/hooks/hooks-cursor.json +21 -0
  11. package/hooks/hooks.json +31 -0
  12. package/hooks/pre-commit-doctor.sh +123 -0
  13. package/hooks/run-hook.cmd +23 -0
  14. package/hooks/session-start.sh +120 -0
  15. package/marketplace.json +24 -0
  16. package/package.json +9 -1
  17. package/skills/_tests/specs/design-npc.md +43 -12
  18. package/skills/_tests/specs/fps-controller.md +33 -20
  19. package/skills/_tests/specs/host-authoritative-state.md +104 -0
  20. package/skills/_tests/specs/peer-to-peer-multiplayer.md +99 -0
  21. package/skills/_tests/specs/vfx.md +56 -38
  22. package/skills/ai-and-npcs/design-npc/SKILL.md +264 -122
  23. package/skills/asset-pipeline/asset-strategy/SKILL.md +8 -0
  24. package/skills/catalog.yaml +84 -0
  25. package/skills/character-controllers/fps-controller/SKILL.md +277 -69
  26. package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +332 -0
  27. package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +378 -0
  28. package/skills/rendering-and-lighting/3d-lighting/SKILL.md +20 -0
  29. package/skills/scene-and-project/make-game/SKILL.md +10 -0
  30. package/skills/scene-and-project/scene-composition/SKILL.md +8 -0
  31. package/skills/ui-and-ux/ui-basics/SKILL.md +28 -0
  32. package/skills/visual-effects/vfx/SKILL.md +233 -134
@@ -0,0 +1,99 @@
1
+ # Skill Spec: /peer-to-peer-multiplayer
2
+
3
+ ## Fixture
4
+
5
+ - A Godot 4.5 / Summer Engine project that does NOT yet have multiplayer.
6
+ - Project may be empty or may have an existing single-player scene.
7
+ - Summer MCP tools available; engine running on localhost:6550.
8
+
9
+ ## Case 1: Happy Path — fresh multiplayer architecture from scratch
10
+
11
+ **Input:** "I want to add 2-player co-op to my game. Players will connect through Steam friend invites."
12
+
13
+ **Expected behavior:**
14
+
15
+ 1. Skill confirms P2P is the right architecture (Steam friend invite ≤8 players → P2P, not dedicated server).
16
+ 2. Skill walks the four layers in order, checkpointing between each.
17
+ 3. Layer 1: asks "May I create `autoloads/network_manager.gd`?" — creates it on user OK, calls `summer_project_setting` to register the autoload.
18
+ 4. Layer 2: asks "May I create `autoloads/game_state.gd` and walk through the authority decision matrix?" — creates it, prompts user for game-specific state fields and proposes ownership.
19
+ 5. Layer 3: explains the three RPC patterns with examples; doesn't auto-apply (this is reference material until concrete game logic exists).
20
+ 6. Layer 4: defers prediction/interpolation until there's a player scene to apply it to.
21
+
22
+ **Expected MCP tool sequence (in order, partial):**
23
+
24
+ 1. `summer_get_scene_tree` — see what already exists.
25
+ 2. `summer_get_project_context` — read autoload list to avoid name collisions.
26
+ 3. (User approves Layer 1) `Write autoloads/network_manager.gd`.
27
+ 4. `summer_project_setting(key="autoload/NetworkManager", value="*res://autoloads/network_manager.gd")`.
28
+ 5. (User approves Layer 2) `Write autoloads/game_state.gd`.
29
+ 6. `summer_project_setting(key="autoload/GameState", value="*res://autoloads/game_state.gd")`.
30
+ 7. `summer_save_scene` and `summer_get_script_errors` to verify clean.
31
+
32
+ **Assertions:**
33
+
34
+ - [ ] Skill explicitly checks Step 0 (P2P vs. client-server) before any code is written.
35
+ - [ ] Skill creates Layer 1 (NetworkManager) before Layer 2 (GameState).
36
+ - [ ] NetworkManager is the only place that calls `multiplayer.peer_connected.connect()` directly. GameState listens to NetworkManager signals, NOT to the multiplayer API directly.
37
+ - [ ] GameState uses `@rpc("authority", "call_remote", "reliable")` for host-broadcast functions and `@rpc("any_peer", "call_remote", "reliable")` with a `is_host` guard for client-request functions.
38
+ - [ ] Skill walks the user through the authority decision matrix before writing GameState. Doesn't dump generic state fields without asking what the game has.
39
+ - [ ] Skill asks "May I…" before each new file creation and before the autoload registration.
40
+ - [ ] Skill does NOT apply prediction/interpolation in Layer 4 unless there's an existing player scene to wire into.
41
+ - [ ] At any layer, `summer_get_script_errors` is called after the file write to confirm clean compile.
42
+
43
+ ## Case 2: Failure Path — user wants matchmaking at scale
44
+
45
+ **Input:** "I'm building a competitive shooter. I want matchmaking with anti-cheat for 10,000 concurrent matches."
46
+
47
+ **Expected behavior:**
48
+
49
+ - Skill recognizes Step 0: this is dedicated client-server territory, not P2P.
50
+ - Skill explains why P2P is wrong (host can cheat, no anti-cheat hooks, scale concerns).
51
+ - Skill defers to `/summer:client-server-multiplayer` (when shipped) OR explains the user needs to roll a custom server.
52
+ - Does NOT start writing P2P NetworkManager code anyway.
53
+
54
+ **Assertions:**
55
+
56
+ - [ ] Skill stops at Step 0 — does NOT proceed to Layer 1.
57
+ - [ ] Skill explains the architecture mismatch in one sentence.
58
+ - [ ] Skill names the right alternative (client-server) and which skill to use instead.
59
+
60
+ ## Case 3: Edge Case — retrofitting multiplayer to a single-player game
61
+
62
+ **Input:** "I have a single-player platformer that's mostly done. Can you add multiplayer?"
63
+
64
+ **Expected behavior:**
65
+
66
+ - Skill is honest about the cost: retrofitting multiplayer is 5× harder than starting MP-first.
67
+ - Skill asks: "Are you committed? It will require auditing every state mutation in your existing code. Time estimate: significant."
68
+ - If user proceeds: skill walks the same 4 layers but adds an AUDIT phase before Layer 2: identify every place existing code writes to state that should be host-authoritative.
69
+ - If user balks: skill points to alternatives (release MP as a sequel; ship single-player; add async leaderboards instead).
70
+
71
+ **Assertions:**
72
+
73
+ - [ ] Skill warns about retrofit cost BEFORE starting Layer 1.
74
+ - [ ] Skill adds an AUDIT step that doesn't exist in the happy-path workflow.
75
+ - [ ] Skill never silently proceeds as if the game were greenfield.
76
+
77
+ ## Case 4: No Summer MCP — fallback path
78
+
79
+ **Fixture:** Same as Case 1, but Summer MCP unavailable.
80
+
81
+ **Input:** "Add multiplayer to my Godot game (P2P, friend invite)."
82
+
83
+ **Expected behavior:**
84
+
85
+ - Skill detects MCP unavailable.
86
+ - Walks the same 4 layers.
87
+ - Instead of `summer_project_setting`, asks the user to manually edit `project.godot`'s `[autoload]` section — provides the exact lines to paste.
88
+ - Instead of `summer_save_scene` / `summer_get_script_errors`, asks the user to save and check errors via the Godot editor.
89
+ - All file writes still go through `Write` host tool with "May I…" approval per file.
90
+
91
+ **Assertions:**
92
+
93
+ - [ ] Skill detects MCP unavailable; doesn't blindly call `summer_*` tools and fail.
94
+ - [ ] Project.godot edits are provided as exact paste-able lines.
95
+ - [ ] Workflow shape (4 layers, checkpoints between) is identical regardless of MCP availability.
96
+
97
+ ---
98
+
99
+ This spec runs via `/skill-test peer-to-peer-multiplayer spec` (see `_meta/skill-test/SKILL.md`).
@@ -2,7 +2,8 @@
2
2
 
3
3
  ## Fixture
4
4
 
5
- - Godot 4.5 / Summer Engine project, main scene with `World/Player` (CharacterBody3D + Camera3D) and `World/Enemy` (CharacterBody3D + MeshInstance3D + a `damaged` signal on a script).
5
+ - Godot 4.5 / Summer Engine project, main scene with `World/Player` (CharacterBody3D + Camera3D) and `World/Enemy` (CharacterBody3D + MeshInstance3D + a `damaged(amount)` signal).
6
+ - `default_bus_layout.tres` defines `Master`, `Music`, `Ambient`, `SFX` buses (at minimum).
6
7
  - Summer MCP tools available (engine running on localhost:6550).
7
8
  - Host file tools available (Read, Edit, Write).
8
9
 
@@ -12,14 +13,16 @@
12
13
 
13
14
  **Expected behavior:**
14
15
 
15
- 1. Skill asks one focused question: "What feels flat? combat hits / movement / pickups / damage / explosions / spell casts."
16
+ 1. Skill asks one focused question: "What feels flat? combat hits / pickups / explosions / spell casts / something else."
16
17
  2. User says "combat hits".
17
- 3. Skill calls `summer_get_scene_tree`, then `summer_inspect_node "./World/Enemy"` to confirm a MeshInstance3D and a `damaged` signal exist.
18
- 4. Skill proposes hit flash + camera shake bundle: "I'm about to add HitFlash on `./World/Enemy`, attach `scripts/hit_flash.gd`, attach `scripts/camera_shake.gd` to `./World/Player/Camera3D`, and connect the `damaged` signal. OK?"
18
+ 3. Skill calls `summer_get_scene_tree`, `summer_inspect_node "./World/Enemy"`, `summer_inspect_node "./World/Player/Camera3D"`, and confirms the audio bus list.
19
+ 4. Skill proposes the full trio bundle: "I'm about to add HitFlash on `./World/Enemy`, CameraShake script on `./World/Player/Camera3D`, AudioDucker autoload, and wire the `damaged` signal so one hit fires all three. OK?"
19
20
  5. After user OK:
20
21
  - `summer_add_node(parent="./World/Enemy", type="Node", name="HitFlash")`
21
- - `Write scripts/hit_flash.gd`
22
- - `Write scripts/camera_shake.gd`
22
+ - `Write scripts/vfx/hit_flash.gd`
23
+ - `Write scripts/vfx/camera_shake.gd`
24
+ - `Write scripts/vfx/audio_ducker.gd`
25
+ - Register `AudioDucker` as an autoload (project settings or `.cfg` edit).
23
26
  - `summer_connect_signal(from="./World/Enemy", signal="damaged", to="./World/Enemy/HitFlash", method="flash")`
24
27
  - `summer_save_scene`
25
28
  - `summer_get_script_errors`
@@ -27,71 +30,86 @@
27
30
  **Assertions:**
28
31
 
29
32
  - [ ] Skill asks the "what feels flat?" question before any tool call.
30
- - [ ] Skill reads the scene tree and inspects the relevant node before adding nodes.
33
+ - [ ] Skill reads scene tree AND inspects both Enemy mesh and Player Camera3D before mutation.
34
+ - [ ] Skill confirms audio bus names exist before installing AudioDucker.
31
35
  - [ ] Skill explicitly states the bundle of changes and asks "May I" / "OK?" before mutation.
32
- - [ ] HitFlash script uses Tween + `set_surface_override_material`, NOT a polled timer in `_process`.
36
+ - [ ] HitFlash uses `create_tween()` + `tween_callback`, NOT `await create_timer().timeout`.
37
+ - [ ] HitFlash kills any in-flight tween on re-entry (rapid hits).
33
38
  - [ ] CameraShake uses quadratic falloff (`_trauma * _trauma`), NOT linear.
34
- - [ ] Skill never calls `summer_set_resource_property` on an inline sub_resource (e.g. ParticleProcessMaterial).
39
+ - [ ] CameraShake subtracts last frame's `_shake_offset` before applying the new one.
40
+ - [ ] AudioDucker captures `_initial_volumes` once in `_ready()` and applies ducking as an offset (relative dB drop), NOT absolute writes.
41
+ - [ ] AudioDucker kills any in-flight tween before starting a new duck.
42
+ - [ ] Final hit flash duration is 0.06–0.12 sec.
43
+ - [ ] Skill never calls `summer_set_resource_property` on an inline sub_resource (e.g. for the flash StandardMaterial3D).
35
44
  - [ ] Skill ends with `summer_save_scene` then `summer_get_script_errors`.
36
- - [ ] Final hit flash duration is 0.06–0.12 sec (NOT 0.3 sec).
37
45
 
38
- ## Case 2: Failure Path — no Camera3D in scene
46
+ ## Case 2: Failure Path — missing audio buses
39
47
 
40
- **Fixture:** `World/Player` exists but has no Camera3D child. User asks for screen shake.
48
+ **Fixture:** project's `default_bus_layout.tres` has only `Master`. No `Music`, `Ambient`, `SFX`.
41
49
 
42
- **Input:** "Add screen shake when I take damage."
50
+ **Input:** "Add hit feedback. Audio ducking too."
43
51
 
44
52
  **Expected behavior:**
45
53
 
46
- - Skill calls `summer_get_scene_tree` and `summer_inspect_node "./World/Player"`, sees no Camera3D.
47
- - Skill does NOT silently spawn a Camera3D — it asks: "I don't see a Camera3D under `./World/Player`. Should I add one (and risk conflicting with an existing camera elsewhere), or do you have a camera node I should target?"
48
- - Waits for the answer.
54
+ - Skill calls `summer_get_scene_tree` then inspects the bus layout (or asks the user to paste it).
55
+ - Sees only `Master` exists.
56
+ - Skill does NOT install AudioDucker silently — it explains: "Audio ducking only works if at least Music/Ambient/SFX buses exist. With one Master bus, ducking would also duck the impact SFX you're trying to highlight. I can either (a) install hit-flash + camera-shake now and defer ducking until you set up buses via the `audio-direction` skill, or (b) walk through bus setup first."
57
+ - Waits for user choice.
58
+ - Whichever path: hit-flash + camera-shake still install correctly.
49
59
 
50
60
  **Assertions:**
51
61
 
52
- - [ ] Skill detects the missing Camera3D and stops to ask.
53
- - [ ] Skill does NOT add a Camera3D unilaterally.
54
- - [ ] Skill names a concrete next-step path (point to existing camera OR add new one explicitly).
62
+ - [ ] Skill detects single-bus layout and stops to ask.
63
+ - [ ] Skill does NOT register AudioDucker autoload silently.
64
+ - [ ] Skill names `audio-direction` skill as the prerequisite.
65
+ - [ ] Skill still ships the other two systems in this session if the user picks (a).
55
66
 
56
- ## Case 3: Edge Case — user wants "all the juice"
67
+ ## Case 3: Edge Case — pickup pulse without trauma
57
68
 
58
- **Fixture:** Same as Case 1.
69
+ **Fixture:** Same as Case 1, but the user is polishing pickups (peaceful glow), not combat.
59
70
 
60
- **Input:** "Add all the VFX. Make it feel like Hades."
71
+ **Input:** "Make my health pickups feel more rewarding when collected."
61
72
 
62
73
  **Expected behavior:**
63
74
 
64
- - Skill resists the temptation to stack 5 recipes at once.
65
- - Anchors on combat hits first (per skill's own guidance: "loudest perceived improvement per minute spent").
66
- - Says: "I'd rather land hit-flash + screen-shake first so we can see them work, then stack pickups/explosions next. Sound good?"
67
- - Does NOT propose a single bundle of 5 recipes.
75
+ - Skill asks the focused question; user says "pickups".
76
+ - Skill recognizes pickups should NOT trigger camera shake or aggressive audio ducking — those read as combat, not reward.
77
+ - Skill installs only the HitFlash module (renaming usage as a pickup pulse — same script, called on collection), and proposes a small upward duck (0.2 amount, 0.3 duration) so the pickup "ding" reads above ambient.
78
+ - Skill explicitly says: "Skipping camera shake here — shake reads as 'something hit me', wrong feeling for pickups. Same for heavy ducking. Want a tiny duck (0.2) to make the pickup chime pop?"
79
+ - Does NOT call `add_trauma` from the pickup handler.
68
80
 
69
81
  **Assertions:**
70
82
 
71
- - [ ] Skill explicitly chooses ONE recipe to start with, not all.
72
- - [ ] Skill names "combat hits" as the anchor.
73
- - [ ] Skill defers other recipes to a follow-up pass.
83
+ - [ ] Skill recognizes pickups ≠ combat and adapts the trio.
84
+ - [ ] Skill explicitly skips camera-shake with reasoning, not silently.
85
+ - [ ] HitFlash script is reused (not a forked copy) — `flash()` called on the pickup mesh.
86
+ - [ ] Audio duck `amount` ≤ 0.3, duration ≤ 0.4 (gentle).
87
+ - [ ] Skill does NOT install the full combat trio when the answer was "pickups".
74
88
 
75
89
  ## Case 4: No Summer MCP — file-edit fallback
76
90
 
77
91
  **Fixture:** Same as Case 1, but Summer MCP is unavailable (Cursor in a project where the engine is not connected).
78
92
 
79
- **Input:** "Add a hit flash to my enemy."
93
+ **Input:** "Add hit-flash + camera-shake + audio ducking to my combat."
80
94
 
81
95
  **Expected behavior:**
82
96
 
83
97
  - Skill detects MCP unavailable.
84
- - Asks the user to paste the relevant `.tscn` snippet (the Enemy node + its children) so the skill can write the right node-path references.
85
- - Writes `scripts/hit_flash.gd` directly via host file tools.
86
- - Provides a `.tscn` patch (or step-by-step manual editor instructions) for adding the HitFlash node and connecting the signal — does NOT blindly call `summer_*` tools.
87
- - Still asks "May I write `scripts/hit_flash.gd`?" before each file write.
98
+ - Asks the user to paste (a) the relevant `.tscn` snippet showing Enemy + Player + Camera3D node paths, and (b) the bus list from `default_bus_layout.tres`.
99
+ - Writes `scripts/vfx/hit_flash.gd`, `scripts/vfx/camera_shake.gd`, `scripts/vfx/audio_ducker.gd` directly via host file tools.
100
+ - Provides a `.tscn` patch for adding the HitFlash node and a manual instruction for registering the AudioDucker autoload via `project.godot` or the editor.
101
+ - Provides a manual signal-connect instruction (or a `.tscn` connection block) instead of `summer_connect_signal`.
102
+ - Still asks "May I write `scripts/vfx/<file>.gd`?" before each file write.
103
+ - Does NOT blindly call `summer_*` tools.
88
104
 
89
105
  **Assertions:**
90
106
 
91
- - [ ] Skill identifies MCP is unavailable and adapts.
92
- - [ ] Generated GDScript is syntactically valid Godot 4 GDScript with type hints.
93
- - [ ] Skill asks the user to paste the `.tscn` snippet for accurate node paths.
94
- - [ ] Skill still applies the "May I write …" protocol on file writes.
107
+ - [ ] Skill identifies MCP unavailable and adapts.
108
+ - [ ] Generated GDScript is syntactically valid Godot 4.5 with type hints.
109
+ - [ ] Skill asks the user to paste the scene snippet AND the bus list.
110
+ - [ ] Skill provides explicit autoload-registration instructions (no `summer_*` autoload tool exists).
111
+ - [ ] Skill applies "May I write …" protocol on each of the 3 file writes.
112
+ - [ ] No `summer_*` tool calls appear in the transcript when MCP is flagged unavailable.
95
113
 
96
114
  ---
97
115