summer-engine 3.5.0 → 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 +23 -0
- package/README.md +3 -3
- package/commands/summer.md +1 -0
- package/dist/cli/commands/setup.js +2 -2
- package/dist/core/capabilities/publish-build.d.ts +4 -0
- package/dist/core/capabilities/publish-build.js +67 -34
- package/dist/core/capabilities/runtime-control.d.ts +2 -2
- package/dist/installer/agent-config.d.ts +5 -5
- package/dist/installer/agent-config.js +96 -32
- package/dist/installer/agent-table.d.ts +7 -6
- package/dist/installer/agent-table.js +117 -6
- 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/integrations/README.md +6 -0
- 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
|
@@ -176,7 +176,7 @@ func _ready() -> void:
|
|
|
176
176
|
spawner.entity_spawned.connect(_on_player_spawned)
|
|
177
177
|
spawner.command_received.connect(_on_command)
|
|
178
178
|
world.session_left.connect(_on_session_left)
|
|
179
|
-
var initialized: SummerResult = await Summer.initialize(
|
|
179
|
+
var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
|
|
180
180
|
if not initialized.ok:
|
|
181
181
|
push_error(initialized.message)
|
|
182
182
|
return
|
|
@@ -26,7 +26,7 @@ func _ready() -> void:
|
|
|
26
26
|
spawner.entity_spawned.connect(_on_player_spawned)
|
|
27
27
|
spawner.command_received.connect(_on_command)
|
|
28
28
|
world.session_left.connect(_on_session_left)
|
|
29
|
-
var initialized: SummerResult = await Summer.initialize(
|
|
29
|
+
var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
|
|
30
30
|
if not initialized.ok:
|
|
31
31
|
push_error(initialized.message)
|
|
32
32
|
return
|
|
@@ -141,7 +141,7 @@ func _ready() -> void:
|
|
|
141
141
|
# Connect before joining, or the first values arrive unseen.
|
|
142
142
|
spawner.state_group_created.connect(_on_group_created)
|
|
143
143
|
spawner.entity_spawned.connect(_on_entity_spawned)
|
|
144
|
-
var initialized: SummerResult = await Summer.initialize(
|
|
144
|
+
var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
|
|
145
145
|
if not initialized.ok:
|
|
146
146
|
push_error(initialized.message)
|
|
147
147
|
return
|
|
@@ -440,7 +440,6 @@ occurrence_streams = Array[SummerNetworkOccurrenceStream]([SubResource("Commands
|
|
|
440
440
|
extends RefCounted
|
|
441
441
|
## Shared by the client and the authority: ids, streams and shared rules.
|
|
442
442
|
|
|
443
|
-
const GAME_ID := "game_courtyard"
|
|
444
443
|
const QUEUE := &"courtyard"
|
|
445
444
|
const MOTION := &"courtyard.motion"
|
|
446
445
|
const CMD := &"courtyard.cmd"
|
|
@@ -74,7 +74,14 @@ textures/vram_compression/import_etc2_astc=true
|
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
The `.summer_client` and `.summer_authority` overrides tell each exported pack
|
|
77
|
-
which scene to start.
|
|
77
|
+
which scene to start. Summer starts the hosted server with no scene
|
|
78
|
+
argument, so `run/main_scene.summer_authority` is the only thing that makes
|
|
79
|
+
`server.pck` start the authority. It applies only when the server export
|
|
80
|
+
preset carries the custom feature `summer_authority` (`multiplayer-publish`).
|
|
81
|
+
Without it the server starts the client scene, never reports ready, and every
|
|
82
|
+
online join fails with `world_start_timeout`. Local Play names the scene
|
|
83
|
+
itself, so it works either way. Leave the `[summer] version` line the editor
|
|
84
|
+
writes.
|
|
78
85
|
|
|
79
86
|
## 4. The declarations
|
|
80
87
|
|
|
@@ -116,6 +123,9 @@ starts. Summer rejects unknown fields, so copy the shape exactly.
|
|
|
116
123
|
}
|
|
117
124
|
```
|
|
118
125
|
|
|
126
|
+
- `gameId` is the game's id in Summer Studio, for your publishing tools. The
|
|
127
|
+
summer.games export leaves it out of the bundle, so game code never reads
|
|
128
|
+
it: both sides call `Summer.initialize()` with no ID (sections 7 and 8).
|
|
119
129
|
- `queues[].minPlayers` / `maxPlayers` bound a match. `worldDefinition` names
|
|
120
130
|
the `definition_id` in `world.json`.
|
|
121
131
|
- `server.exportPreset` names the server export preset (`multiplayer-publish`).
|
|
@@ -250,7 +260,6 @@ on both sides:
|
|
|
250
260
|
extends RefCounted
|
|
251
261
|
## Shared by the client and the authority: ids, streams and shared rules.
|
|
252
262
|
|
|
253
|
-
const GAME_ID := "game_courtyard"
|
|
254
263
|
const QUEUE := &"courtyard"
|
|
255
264
|
const CMD := &"courtyard.cmd"
|
|
256
265
|
const MAX_PLAYERS := 8
|
|
@@ -321,7 +330,7 @@ func _ready() -> void:
|
|
|
321
330
|
spawner.entity_spawned.connect(_on_player_spawned)
|
|
322
331
|
spawner.command_received.connect(_on_command)
|
|
323
332
|
world.session_left.connect(_on_session_left)
|
|
324
|
-
var initialized: SummerResult = await Summer.initialize(
|
|
333
|
+
var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
|
|
325
334
|
if not initialized.ok:
|
|
326
335
|
push_error(initialized.message)
|
|
327
336
|
return
|
|
@@ -379,6 +388,11 @@ func _on_session_left(session: SummerSession, reason: String) -> void:
|
|
|
379
388
|
|
|
380
389
|
`authority/main.tscn` is a plain `Node` with that script ([files.md](files.md)).
|
|
381
390
|
|
|
391
|
+
- `Summer.initialize()` takes no Game ID. Summer takes the game's identity
|
|
392
|
+
from where it runs: Local Play, the hosted server or the Summer Games app.
|
|
393
|
+
Never pass a literal, a placeholder or a fallback ID: any ID that differs
|
|
394
|
+
from the hosted one fails with `game_identity_mismatch`, and the authority
|
|
395
|
+
stops before it reports ready.
|
|
382
396
|
- **Never** read who sent a Command from its payload: `request.get_session()`
|
|
383
397
|
is verified. Don't name your own classes `SummerSession`, `SummerWorld` or
|
|
384
398
|
other engine class names.
|
|
@@ -426,7 +440,7 @@ func _ready() -> void:
|
|
|
426
440
|
spawner = Game.build_network(self, PlayerArchetype)
|
|
427
441
|
# Connect signals like state_group_created here, before joining, or values
|
|
428
442
|
# that arrive during the join go unseen (multiplayer-movement adds them).
|
|
429
|
-
var initialized: SummerResult = await Summer.initialize(
|
|
443
|
+
var initialized: SummerResult = await Summer.initialize().get_result_or_completed_signal()
|
|
430
444
|
if not initialized.ok:
|
|
431
445
|
push_error(initialized.message)
|
|
432
446
|
return
|
|
@@ -510,6 +524,8 @@ warning yourself.
|
|
|
510
524
|
| `@rpc`, `MultiplayerSynchronizer`, `ENetMultiplayerPeer` | The Spawner, State groups and Commands | Unverified peers, no late join, no Summer hosting |
|
|
511
525
|
| `if multiplayer.is_server()` in one shared scene | Separate `client/` and `authority/` scenes | The engine starts the right scene on each side |
|
|
512
526
|
| Load an `authority/` file from client or shared code | Move what both sides need into `network/` | The export leaves `authority/` out of the players' pack |
|
|
527
|
+
| `Summer.initialize("game_…")`, or a fallback ID when `gameId` is missing | `Summer.initialize()` | The bundle has no `gameId`; a different ID fails hosted with `game_identity_mismatch` |
|
|
528
|
+
| Set `run/main_scene.summer_authority` and stop there | Also give the server preset the `summer_authority` feature | Without the feature the hosted server starts the client scene |
|
|
513
529
|
| Build the composition differently on each side | One `network/composition.tres`, loaded by both | Different compositions refuse each other |
|
|
514
530
|
| Send a Command right after `join` succeeds | Await `spawner.network_ready` first | The authority does not know the client's network until then |
|
|
515
531
|
| Free a player's things on `session_disconnected` | Free them on `session_left` | A disconnected player keeps their seat and may reconnect |
|
|
@@ -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(
|
|
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(
|
|
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,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.
|