summer-engine 3.5.2 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +3 -3
- package/.cursor-plugin/plugin.json +2 -2
- package/.factory-plugin/plugin.json +2 -2
- package/CHANGELOG.md +16 -2
- package/README.md +0 -4
- package/dist/cli/commands/login.d.ts +0 -10
- package/dist/cli/commands/login.js +2 -82
- package/dist/cli/index.js +0 -4
- package/dist/core/auth.d.ts +0 -8
- package/dist/core/auth.js +5 -35
- package/dist/core/capabilities/seeing/args.d.ts +2 -2
- package/dist/core/capabilities/seeing/seeing.d.ts +1 -1
- package/dist/core/capabilities/sfx-choices.d.ts +78 -0
- package/dist/core/capabilities/sfx-choices.js +253 -0
- package/dist/core/capabilities/tool-dispatch.js +35 -52
- package/dist/core/config.d.ts +1 -7
- package/dist/core/config.js +5 -75
- package/dist/mcp/server.d.ts +2 -1
- package/dist/mcp/server.js +6 -5
- package/dist/mcp/tools/creator-tools.js +0 -71
- package/dist/mcp/tools/generate-tools.js +69 -3
- package/gemini-extension.json +1 -1
- package/library/references/mcp-tools-reference/mcp-tools-reference.md +6 -7
- package/library/references/mcp-tools-reference/resource.yaml +1 -1
- package/library/skills/README.md +2 -2
- package/library/skills/ambient-bed/SKILL.md +3 -1
- package/library/skills/ambient-bed/resource.yaml +1 -1
- package/library/skills/audio-direction/SKILL.md +5 -5
- package/library/skills/audio-direction/resource.yaml +1 -1
- package/library/skills/export-and-ship/SKILL.md +2 -0
- package/library/skills/multiplayer-publish/SKILL.md +8 -4
- package/library/skills/publish-your-game/SKILL.md +2 -0
- package/library/skills/release-readiness/SKILL.md +141 -2
- package/library/skills/release-readiness/resource.yaml +4 -1
- package/library/skills/sound-effect/SKILL.md +83 -158
- package/library/skills/sound-effect/resource.yaml +8 -2
- package/library/skills/ui-basics/SKILL.md +1 -0
- package/library/tools/generate-audio/resource.yaml +6 -2
- package/library/tools/generate-sfx-choices/resource.yaml +69 -0
- package/library/tools/get-choices/resource.yaml +50 -0
- package/package.json +1 -1
- package/registry/generated/aliases.json +2 -3
- package/registry/generated/counts.json +2 -2
- package/registry/generated/gemini-extension.json +1 -1
- package/registry/generated/index.json +105 -121
- package/registry/generated/marketplace.claude.json +2 -2
- package/registry/generated/plugin.claude.json +2 -2
- package/registry/generated/plugin.codex.json +3 -3
- package/registry/generated/plugin.cursor.json +2 -2
- package/registry/generated/plugin.factory.json +2 -2
- package/registry/generated/skills-index.md +2 -2
- package/registry/generated/skills-registry.json +2 -2
- package/dist/cli/commands/publish.d.ts +0 -2
- package/dist/cli/commands/publish.js +0 -21
- package/dist/cli/commands/releases.d.ts +0 -2
- package/dist/cli/commands/releases.js +0 -20
- package/dist/core/capabilities/creator.d.ts +0 -65
- package/dist/core/capabilities/creator.js +0 -374
- package/library/tools/creator-config/resource.yaml +0 -63
- package/library/tools/creator-publish/resource.yaml +0 -74
- package/library/tools/creator-releases/resource.yaml +0 -53
|
@@ -2,6 +2,8 @@ import { z } from "zod";
|
|
|
2
2
|
import { BOARD_ENDPOINT, boardArgsSchema, boardContent, boardQuery } from "../../core/capabilities/board.js";
|
|
3
3
|
import { IMAGE_GENERATION_TIMEOUT_MS, imageGenerationArgsSchema, saveGeneratedImage } from "../../core/capabilities/image-generation.js";
|
|
4
4
|
import { buildMotionRequestBody, motionErrorHint, motionGenerationArgsSchema, motionJobFailureHint, } from "../../core/capabilities/motion-generation.js";
|
|
5
|
+
import { MAX_CHOICES_WAIT_SECONDS, defaultCanOpenBrowser, generateSfxChoices, getChoices, getChoicesArgsSchema, sfxChoicesArgsSchema, SFX_CHOICES_ENDPOINT, } from "../../core/capabilities/sfx-choices.js";
|
|
6
|
+
import open from "open";
|
|
5
7
|
import { getAuthToken } from "../../core/auth.js";
|
|
6
8
|
import { resolveGatewayUrl } from "../../core/config.js";
|
|
7
9
|
import { readJsonResponse } from "../../core/util/http.js";
|
|
@@ -10,6 +12,7 @@ import { TOOLKIT_VERSION as CLI_VERSION } from "../../core/version.js";
|
|
|
10
12
|
const TOOL_BY_ENDPOINT = {
|
|
11
13
|
"/api/mcp/generate/image": "summer_generate_image",
|
|
12
14
|
"/api/mcp/generate/audio": "summer_generate_audio",
|
|
15
|
+
[SFX_CHOICES_ENDPOINT]: "summer_generate_sfx_choices",
|
|
13
16
|
"/api/mcp/generate/3d": "summer_generate_3d",
|
|
14
17
|
"/api/mcp/generate/video": "summer_generate_video",
|
|
15
18
|
"/api/mcp/generate/motion": "summer_generate_motion",
|
|
@@ -356,10 +359,21 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
|
|
|
356
359
|
|
|
357
360
|
Capabilities:
|
|
358
361
|
- "text_to_speech" — Convert text to spoken audio. Requires 'text'. Optional 'voiceId'.
|
|
359
|
-
- "sound_effects" — Generate sound effects from description. Requires 'text'. Optional 'durationSeconds'.
|
|
362
|
+
- "sound_effects" — Generate sound effects from description. Requires 'text'. Optional 'durationSeconds', 'modelId', 'loop'.
|
|
360
363
|
- "music" — Generate background music. Requires 'prompt'. Optional 'durationSeconds'.
|
|
361
364
|
- "text_to_dialogue" — Multi-voice dialogue. Requires 'inputs' array of {text, voiceId} objects.
|
|
362
365
|
|
|
366
|
+
Sound-effect models (modelId; omit it to use the person's approved default,
|
|
367
|
+
else ElevenLabs):
|
|
368
|
+
- "eleven_text_to_sound_v2" — ElevenLabs SFX v2. Strong all-rounder, 0.5-30 s,
|
|
369
|
+
the only one that makes seamless loops (loop: true).
|
|
370
|
+
- "sonilo-sfx-1.1" — Sonilo SFX 1.1. Strong all-rounder, >= 0.5 s.
|
|
371
|
+
- "stable-audio-3-sfx" — Stable Audio 3 SFX. Sometimes best on fast movement
|
|
372
|
+
(swings, whooshes), less consistent; >= 1 s.
|
|
373
|
+
The best model changes a lot from one sound to the next. For the first sound
|
|
374
|
+
effect in a chat, offer the person three versions to pick from by ear:
|
|
375
|
+
summer_generate_sfx_choices.
|
|
376
|
+
|
|
363
377
|
The 'options' object is spread into the ElevenLabs SDK call at the TOP level, so
|
|
364
378
|
only keys the SDK accepts there have any effect. Voice tuning is NOT top-level and
|
|
365
379
|
is NOT snake_case: pass it as options.voiceSettings with camelCase keys —
|
|
@@ -388,11 +402,16 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
|
|
|
388
402
|
modelId: z
|
|
389
403
|
.string()
|
|
390
404
|
.optional()
|
|
391
|
-
.describe("ElevenLabs model
|
|
405
|
+
.describe("Model id. text_to_speech: an ElevenLabs model (e.g. 'eleven_multilingual_v2'). " +
|
|
406
|
+
"sound_effects: eleven_text_to_sound_v2, sonilo-sfx-1.1 or stable-audio-3-sfx; omit to use the person's approved default"),
|
|
392
407
|
durationSeconds: z
|
|
393
408
|
.number()
|
|
394
409
|
.optional()
|
|
395
410
|
.describe("Duration in seconds for SFX or music"),
|
|
411
|
+
loop: z
|
|
412
|
+
.boolean()
|
|
413
|
+
.optional()
|
|
414
|
+
.describe("sound_effects only: ask for a seamless loop (eleven_text_to_sound_v2 only)"),
|
|
396
415
|
inputs: z
|
|
397
416
|
.array(z.object({ text: z.string(), voiceId: z.string() }))
|
|
398
417
|
.optional()
|
|
@@ -403,7 +422,7 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
|
|
|
403
422
|
.describe("Provider params, spread at the SDK's top level. Voice tuning goes in " +
|
|
404
423
|
"options.voiceSettings with camelCase keys (stability, similarityBoost, " +
|
|
405
424
|
"style, speed, useSpeakerBoost); flat snake_case is silently ignored."),
|
|
406
|
-
}, async ({ capability, text, prompt, voiceId, modelId, durationSeconds, inputs, options }) => {
|
|
425
|
+
}, async ({ capability, text, prompt, voiceId, modelId, durationSeconds, loop, inputs, options }) => {
|
|
407
426
|
const body = { capability };
|
|
408
427
|
if (text)
|
|
409
428
|
body.text = text;
|
|
@@ -415,6 +434,8 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
|
|
|
415
434
|
body.modelId = modelId;
|
|
416
435
|
if (durationSeconds)
|
|
417
436
|
body.durationSeconds = durationSeconds;
|
|
437
|
+
if (loop !== undefined)
|
|
438
|
+
body.loop = loop;
|
|
418
439
|
if (inputs)
|
|
419
440
|
body.inputs = inputs;
|
|
420
441
|
if (options)
|
|
@@ -426,6 +447,51 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
|
|
|
426
447
|
return successResult(result.data);
|
|
427
448
|
});
|
|
428
449
|
// ========================================================================
|
|
450
|
+
// summer_generate_sfx_choices + summer_get_choices
|
|
451
|
+
// Shared implementation: core/capabilities/sfx-choices.ts
|
|
452
|
+
// ========================================================================
|
|
453
|
+
const sfxChoicesDeps = {
|
|
454
|
+
post: (endpoint, body, timeoutMs) => mcpGenerate(endpoint, body, timeoutMs),
|
|
455
|
+
get: (endpoint, params, timeoutMs) => mcpGet(endpoint, params, timeoutMs),
|
|
456
|
+
openUrl: (url) => open(url),
|
|
457
|
+
canOpenBrowser: () => defaultCanOpenBrowser(),
|
|
458
|
+
};
|
|
459
|
+
server.tool("summer_generate_sfx_choices", `Make one sound effect with several models (default three) and show the
|
|
460
|
+
versions to the person on a Summer Studio page, where they listen and approve
|
|
461
|
+
one or more. The approved model becomes their default for sound effects.
|
|
462
|
+
|
|
463
|
+
Use it for the first sound effect in a chat after the person said yes to
|
|
464
|
+
"three versions to pick from", or whenever they want to compare. The page
|
|
465
|
+
opens in their open Summer Studio tab when there is one, else in the browser
|
|
466
|
+
(open:false skips the browser and only returns reviewUrl).
|
|
467
|
+
|
|
468
|
+
Then tell the person the returned "say" text and call summer_get_choices
|
|
469
|
+
with the choiceSetId. Do not pick for them.
|
|
470
|
+
|
|
471
|
+
Models: eleven_text_to_sound_v2 (0.5-30 s, loops), sonilo-sfx-1.1 (>= 0.5 s),
|
|
472
|
+
stable-audio-3-sfx (>= 1 s; give durationSeconds >= 1 when it is included).
|
|
473
|
+
Each version is a billed generation.
|
|
474
|
+
|
|
475
|
+
Cloud tool — runs on Summer's servers and works WITHOUT the Summer Engine app open.
|
|
476
|
+
Requires authentication: run 'npx -y summer-engine@latest login' first.`, sfxChoicesArgsSchema.shape, async (args) => {
|
|
477
|
+
const result = await generateSfxChoices(sfxChoicesArgsSchema.parse(args), sfxChoicesDeps);
|
|
478
|
+
return result.ok ? successResult(result) : errorResult(String(result.error), result);
|
|
479
|
+
});
|
|
480
|
+
server.tool("summer_get_choices", `Read a sound-effect choice set from summer_generate_sfx_choices: whether the
|
|
481
|
+
person decided ("pending" or "decided"), which versions they approved (with
|
|
482
|
+
audioUrl, assetId and their note) and their default sound-effect model.
|
|
483
|
+
|
|
484
|
+
waitSeconds (max ${MAX_CHOICES_WAIT_SECONDS}) waits for the decision before answering; call again
|
|
485
|
+
while status is "pending". Import each approved clip with
|
|
486
|
+
summer_import_from_url (url: audioUrl, path: res://audio/sfx/<name>.<fileExtension>)
|
|
487
|
+
or summer_import_asset_by_id (assetId), then wire it.
|
|
488
|
+
|
|
489
|
+
Cloud tool — runs on Summer's servers and works WITHOUT the Summer Engine app open.
|
|
490
|
+
Requires authentication: run 'npx -y summer-engine@latest login' first.`, getChoicesArgsSchema.shape, async (args) => {
|
|
491
|
+
const result = await getChoices(getChoicesArgsSchema.parse(args), sfxChoicesDeps);
|
|
492
|
+
return result.ok ? successResult(result) : errorResult(String(result.error), result);
|
|
493
|
+
});
|
|
494
|
+
// ========================================================================
|
|
429
495
|
// summer_generate_3d
|
|
430
496
|
// ========================================================================
|
|
431
497
|
server.tool("summer_generate_3d", `Generate a 3D model via Summer Engine Studio.
|
package/gemini-extension.json
CHANGED
|
@@ -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.
|
|
4
|
+
"version": "3.7.0",
|
|
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": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
**Rule of thumb:** project reads/writes go through Summer; live hierarchy/inspector changes use scene tools; process-level work remains with the host.
|
|
19
19
|
|
|
20
|
-
## Tool surface (
|
|
20
|
+
## Tool surface (104 tools)
|
|
21
21
|
|
|
22
22
|
### Project files (4)
|
|
23
23
|
|
|
@@ -211,13 +211,15 @@ Preview. One fast, read-only call that walks every node of a 3D scene and lists
|
|
|
211
211
|
| `summer_import_hdri` | Search Poly Haven's CC0 HDRIs (public API, no Summer login), import the `.hdr`/`.exr` into `res://sky/`, and get the exact `summer_run_script` snippet that wires it as the WorldEnvironment sky. |
|
|
212
212
|
| `summer_slice_asset_sheet` | Detect and crop every distinct asset from a generated sheet image into named individual assets (works without the engine; import the results afterwards). |
|
|
213
213
|
|
|
214
|
-
### Asset generation (
|
|
214
|
+
### Asset generation (7 — metered)
|
|
215
215
|
|
|
216
216
|
| Tool | Use |
|
|
217
217
|
|---|---|
|
|
218
218
|
| `summer_generate_image` | AI image gen. |
|
|
219
219
|
| `summer_generate_3d` | Image-to-3D. |
|
|
220
|
-
| `summer_generate_audio` | SFX / music gen. |
|
|
220
|
+
| `summer_generate_audio` | SFX / music gen. Sound effects: `modelId` picks ElevenLabs SFX v2, Sonilo SFX 1.1 or Stable Audio 3 SFX; omitted = the person's approved default. |
|
|
221
|
+
| `summer_generate_sfx_choices` | One sound effect from several models, shown on a Summer Studio page where the person approves one or more. |
|
|
222
|
+
| `summer_get_choices` | Read which sound-effect versions the person approved (audioUrl, assetId, note). |
|
|
221
223
|
| `summer_generate_video` | Video gen. |
|
|
222
224
|
| `summer_generate_motion` | Generate/apply 3D skeletal motion from a rigged asset. |
|
|
223
225
|
|
|
@@ -238,16 +240,13 @@ Preview. One fast, read-only call that walks every node of a 3D scene and lists
|
|
|
238
240
|
| `summer_get_agent_playbook` | Daily operating contract (observe-first loop, content routing, invariants, verification ritual) — call at start of session. Also served natively as the `summer_agent_playbook` MCP prompt. |
|
|
239
241
|
| `summer_get_board` | Read the person's approved planning board (look, characters, place, storyboard, picks), with the look and picked cards as images to compare screenshots against. Needs the project id from the build brief; works without the engine. |
|
|
240
242
|
|
|
241
|
-
### Creator platform (
|
|
243
|
+
### Creator platform (4)
|
|
242
244
|
|
|
243
245
|
| Tool | Use |
|
|
244
246
|
|---|---|
|
|
245
247
|
| `summer_export_game` | Export the game in the file the Summer Games store takes, headless (no window), no running editor needed. `format:"bundle"` (default): the `summer.games` `.zip` the Summer apps run; `targets` picks `ios`, `android`, `macos`, `windows` (a game without a server: phones only) through a named `summer.games <targets>` preset in `export_presets.cfg`. `format:"download"` with one target: `web` (HTML5 `.zip` on Summer's WebGPU Forward+ template; refuses Compatibility projects), `macos` (ad hoc signed `.app` zip, `macos-universal`) or `windows` (`.exe` with embedded pack, zipped, `windows-x64`). Returns path, sha256, size, bundle manifest or store platform, warnings. |
|
|
246
248
|
| `summer_export_templates` | `list` or `install` export templates from Summer's CDN (`downloads.summer.games/engine-templates/<summerVersion>/manifest.json`) into the engine's user template folder (`<data>/Godot/export_templates/<FULL_CONFIG>/`), sha256-checked. Only download exports need them; store bundles need none. `summerVersion` is read on macOS, passed elsewhere. |
|
|
247
249
|
| `summer_publish_build` | Upload that `.zip` to the creator's game through Studio's store upload: confirm-gated preview first, then declare, part upload from disk, seal, wait for the Build, name its client pack; `publish:true` also approves it. Needs `summer login --store`; a retry with the same file and version continues the same upload. |
|
|
248
|
-
| `summer_creator_publish` | **Deprecated** (use the two tools above). Compute the exact `.pck` digest and size, require user confirmation, then run versioned prepare → write-once upload → finalize. The server independently verifies `publish` scope, ownership, bytes, and review state. |
|
|
249
|
-
| `summer_creator_releases` | **Deprecated.** Lists releases on the legacy creator API. For summer.games use `summer_store_releases` (hosted, mounted after `summer login --store`). |
|
|
250
|
-
| `summer_creator_config` | Read or confirm updates to the shared non-secret `~/.summer/config.json`. It never accepts or returns tokens. |
|
|
251
250
|
| `summer_capture_gameplay` | Real gameplay frames without a running editor: starts the game (main scene or `scene`) in the engine's offscreen verify instance (`--summer-verify`, real renderer, window parked offscreen, no focus) (`--summer-offscreen`) at `resolution` (default `1920x1080`), waits `waitSeconds`, runs `steps` (`press` a button by text, `key`, `action`, `click`, `drag`, `wait`, `shot`), saves `frames` PNGs (HUD included; with a `shot` step, one per shot) to `<project>/.summer/captures/<time>/`. `args` are the game's own flags, passed after `--` (e.g. `["--autostart"]` to skip the title screen). Imports the project first when `.godot/` is missing. Returns each path with its real width and height; warns when the stretch settings render another size. For store screenshots. |
|
|
252
251
|
|
|
253
252
|
### Library search (2)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
id: reference/mcp-tools-reference
|
|
2
2
|
kind: reference
|
|
3
|
-
version: 1.4.
|
|
3
|
+
version: 1.4.1
|
|
4
4
|
summary: Canonical reference for which Summer MCP tool to call — skills should reference tool names exactly as written here.
|
|
5
5
|
use_when:
|
|
6
6
|
- choosing between Summer MCP tools and host tools for an operation
|
package/library/skills/README.md
CHANGED
|
@@ -117,7 +117,7 @@ Status: **stable** unless marked; *preview* = not yet exercised in-engine by the
|
|
|
117
117
|
| [ambient-bed](./ambient-bed/SKILL.md) | Generate a long looping location ambience — forest, dungeon, city, spaceship, cave — a looping AudioStreamPlayer on the Ambient bus with a seamless loop. | assets |
|
|
118
118
|
| [audio-direction](./audio-direction/SKILL.md) ★ | Define the game's sonic identity — music style, instruments, SFX vocabulary, dynamic music plan — output as an audio bible at .summer/audio-bible.md. | game-design |
|
|
119
119
|
| [music-track](./music-track/SKILL.md) ★ | Generate a looped or cinematic music track — loops authored at >=30s with a marked loop point, cinematic tracks at >=60s linear. | assets |
|
|
120
|
-
| [sound-effect](./sound-effect/SKILL.md) ★ |
|
|
120
|
+
| [sound-effect](./sound-effect/SKILL.md) ★ | Make SFX one-shots and timed sequences (swings, hits, whooshes, reloads, UI) - offer three model versions to pick from, then wire them as AudioStreamPlayers. | assets |
|
|
121
121
|
| [voice-line](./voice-line/SKILL.md) ★ | Generate TTS voice lines — NPC barks, narrator, dialogue — with voice-id sourcing, a character-to-voice decision tree, and multi-line dialogue support. | assets |
|
|
122
122
|
|
|
123
123
|
## character-controller
|
|
@@ -147,7 +147,7 @@ Status: **stable** unless marked; *preview* = not yet exercised in-engine by the
|
|
|
147
147
|
| skill | when to use | also |
|
|
148
148
|
|---|---|---|
|
|
149
149
|
| [export-and-ship](./export-and-ship/SKILL.md) ★ | Assess and prepare a game export: inventory installed templates and targets, validate release assets and config, produce supported builds after approval. | project |
|
|
150
|
-
| [*release-readiness*](./release-readiness/SKILL.md) (preview) | Before releasing a Summer game version, prove players can play it: server scene, online join,
|
|
150
|
+
| [*release-readiness*](./release-readiness/SKILL.md) (preview) | Before releasing a Summer game version, prove players can play it: server scene, online join, progress, Game ID, released Summer, packed files, app version. | multiplayer, playtest |
|
|
151
151
|
| [remote-deploy](./remote-deploy/SKILL.md) ★ | Run or test the game on a real device — phone, tablet, another computer — via the Remote Deploy button, runnable export presets, and on-device debugging. | project |
|
|
152
152
|
|
|
153
153
|
## editor
|
|
@@ -103,13 +103,15 @@ If the user wants a busier bed (market, party), still prevent foreground events:
|
|
|
103
103
|
```
|
|
104
104
|
summer_generate_audio(
|
|
105
105
|
capability: "sound_effects",
|
|
106
|
+
modelId: "eleven_text_to_sound_v2",
|
|
107
|
+
loop: true,
|
|
106
108
|
text: "forest at dawn, gentle wind through leaves, distant bird calls every 6 seconds, soft creaking branches, no music, no human sound, 22s seamless loop",
|
|
107
109
|
durationSeconds: 22
|
|
108
110
|
)
|
|
109
111
|
// Then: summer_import_from_url(url: "<fileUrl>", path: "res://audio/ambient/forest_dawn.wav")
|
|
110
112
|
```
|
|
111
113
|
|
|
112
|
-
`sound_effects` reads from **`text`**, not `prompt` — passing `prompt` is a 400 `text_required`. (`prompt` is the `music` capability's field.) The clip comes back as WAV, so a `.wav` target path is correct.
|
|
114
|
+
Name `modelId: "eleven_text_to_sound_v2"` with `loop: true`: it is the only sound-effect model that makes seamless loops, and without a `modelId` the person's default sound-effect model runs, which may not loop. `sound_effects` reads from **`text`**, not `prompt` — passing `prompt` is a 400 `text_required`. (`prompt` is the `music` capability's field.) The clip comes back as WAV, so a `.wav` target path is correct.
|
|
113
115
|
|
|
114
116
|
22s is the SFX ceiling. Always generate at the ceiling for ambient — longer cycle means less recognized repetition.
|
|
115
117
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
id: skill/ambient-bed
|
|
2
2
|
kind: skill
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.3
|
|
4
4
|
summary: Generate a long looping location ambience — forest, dungeon, city, spaceship, cave — a looping AudioStreamPlayer on the Ambient bus with a seamless loop.
|
|
5
5
|
use_when:
|
|
6
6
|
- generating a long looping location ambience — forest at dawn, dungeon air, city street, spaceship hum, cave drip — non-melodic and low-energy
|
|
@@ -203,15 +203,15 @@ Ask:
|
|
|
203
203
|
|
|
204
204
|
### 10. Optional — generate first SFX seeds
|
|
205
205
|
|
|
206
|
-
If the user wants to start generating, propose 3-5 SFX seeds aligned with the vocabulary. These are starting points, not finals.
|
|
206
|
+
If the user wants to start generating, propose 3-5 SFX seeds aligned with the vocabulary. These are starting points, not finals. Generate them with the `sound-effect` skill: the first sound effect in a chat starts with its question (three versions from three models, picked by ear in Summer Studio), and its prompt shape is the one that tested well.
|
|
207
207
|
|
|
208
208
|
```
|
|
209
|
-
summer_generate_audio(capability="sound_effects", text="soft woody
|
|
210
|
-
summer_generate_audio(capability="sound_effects", text="
|
|
211
|
-
summer_generate_audio(capability="sound_effects", text="
|
|
209
|
+
summer_generate_audio(capability="sound_effects", text="Foley one-shot: a fingertip taps a small wooden button, soft woody click, no tail, close-mic, dry, no reverb, no music, no voices.", durationSeconds=0.5)
|
|
210
|
+
summer_generate_audio(capability="sound_effects", text="Foley one-shot: a small gold coin drops onto a wooden table, bright metallic ting with a short ring, close-mic, dry, no music, no voices.", durationSeconds=0.5)
|
|
211
|
+
summer_generate_audio(capability="sound_effects", text="Foley one-shot: a fist hits a padded leather vest, low-mid thump, no tail, close-mic, dry, no reverb, no music, no voices.", durationSeconds=0.5)
|
|
212
212
|
```
|
|
213
213
|
|
|
214
|
-
`capability` is required; `sound_effects` reads from `text` (not `prompt`), and the length argument is `durationSeconds` (not `duration`) with a floor of 0.5 s. Ask for the character you want inside the text and let the player only use the front of the clip — you cannot request 80 ms.
|
|
214
|
+
`capability` is required; `sound_effects` reads from `text` (not `prompt`), and the length argument is `durationSeconds` (not `duration`) with a floor of 0.5 s (1 s for Stable Audio 3 SFX). Leave out `modelId` so the person's approved default model runs. Ask for the character you want inside the text and let the player only use the front of the clip — you cannot request 80 ms.
|
|
215
215
|
|
|
216
216
|
Ask first:
|
|
217
217
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
id: skill/audio-direction
|
|
2
2
|
kind: skill
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.7
|
|
4
4
|
summary: Define the game's sonic identity — music style, instruments, SFX vocabulary, dynamic music plan — output as an audio bible at .summer/audio-bible.md.
|
|
5
5
|
use_when:
|
|
6
6
|
- defining the sonic identity — music style, instruments, SFX vocabulary, dynamic music plan
|
|
@@ -299,6 +299,8 @@ Per platform, point the user at the correct upload path:
|
|
|
299
299
|
- Per platform, the store takes: iPhone, Android, macOS and Windows in the Summer apps = one summer.games bundle (`summer_export_game` `targets`, format `bundle`; no template, no signing; a game without a server targets `ios`/`android` only). Web = an HTML5 `.zip` on Summer's WebGPU Forward+ template (`targets:["web"]`; the project must render with Forward+ or Mobile). A macOS or Windows download for the store page = `targets:["macos"]` or `["windows"]` with format `download`. Download exports need the template: `summer_export_templates` `install` fetches it from Summer's CDN.
|
|
300
300
|
- Hosted games: if `summer_export_game` fails with "… is in the source graph's authority_engine domain, which the client pack leaves out", an authority root in `source-domains.json` holds a file the client loads (often the composition `.tres`). Narrow that root to the server-only files, or move the shared file under a `shared` path, then export again. Every exporter message is in the `multiplayer-publish` skill's export-errors.md; the folder rules are in `multiplayer-project`.
|
|
301
301
|
- Every summer.games bundle: export with the released Summer editor from the download page, never a development build, and export again after updating Summer. Otherwise its scripts can fail to compile on players' devices and the game opens to an empty window, though every upload check passes. `release-readiness` check 7 proves it.
|
|
302
|
+
- Every file the game reads by path at run time (`FileAccess`, `DirAccess`, `load_from_file`) that Summer doesn't import, such as a `.bin` or `.json`, must match the **summer.games** preset's own `include_filter` (Resources > Filters to export non-resource files/folders); a filter on another preset doesn't carry over. A left-out file is no export error, it is just missing on players' devices. Never use `SystemFont` for phone text: on iPhone it draws every glyph as a box. `release-readiness` check 8 lists the pack.
|
|
303
|
+
- iPhone and Android bundles: the Summer Games apps start only exports on their Summer version line (same MAJOR.MINOR, patch no newer). Export with the current Summer release and export again after every Summer minor update, or players see "The game could not start" on phones while desktop works. `release-readiness` check 9.
|
|
302
304
|
- Hosted games, before the upload: a clean export does not prove players can join. Run `release-readiness` on the `.zip`: the bundle's `server.pck`, started with no scene, must load the authority scene (the server preset needs the `summer_authority` custom feature), and `Summer.initialize` must pass no hard-coded Game ID. Otherwise every online join fails with `world_start_timeout`.
|
|
303
305
|
- Store page art: key art, covers and icons carry no text, logos or UI (the store page shows the title). Screenshots are real gameplay and may show the game's own HUD; add no captions, logos or overlays. Capture them with `summer_capture_gameplay` (offscreen, no editor needed; `resolution` `1920x1080`, or `1080x1920` for portrait; get past a title menu with the game's own flags in `args`, e.g. `["--autostart"]`, or `steps` such as `[{"press":"Play"},{"wait":3000},{"shot":true}]`), or `summer_screenshot` target `game` while the editor runs the game.
|
|
304
306
|
- **Steam:** `steamcmd` + Steam Pipe (`builder_app_xxx.vdf`). Set up depots first in Steamworks.
|
|
@@ -141,7 +141,9 @@ scene the pack will start; step 4d checks that. The `Exported by Summer`
|
|
|
141
141
|
line must name a released Summer: export with the released editor from the
|
|
142
142
|
download page, never a development build, and export again after you update
|
|
143
143
|
Summer. Players' apps run the packs on the released Summer of that version;
|
|
144
|
-
step 4e checks it.
|
|
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
|
|
145
147
|
result message and every export error, with its fix, is in
|
|
146
148
|
[export-errors.md](export-errors.md).
|
|
147
149
|
|
|
@@ -265,8 +267,10 @@ of `.zip`. That writes `client.pck` alone.
|
|
|
265
267
|
Right after the Build is released, open the game in a Summer Games app,
|
|
266
268
|
join online and play until you are in the game, before players hear about
|
|
267
269
|
the update. A wrong Game ID only fails under a real hosted launch, so
|
|
268
|
-
nothing before this step catches it.
|
|
269
|
-
|
|
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
|
|
270
274
|
`release-readiness`, and the creator docs have it at
|
|
271
275
|
https://docs.summerengine.com/publishing/release-readiness.
|
|
272
276
|
|
|
@@ -293,7 +297,7 @@ Use step 4d to see which scene runs.
|
|
|
293
297
|
- [ ] The bundle's `server.pck`, run with no scene, loads the authority scene first.
|
|
294
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`.
|
|
295
299
|
- [ ] Every `Summer.initialize` call passes no Game ID.
|
|
296
|
-
- [ ] After release: a real online join reaches the game (`release-readiness`).
|
|
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).
|
|
297
301
|
- [ ] Local Play passed with the same project.
|
|
298
302
|
|
|
299
303
|
## Common mistakes
|
|
@@ -21,3 +21,5 @@ Its current text lives on the hosted Summer Engine MCP, the same text the Studio
|
|
|
21
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
22
|
|
|
23
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.
|
|
24
|
+
|
|
25
|
+
After the review: `summer_store_review` (hosted) returns Summer's decision, the reviewer's feedback and the next step. When Summer asks for changes or does not approve the game, fix every point in the feedback, then call `summer_store_submit` again; the owner approves the resubmission. If there is no written feedback, say so and ask the owner instead of guessing. The game is not live until Summer approves it.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: release-readiness
|
|
3
|
-
description: "Before releasing a Summer game version, prove players can play it: server scene, online join,
|
|
3
|
+
description: "Before releasing a Summer game version, prove players can play it: server scene, online join, progress, Game ID, released Summer, packed files, app version."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: deployment
|
|
@@ -78,7 +78,8 @@ failures:
|
|
|
78
78
|
|
|
79
79
|
Checks 1 and 2 apply to every game with a server (`summer.build.json` names
|
|
80
80
|
a `server.exportPreset`). Checks 3 and 4 apply to every game with online
|
|
81
|
-
play. Checks 5
|
|
81
|
+
play. Checks 5 to 8 and 10 apply to every game. Check 9 applies to every
|
|
82
|
+
bundle for iPhone or Android.
|
|
82
83
|
|
|
83
84
|
### 1. The server pack starts the authority scene
|
|
84
85
|
|
|
@@ -242,6 +243,120 @@ https://summerengine.com/download (or, with their OK, run
|
|
|
242
243
|
`summer install --yes`). Export again with it, and rerun this check on the
|
|
243
244
|
new `.zip` before you upload it.
|
|
244
245
|
|
|
246
|
+
### 8. Every file the game reads at run time is in the pack
|
|
247
|
+
|
|
248
|
+
**Why.** The export packs scenes, scripts and imported assets. A file the
|
|
249
|
+
game opens itself by path (`FileAccess`, `DirAccess`, `load_from_file`,
|
|
250
|
+
`FontFile.load_dynamic_font`, `ConfigFile.load`) that has no `.import`
|
|
251
|
+
beside it, such as a `.bin`, `.json` or `.txt`, is a non-resource file. It
|
|
252
|
+
goes into the pack only when the preset's `include_filter` (**Resources >
|
|
253
|
+
Filters to export non-resource files/folders**) matches it and
|
|
254
|
+
`exclude_filter` doesn't. Each preset has its own filters: the summer.games
|
|
255
|
+
preset doesn't inherit one set on another preset. A file left out is not an
|
|
256
|
+
export error; on players' devices `FileAccess` just returns nothing and the
|
|
257
|
+
game's fallback runs. Fonts show it first: in the Summer Games app on iPhone
|
|
258
|
+
a `SystemFont` has no system fonts to use, so every glyph draws as a box,
|
|
259
|
+
while the editor, Local Play and desktop find a system font and look right.
|
|
260
|
+
A real release shipped this way: its font file was missing from the
|
|
261
|
+
uploaded pack, and every letter on iPhone was a box.
|
|
262
|
+
|
|
263
|
+
**Check it.**
|
|
264
|
+
|
|
265
|
+
1. Find every read by path:
|
|
266
|
+
`grep -rn -E 'FileAccess\.|DirAccess\.|load_from_file|load_dynamic_font|ConfigFile' --include=*.gd .`
|
|
267
|
+
Note each `res://` file or folder they read; skip `user://` (saves). A
|
|
268
|
+
file is raw when no `<file>.import` sits beside it.
|
|
269
|
+
2. Check the filters:
|
|
270
|
+
`grep -n -E '^name=|^include_filter=|^exclude_filter=' export_presets.cfg`.
|
|
271
|
+
The summer.games preset's `include_filter` must match each raw file the
|
|
272
|
+
client reads, and its `exclude_filter` must not. Do the same on the
|
|
273
|
+
server preset for files the authority reads.
|
|
274
|
+
3. List the pack. Save this script **outside** the project, for example as
|
|
275
|
+
`~/list_pack.gd`:
|
|
276
|
+
|
|
277
|
+
```gdscript
|
|
278
|
+
extends SceneTree
|
|
279
|
+
# Prints one "PACK res://..." line per file in the pack mounted with --main-pack.
|
|
280
|
+
func _init() -> void:
|
|
281
|
+
_walk("res://")
|
|
282
|
+
quit()
|
|
283
|
+
|
|
284
|
+
func _walk(dir: String) -> void:
|
|
285
|
+
var d := DirAccess.open(dir)
|
|
286
|
+
if d == null:
|
|
287
|
+
return
|
|
288
|
+
d.include_hidden = true
|
|
289
|
+
for f in d.get_files():
|
|
290
|
+
print("PACK ", dir.path_join(f))
|
|
291
|
+
for s in d.get_directories():
|
|
292
|
+
_walk(dir.path_join(s))
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
```sh
|
|
296
|
+
perl -e 'alarm shift; exec @ARGV' 60 <summer> --headless --main-pack build/bundle/client.pck --script ~/list_pack.gd > build/client-pack.txt 2>&1
|
|
297
|
+
grep -Fx 'PACK res://fonts/MyFont.bin' build/client-pack.txt # once per raw file from step 1
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Every raw file must print its line. No line means the file is not in the
|
|
301
|
+
pack, whatever the preset says. List `server.pck` the same way for files
|
|
302
|
+
the authority reads.
|
|
303
|
+
4. `grep -rn SystemFont --include=*.gd --include=*.tscn --include=*.tres .`
|
|
304
|
+
must find nothing on a path phone players reach, fallbacks included.
|
|
305
|
+
5. After publishing, open the game on an iPhone in the Summer Games app and
|
|
306
|
+
look at the title and one menu: letters, not boxes. An agent can't do
|
|
307
|
+
this step; report it as **not run** and ask the user.
|
|
308
|
+
|
|
309
|
+
**Fix.** Add each missing file to the summer.games preset's non-resource
|
|
310
|
+
filter (for example `fonts/*.bin`), or import it as a resource instead.
|
|
311
|
+
Ship the font in the project (an imported `.ttf`/`.otf`, or raw bytes that
|
|
312
|
+
step 3 proves are packed) and fall back to `ThemeDB.fallback_font`, Summer's
|
|
313
|
+
built-in font, never to `SystemFont`. Export again and rerun steps 3 and 5.
|
|
314
|
+
|
|
315
|
+
### 9. Export with the Summer version line the Summer Games apps run
|
|
316
|
+
|
|
317
|
+
**Why.** The Summer Games apps for iPhone and Android carry Summer inside
|
|
318
|
+
the app and download none. An app starts a game only when the export's
|
|
319
|
+
`summerVersion` has the app's MAJOR.MINOR (for example `0.7`) and a patch no
|
|
320
|
+
newer than the app's. A `0.6.x` export doesn't start in an app that carries
|
|
321
|
+
`0.7`: the player sees **The game could not start**. The desktop app fetches
|
|
322
|
+
the right Summer for each game, so the game can run on Mac and Windows and
|
|
323
|
+
still fail on every phone. The upload checks don't catch it.
|
|
324
|
+
|
|
325
|
+
**Check it.**
|
|
326
|
+
|
|
327
|
+
1. Read the stamp and platforms:
|
|
328
|
+
`python3 -c 'import json; b=json.load(open("build/bundle/summer-bundle.json")); print(b["export"]["summerVersion"], b["client"]["targetPlatforms"])'`
|
|
329
|
+
2. If `targetPlatforms` lists `ios` or `android`, the first two numbers of
|
|
330
|
+
`summerVersion` must match the current Summer release, shown on
|
|
331
|
+
https://summerengine.com/download and in Help > About after updating.
|
|
332
|
+
3. After publishing, open the game on a phone in the Summer Games app, as in
|
|
333
|
+
check 2. "The game could not start" there, while desktop works, is this
|
|
334
|
+
check failing.
|
|
335
|
+
|
|
336
|
+
**Fix.** Ask the user to update Summer to the current release (or, with
|
|
337
|
+
their OK, run `summer install --yes`). Export again, upload it as a new
|
|
338
|
+
version and promote it. Do this again after every Summer minor update
|
|
339
|
+
(0.6 to 0.7), because the apps move to the new line.
|
|
340
|
+
|
|
341
|
+
### 10. A signed-in player keeps playing for three minutes
|
|
342
|
+
|
|
343
|
+
**Why.** While the game runs, it calls Summer services for the signed-in
|
|
344
|
+
player: analytics, player data, the store. A short test can end before the
|
|
345
|
+
first of those calls. A real release closed for every player about a minute
|
|
346
|
+
in, with "That link can't be opened", and left them signed out: a Summer
|
|
347
|
+
service refused the player's sign-in, and the app ended play. The fault was
|
|
348
|
+
Summer's, not the game's, and no check on the game's files could see it.
|
|
349
|
+
|
|
350
|
+
**Check it.** After publishing, sign in to a Summer Games app on a phone,
|
|
351
|
+
open the released version and play it for at least 3 minutes, through at
|
|
352
|
+
least one analytics event. The game must not close, and the player must
|
|
353
|
+
still be signed in afterwards. Do it in each Summer Games app the game
|
|
354
|
+
targets. An agent can't do this step; report it as **not run** and ask the
|
|
355
|
+
user, then record what they saw.
|
|
356
|
+
|
|
357
|
+
**Fix.** Nothing in the game. Ask the user to report it to Summer with the
|
|
358
|
+
game's name, the app and the time it happened.
|
|
359
|
+
|
|
245
360
|
## Troubleshooting
|
|
246
361
|
|
|
247
362
|
### Every online join fails with `world_start_timeout`, but Local Play works
|
|
@@ -263,6 +378,27 @@ export, and the scripts use something the released version doesn't have.
|
|
|
263
378
|
Re-export with the current Summer release, upload the new version and
|
|
264
379
|
promote it.
|
|
265
380
|
|
|
381
|
+
### Text shows as boxes on iPhone
|
|
382
|
+
|
|
383
|
+
Every letter draws as an empty box in the Summer Games app on iPhone, while
|
|
384
|
+
the game looks right on desktop. The game most likely reads a font file that
|
|
385
|
+
isn't in the pack and falls back to `SystemFont`. Run check 8.
|
|
386
|
+
|
|
387
|
+
### "The game could not start" on iPhone or Android
|
|
388
|
+
|
|
389
|
+
The game works on desktop, but the phone app says "The game could not
|
|
390
|
+
start". The `.zip` most likely comes from a Summer version line the app
|
|
391
|
+
doesn't carry. Run check 9, then export again with the current Summer
|
|
392
|
+
release, upload and promote.
|
|
393
|
+
|
|
394
|
+
### The game closes after about a minute and the player is signed out
|
|
395
|
+
|
|
396
|
+
The Summer Games app closes the game 20 to 60 seconds into play with "Play
|
|
397
|
+
paused" or "That link can't be opened", and the player finds they are signed
|
|
398
|
+
out. A Summer service refused the player's sign-in while the game played.
|
|
399
|
+
This is Summer's fault, not the game's: see check 10, and ask the user to
|
|
400
|
+
report it with the time it happened.
|
|
401
|
+
|
|
266
402
|
### The game server's log is empty
|
|
267
403
|
|
|
268
404
|
An empty server log is not proof that the server hung or never started. A
|
|
@@ -295,4 +431,7 @@ here would have caught:
|
|
|
295
431
|
- [ ] 5. Players can get back to the title from inside a session, online and offline.
|
|
296
432
|
- [ ] 6. Every `Summer.initialize` passes no ID, or an ID the game got from Summer.
|
|
297
433
|
- [ ] 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`.
|
|
434
|
+
- [ ] 8. Every file the game reads by path has a `PACK res://…` line in the listing of `client.pck` (or `server.pck`), no phone text uses `SystemFont`, and text shows as letters on an iPhone (or is reported as not run).
|
|
435
|
+
- [ ] 9. For an iPhone or Android bundle, `summerVersion` has the current Summer release's MAJOR.MINOR.
|
|
436
|
+
- [ ] 10. A signed-in player played the released version for 3 minutes in each Summer Games app, through an analytics event, without the game closing or being signed out (or it is reported as not run).
|
|
298
437
|
- [ ] One line per check reported to the user before anything is changed.
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
id: skill/release-readiness
|
|
2
2
|
kind: skill
|
|
3
3
|
version: 1.0.0
|
|
4
|
-
summary: "Before releasing a Summer game version, prove players can play it: server scene, online join,
|
|
4
|
+
summary: "Before releasing a Summer game version, prove players can play it: server scene, online join, progress, Game ID, released Summer, packed files, app version."
|
|
5
5
|
use_when:
|
|
6
6
|
- "before uploading, promoting or releasing a new version to players: is it ready to release"
|
|
7
7
|
- "every online join fails with world_start_timeout, or the hosted server's log is empty, while Local Play works"
|
|
8
8
|
- "Summer.initialize fails with game_identity_mismatch: the initialized Game ID does not match hosted runtime context"
|
|
9
9
|
- "checking that a hosted game's server.pck starts the authority scene and not the title screen"
|
|
10
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
|
+
- "text shows as boxes on iPhone but looks fine on desktop: a font or other file read with FileAccess is missing from the pack, or SystemFont is used"
|
|
12
|
+
- "the Summer Games phone app says the game could not start, but it works on desktop: the game's Summer version line differs from the app's"
|
|
13
|
+
- "the game closes about a minute into play with Play paused or That link can't be opened, and the player is signed out"
|
|
11
14
|
- "a game release failed for players and the check that would have caught it needs adding"
|
|
12
15
|
do_not_use_when:
|
|
13
16
|
- "only producing a local export for a jam or prototype nobody else plays — skill/export-and-ship"
|