summer-engine 3.5.1 → 3.5.2
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/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -1
- package/.codex-plugin/plugin.json +2 -1
- package/.cursor-plugin/plugin.json +2 -1
- package/.factory-plugin/plugin.json +2 -1
- package/CHANGELOG.md +15 -0
- package/commands/summer.md +1 -0
- package/dist/mcp/hosted-mount.js +2 -1
- package/dist/mcp/provider-safe-schema.d.ts +10 -0
- package/dist/mcp/provider-safe-schema.js +96 -0
- package/dist/mcp/server.js +3 -0
- package/gemini-extension.json +2 -1
- package/library/skills/README.md +3 -2
- package/library/skills/export-and-ship/SKILL.md +2 -0
- package/library/skills/make-game/SKILL.md +21 -2
- package/library/skills/make-game/resource.yaml +1 -0
- package/library/skills/multiplayer/SKILL.md +3 -1
- package/library/skills/multiplayer/resource.yaml +1 -0
- package/library/skills/multiplayer-movement/SKILL.md +1 -1
- package/library/skills/multiplayer-movement/files.md +2 -3
- package/library/skills/multiplayer-project/SKILL.md +20 -4
- package/library/skills/multiplayer-project/files.md +2 -3
- package/library/skills/multiplayer-publish/SKILL.md +86 -5
- package/library/skills/multiplayer-publish/resource.yaml +1 -0
- package/library/skills/multiplayer-state/SKILL.md +1 -1
- package/library/skills/multiplayer-state/files.md +2 -3
- package/library/skills/multiplayer-testing/SKILL.md +13 -0
- package/library/skills/multiplayer-testing/resource.yaml +1 -0
- package/library/skills/publish-your-game/SKILL.md +2 -0
- package/library/skills/release-readiness/SKILL.md +298 -0
- package/library/skills/release-readiness/resource.yaml +41 -0
- package/library/skills/summer-parties/SKILL.md +1 -1
- package/package.json +1 -1
- package/registry/generated/counts.json +2 -2
- package/registry/generated/gemini-extension.json +2 -1
- package/registry/generated/index.json +63 -11
- package/registry/generated/marketplace.claude.json +1 -1
- package/registry/generated/plugin.claude.json +2 -1
- package/registry/generated/plugin.codex.json +2 -1
- package/registry/generated/plugin.cursor.json +2 -1
- package/registry/generated/plugin.factory.json +2 -1
- package/registry/generated/skills-index.md +3 -2
- package/registry/generated/skills-registry.json +14 -0
|
@@ -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,22 @@ 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.
|
|
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. Every
|
|
130
145
|
result message and every export error, with its fix, is in
|
|
131
146
|
[export-errors.md](export-errors.md).
|
|
132
147
|
|
|
133
148
|
## 4. Check before uploading
|
|
134
149
|
|
|
135
|
-
Do all
|
|
150
|
+
Do all five. Each catches problems the export doesn't. Run them on the
|
|
151
|
+
`.zip` you will upload, not on a pack exported separately with the server
|
|
152
|
+
preset (`--export-pack`): that pack differs from the bundle's `server.pck`,
|
|
153
|
+
for example it keeps `gameId`, and can pass where the upload fails.
|
|
136
154
|
|
|
137
155
|
**a. Local Play passes** (`multiplayer-testing`): every process has
|
|
138
156
|
`script_errors` 0, there's no `cannot attach`, and your ready lines appear.
|
|
@@ -187,12 +205,45 @@ unzip -o build/courtyard.summer.zip client.pck server.pck -d "$P/out"
|
|
|
187
205
|
Paths must be absolute. Pass: both reports say `"sceneLoaded": true`, and
|
|
188
206
|
their `compositionManifest` objects are identical. On failure the probe
|
|
189
207
|
writes `rejection.json`; its codes are in [export-errors.md](export-errors.md).
|
|
208
|
+
The probe names the scene to load, so it does not show which scene the
|
|
209
|
+
server starts on its own.
|
|
210
|
+
|
|
211
|
+
**d. The server pack starts the authority scene.** Start the bundle's
|
|
212
|
+
`server.pck` the way Summer does, with no scene argument, and stop it after
|
|
213
|
+
a few seconds:
|
|
214
|
+
|
|
215
|
+
```sh
|
|
216
|
+
perl -e 'alarm shift; exec @ARGV' 15 <summer> --headless --verbose --main-pack "$P/out/server.pck"
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The first `Completed load for: 'res://….tscn'` line must be the authority
|
|
220
|
+
scene (`res://authority/main.tscn` here). If it is the client or title
|
|
221
|
+
scene, add `summer_authority` to the server preset's custom features and
|
|
222
|
+
export again. Later lines may complain that there is no hosted World; that
|
|
223
|
+
is expected locally.
|
|
224
|
+
|
|
225
|
+
**e. The client compiles on the released Summer.** Run the bundle's
|
|
226
|
+
`client.pck` with the released Summer of the version the export names (see
|
|
227
|
+
`release-readiness` check 7 for how to confirm the stamp), and fail on any
|
|
228
|
+
compile error:
|
|
229
|
+
|
|
230
|
+
```sh
|
|
231
|
+
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
|
|
232
|
+
grep -E 'SCRIPT ERROR|Parse Error|Failed to load script' "$P/out/client-run.log"
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
The grep must print nothing; the run itself exits normally even when a
|
|
236
|
+
script fails. A failure here, such as `Static function "party_queue()" not
|
|
237
|
+
found`, means the scripts use an API the released version lacks, usually
|
|
238
|
+
because a development build made the export. Every player would see an
|
|
239
|
+
empty window. Re-export with the current Summer release.
|
|
190
240
|
|
|
191
241
|
## 5. Upload the Build
|
|
192
242
|
|
|
193
243
|
1. The game must exist in Summer Studio, and `gameId` in
|
|
194
|
-
`summer.build.json`
|
|
195
|
-
|
|
244
|
+
`summer.build.json` must be its id. The export leaves `gameId` out of the
|
|
245
|
+
bundle, and the game code calls `Summer.initialize()` with no ID: a
|
|
246
|
+
literal or fallback ID fails hosted with `game_identity_mismatch`.
|
|
196
247
|
2. Open the game's Builds page: `summer_open` with target `game`,
|
|
197
248
|
`gameId` and section `builds`, or summerengine.com → Studio → your game →
|
|
198
249
|
Builds.
|
|
@@ -209,6 +260,28 @@ writes `rejection.json`; its codes are in [export-errors.md](export-errors.md).
|
|
|
209
260
|
For a client-only fix to an existing Build, export to a `.pck` path instead
|
|
210
261
|
of `.zip`. That writes `client.pck` alone.
|
|
211
262
|
|
|
263
|
+
## 6. Join it for real
|
|
264
|
+
|
|
265
|
+
Right after the Build is released, open the game in a Summer Games app,
|
|
266
|
+
join online and play until you are in the game, before players hear about
|
|
267
|
+
the update. A wrong Game ID only fails under a real hosted launch, so
|
|
268
|
+
nothing before this step catches it. An agent can't do this; ask the user
|
|
269
|
+
and record the result. The whole list of checks before a release is
|
|
270
|
+
`release-readiness`, and the creator docs have it at
|
|
271
|
+
https://docs.summerengine.com/publishing/release-readiness.
|
|
272
|
+
|
|
273
|
+
## When online joins fail
|
|
274
|
+
|
|
275
|
+
Every join ends in `world_start_timeout`, but Local Play works:
|
|
276
|
+
|
|
277
|
+
1. The server starts the wrong scene: run step 4d.
|
|
278
|
+
2. The game passes a fixed Game ID to `Summer.initialize`: pass none.
|
|
279
|
+
|
|
280
|
+
Then export, upload and release a new Build, and join again. An empty game
|
|
281
|
+
server log is not proof that the server hung: a release server holds back
|
|
282
|
+
what the game prints until it exits when it isn't attached to a terminal.
|
|
283
|
+
Use step 4d to see which scene runs.
|
|
284
|
+
|
|
212
285
|
## Checklist
|
|
213
286
|
|
|
214
287
|
- [ ] `summer.build.json`: `gameId`, `targetPlatforms`, `server.exportPreset`, every WorldDefinition selected by a queue.
|
|
@@ -217,6 +290,10 @@ of `.zip`. That writes `client.pck` alone.
|
|
|
217
290
|
- [ ] The export ends with `Publish uploads this one file as a new Build.`
|
|
218
291
|
- [ ] The analyzer prints `ok=true` twice.
|
|
219
292
|
- [ ] Both probes load their scene, with identical composition manifests.
|
|
293
|
+
- [ ] The bundle's `server.pck`, run with no scene, loads the authority scene first.
|
|
294
|
+
- [ ] `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`.
|
|
295
|
+
- [ ] Every `Summer.initialize` call passes no Game ID.
|
|
296
|
+
- [ ] After release: a real online join reaches the game (`release-readiness`).
|
|
220
297
|
- [ ] Local Play passed with the same project.
|
|
221
298
|
|
|
222
299
|
## Common mistakes
|
|
@@ -229,5 +306,9 @@ of `.zip`. That writes `client.pck` alone.
|
|
|
229
306
|
| Ship C#, `.gdextension` or native libraries in the client | GDScript only | Summer Games runs GDScript client packs only |
|
|
230
307
|
| Skip the source graph | Keep `source-domains.json` complete | Without it the server code ships to players (export warns) |
|
|
231
308
|
| 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
|
|
309
|
+
| Upload after only exporting | Run Local Play, the analyzer, both probes and the server start check first | Each catches what the others miss |
|
|
310
|
+
| Server preset without the `summer_authority` feature | `custom_features="summer_authority"` | The hosted server starts the title and every join times out |
|
|
311
|
+
| 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 |
|
|
312
|
+
| 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 |
|
|
313
|
+
| Read an empty server log as a hang | Run step 4d | A release server holds back its output until it exits |
|
|
233
314
|
| Export a patch | Export Project, or Export PCK/ZIP without Export As Patch | summer.games takes complete bundles or packs |
|
|
@@ -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(
|
|
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(
|
|
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(
|
|
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 %.
|
|
@@ -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.
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release-readiness
|
|
3
|
+
description: "Before releasing a Summer game version, prove players can play it: server scene, online join, saved progress, no fixed Game ID, a released Summer compiles it."
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: deployment
|
|
7
|
+
user-invocable: true
|
|
8
|
+
allowed-tools: Read Grep Glob Bash summer_read_file summer_get_diagnostics
|
|
9
|
+
paths: ["export_presets.cfg", "project.godot", "summer.build.json", "world.json", "**/*.gd"]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# /release-readiness: prove players can play it
|
|
13
|
+
|
|
14
|
+
Summer checks every upload: platforms, packs, and the files they name. Those
|
|
15
|
+
checks prove the export is well formed. They can't prove that a player who
|
|
16
|
+
presses **Play online** gets into a game. Each check below exists because a
|
|
17
|
+
real release passed every upload check and still failed for its players.
|
|
18
|
+
|
|
19
|
+
The creator docs have the same checklist, with the same numbers:
|
|
20
|
+
https://docs.summerengine.com/publishing/release-readiness (fetch it as `.md`).
|
|
21
|
+
|
|
22
|
+
## When to run it
|
|
23
|
+
|
|
24
|
+
- Before you upload a new Build of a game that will go to players.
|
|
25
|
+
- Before you promote or release a version.
|
|
26
|
+
- After a release fails for players, to find the cause, and then to add the
|
|
27
|
+
check that would have caught it (see the last section).
|
|
28
|
+
|
|
29
|
+
For a jam build or a prototype nobody else plays, skip it.
|
|
30
|
+
|
|
31
|
+
## How to report
|
|
32
|
+
|
|
33
|
+
Run every check that applies. Each check needs **evidence**: a command's
|
|
34
|
+
output or something you saw in the running game. Reading the project and
|
|
35
|
+
deciding it looks right is not evidence.
|
|
36
|
+
|
|
37
|
+
Report one line per check:
|
|
38
|
+
|
|
39
|
+
- **pass**, with the evidence;
|
|
40
|
+
- **fail**, with what you saw;
|
|
41
|
+
- **not applicable**, with the reason (for example, no server);
|
|
42
|
+
- **not run**, with what is still needed (for example, "needs a real online
|
|
43
|
+
join after publishing").
|
|
44
|
+
|
|
45
|
+
A check that was not run is not a pass. Show the list to the user before you
|
|
46
|
+
change anything; the user decides what to fix and whether to release with a
|
|
47
|
+
check still open.
|
|
48
|
+
|
|
49
|
+
## Test the file you upload
|
|
50
|
+
|
|
51
|
+
Run the checks on the summer.games `.zip`, not on something close to it.
|
|
52
|
+
Export the bundle (in the editor: **Project > Export**, preset
|
|
53
|
+
**summer.games**, **Export Project**; from an agent: `summer_export_game`; or
|
|
54
|
+
from a terminal), then take the server pack and the packaged build file out
|
|
55
|
+
of it:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
<summer> --headless --path . --import
|
|
59
|
+
<summer> --headless --path . --export-release "summer.games" build/<game>.summer.zip
|
|
60
|
+
mkdir -p build/bundle
|
|
61
|
+
unzip -o build/<game>.summer.zip server.pck client.pck summer-bundle.json config/summer.build.json -d build/bundle
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
A game without a server has no `server.pck` or `config/`; `unzip` then
|
|
65
|
+
warns about the missing names and extracts the rest.
|
|
66
|
+
|
|
67
|
+
`<summer>` is the Summer Engine executable. Two look-alikes hide real
|
|
68
|
+
failures:
|
|
69
|
+
|
|
70
|
+
- **A server pack exported on its own** with your server preset
|
|
71
|
+
(`--export-pack`) is not the bundle's `server.pck`. For example, it keeps
|
|
72
|
+
`gameId`, which the bundle leaves out, so it can pass check 6 while the
|
|
73
|
+
uploaded `.zip` fails it.
|
|
74
|
+
- **Local Play** always starts the authority scene by name, so it can't catch
|
|
75
|
+
check 1. It also runs without a hosted identity, so it can't catch check 6.
|
|
76
|
+
|
|
77
|
+
## The checks
|
|
78
|
+
|
|
79
|
+
Checks 1 and 2 apply to every game with a server (`summer.build.json` names
|
|
80
|
+
a `server.exportPreset`). Checks 3 and 4 apply to every game with online
|
|
81
|
+
play. Checks 5, 6 and 7 apply to every game.
|
|
82
|
+
|
|
83
|
+
### 1. The server pack starts the authority scene
|
|
84
|
+
|
|
85
|
+
**Why.** Summer starts a hosted World's `server.pck` with no scene argument,
|
|
86
|
+
so the pack's own main scene decides what runs. The server preset must carry
|
|
87
|
+
the custom feature `summer_authority`, and `project.godot` must set that
|
|
88
|
+
feature's main scene:
|
|
89
|
+
|
|
90
|
+
```ini
|
|
91
|
+
[application]
|
|
92
|
+
|
|
93
|
+
run/main_scene="res://client/main.tscn"
|
|
94
|
+
run/main_scene.summer_client="res://client/main.tscn"
|
|
95
|
+
run/main_scene.summer_authority="res://authority/main.tscn"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```ini
|
|
99
|
+
# export_presets.cfg, the server preset
|
|
100
|
+
platform="Linux"
|
|
101
|
+
dedicated_server=true
|
|
102
|
+
custom_features="summer_authority"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Without the feature, `run/main_scene.summer_authority` never applies and
|
|
106
|
+
the server starts the players' main scene, usually the title screen. That
|
|
107
|
+
scene never restores the World or tells Summer it is ready, so **every
|
|
108
|
+
online join fails with `world_start_timeout`**. The bundle manifest still
|
|
109
|
+
names the authority scene as the server's main scene, so reading the
|
|
110
|
+
manifest proves nothing.
|
|
111
|
+
|
|
112
|
+
**Check it.** Start the bundle's `server.pck` the way Summer does, with no
|
|
113
|
+
scene argument, and stop it after a few seconds:
|
|
114
|
+
|
|
115
|
+
```sh
|
|
116
|
+
perl -e 'alarm shift; exec @ARGV' 15 <summer> --headless --verbose --main-pack build/bundle/server.pck
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Find the first `Completed load for: 'res://….tscn'` line. It must be the
|
|
120
|
+
authority scene: the `entry_point` of the `headless_engine` component in
|
|
121
|
+
`world.json`. Later lines may complain that there is no hosted World; that
|
|
122
|
+
is expected in a local run. Then confirm the source too: the server preset in
|
|
123
|
+
`export_presets.cfg` has `summer_authority` in `custom_features`, and
|
|
124
|
+
`project.godot` sets `run/main_scene.summer_authority`.
|
|
125
|
+
|
|
126
|
+
**Fix.** Add `summer_authority` to the server preset's **Features > Custom**,
|
|
127
|
+
set `application/run/main_scene.summer_authority` to the authority scene,
|
|
128
|
+
export again and rerun the check. If your Summer version's export refuses a
|
|
129
|
+
server pack that starts the wrong scene, that refusal is this check failing;
|
|
130
|
+
run the check anyway, because older versions don't refuse it.
|
|
131
|
+
|
|
132
|
+
### 2. Join online with the version you release
|
|
133
|
+
|
|
134
|
+
**Why.** Check 1 runs on your computer. Players use a hosted server, and some
|
|
135
|
+
failures, such as check 6, only show up there.
|
|
136
|
+
|
|
137
|
+
**Check it.** Right after you publish or promote the version, open the game
|
|
138
|
+
in a Summer Games app as a player, join online and play until you are in the
|
|
139
|
+
game. Do it before you tell players about the update. An agent can't do this
|
|
140
|
+
step; report it as **not run** and ask the user to do it, then record what
|
|
141
|
+
they saw. If the join fails, see [Troubleshooting](#troubleshooting).
|
|
142
|
+
|
|
143
|
+
### 3. Players can find online play
|
|
144
|
+
|
|
145
|
+
**Why.** If nobody, including you, reaches online play, nobody notices when
|
|
146
|
+
it breaks. A game hid online play behind a grown-ups setting, so its hosted
|
|
147
|
+
join was never tried before release, and it failed for every player who
|
|
148
|
+
found it.
|
|
149
|
+
|
|
150
|
+
**Check it.** Start the client as a new player and follow the default path
|
|
151
|
+
to online play. List every gate on that path: settings, parental or age
|
|
152
|
+
gates, debug toggles. A new player should reach online play without
|
|
153
|
+
changing a setting. If online play is off by default on purpose, the user
|
|
154
|
+
must confirm that decision, and then check 2 must run before every release.
|
|
155
|
+
|
|
156
|
+
### 4. The server saves online progress
|
|
157
|
+
|
|
158
|
+
**Why.** Progress kept only in the player's local files is lost on
|
|
159
|
+
reinstall or a new device, and players can edit it.
|
|
160
|
+
|
|
161
|
+
**Check it.** In code, the authority loads each player's progress when they
|
|
162
|
+
join (`Summer.authority.player_data.load(session)`) and saves it with
|
|
163
|
+
`commit_public` or `commit_secret` (`summer-player-data`). Then play online,
|
|
164
|
+
earn something, leave, and join again from a fresh install or another
|
|
165
|
+
device. The progress must still be there. Local Play stores player data on
|
|
166
|
+
disk; only hosted play proves it lasts.
|
|
167
|
+
|
|
168
|
+
### 5. Players can get back to the title
|
|
169
|
+
|
|
170
|
+
**Why.** A player with no way out of a session has to kill the app.
|
|
171
|
+
|
|
172
|
+
**Check it.** Play into a session, online and offline, and find the way
|
|
173
|
+
back: a pause menu or a **Leave** button. Use it, then start a new session
|
|
174
|
+
from the title. In online play, leaving should call
|
|
175
|
+
`Summer.client.leave()` before the title loads.
|
|
176
|
+
|
|
177
|
+
### 6. The game doesn't hard-code its Game ID
|
|
178
|
+
|
|
179
|
+
**Why.** The summer.games export is portable: the bundle's
|
|
180
|
+
`summer.build.json` has no `gameId`. Summer takes the game's identity from
|
|
181
|
+
wherever it runs: the Summer Games app, the hosted server or Local Play.
|
|
182
|
+
Any other ID fails on the hosted server with `game_identity_mismatch`, "The
|
|
183
|
+
initialized Game ID does not match hosted runtime context." The authority
|
|
184
|
+
then stops before it restores the World or reports ready, and every online
|
|
185
|
+
join ends in `world_start_timeout`, even though check 1 passes. The Summer
|
|
186
|
+
Games app refuses a mismatched ID the same way.
|
|
187
|
+
|
|
188
|
+
**Check it.**
|
|
189
|
+
|
|
190
|
+
1. Find every call: `grep -rn "Summer.initialize" --include=*.gd .`
|
|
191
|
+
2. For each, trace the argument back to where it comes from. It must be
|
|
192
|
+
nothing (`Summer.initialize()`) or an ID the game got from Summer. It must
|
|
193
|
+
never be a literal, a placeholder, or a fallback such as
|
|
194
|
+
`"game.my-game"` used when `gameId` is missing.
|
|
195
|
+
3. `cat build/bundle/config/summer.build.json`: it has no `gameId`, so
|
|
196
|
+
anything the game reads from this file at run time comes back empty.
|
|
197
|
+
|
|
198
|
+
Local Play and the local run in check 1 have no hosted identity, so a wrong
|
|
199
|
+
ID passes there. Only check 2 proves this one.
|
|
200
|
+
|
|
201
|
+
**Fix.** Call `Summer.initialize()` with no ID (Summer 0.7.1 and later), on
|
|
202
|
+
the client and on the authority.
|
|
203
|
+
|
|
204
|
+
### 7. Export with a released Summer, and its scripts compile on the players' runtime
|
|
205
|
+
|
|
206
|
+
**Why.** The export records which Summer made it, in the client pack's
|
|
207
|
+
`.summer/export.json` and under `export` in the bundle's
|
|
208
|
+
`summer-bundle.json`: `summerVersion` and `engineSha`. Players' apps run the
|
|
209
|
+
game on a released Summer runtime with the same MAJOR.MINOR and a patch at
|
|
210
|
+
least the stamped one. A development build of Summer
|
|
211
|
+
can stamp a version that is already released while it has APIs that release
|
|
212
|
+
lacks. Scripts that use them then fail to compile on every player's device,
|
|
213
|
+
and the game opens to an empty or black window. Summer doesn't compile
|
|
214
|
+
scripts when you upload, so every upload check passes.
|
|
215
|
+
|
|
216
|
+
**Check it.**
|
|
217
|
+
|
|
218
|
+
1. Read the stamp: `cat build/bundle/summer-bundle.json`. The export log
|
|
219
|
+
shows it too: `Exported by Summer <version> (engine <sha>)`.
|
|
220
|
+
2. `summerVersion` must be a released Summer version, and `engineSha` must
|
|
221
|
+
equal that release's `engineSha` in
|
|
222
|
+
`downloads.summer.games/engine-templates/<summerVersion>/manifest.json`
|
|
223
|
+
(published for Summer 0.7.1 and later). If it differs, or that address has
|
|
224
|
+
nothing for the version, a development build made the export.
|
|
225
|
+
3. Run the client pack on that released Summer, and fail on any compile
|
|
226
|
+
error. The run exits normally even when a script fails, so the grep is the
|
|
227
|
+
check:
|
|
228
|
+
|
|
229
|
+
```sh
|
|
230
|
+
perl -e 'alarm shift; exec @ARGV' 60 <released-summer> --headless --verbose --main-pack build/bundle/client.pck --quit-after 600 > build/client-run.log 2>&1
|
|
231
|
+
grep -E 'SCRIPT ERROR|Parse Error|Failed to load script' build/client-run.log
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
`<released-summer>` is the Summer executable of the stamped version from
|
|
235
|
+
the download page, not the development build that made the export. The
|
|
236
|
+
grep must print nothing. The run compiles the scripts that the main
|
|
237
|
+
scene and autoloads load; a script that loads only later in play compiles
|
|
238
|
+
when play reaches it, so check 2 still matters for online games.
|
|
239
|
+
|
|
240
|
+
**Fix.** Ask the user to install the current Summer release from
|
|
241
|
+
https://summerengine.com/download (or, with their OK, run
|
|
242
|
+
`summer install --yes`). Export again with it, and rerun this check on the
|
|
243
|
+
new `.zip` before you upload it.
|
|
244
|
+
|
|
245
|
+
## Troubleshooting
|
|
246
|
+
|
|
247
|
+
### Every online join fails with `world_start_timeout`, but Local Play works
|
|
248
|
+
|
|
249
|
+
Most likely, in this order:
|
|
250
|
+
|
|
251
|
+
1. The server pack starts the wrong scene. Run check 1.
|
|
252
|
+
2. The game passes a fixed Game ID. Run check 6.
|
|
253
|
+
|
|
254
|
+
After the fix, export a new `.zip`, upload it, promote it and run check 2.
|
|
255
|
+
|
|
256
|
+
### The game opens to a blank window for every player
|
|
257
|
+
|
|
258
|
+
The game works in your editor, but every player sees an empty or black
|
|
259
|
+
window. Running the client pack as in check 7 prints
|
|
260
|
+
`Parse Error: Static function "…" not found` and
|
|
261
|
+
`Failed to load script "res://…"`. A development build of Summer made the
|
|
262
|
+
export, and the scripts use something the released version doesn't have.
|
|
263
|
+
Re-export with the current Summer release, upload the new version and
|
|
264
|
+
promote it.
|
|
265
|
+
|
|
266
|
+
### The game server's log is empty
|
|
267
|
+
|
|
268
|
+
An empty server log is not proof that the server hung or never started. A
|
|
269
|
+
release server holds back what the game prints until it exits when it isn't
|
|
270
|
+
attached to a terminal, so its log can look empty while the title scene
|
|
271
|
+
runs. Don't debug from the empty log; run check 1 on your own computer to
|
|
272
|
+
see which scene starts.
|
|
273
|
+
|
|
274
|
+
## Add a check after every incident
|
|
275
|
+
|
|
276
|
+
The list grows from real failures. When a release fails in a way no check
|
|
277
|
+
here would have caught:
|
|
278
|
+
|
|
279
|
+
1. Fix the game, and record the cause in the project's `.summer/memory/`.
|
|
280
|
+
2. Write the check that would have caught it: **Why**, **Check it** (a
|
|
281
|
+
command to run or something to observe, against the real summer.games
|
|
282
|
+
`.zip`), and **Fix**.
|
|
283
|
+
3. Propose it for this skill and for the docs page
|
|
284
|
+
(`/publishing/release-readiness`), with the same number in both, through
|
|
285
|
+
a pull request to summerengine/summer and to the docs. Until it lands,
|
|
286
|
+
keep it in the project's memory so the next release runs it.
|
|
287
|
+
|
|
288
|
+
## Checklist
|
|
289
|
+
|
|
290
|
+
- [ ] Ran the checks on the summer.games `.zip` you upload, not a separately exported pack.
|
|
291
|
+
- [ ] 1. The bundle's `server.pck`, run with no scene, loads the authority scene first.
|
|
292
|
+
- [ ] 2. A real online join with the released version reaches the game (or is reported as not run).
|
|
293
|
+
- [ ] 3. A new player reaches online play without changing a setting, or the user confirmed it is off on purpose.
|
|
294
|
+
- [ ] 4. Online progress is loaded and committed through authority player data, and survives a fresh install.
|
|
295
|
+
- [ ] 5. Players can get back to the title from inside a session, online and offline.
|
|
296
|
+
- [ ] 6. Every `Summer.initialize` passes no ID, or an ID the game got from Summer.
|
|
297
|
+
- [ ] 7. The export stamp names a released Summer and its `engineSha`, and `client.pck` run on that released Summer prints no `SCRIPT ERROR`, `Parse Error` or `Failed to load script`.
|
|
298
|
+
- [ ] One line per check reported to the user before anything is changed.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
id: skill/release-readiness
|
|
2
|
+
kind: skill
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
summary: "Before releasing a Summer game version, prove players can play it: server scene, online join, saved progress, no fixed Game ID, a released Summer compiles it."
|
|
5
|
+
use_when:
|
|
6
|
+
- "before uploading, promoting or releasing a new version to players: is it ready to release"
|
|
7
|
+
- "every online join fails with world_start_timeout, or the hosted server's log is empty, while Local Play works"
|
|
8
|
+
- "Summer.initialize fails with game_identity_mismatch: the initialized Game ID does not match hosted runtime context"
|
|
9
|
+
- "checking that a hosted game's server.pck starts the authority scene and not the title screen"
|
|
10
|
+
- "players get a blank or black screen when they open the released game, but it runs in the editor: client scripts fail with Parse Error or Failed to load script"
|
|
11
|
+
- "a game release failed for players and the check that would have caught it needs adding"
|
|
12
|
+
do_not_use_when:
|
|
13
|
+
- "only producing a local export for a jam or prototype nobody else plays — skill/export-and-ship"
|
|
14
|
+
facets:
|
|
15
|
+
lifecycle:
|
|
16
|
+
- launch
|
|
17
|
+
- support
|
|
18
|
+
domains:
|
|
19
|
+
- deployment
|
|
20
|
+
- multiplayer
|
|
21
|
+
- playtest
|
|
22
|
+
modalities:
|
|
23
|
+
- project
|
|
24
|
+
- docs
|
|
25
|
+
compatibility:
|
|
26
|
+
engine: ">=4.6"
|
|
27
|
+
related:
|
|
28
|
+
skills:
|
|
29
|
+
- skill/multiplayer
|
|
30
|
+
- skill/multiplayer-publish
|
|
31
|
+
- skill/multiplayer-testing
|
|
32
|
+
- skill/multiplayer-project
|
|
33
|
+
- skill/summer-player-data
|
|
34
|
+
- skill/publish-your-game
|
|
35
|
+
- skill/export-and-ship
|
|
36
|
+
- skill/make-game
|
|
37
|
+
- skill/bounded-engine-runs
|
|
38
|
+
source: official
|
|
39
|
+
license: MIT
|
|
40
|
+
status: preview
|
|
41
|
+
recommended: false
|
|
@@ -57,7 +57,7 @@ func _ready() -> void:
|
|
|
57
57
|
spawner.state_group_created.connect(_on_group_created)
|
|
58
58
|
spawner.entity_spawned.connect(_on_entity_spawned)
|
|
59
59
|
spawner.event_received.connect(_on_event)
|
|
60
|
-
var initialized: SummerResult = await Summer.initialize(
|
|
60
|
+
var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
|
|
61
61
|
if not initialized.ok:
|
|
62
62
|
push_error(initialized.message)
|
|
63
63
|
return
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "summer-engine",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.2",
|
|
4
4
|
"description": "Local Summer CLI and MCP server for Summer Engine. Install and run the engine, connect Claude Code, Cursor, Codex, Gemini, and other agents, and build real games with bundled skills, hooks, and plugins.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"summer-engine",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_generated": "GENERATED from integrations/gemini — do not edit; npm run generate:registry",
|
|
3
3
|
"name": "summer",
|
|
4
|
-
"version": "3.5.
|
|
4
|
+
"version": "3.5.2",
|
|
5
5
|
"description": "Agent tooling for Summer Engine: MCP bridge, context primer, and game-dev skills. Use with the npm CLI for skill files on disk.",
|
|
6
6
|
"contextFileName": "GEMINI.md",
|
|
7
7
|
"mcpServers": {
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
"./library/skills/psx-retro-rendering/",
|
|
94
94
|
"./library/skills/publish-your-game/",
|
|
95
95
|
"./library/skills/realtime-wet-surfaces/",
|
|
96
|
+
"./library/skills/release-readiness/",
|
|
96
97
|
"./library/skills/remote-deploy/",
|
|
97
98
|
"./library/skills/retarget/",
|
|
98
99
|
"./library/skills/running-in-the-cloud/",
|