summer-engine 3.5.1 → 3.6.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 (60) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +3 -2
  3. package/.codex-plugin/plugin.json +4 -3
  4. package/.cursor-plugin/plugin.json +3 -2
  5. package/.factory-plugin/plugin.json +3 -2
  6. package/CHANGELOG.md +22 -1
  7. package/commands/summer.md +1 -0
  8. package/dist/core/capabilities/sfx-choices.d.ts +91 -0
  9. package/dist/core/capabilities/sfx-choices.js +291 -0
  10. package/dist/core/capabilities/tool-dispatch.js +35 -0
  11. package/dist/mcp/hosted-mount.js +2 -1
  12. package/dist/mcp/provider-safe-schema.d.ts +10 -0
  13. package/dist/mcp/provider-safe-schema.js +96 -0
  14. package/dist/mcp/server.js +3 -0
  15. package/dist/mcp/tools/generate-tools.js +70 -3
  16. package/gemini-extension.json +2 -1
  17. package/library/references/mcp-tools-reference/mcp-tools-reference.md +5 -3
  18. package/library/references/mcp-tools-reference/resource.yaml +1 -1
  19. package/library/skills/README.md +4 -3
  20. package/library/skills/ambient-bed/SKILL.md +3 -1
  21. package/library/skills/ambient-bed/resource.yaml +1 -1
  22. package/library/skills/audio-direction/SKILL.md +5 -5
  23. package/library/skills/audio-direction/resource.yaml +1 -1
  24. package/library/skills/export-and-ship/SKILL.md +4 -0
  25. package/library/skills/make-game/SKILL.md +21 -2
  26. package/library/skills/make-game/resource.yaml +1 -0
  27. package/library/skills/multiplayer/SKILL.md +3 -1
  28. package/library/skills/multiplayer/resource.yaml +1 -0
  29. package/library/skills/multiplayer-movement/SKILL.md +1 -1
  30. package/library/skills/multiplayer-movement/files.md +2 -3
  31. package/library/skills/multiplayer-project/SKILL.md +20 -4
  32. package/library/skills/multiplayer-project/files.md +2 -3
  33. package/library/skills/multiplayer-publish/SKILL.md +90 -5
  34. package/library/skills/multiplayer-publish/resource.yaml +1 -0
  35. package/library/skills/multiplayer-state/SKILL.md +1 -1
  36. package/library/skills/multiplayer-state/files.md +2 -3
  37. package/library/skills/multiplayer-testing/SKILL.md +13 -0
  38. package/library/skills/multiplayer-testing/resource.yaml +1 -0
  39. package/library/skills/publish-your-game/SKILL.md +2 -0
  40. package/library/skills/release-readiness/SKILL.md +437 -0
  41. package/library/skills/release-readiness/resource.yaml +44 -0
  42. package/library/skills/sound-effect/SKILL.md +83 -158
  43. package/library/skills/sound-effect/resource.yaml +8 -2
  44. package/library/skills/summer-parties/SKILL.md +1 -1
  45. package/library/skills/ui-basics/SKILL.md +1 -0
  46. package/library/tools/generate-audio/resource.yaml +6 -2
  47. package/library/tools/generate-sfx-choices/resource.yaml +69 -0
  48. package/library/tools/get-choices/resource.yaml +50 -0
  49. package/package.json +1 -1
  50. package/registry/generated/aliases.json +2 -0
  51. package/registry/generated/counts.json +3 -3
  52. package/registry/generated/gemini-extension.json +2 -1
  53. package/registry/generated/index.json +163 -24
  54. package/registry/generated/marketplace.claude.json +2 -2
  55. package/registry/generated/plugin.claude.json +3 -2
  56. package/registry/generated/plugin.codex.json +4 -3
  57. package/registry/generated/plugin.cursor.json +3 -2
  58. package/registry/generated/plugin.factory.json +3 -2
  59. package/registry/generated/skills-index.md +4 -3
  60. package/registry/generated/skills-registry.json +15 -1
@@ -22,7 +22,7 @@ func _ready() -> void:
22
22
  spawner.entity_spawned.connect(_on_player_spawned)
23
23
  spawner.command_received.connect(_on_command)
24
24
  world.session_left.connect(_on_session_left)
25
- var initialized: SummerResult = await Summer.initialize(Game.GAME_ID).get_result_or_completed_signal()
25
+ var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
26
26
  if not initialized.ok:
27
27
  push_error(initialized.message)
28
28
  return
@@ -127,7 +127,7 @@ func _ready() -> void:
127
127
  spawner = Game.build_network(self, PlayerArchetype)
128
128
  # Connect signals like state_group_created here, before joining, or values
129
129
  # that arrive during the join go unseen (multiplayer-movement adds them).
130
- var initialized: SummerResult = await Summer.initialize(Game.GAME_ID).get_result_or_completed_signal()
130
+ var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
131
131
  if not initialized.ok:
132
132
  push_error(initialized.message)
133
133
  return
@@ -283,7 +283,6 @@ occurrence_streams = Array[SummerNetworkOccurrenceStream]([SubResource("Commands
283
283
  extends RefCounted
284
284
  ## Shared by the client and the authority: ids, streams and shared rules.
285
285
 
286
- const GAME_ID := "game_courtyard"
287
286
  const QUEUE := &"courtyard"
288
287
  const CMD := &"courtyard.cmd"
289
288
  const MAX_PLAYERS := 8
@@ -96,6 +96,15 @@ To make the same in the Export dialog:
96
96
  Both presets must include the composition; each must include its entry
97
97
  scene.
98
98
 
99
+ The `summer_authority` custom feature is what makes the server start the
100
+ authority. Summer starts `server.pck` with no scene argument, so the pack's
101
+ own main scene decides what runs: `run/main_scene.summer_authority` from
102
+ `project.godot` (`multiplayer-project`), which applies only to a pack whose
103
+ preset carries that feature. Without it, the server runs the client's main
104
+ scene, usually the title. It never restores the World or reports ready, and
105
+ every online join fails with `world_start_timeout`. Local Play and the upload
106
+ checks name the scene themselves, so they can't catch this; step 4d can.
107
+
99
108
  Textures: iOS and macOS read ETC2/ASTC (`textures/vram_compression/import_etc2_astc=true`
100
109
  in `project.godot`), and Windows reads S3TC/BPTC (`import_s3tc_bptc=true`).
101
110
  Enable the ones for the platforms you tick. The exporter's **Fix Import**
@@ -126,13 +135,24 @@ summer.games: Publish uploads this one file as a new Build.
126
135
  ```
127
136
 
128
137
  Check that `server.pck` and your `config/` files are listed, and that the
129
- "Left N server-only files" count covers your `authority/` files. Every
138
+ "Left N server-only files" count covers your `authority/` files. The
139
+ `Server: … mainScene …` line names the scene the Build declares, not the
140
+ scene the pack will start; step 4d checks that. The `Exported by Summer`
141
+ line must name a released Summer: export with the released editor from the
142
+ download page, never a development build, and export again after you update
143
+ Summer. Players' apps run the packs on the released Summer of that version;
144
+ step 4e checks it. The Summer Games apps for iPhone and Android start only
145
+ exports on their own MAJOR.MINOR, so export with the current Summer release
146
+ (`release-readiness` check 9). Every
130
147
  result message and every export error, with its fix, is in
131
148
  [export-errors.md](export-errors.md).
132
149
 
133
150
  ## 4. Check before uploading
134
151
 
135
- Do all three. Each catches problems the export doesn't.
152
+ Do all five. Each catches problems the export doesn't. Run them on the
153
+ `.zip` you will upload, not on a pack exported separately with the server
154
+ preset (`--export-pack`): that pack differs from the bundle's `server.pck`,
155
+ for example it keeps `gameId`, and can pass where the upload fails.
136
156
 
137
157
  **a. Local Play passes** (`multiplayer-testing`): every process has
138
158
  `script_errors` 0, there's no `cannot attach`, and your ready lines appear.
@@ -187,12 +207,45 @@ unzip -o build/courtyard.summer.zip client.pck server.pck -d "$P/out"
187
207
  Paths must be absolute. Pass: both reports say `"sceneLoaded": true`, and
188
208
  their `compositionManifest` objects are identical. On failure the probe
189
209
  writes `rejection.json`; its codes are in [export-errors.md](export-errors.md).
210
+ The probe names the scene to load, so it does not show which scene the
211
+ server starts on its own.
212
+
213
+ **d. The server pack starts the authority scene.** Start the bundle's
214
+ `server.pck` the way Summer does, with no scene argument, and stop it after
215
+ a few seconds:
216
+
217
+ ```sh
218
+ perl -e 'alarm shift; exec @ARGV' 15 <summer> --headless --verbose --main-pack "$P/out/server.pck"
219
+ ```
220
+
221
+ The first `Completed load for: 'res://….tscn'` line must be the authority
222
+ scene (`res://authority/main.tscn` here). If it is the client or title
223
+ scene, add `summer_authority` to the server preset's custom features and
224
+ export again. Later lines may complain that there is no hosted World; that
225
+ is expected locally.
226
+
227
+ **e. The client compiles on the released Summer.** Run the bundle's
228
+ `client.pck` with the released Summer of the version the export names (see
229
+ `release-readiness` check 7 for how to confirm the stamp), and fail on any
230
+ compile error:
231
+
232
+ ```sh
233
+ perl -e 'alarm shift; exec @ARGV' 60 <released-summer> --headless --verbose --main-pack "$P/out/client.pck" --quit-after 600 > "$P/out/client-run.log" 2>&1
234
+ grep -E 'SCRIPT ERROR|Parse Error|Failed to load script' "$P/out/client-run.log"
235
+ ```
236
+
237
+ The grep must print nothing; the run itself exits normally even when a
238
+ script fails. A failure here, such as `Static function "party_queue()" not
239
+ found`, means the scripts use an API the released version lacks, usually
240
+ because a development build made the export. Every player would see an
241
+ empty window. Re-export with the current Summer release.
190
242
 
191
243
  ## 5. Upload the Build
192
244
 
193
245
  1. The game must exist in Summer Studio, and `gameId` in
194
- `summer.build.json` and `GAME_ID` in `network/game.gd` must both be its
195
- id.
246
+ `summer.build.json` must be its id. The export leaves `gameId` out of the
247
+ bundle, and the game code calls `Summer.initialize()` with no ID: a
248
+ literal or fallback ID fails hosted with `game_identity_mismatch`.
196
249
  2. Open the game's Builds page: `summer_open` with target `game`,
197
250
  `gameId` and section `builds`, or summerengine.com → Studio → your game →
198
251
  Builds.
@@ -209,6 +262,30 @@ writes `rejection.json`; its codes are in [export-errors.md](export-errors.md).
209
262
  For a client-only fix to an existing Build, export to a `.pck` path instead
210
263
  of `.zip`. That writes `client.pck` alone.
211
264
 
265
+ ## 6. Join it for real
266
+
267
+ Right after the Build is released, open the game in a Summer Games app,
268
+ join online and play until you are in the game, before players hear about
269
+ the update. A wrong Game ID only fails under a real hosted launch, so
270
+ nothing before this step catches it. Keep playing, signed in, for at least 3
271
+ minutes: the game must not close and the player must stay signed in
272
+ (`release-readiness` check 10). An agent can't do this; ask the user and
273
+ record the result. The whole list of checks before a release is
274
+ `release-readiness`, and the creator docs have it at
275
+ https://docs.summerengine.com/publishing/release-readiness.
276
+
277
+ ## When online joins fail
278
+
279
+ Every join ends in `world_start_timeout`, but Local Play works:
280
+
281
+ 1. The server starts the wrong scene: run step 4d.
282
+ 2. The game passes a fixed Game ID to `Summer.initialize`: pass none.
283
+
284
+ Then export, upload and release a new Build, and join again. An empty game
285
+ server log is not proof that the server hung: a release server holds back
286
+ what the game prints until it exits when it isn't attached to a terminal.
287
+ Use step 4d to see which scene runs.
288
+
212
289
  ## Checklist
213
290
 
214
291
  - [ ] `summer.build.json`: `gameId`, `targetPlatforms`, `server.exportPreset`, every WorldDefinition selected by a queue.
@@ -217,6 +294,10 @@ of `.zip`. That writes `client.pck` alone.
217
294
  - [ ] The export ends with `Publish uploads this one file as a new Build.`
218
295
  - [ ] The analyzer prints `ok=true` twice.
219
296
  - [ ] Both probes load their scene, with identical composition manifests.
297
+ - [ ] The bundle's `server.pck`, run with no scene, loads the authority scene first.
298
+ - [ ] `Exported by Summer` names a released Summer, and the bundle's `client.pck` run on that release prints no `SCRIPT ERROR`, `Parse Error` or `Failed to load script`.
299
+ - [ ] Every `Summer.initialize` call passes no Game ID.
300
+ - [ ] After release: a real online join reaches the game, and a signed-in player keeps playing for 3 minutes (`release-readiness` checks 2 and 10).
220
301
  - [ ] Local Play passed with the same project.
221
302
 
222
303
  ## Common mistakes
@@ -229,5 +310,9 @@ of `.zip`. That writes `client.pck` alone.
229
310
  | Ship C#, `.gdextension` or native libraries in the client | GDScript only | Summer Games runs GDScript client packs only |
230
311
  | Skip the source graph | Keep `source-domains.json` complete | Without it the server code ships to players (export warns) |
231
312
  | Load an `authority/` file from client code | Move shared code into `network/` | The export stops: the client would load a missing file |
232
- | Upload after only exporting | Run Local Play, the analyzer and both probes first | Each catches what the others miss |
313
+ | Upload after only exporting | Run Local Play, the analyzer, both probes and the server start check first | Each catches what the others miss |
314
+ | Server preset without the `summer_authority` feature | `custom_features="summer_authority"` | The hosted server starts the title and every join times out |
315
+ | Test a server pack exported on its own | Test the `server.pck` inside the `.zip` | The separate pack keeps `gameId` and hides a wrong Game ID |
316
+ | Export with a development build of Summer | Export with the released editor from the download page, again after every update | Players run the pack on the released Summer of the stamped version; newer APIs fail to compile and the game opens to an empty window |
317
+ | Read an empty server log as a hang | Run step 4d | A release server holds back its output until it exits |
233
318
  | Export a patch | Export Project, or Export PCK/ZIP without Export As Patch | summer.games takes complete bundles or packs |
@@ -22,6 +22,7 @@ related:
22
22
  - skill/multiplayer
23
23
  - skill/multiplayer-project
24
24
  - skill/multiplayer-testing
25
+ - skill/release-readiness
25
26
  source: official
26
27
  license: MIT
27
28
  status: preview
@@ -174,7 +174,7 @@ func _ready() -> void:
174
174
  spawner.entity_spawned.connect(_on_player_spawned)
175
175
  spawner.command_received.connect(_on_command)
176
176
  world.session_left.connect(_on_session_left)
177
- var initialized: SummerResult = await Summer.initialize(Game.GAME_ID).get_result_or_completed_signal()
177
+ var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
178
178
  if not initialized.ok:
179
179
  push_error(initialized.message)
180
180
  return
@@ -33,7 +33,7 @@ func _ready() -> void:
33
33
  spawner.entity_spawned.connect(_on_player_spawned)
34
34
  spawner.command_received.connect(_on_command)
35
35
  world.session_left.connect(_on_session_left)
36
- var initialized: SummerResult = await Summer.initialize(Game.GAME_ID).get_result_or_completed_signal()
36
+ var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
37
37
  if not initialized.ok:
38
38
  push_error(initialized.message)
39
39
  return
@@ -266,7 +266,7 @@ func _ready() -> void:
266
266
  spawner.state_group_created.connect(_on_group_created)
267
267
  spawner.entity_spawned.connect(_on_entity_spawned)
268
268
  spawner.event_received.connect(_on_event)
269
- var initialized: SummerResult = await Summer.initialize(Game.GAME_ID).get_result_or_completed_signal()
269
+ var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
270
270
  if not initialized.ok:
271
271
  push_error(initialized.message)
272
272
  return
@@ -528,7 +528,6 @@ occurrence_streams = Array[SummerNetworkOccurrenceStream]([SubResource("Commands
528
528
  extends RefCounted
529
529
  ## Shared by the client and the authority: ids, streams and shared rules.
530
530
 
531
- const GAME_ID := "game_courtyard"
532
531
  const QUEUE := &"courtyard"
533
532
  const MOTION := &"courtyard.motion"
534
533
  const CMD := &"courtyard.cmd"
@@ -207,9 +207,22 @@ capture, window size) with `DisplayServer.get_name() != "headless"`.
207
207
  `Summer.client.leave()` only disconnects. `session_disconnected` fires and
208
208
  their seat is held. `session_left` arrives when the World ends; hosted, it
209
209
  arrives when Summer ends the Session.
210
+ - **Which scene the hosted server starts.** Local Play starts the authority
211
+ scene by name. Summer starts the exported `server.pck` with no scene, so a
212
+ server preset without the `summer_authority` feature still passes here and
213
+ then runs the title screen hosted, where every join fails with
214
+ `world_start_timeout`. Run the bundle's `server.pck` with no scene
215
+ (`multiplayer-publish`, step 4d).
216
+ - **A wrong Game ID.** Local Play has no hosted identity, so
217
+ `Summer.initialize("some-id")` passes here and fails hosted with
218
+ `game_identity_mismatch`. Call `Summer.initialize()` with no ID; only a
219
+ real online join after publishing proves it.
210
220
  - **Real devices, real accounts, real distances.** Publish to staging for that
211
221
  (`multiplayer-publish`).
212
222
 
223
+ Before a version reaches players, run `release-readiness`: it covers these
224
+ gaps on the `.zip` you upload.
225
+
213
226
  ## Checklist for any multiplayer change
214
227
 
215
228
  - [ ] Ran Local Play with at least 2 players, and once with 100 ms / 10 ms / 1 %.
@@ -26,6 +26,7 @@ related:
26
26
  - skill/multiplayer-movement
27
27
  - skill/multiplayer-state
28
28
  - skill/multiplayer-publish
29
+ - skill/release-readiness
29
30
  - skill/summer-friends
30
31
  - skill/summer-match-results
31
32
  - skill/summer-matchmaking
@@ -18,4 +18,6 @@ Its current text lives on the hosted Summer Engine MCP, the same text the Studio
18
18
  2. A host that shows MCP prompts or resources has it as the `publish-your-game` prompt and the resource `summer://skills/publish-your-game`.
19
19
  3. Without a store sign-in: https://docs.summerengine.com/llms.txt lists every docs page; fetch any page as .md.
20
20
 
21
+ Before the build upload, run `release-readiness` on the exact `.zip` you upload, and report each check to the owner; a hosted game's upload checks can pass while every online join fails.
22
+
21
23
  The one rule to keep even before you load it: Submitting does not publish. `summer_store_submit` returns an approval link; only the owner's click sends the game to review, and review comes before live.