summer-engine 2.7.0 → 2.8.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/plugin.json +2 -1
- package/.codex-plugin/plugin.json +3 -2
- package/.cursor-plugin/plugin.json +2 -1
- package/.opencode/INSTALL.md +1 -1
- package/.opencode/plugins/summer.js +1 -1
- package/AGENTS.md +4 -4
- package/CHANGELOG.md +10 -0
- package/GEMINI.md +5 -4
- package/README.md +58 -19
- package/assets/autopilot/README.md +51 -0
- package/assets/autopilot/autopilot.gd +222 -0
- package/assets/autopilot/probe_base.gd +262 -0
- package/assets/autopilot/run.sh +78 -0
- package/commands/gameskill.md +11 -2
- package/dist/bin/summer.js +8 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +53 -0
- package/dist/commands/create.d.ts +1 -0
- package/dist/commands/create.js +38 -6
- package/dist/commands/list.js +1 -1
- package/dist/commands/login.d.ts +19 -0
- package/dist/commands/login.js +123 -36
- package/dist/commands/logout.js +3 -16
- package/dist/commands/logs.d.ts +2 -0
- package/dist/commands/logs.js +19 -0
- package/dist/commands/mcp.js +7 -2
- package/dist/commands/open.js +1 -1
- package/dist/commands/publish.d.ts +2 -0
- package/dist/commands/publish.js +20 -0
- package/dist/commands/releases.d.ts +2 -0
- package/dist/commands/releases.js +20 -0
- package/dist/commands/run.js +1 -1
- package/dist/lib/api-client.d.ts +4 -2
- package/dist/lib/api-client.js +28 -4
- package/dist/lib/auth.d.ts +40 -12
- package/dist/lib/auth.js +173 -37
- package/dist/lib/cloud/engine-bridge.d.ts +17 -4
- package/dist/lib/cloud/engine-bridge.js +32 -6
- package/dist/lib/config.d.ts +20 -0
- package/dist/lib/config.js +142 -0
- package/dist/lib/creator.d.ts +93 -0
- package/dist/lib/creator.js +393 -0
- package/dist/lib/engine.d.ts +35 -2
- package/dist/lib/engine.js +240 -6
- package/dist/lib/public-surface-paths.d.ts +13 -0
- package/dist/lib/public-surface-paths.js +42 -0
- package/dist/lib/skills-registry.d.ts +8 -0
- package/dist/lib/skills-registry.js +9 -0
- package/dist/lib/store.d.ts +14 -0
- package/dist/lib/store.js +145 -0
- package/dist/lib/summer-compatibility.d.ts +6 -0
- package/dist/lib/summer-compatibility.js +22 -0
- package/dist/mcp/server.d.ts +8 -1
- package/dist/mcp/server.js +25 -4
- package/dist/mcp/tools/creator-tools.d.ts +2 -0
- package/dist/mcp/tools/creator-tools.js +105 -0
- package/dist/mcp/tools/generate-tools.js +16 -6
- package/dist/mcp/tools/project-tools.js +12 -7
- package/dist/mcp/tools/scene-tools.js +6 -6
- package/dist/mcp/tools/visual-tools.js +4 -3
- package/hooks/pre-commit-doctor.sh +0 -0
- package/hooks/run-hook.cmd +0 -0
- package/hooks/session-start.sh +5 -5
- package/package.json +3 -1
- package/references/collaborative-protocol.md +50 -0
- package/references/gd-style.md +121 -0
- package/references/godot-version.md +51 -0
- package/references/mcp-tools-reference.md +199 -0
- package/references/public-surface-language.md +30 -0
- package/references/summer-folder.md +90 -0
- package/references/template-registry.md +73 -0
- package/skills/2d-assets/character-portrait/SKILL.md +17 -12
- package/skills/2d-assets/concept-art/SKILL.md +10 -9
- package/skills/2d-assets/pixel-art/SKILL.md +36 -20
- package/skills/2d-assets/skybox-panorama/SKILL.md +32 -37
- package/skills/2d-assets/sprite-sheet/SKILL.md +40 -35
- package/skills/2d-assets/tileable-texture/SKILL.md +28 -22
- package/skills/2d-assets/ui-graphics/SKILL.md +46 -32
- package/skills/2d-assets/use-widget-asset/SKILL.md +8 -6
- package/skills/3d-assets/character-model/SKILL.md +34 -19
- package/skills/3d-assets/environment-kit/SKILL.md +11 -5
- package/skills/3d-assets/organic-model/SKILL.md +8 -5
- package/skills/3d-assets/prop-model/SKILL.md +9 -3
- package/skills/3d-assets/vehicle-model/SKILL.md +32 -19
- package/skills/README.md +1 -1
- package/skills/ai-and-npcs/design-npc/SKILL.md +31 -13
- package/skills/animation/animation-tree/SKILL.md +39 -15
- package/skills/animation/facial-and-lipsync/SKILL.md +25 -8
- package/skills/animation/generate-motion/SKILL.md +47 -15
- package/skills/animation/procedural-animation/SKILL.md +31 -13
- package/skills/animation/retarget/SKILL.md +127 -79
- package/skills/audio/adaptive-music/SKILL.md +24 -20
- package/skills/audio/ambient-bed/SKILL.md +22 -16
- package/skills/audio/audio-direction/SKILL.md +15 -10
- package/skills/audio/music-track/SKILL.md +18 -12
- package/skills/audio/sound-effect/SKILL.md +17 -12
- package/skills/audio/voice-line/SKILL.md +42 -42
- package/skills/character-controllers/fps-controller/SKILL.md +26 -16
- package/skills/debugging/debug/SKILL.md +52 -20
- package/skills/deployment/export-and-ship/SKILL.md +105 -38
- package/skills/deployment/remote-deploy/SKILL.md +56 -23
- package/skills/gameplay-mechanics/auto-fire-targeting/SKILL.md +26 -1
- package/skills/gameplay-mechanics/design-mechanic/SKILL.md +23 -15
- package/skills/level-design/design-level/SKILL.md +22 -8
- package/skills/level-design/scene-to-level/SKILL.md +13 -7
- package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +8 -8
- package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +2 -7
- package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +26 -18
- package/skills/performance/tune-performance/SKILL.md +51 -32
- package/skills/rendering-and-lighting/3d-lighting/SKILL.md +34 -5
- package/skills/rendering-and-lighting/art-direction/SKILL.md +6 -8
- package/skills/scene-and-project/brainstorm-game/SKILL.md +3 -5
- package/skills/scene-and-project/make-game/SKILL.md +2 -1
- package/skills/scene-and-project/play/SKILL.md +10 -4
- package/skills/scene-and-project/scene-composition/SKILL.md +21 -8
- package/skills/scene-and-project/summer-cloud/SKILL.md +1 -1
- package/skills/ui-and-ux/ui-basics/SKILL.md +16 -7
- package/skills/video/animated-loop/SKILL.md +63 -39
- package/skills/video/cinematic-cutscene/SKILL.md +66 -30
- package/skills/video/trailer-shot/SKILL.md +30 -21
- package/skills/visual-effects/_building-blocks/additive-billboard-particles.md +25 -16
- package/skills/visual-effects/_building-blocks/trauma-shake-snippet.md +5 -3
- package/skills/visual-effects/game-feel/SKILL.md +51 -33
- package/skills/visual-effects/recipes/dissolve/SKILL.md +51 -9
- package/skills/visual-effects/recipes/fire/SKILL.md +136 -49
- package/skills/visual-effects/recipes/hit-spark/SKILL.md +45 -8
- package/skills/visual-effects/recipes/lightning/SKILL.md +59 -27
- package/skills/visual-effects/recipes/magic-glow/SKILL.md +59 -26
- package/skills/visual-effects/recipes/muzzle-flash/SKILL.md +68 -25
- package/skills/visual-effects/recipes/smoke/SKILL.md +89 -28
- package/skills/visual-effects/recipes/water-ripple/SKILL.md +83 -23
- package/skills/workflow/brainstorming/SKILL.md +1 -1
- package/skills/workflow/brainstorming/scripts/start-server.sh +0 -0
- package/skills/workflow/brainstorming/scripts/stop-server.sh +0 -0
- package/skills/workflow/debugging-game-feel/SKILL.md +29 -9
- package/skills/workflow/diagnosing-perf-regressions/SKILL.md +46 -21
- package/skills/workflow/gameskill/SKILL.md +11 -2
- package/skills/workflow/headless-scripting/SKILL.md +407 -0
- package/skills/workflow/investigating-bugs/SKILL.md +4 -2
- package/skills/workflow/investigating-bugs/find-polluter.sh +0 -0
- package/skills/workflow/mcpupdate/SKILL.md +3 -3
- package/skills/workflow/playtesting-a-feature/SKILL.md +94 -21
- package/skills/workflow/skill-create/SKILL.md +7 -7
- package/skills/workflow/skill-test/SKILL.md +3 -3
- package/skills/workflow/using-summer/SKILL.md +12 -2
- package/skills/workflow/verification-before-completion/SKILL.md +2 -0
- package/skills/workflow/writing-plans/SKILL.md +7 -7
- package/skills/workflow/writing-skills/SKILL.md +7 -5
- package/skills/workflow/writing-skills/render-graphs.js +0 -0
- package/skills/workflow/writing-skills/testing-skills-with-subagents.md +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ui-basics
|
|
3
|
-
description: Use when building
|
|
3
|
+
description: Use when building Summer Engine UI: HUDs, main menus, pause menus, health bars, progress bars, dialogue boxes, or any Control-node tree. Covers anchors, containers (VBox/HBox/Margin), responsive layout, and theme versus inline styling. Trigger on "UI", "HUD", "menu", "health bar", "Control", "anchors", "VBoxContainer", "main menu", "pause menu".
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: ui-and-ux
|
|
@@ -11,7 +11,8 @@ paths: ["**/*.tscn", "**/*.gd"]
|
|
|
11
11
|
|
|
12
12
|
# UI Basics for Summer Engine
|
|
13
13
|
|
|
14
|
-
Build menus and HUDs using
|
|
14
|
+
Build menus and HUDs using Summer Engine Control nodes. Follow these patterns
|
|
15
|
+
for layout, buttons, and responsive design.
|
|
15
16
|
|
|
16
17
|
## Control Hierarchy
|
|
17
18
|
|
|
@@ -57,14 +58,17 @@ summer_add_node(parent="./MainMenu/Margin/VBox", type="Button", name="QuitButton
|
|
|
57
58
|
summer_set_prop(path="./MainMenu/Margin/VBox/QuitButton", key="text", value="Quit")
|
|
58
59
|
```
|
|
59
60
|
|
|
60
|
-
For nested theme overrides, use `summer_set_resource_property` if the property
|
|
61
|
+
For nested theme overrides, use `summer_set_resource_property` if the property
|
|
62
|
+
is on a resource. For `theme_override_constants/margin_left`, inspect the live
|
|
63
|
+
node or the upstream API reference matching the current Summer technical base.
|
|
64
|
+
Some constants use `add_theme_constant_override`.
|
|
61
65
|
|
|
62
66
|
## HUD (Health Bar)
|
|
63
67
|
|
|
64
68
|
```
|
|
65
69
|
summer_add_node(parent="./", type="CanvasLayer", name="HUD")
|
|
66
70
|
summer_add_node(parent="./HUD", type="MarginContainer", name="TopLeft")
|
|
67
|
-
summer_set_prop(path="./HUD/TopLeft", key="anchors_preset", value="
|
|
71
|
+
summer_set_prop(path="./HUD/TopLeft", key="anchors_preset", value="0") # Top-left is 0; 1 is Top-right
|
|
68
72
|
summer_add_node(parent="./HUD/TopLeft", type="HBoxContainer", name="HealthContainer")
|
|
69
73
|
summer_add_node(parent="./HUD/TopLeft/HealthContainer", type="Label", name="HealthLabel")
|
|
70
74
|
summer_set_prop(path="./HUD/TopLeft/HealthContainer/HealthLabel", key="text", value="Health:")
|
|
@@ -78,7 +82,7 @@ ProgressBar uses `value` and `max_value` for the fill. Update `value` from a scr
|
|
|
78
82
|
|
|
79
83
|
## Anchors Preset
|
|
80
84
|
|
|
81
|
-
Common preset values
|
|
85
|
+
Common preset values in the current Summer Engine UI API:
|
|
82
86
|
|
|
83
87
|
| Preset | Value | Description |
|
|
84
88
|
|--------|-------|-------------|
|
|
@@ -95,9 +99,14 @@ Set via `summer_set_prop(path, key="anchors_preset", value="15")`.
|
|
|
95
99
|
Wire the `pressed` signal to a handler:
|
|
96
100
|
|
|
97
101
|
```
|
|
98
|
-
summer_connect_signal(emitter="./MainMenu/Margin/VBox/StartButton", signal="pressed", receiver="./MainMenu", method="_on_start_pressed")
|
|
102
|
+
summer_connect_signal(scenePath="res://main.tscn", emitter="./MainMenu/Margin/VBox/StartButton", signal="pressed", receiver="./MainMenu", method="_on_start_pressed")
|
|
99
103
|
```
|
|
100
104
|
|
|
105
|
+
`scenePath` is required on every scene-mutating tool in this skill
|
|
106
|
+
(`summer_add_node`, `summer_set_prop`, `summer_connect_signal`,
|
|
107
|
+
`summer_save_scene`). The examples above omit it only for readability — a real
|
|
108
|
+
call without it is rejected before it reaches the engine.
|
|
109
|
+
|
|
101
110
|
The receiver node must have a script with `func _on_start_pressed() -> void:`.
|
|
102
111
|
|
|
103
112
|
## Property Reference
|
|
@@ -147,4 +156,4 @@ text = "Start Game"
|
|
|
147
156
|
|
|
148
157
|
## Collaborative protocol
|
|
149
158
|
|
|
150
|
-
This skill writes UI scene nodes and wires button signals. Always ask before applying: "May I add the MainMenu (Control + Margin + VBox + Title + Start/Quit buttons) and connect Start.pressed to `_on_start_pressed`?".
|
|
159
|
+
This skill writes UI scene nodes and wires button signals. Always ask before applying: "May I add the MainMenu (Control + Margin + VBox + Title + Start/Quit buttons) and connect Start.pressed to `_on_start_pressed`?".
|
|
@@ -5,13 +5,15 @@ license: MIT
|
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: video
|
|
7
7
|
user-invocable: true
|
|
8
|
-
allowed-tools: Read Grep Glob Write Edit summer_generate_video summer_generate_image summer_search_assets summer_import_from_url summer_add_node summer_set_prop
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_generate_video summer_check_job summer_generate_image summer_search_assets summer_import_from_url summer_add_node summer_set_prop
|
|
9
9
|
paths: ["assets/video/**", "menus/**", "ui/**"]
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
# animated-loop —
|
|
12
|
+
# animated-loop — 5 Second Seamless Background Loop
|
|
13
13
|
|
|
14
|
-
A loop is the only video format that has to *not have* a beginning or end. The viewer sees it on the title screen for 30 seconds; if the seam between loop iterations is visible, the whole thing reads as broken. This skill exists to force the constraints that make seams invisible:
|
|
14
|
+
A loop is the only video format that has to *not have* a beginning or end. The viewer sees it on the title screen for 30 seconds; if the seam between loop iterations is visible, the whole thing reads as broken. This skill exists to force the constraints that make seams invisible: take the shortest duration available, keep the motion ambient (no narrative, no big camera moves), use the cheap fast model (`ltx`), and prompt for a composition where the first and last frames are functionally identical.
|
|
15
|
+
|
|
16
|
+
**Duration is not a dial here.** `summer_generate_video` accepts only `duration=5` or `duration=10`; the server coerces every other value to 5. So "drop to 3s to hide the seam" is not an option — 5s is the floor, and the seam has to be won in the prompt and the reference frame instead.
|
|
15
17
|
|
|
16
18
|
If the user wants a 5s punchy marketing shot, that's `video/trailer-shot`. If they want a 10s narrative cutscene, that's `video/cinematic-cutscene`. This skill is the one for video that has to *disappear* — atmosphere behind a logo, mood behind a menu, ambience behind a splash card.
|
|
17
19
|
|
|
@@ -30,13 +32,13 @@ If the user wants a 5s punchy marketing shot, that's `video/trailer-shot`. If th
|
|
|
30
32
|
- Narrative cutscene with a beginning and end — `video/cinematic-cutscene`.
|
|
31
33
|
- Static splash image — generate with `2d-assets/concept-art` and use a `TextureRect`. A still is cheaper, lighter, and never seams.
|
|
32
34
|
- UI element animation (icons, button states) — those are GDScript `Tween` or sprite sheets, not video.
|
|
33
|
-
- A 10-second shot you want to "loop". That seam will be visible. Either accept a hard cut every 10s (ugly) or generate a
|
|
35
|
+
- A 10-second shot you want to "loop". That seam will be visible. Either accept a hard cut every 10s (ugly) or generate a 5s clip designed to loop.
|
|
34
36
|
|
|
35
37
|
## Steps
|
|
36
38
|
|
|
37
39
|
### 1. Confirm the loop will be visible for a long time
|
|
38
40
|
|
|
39
|
-
> Quick check — this loop will play on a screen the user might stare at for 30+ seconds. That means the loop point must be invisible. I'll
|
|
41
|
+
> Quick check — this loop will play on a screen the user might stare at for 30+ seconds. That means the loop point must be invisible. I'll take the 5s minimum and prompt for ambient motion (drift, flicker, shimmer) rather than a narrative beat. OK?
|
|
40
42
|
|
|
41
43
|
If the user wants narrative motion (a character walking, a door opening), this is the wrong skill — route to `video/cinematic-cutscene`.
|
|
42
44
|
|
|
@@ -44,13 +46,15 @@ If the user wants narrative motion (a character walking, a door opening), this i
|
|
|
44
46
|
|
|
45
47
|
For loops, `ltx` is correct ~95% of the time. It's $0.10, ~30s, and the constraints (short duration, ambient motion) are exactly the ones `ltx` handles best. Premium models add cost without adding loop quality.
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
|
50
|
-
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `minimax` |
|
|
49
|
+
This skill always passes `imageUrl` (step 3), which puts every call on the image-to-video route — and that route accepts only `ltx`, `kling`, and `minimax`. `kling-turbo` and `veo3` are text-to-video only; pairing either with an `imageUrl` is a 400 `invalid_model`, not a silent downgrade.
|
|
50
|
+
|
|
51
|
+
| Model | i2v? | Cost | Speed | When |
|
|
52
|
+
|---|---|---|---|---|
|
|
53
|
+
| `ltx` | yes | $0.10 | ~30s | Default. Use this. |
|
|
54
|
+
| `kling` | yes | $0.50 | 2-4 min | Only if the loop is the centerpiece of a premium splash and quality is visibly lacking on `ltx` |
|
|
55
|
+
| `minimax` | yes | $0.25 | 2-3 min | Stylized / anime aesthetic loops |
|
|
56
|
+
| `kling-turbo` | **no** | $0.30 | 1-2 min | Not reachable from this skill — text-to-video only |
|
|
57
|
+
| `veo3` | **no** | $1.00 | 3-5 min | Not reachable from this skill, and pointless for ambient loops anyway |
|
|
54
58
|
|
|
55
59
|
### 3. Lock the look with a reference still
|
|
56
60
|
|
|
@@ -58,13 +62,14 @@ The reference still doubles as the *target* loop frame. Generate it deliberately
|
|
|
58
62
|
|
|
59
63
|
```
|
|
60
64
|
summer_generate_image(
|
|
61
|
-
prompt="<subject>, ambient atmospheric scene, cinematic lighting, painterly, balanced composition with no clear focal action",
|
|
62
|
-
model="nano-banana-2"
|
|
63
|
-
options={ image_size: "landscape_16_9" }
|
|
65
|
+
prompt="<subject>, ambient atmospheric scene, cinematic lighting, painterly, wide 16:9 framing, balanced composition with no clear focal action",
|
|
66
|
+
model="nano-banana-2"
|
|
64
67
|
)
|
|
65
68
|
```
|
|
66
69
|
|
|
67
|
-
|
|
70
|
+
`summer_generate_image` has no size or aspect argument — `options.image_size` is dropped without an error and every MCP image comes back at the server's 1:1 default. Ask for the framing in the prompt, or generate the reference in the Summer dashboard (which exposes aspect ratio) and pass its URL.
|
|
71
|
+
|
|
72
|
+
This matters more than usual here: on the image-to-video route `aspectRatio` is **not applied at all** — the clip inherits the reference image's framing. So a vertical mobile splash needs a genuinely 9:16 reference image, and setting `aspectRatio="9:16"` on the video call does nothing.
|
|
68
73
|
|
|
69
74
|
### 4. Prompt for loopable motion only
|
|
70
75
|
|
|
@@ -79,13 +84,16 @@ summer_generate_video(
|
|
|
79
84
|
prompt="<subject from reference>, <ambient loopable motion>, slow continuous, looping, seamless, cinematic",
|
|
80
85
|
model="ltx",
|
|
81
86
|
imageUrl="<reference URL from step 3>",
|
|
82
|
-
duration=
|
|
83
|
-
aspectRatio="16:9",
|
|
87
|
+
duration=5,
|
|
84
88
|
options={ negative_prompt: "sudden movement, character action, narrative event, fade to black" }
|
|
85
89
|
)
|
|
86
90
|
```
|
|
87
91
|
|
|
88
|
-
The phrase **"looping, seamless"** in the prompt biases the model toward stable first/last frames.
|
|
92
|
+
The phrase **"looping, seamless"** in the prompt biases the model toward stable first/last frames. `options.negative_prompt` is one of the few provider keys that does pass through on the video route (`prompt`, `image_url`, `num_frames`, `duration`, `resolution`, and `model` are stripped; everything else is forwarded), so the negative genuinely rules out narrative drift here — unlike on `summer_generate_image`, where no such argument exists.
|
|
93
|
+
|
|
94
|
+
`aspectRatio` is omitted deliberately: it is applied on the text-to-video path only, and this call passes `imageUrl`.
|
|
95
|
+
|
|
96
|
+
The call returns `{ success, queued: true, jobId, ... }` and **no URL** — video generation is asynchronous. Poll `summer_check_job(jobId="<jobId>")` until it reports `completed`, and only then treat the clip as existing.
|
|
89
97
|
|
|
90
98
|
### 5. Inspect the seam
|
|
91
99
|
|
|
@@ -93,25 +101,40 @@ Watch the result and the seam (the cut between the last and first frame on repla
|
|
|
93
101
|
|
|
94
102
|
- **Most common cause:** something moved across the frame and didn't return (a particle drifted off-screen, a cloud moved). Regenerate with `slow continuous, returning motion, oscillating` in the prompt.
|
|
95
103
|
- **Second cause:** lighting drifted. Regenerate with `constant lighting, no time of day change`.
|
|
96
|
-
- **Third cause:** the
|
|
104
|
+
- **Third cause:** the motion is simply too fast to close in the time available. You cannot shorten the clip — 5s is the minimum the API offers — so slow the motion in the prompt instead (`very slow`, `barely perceptible drift`).
|
|
97
105
|
|
|
98
106
|
If three regenerations don't seam-close, accept a small crossfade in the engine: set up two `VideoStreamPlayer` nodes and crossfade between them via a `Tween`. This is a fallback, not the goal.
|
|
99
107
|
|
|
100
108
|
### 6. Import and wire as a looping VideoStreamPlayer
|
|
101
109
|
|
|
110
|
+
**Transcode to Ogg Theora first.** The generated clip is an `.mp4`, and Summer Engine cannot load `.mp4`. `.ogv` is the only video container in the build — there is no bundled WebM or MP4 plugin, and nothing transcodes on your behalf. Measured against the shipped binary (4.6.1):
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
$ Summer --headless --path <proj> -s res://probe.gd
|
|
114
|
+
VideoStream exts: ["ogv", "tres", "res"]
|
|
115
|
+
ERROR: No loader found for resource: res://clip.mp4 (expected type: unknown)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
`summer_import_from_url` downloads the bytes, runs Godot's import pipeline, and *fails the import* if the file never becomes a loadable resource — so importing the `.mp4` does not quietly half-work, it is rejected and rolled back. Convert first:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
ffmpeg -i title_screen_bg.mp4 -c:v libtheora -q:v 8 -an title_screen_bg.ogv
|
|
122
|
+
```
|
|
123
|
+
|
|
102
124
|
```
|
|
103
|
-
summer_import_from_url(url="<
|
|
125
|
+
summer_import_from_url(url="<hosted .ogv url>", path="res://assets/video/loops/title_screen_bg.ogv")
|
|
104
126
|
```
|
|
105
127
|
|
|
106
|
-
|
|
128
|
+
Then wire it. Every scene-mutating tool takes an explicit `scenePath`, and `summer_set_prop`'s property argument is named `key`, not `property`:
|
|
107
129
|
|
|
108
130
|
```
|
|
109
|
-
summer_add_node(parent="
|
|
110
|
-
summer_set_prop(path="./
|
|
111
|
-
summer_set_prop(path="./
|
|
112
|
-
summer_set_prop(path="./
|
|
113
|
-
summer_set_prop(path="./
|
|
114
|
-
summer_set_prop(path="./
|
|
131
|
+
summer_add_node(scenePath="res://ui/title_screen.tscn", parent=".", type="VideoStreamPlayer", name="BackgroundLoop")
|
|
132
|
+
summer_set_prop(scenePath="res://ui/title_screen.tscn", path="./BackgroundLoop", key="stream", value="res://assets/video/loops/title_screen_bg.ogv")
|
|
133
|
+
summer_set_prop(scenePath="res://ui/title_screen.tscn", path="./BackgroundLoop", key="autoplay", value=true)
|
|
134
|
+
summer_set_prop(scenePath="res://ui/title_screen.tscn", path="./BackgroundLoop", key="loop", value=true)
|
|
135
|
+
summer_set_prop(scenePath="res://ui/title_screen.tscn", path="./BackgroundLoop", key="expand", value=true)
|
|
136
|
+
summer_set_prop(scenePath="res://ui/title_screen.tscn", path="./BackgroundLoop", key="anchors_preset", value=15)
|
|
137
|
+
summer_save_scene(scenePath="res://ui/title_screen.tscn")
|
|
115
138
|
```
|
|
116
139
|
|
|
117
140
|
Anchors preset 15 is "full rect" — the loop fills the menu. Place the logo and menu buttons as children *above* the `VideoStreamPlayer` in the tree (Godot draws siblings in tree order; later siblings render on top).
|
|
@@ -121,7 +144,7 @@ Anchors preset 15 is "full rect" — the loop fills the menu. Place the logo and
|
|
|
121
144
|
Loops should never have a baked audio track that loops with them — the audio seam will be even more obvious than the visual one. The video models don't generate audio anyway, but if you ever import a clip that has audio, mute it:
|
|
122
145
|
|
|
123
146
|
```
|
|
124
|
-
summer_set_prop(path="./
|
|
147
|
+
summer_set_prop(scenePath="res://ui/title_screen.tscn", path="./BackgroundLoop", key="volume_db", value=-80)
|
|
125
148
|
```
|
|
126
149
|
|
|
127
150
|
Score the menu separately with `audio/music-track`.
|
|
@@ -132,13 +155,13 @@ Pattern: `<subject> + <ambient loopable motion> + <constant lighting> + "looping
|
|
|
132
155
|
|
|
133
156
|
| Goal | Model | Prompt | Cost | Duration |
|
|
134
157
|
|---|---|---|---|---|
|
|
135
|
-
| Title menu — fog forest | `ltx` | `dense pine forest in low fog, fog drifting slowly between trunks, soft moonlight, ambient particles rising, looping, seamless, cinematic painterly` | $0.10 |
|
|
136
|
-
| Title menu — dungeon torch | `ltx` | `stone dungeon corridor lit by a single torch, flame flickering steadily, dust motes drifting in the light cone, looping, seamless` | $0.10 |
|
|
158
|
+
| Title menu — fog forest | `ltx` | `dense pine forest in low fog, fog drifting slowly between trunks, soft moonlight, ambient particles rising, looping, seamless, cinematic painterly` | $0.10 | 5s |
|
|
159
|
+
| Title menu — dungeon torch | `ltx` | `stone dungeon corridor lit by a single torch, flame flickering steadily, dust motes drifting in the light cone, looping, seamless` | $0.10 | 5s |
|
|
137
160
|
| Splash — embers / sky | `ltx` | `dusk sky with slow drifting embers rising upward across frame, deep blue gradient, looping, seamless, cinematic` | $0.10 | 5s |
|
|
138
|
-
| Logo backdrop — magic runes | `ltx` | `dark surface with glowing blue runes pulsing softly in slow rhythm, faint shimmer, no narrative motion, looping, seamless` | $0.10 |
|
|
161
|
+
| Logo backdrop — magic runes | `ltx` | `dark surface with glowing blue runes pulsing softly in slow rhythm, faint shimmer, no narrative motion, looping, seamless` | $0.10 | 5s |
|
|
139
162
|
| Menu — underwater | `ltx` | `underwater scene with caustic light dancing on a sandy floor, slow drifting bubbles, gentle current sway on kelp, looping, seamless` | $0.10 | 5s |
|
|
140
|
-
| Pause screen — slow rain | `ltx` | `window pane with continuous gentle rain drops, blurred warm interior glow behind, looping, seamless, ambient` | $0.10 |
|
|
141
|
-
| Title — anime sky | `minimax` | `anime style cumulus clouds drifting slowly across a pastel sunset sky, soft, painterly, looping, seamless, Ghibli` | $0.
|
|
163
|
+
| Pause screen — slow rain | `ltx` | `window pane with continuous gentle rain drops, blurred warm interior glow behind, looping, seamless, ambient` | $0.10 | 5s |
|
|
164
|
+
| Title — anime sky | `minimax` | `anime style cumulus clouds drifting slowly across a pastel sunset sky, soft, painterly, looping, seamless, Ghibli` | $0.25 | 5s |
|
|
142
165
|
| Premium splash centerpiece | `kling` | `dragon silhouette breathing in profile against a vast sunset sky, only the chest rising and falling and clouds drifting, looping, seamless` | $0.50 | 5s |
|
|
143
166
|
|
|
144
167
|
### Bad prompts and why
|
|
@@ -153,18 +176,19 @@ Pattern: `<subject> + <ambient loopable motion> + <constant lighting> + "looping
|
|
|
153
176
|
|
|
154
177
|
## Anti-patterns
|
|
155
178
|
|
|
156
|
-
- **Asking the model for a 10s loop.** Past ~6s, identity drifts and the seam shows.
|
|
179
|
+
- **Asking the model for a 10s loop.** Past ~6s, identity drifts and the seam shows. `duration=5` is both the floor and the right answer; 10 is the only other value the API accepts.
|
|
180
|
+
- **Treating `summer_generate_video` as synchronous.** It returns `{ queued: true, jobId }` and no URL. Poll `summer_check_job` before claiming a clip exists.
|
|
157
181
|
- **Spending `kling` money on a loop.** `ltx` is the right call ~95% of the time. The constraints favor the cheap model.
|
|
158
182
|
- **Prompting narrative motion.** "Hero draws sword" doesn't loop. Use ambient verbs.
|
|
159
183
|
- **Forgetting `loop=true` on the `VideoStreamPlayer`.** The clip will play once and freeze on the last frame.
|
|
160
184
|
- **Forgetting to mute baked audio.** If audio is on, the loop point becomes audible even if it's invisible.
|
|
161
|
-
- **
|
|
162
|
-
- **Importing
|
|
185
|
+
- **Expecting `aspectRatio` to reframe an image-to-video call.** It is applied on the text-to-video path only. A portrait splash needs a portrait *reference image* — the argument does nothing here.
|
|
186
|
+
- **Importing the `.mp4` as-is.** `.ogv` is the only video container the engine can load; there is no bundled WebM or MP4 plugin. An un-transcoded import fails and is rolled back.
|
|
163
187
|
|
|
164
188
|
## Edge cases
|
|
165
189
|
|
|
166
190
|
- **Splash loop must be tiny in build size.** Loops compress aggressively because of low motion. Target ≤2MB by exporting at 720p, low bitrate, in DaVinci. Studio's import doesn't re-encode by default.
|
|
167
|
-
- **Mobile portrait splash.**
|
|
191
|
+
- **Mobile portrait splash.** The reference image must genuinely be portrait — `aspectRatio` is ignored on the image-to-video path, and MCP image generation is square-only, so make the reference in the Summer dashboard or crop it. Anchors preset 15 still works.
|
|
168
192
|
- **Loop must sync to a music beat.** The video model doesn't know your BPM. Generate at the duration matching one bar at the menu music tempo (e.g. 120 BPM × 4 beats = 2s, or 8 beats = 4s) and confirm visually.
|
|
169
193
|
- **Loop is behind translucent UI.** Generate with extra contrast headroom — the model tends toward mid-grey, and translucent UI on mid-grey reads muddy. Push for `high contrast cinematic` in the prompt.
|
|
170
194
|
- **Loop seam still visible after 3 regens.** Set up two `VideoStreamPlayer` siblings and crossfade between them with a `Tween` on a 0.5s overlap. Costs an extra GPU decode but hides the seam.
|
|
@@ -197,4 +221,4 @@ Once the loop is wired:
|
|
|
197
221
|
- `audio/music-track` — score the menu.
|
|
198
222
|
- `2d-assets/ui-graphics` — logo, menu buttons, HUD that sits over the loop.
|
|
199
223
|
- `2d-assets/concept-art` — produce the reference still that anchors the loop.
|
|
200
|
-
-
|
|
224
|
+
- `../../../references/mcp-tools-reference.md` — `summer_generate_video` parameter schema and error codes.
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: video
|
|
7
7
|
user-invocable: true
|
|
8
|
-
allowed-tools: Read Grep Glob Write Edit summer_generate_video summer_generate_image summer_generate_audio summer_search_assets summer_import_from_url summer_add_node summer_set_prop
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_generate_video summer_check_job summer_generate_image summer_generate_audio summer_search_assets summer_import_from_url summer_add_node summer_set_prop
|
|
9
9
|
paths: ["assets/video/**", "cinematics/**", "trailers/**"]
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -38,10 +38,11 @@ If the user wants 5 seconds of marketing footage, that's `video/trailer-shot`. I
|
|
|
38
38
|
|
|
39
39
|
```
|
|
40
40
|
Read .summer/GameSoul.md
|
|
41
|
-
summer_search_assets(query="
|
|
42
|
-
summer_search_assets(query="<character name> reference", filter={ kind: "image" })
|
|
41
|
+
summer_search_assets(query="<character name> reference", assetType="2d_image", source="all")
|
|
43
42
|
```
|
|
44
43
|
|
|
44
|
+
`summer_search_assets` has no video filter — `assetType` is one of `2d_image`, `animation`, `3d_model`, `audio`, `music`, `all`, and there is no video member. To find prior cutscene clips, list your own assets with `summer_list_my_assets(query="cutscene")` and read the titles.
|
|
45
|
+
|
|
45
46
|
If a reference image of the character already exists from a prior `concept-art` or `character-portrait` run, **reuse it** as the `imageUrl` — that single decision is the difference between the character looking like themselves and looking like a stranger.
|
|
46
47
|
|
|
47
48
|
### 2. Plan the shot list
|
|
@@ -58,25 +59,28 @@ For any character or hero scene, generate a reference still with `summer_generat
|
|
|
58
59
|
|
|
59
60
|
```
|
|
60
61
|
summer_generate_image(
|
|
61
|
-
prompt="<subject>, <setting>, cinematic lighting, film still, <art style from GameSoul.md>",
|
|
62
|
-
model="nano-banana-2"
|
|
63
|
-
options={ image_size: "landscape_16_9" }
|
|
62
|
+
prompt="<subject>, <setting>, cinematic lighting, film still, wide 16:9 framing, <art style from GameSoul.md>",
|
|
63
|
+
model="nano-banana-2"
|
|
64
64
|
)
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
`summer_generate_image` has no size or aspect argument — `options.image_size` is dropped without an error and every MCP image comes back at the server's 1:1 default. Ask for the framing in the prompt, or generate the reference in the Summer dashboard (which exposes aspect ratio) and pass its URL. For image-to-video this matters more than usual: the clip's framing is inherited from the reference, so a square reference gives you a square cutscene.
|
|
68
|
+
|
|
67
69
|
Show the user the still and confirm it's the right look before video-ing it. Regenerating a $0.05 still beats regenerating a $0.50 video.
|
|
68
70
|
|
|
69
71
|
### 4. Pick the model
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
|---|---|---|---|
|
|
73
|
-
| `ltx` | ~$0.10 | ~30s | Iteration, blocking shots, B-roll, throwaway tests |
|
|
74
|
-
| `kling` | ~$0.50 | 2-4 min | Hero shots, character cutscenes, anything the player will sit and watch |
|
|
75
|
-
| `kling-turbo` | ~$0.30 | 1-2 min | Same as kling when iteration speed matters more than the last 10% of quality |
|
|
76
|
-
| `veo3` | ~$1.00 | 3-5 min | Pitch decks, premium dialogue scenes with synced lip motion, short-form ad |
|
|
77
|
-
| `minimax` | ~$0.40 | 2-3 min | Stylized / anime-leaning content; better at non-photoreal looks than kling |
|
|
73
|
+
**This skill always passes `imageUrl`, which puts every call on the image-to-video route — and that route only accepts three models.** `kling-turbo` and `veo3` are text-to-video only; asking for either with an `imageUrl` set is a 400 `invalid_model`, not a silent downgrade.
|
|
78
74
|
|
|
79
|
-
|
|
75
|
+
| Model | i2v? | Cost | Speed | When |
|
|
76
|
+
|---|---|---|---|---|
|
|
77
|
+
| `ltx` | yes | $0.10 | ~30s | Iteration, blocking shots, B-roll, throwaway tests |
|
|
78
|
+
| `kling` | yes | $0.50 | 2-4 min | Hero shots, character cutscenes, anything the player will sit and watch |
|
|
79
|
+
| `minimax` | yes | $0.25 | 2-3 min | Stylized / anime-leaning content; better at non-photoreal looks than kling |
|
|
80
|
+
| `kling-turbo` | **no** | $0.30 | 1-2 min | Text-to-video only — usable only if you drop the reference image |
|
|
81
|
+
| `veo3` | **no** | $1.00 | 3-5 min | Text-to-video only — usable only if you drop the reference image |
|
|
82
|
+
|
|
83
|
+
Default policy: **`ltx` first** to validate the prompt and shot framing. If it lands the composition but quality is rough, escalate to `kling`. `veo3` is a real tradeoff, not an upgrade: reaching for it means giving up `imageUrl`, which is the one thing that holds character identity across shots. Take that trade only when on-camera lip-sync matters more than continuity, and only with the user's approval on cost.
|
|
80
84
|
|
|
81
85
|
### 5. Generate each shot
|
|
82
86
|
|
|
@@ -90,7 +94,19 @@ summer_generate_video(
|
|
|
90
94
|
)
|
|
91
95
|
```
|
|
92
96
|
|
|
93
|
-
|
|
97
|
+
`duration` accepts **only 5 or 10** — the server coerces anything else to 5. There is no 3s, 4s, 7s or 8s clip.
|
|
98
|
+
|
|
99
|
+
Video generation is **asynchronous**. The call returns immediately with `{ success, queued: true, jobId, model, resolvedModel, estimatedCost, duration }` and **no `fileUrl`** — the clip is rendered by a background worker. Poll for it:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
summer_check_job(jobId="<jobId from the generate call>")
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Only once the job reports `completed` do you have an asset and a URL. Do not tell the user a shot is done off the back of the generate call — at that moment nothing has rendered yet.
|
|
106
|
+
|
|
107
|
+
`aspectRatio` is applied on the text-to-video path only; on image-to-video the framing comes from the reference image, so a `9:16` cutscene needs a `9:16` reference, not a `9:16` argument.
|
|
108
|
+
|
|
109
|
+
When the job completes, show the user the URL and ask:
|
|
94
110
|
|
|
95
111
|
> Shot 1 of 3 done. Land or regenerate? If land, I'll move to shot 2.
|
|
96
112
|
|
|
@@ -110,20 +126,37 @@ Lip-sync caveat: if the video shows the character clearly mouthing words and the
|
|
|
110
126
|
|
|
111
127
|
### 7. Import and wire as a VideoStreamPlayer
|
|
112
128
|
|
|
129
|
+
**Transcode to Ogg Theora first.** The generated clip is an `.mp4`, and Summer Engine cannot load `.mp4` — the only video container in the build is `.ogv`. Measured against the shipped binary (4.6.1):
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
$ Summer --headless --path <proj> -s res://probe.gd
|
|
133
|
+
VideoStream exts: ["ogv", "tres", "res"]
|
|
134
|
+
ERROR: No loader found for resource: res://clip.mp4 (expected type: unknown)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Nothing transcodes for you — `summer_import_from_url` downloads the bytes, runs Godot's import pipeline, and *fails the import* if the file never becomes a loadable resource. Convert with ffmpeg or DaVinci before importing:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
ffmpeg -i intro_shot_01.mp4 -c:v libtheora -q:v 8 -an intro_shot_01.ogv
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Then:
|
|
144
|
+
|
|
113
145
|
```
|
|
114
|
-
summer_import_from_url(url="<
|
|
146
|
+
summer_import_from_url(url="<hosted .ogv url>", path="res://assets/video/cinematics/intro_shot_01.ogv")
|
|
115
147
|
```
|
|
116
148
|
|
|
117
|
-
Build a controller scene at `cinematics/Intro.tscn`:
|
|
149
|
+
Build a controller scene at `res://cinematics/Intro.tscn`. Every scene-mutating tool takes an explicit `scenePath`, and `summer_set_prop`'s property argument is named `key`, not `property`:
|
|
118
150
|
|
|
119
151
|
```
|
|
120
|
-
|
|
121
|
-
summer_add_node(
|
|
122
|
-
summer_add_node(
|
|
123
|
-
summer_set_prop(path="./
|
|
124
|
-
summer_set_prop(path="./
|
|
125
|
-
summer_set_prop(path="./
|
|
126
|
-
summer_set_prop(path="./
|
|
152
|
+
summer_create_scene(path="res://cinematics/Intro.tscn", rootName="Intro", allow_temporary_scene_mutation=true)
|
|
153
|
+
summer_add_node(scenePath="res://cinematics/Intro.tscn", parent=".", type="ColorRect", name="Fade") # black, alpha 1.0 → 0.0
|
|
154
|
+
summer_add_node(scenePath="res://cinematics/Intro.tscn", parent=".", type="VideoStreamPlayer", name="Video")
|
|
155
|
+
summer_set_prop(scenePath="res://cinematics/Intro.tscn", path="./Video", key="stream", value="res://assets/video/cinematics/intro_shot_01.ogv")
|
|
156
|
+
summer_set_prop(scenePath="res://cinematics/Intro.tscn", path="./Video", key="autoplay", value=true)
|
|
157
|
+
summer_set_prop(scenePath="res://cinematics/Intro.tscn", path="./Video", key="expand", value=true)
|
|
158
|
+
summer_set_prop(scenePath="res://cinematics/Intro.tscn", path="./Fade", key="anchors_preset", value=15)
|
|
159
|
+
summer_save_scene(scenePath="res://cinematics/Intro.tscn")
|
|
127
160
|
```
|
|
128
161
|
|
|
129
162
|
Attach a `Tween` script that fades the `ColorRect` from black to clear over 0.5s on `_ready`, then back to black when `Video.finished` fires, then `queue_free()`s the scene. For multi-shot cutscenes, queue the next `VideoStreamPlayer` in the `finished` signal handler.
|
|
@@ -139,11 +172,11 @@ Pattern: `<subject> + <action> + <camera move> + <lighting> + <stylistic anchor>
|
|
|
139
172
|
| Opening establishing shot | `kling` | `wide shot of a fog-shrouded medieval village at dawn, slow dolly-in toward the church spire, warm low sun, cinematic, anamorphic lens flare` | $0.50 | 5s |
|
|
140
173
|
| Character intro (hero turns to camera) | `kling` | `young witch with raven on shoulder turns slowly toward camera, candlelit interior, shallow depth of field, cinematic film still` | $0.50 | 5s |
|
|
141
174
|
| Dialogue close-up (no synced lips) | `kling` | `close-up of a grizzled knight, eyes downcast then looking up, firelight on his face, dust motes, 16mm film grain` | $0.50 | 5s |
|
|
142
|
-
| Dialogue close-up (synced lips) | `veo3` | `close-up of the witch saying "they will come for you at dawn", candlelight, cinematic, shallow DOF` | $1.00 | 5s |
|
|
175
|
+
| Dialogue close-up (synced lips) | `veo3` — text-to-video only, drop `imageUrl` | `close-up of the witch saying "they will come for you at dawn", candlelight, cinematic, shallow DOF` | $1.00 | 5s |
|
|
143
176
|
| Action beat (village burns) | `kling` | `medium wide of a thatched village engulfed in flames at night, embers rising, silhouettes running through smoke, hand-held camera, cinematic` | $0.50 | 5s |
|
|
144
177
|
| Ending shot (hero walks away) | `kling` | `low wide shot of a cloaked figure walking away across a blasted plain at sunset, slow truck-back, golden hour, dust on the wind` | $0.50 | 5s |
|
|
145
178
|
| Throwaway iteration / blocking | `ltx` | same prompt as above | $0.10 | 5s |
|
|
146
|
-
| Anime / stylized cutscene | `minimax` | `anime-style young swordsman draws blade and steps forward, sakura petals, dramatic wind, Studio Ghibli soft painterly` | $0.
|
|
179
|
+
| Anime / stylized cutscene | `minimax` | `anime-style young swordsman draws blade and steps forward, sakura petals, dramatic wind, Studio Ghibli soft painterly` | $0.25 | 5s |
|
|
147
180
|
|
|
148
181
|
### Bad prompts and why
|
|
149
182
|
|
|
@@ -162,11 +195,14 @@ Pattern: `<subject> + <action> + <camera move> + <lighting> + <stylistic anchor>
|
|
|
162
195
|
- **Asking the video model to render dialogue without `veo3`.** `kling` and `ltx` will animate mouths but the motion does not match any audio. Use `veo3` if dialogue is on-camera, or keep the camera off the speaker.
|
|
163
196
|
- **Using `kling` for blocking iterations.** Burn $0.10 on `ltx` to validate framing and prompt; only spend $0.50 once the composition lands.
|
|
164
197
|
- **Putting the cutscene on a `VideoStreamPlayer` without a fade.** Cuts straight from gameplay to video are jarring. Always wrap in a `ColorRect` fade in/out.
|
|
165
|
-
- **
|
|
198
|
+
- **Treating `summer_generate_video` as synchronous.** It returns `{ queued: true, jobId }` and no URL. You must poll `summer_check_job` before there is anything to show or import.
|
|
199
|
+
- **Importing the `.mp4` as-is.** The engine has no MP4 or WebM loader — only Ogg Theora (`.ogv`). Transcode first; an un-transcoded import fails and is rolled back.
|
|
200
|
+
- **Asking for `duration=3` or `duration=8`.** Only 5 and 10 exist; anything else is silently coerced to 5.
|
|
201
|
+
- **Pairing `imageUrl` with `kling-turbo` or `veo3`.** Neither has an image-to-video endpoint — that combination is a 400.
|
|
166
202
|
|
|
167
203
|
## Edge cases
|
|
168
204
|
|
|
169
|
-
- **Vertical cutscene for a mobile target.**
|
|
205
|
+
- **Vertical cutscene for a mobile target.** On the image-to-video path `aspectRatio` is not applied at all — the clip inherits the reference image's framing. So the reference *must* be 9:16, and MCP image generation cannot produce that: make it in the Summer dashboard, or crop a square generation to 9:16, then pass its URL as `imageUrl`.
|
|
170
206
|
- **Cutscene must match an in-engine character precisely.** No video model will hit pixel-perfect identity. Either (a) accept the artistic license, (b) render the cutscene in-engine with `AnimationPlayer` instead of generating it, or (c) generate a reference image *from* a screenshot of the in-engine character (image-to-image first, then image-to-video).
|
|
171
207
|
- **Dialogue is too long for a 5s shot.** Either trim the line, or split: 5s of speaker, 5s of listener reaction (cheaper because the listener doesn't need synced lips).
|
|
172
208
|
- **Cutscene needs to play and the player isn't looking.** Pause the gameplay timer, push a `Control` overlay with the `VideoStreamPlayer`, restore on finish.
|
|
@@ -179,7 +215,7 @@ If the Studio MCP server isn't running, the user can do all of this through the
|
|
|
179
215
|
1. Generate a reference image in the Image tab.
|
|
180
216
|
2. Open the Video tab, paste the reference URL into the image-to-video field.
|
|
181
217
|
3. Set model, duration, aspect ratio, and prompt as listed above.
|
|
182
|
-
4. Download the `.mp4` and drop
|
|
218
|
+
4. Download the `.mp4`, transcode it to Ogg Theora (`ffmpeg -i in.mp4 -c:v libtheora -q:v 8 -an out.ogv`), and drop the `.ogv` into `assets/video/cinematics/`. Summer Engine has no MP4 or WebM loader — `.ogv` is the only video container it can open.
|
|
183
219
|
|
|
184
220
|
Print the exact prompt + model + duration + aspect ratio so the user can paste it into the dashboard verbatim.
|
|
185
221
|
|
|
@@ -201,4 +237,4 @@ Once the cutscene is generated and wired:
|
|
|
201
237
|
- `audio/music-track` — score the cutscene.
|
|
202
238
|
- `2d-assets/concept-art` — generate the reference image axis if no character reference exists yet.
|
|
203
239
|
- `2d-assets/character-portrait` — produce a high-fidelity locked character portrait for use as `imageUrl`.
|
|
204
|
-
-
|
|
240
|
+
- `../../../references/mcp-tools-reference.md` — `summer_generate_video` parameter schema and error codes.
|
|
@@ -5,7 +5,7 @@ license: MIT
|
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: video
|
|
7
7
|
user-invocable: true
|
|
8
|
-
allowed-tools: Read Grep Glob Write Edit summer_generate_video summer_generate_image summer_search_assets summer_import_from_url summer_add_node summer_set_prop
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_generate_video summer_check_job summer_generate_image summer_search_assets summer_import_from_url summer_add_node summer_set_prop
|
|
9
9
|
paths: ["assets/video/**", "trailers/**", "marketing/**"]
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -56,23 +56,26 @@ For shots featuring a specific character, weapon, or environment, generate a ref
|
|
|
56
56
|
|
|
57
57
|
```
|
|
58
58
|
summer_generate_image(
|
|
59
|
-
prompt="<subject>, <archetype-driven framing>, cinematic, dramatic lighting, film still",
|
|
60
|
-
model="nano-banana-2"
|
|
61
|
-
options={ image_size: "landscape_16_9" }
|
|
59
|
+
prompt="<subject>, <archetype-driven framing>, cinematic, dramatic lighting, film still, wide 16:9 framing",
|
|
60
|
+
model="nano-banana-2"
|
|
62
61
|
)
|
|
63
62
|
```
|
|
64
63
|
|
|
65
|
-
|
|
64
|
+
`summer_generate_image` has no size or aspect argument — `options.image_size` is dropped without an error and every MCP image comes back at the server's 1:1 default. Ask for the framing in the prompt, or build the reference in the Summer dashboard (which exposes aspect ratio) and pass its URL. Since image-to-video inherits the reference's framing, a square reference gives you a square trailer shot.
|
|
65
|
+
|
|
66
|
+
For pure environment / abstract / VFX shots, you can skip this and prompt text-to-video directly — that also unlocks `aspectRatio`, `kling-turbo`, and `veo3`.
|
|
66
67
|
|
|
67
68
|
### 3. Pick the model
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
|
72
|
-
|
|
73
|
-
| `
|
|
74
|
-
| `ltx` |
|
|
75
|
-
| `minimax` |
|
|
70
|
+
The available models depend on whether you pass `imageUrl`. With a reference image (step 2) the call goes to the image-to-video route, which accepts only `ltx`, `kling`, and `minimax`; `kling-turbo` and `veo3` exist on the text-to-video route only, and pairing either with an `imageUrl` is a 400 `invalid_model`.
|
|
71
|
+
|
|
72
|
+
| Model | Text-to-video | Image-to-video | Cost | Speed | When |
|
|
73
|
+
|---|---|---|---|---|---|
|
|
74
|
+
| `kling` | yes | yes | $0.50 | 2-4 min | Default for trailer hero shots — best motion + composition |
|
|
75
|
+
| `ltx` | yes | yes | $0.10 | ~30s | B-roll, throwaway tests, blocking the composition before committing |
|
|
76
|
+
| `minimax` | yes | yes | $0.25 | 2-3 min | Anime / stylized trailer looks |
|
|
77
|
+
| `kling-turbo` | yes | **no** | $0.30 | 1-2 min | Same look as kling, faster, slight quality dip — but you lose `imageUrl` |
|
|
78
|
+
| `veo3` | yes | **no** | $1.00 | 3-5 min | Pitch deck for investors, the one shot that has to be perfect — but you lose `imageUrl` |
|
|
76
79
|
|
|
77
80
|
Default: **`ltx` first to block the composition, then `kling` for the final**. For the *one* hero shot that drives the Steam page, escalate to `veo3` only if `kling` failed twice.
|
|
78
81
|
|
|
@@ -88,9 +91,11 @@ summer_generate_video(
|
|
|
88
91
|
)
|
|
89
92
|
```
|
|
90
93
|
|
|
91
|
-
|
|
94
|
+
`duration` accepts **only 5 or 10** — anything else is coerced to 5.
|
|
92
95
|
|
|
93
|
-
|
|
96
|
+
The call is **asynchronous**: it returns `{ success, queued: true, jobId, model, resolvedModel, estimatedCost, duration }` and **no URL**. Poll `summer_check_job(jobId="<jobId>")` until it reports `completed` before showing the user anything or claiming the shot is done.
|
|
97
|
+
|
|
98
|
+
`aspectRatio` (`16:9`, `9:16`, `1:1`, ...) is applied on the **text-to-video path only**. The moment you pass `imageUrl` it is ignored and the clip inherits the reference image's framing — so vertical social needs a genuinely 9:16 reference, and square needs a square one. MCP image generation is square-only, so build non-square references in the Summer dashboard (which exposes aspect ratio) or crop them before use.
|
|
94
99
|
|
|
95
100
|
### 5. Review against trailer logic
|
|
96
101
|
|
|
@@ -107,10 +112,13 @@ If "regenerate", revise *one* axis (camera move, lighting, or framing) — don't
|
|
|
107
112
|
|
|
108
113
|
### 6. Import for archive (optional)
|
|
109
114
|
|
|
110
|
-
Trailer footage usually lives on the user's local disk and goes straight into the NLE
|
|
115
|
+
Trailer footage usually lives on the user's local disk and goes straight into the NLE, where the generated `.mp4` is exactly what you want.
|
|
116
|
+
|
|
117
|
+
For shots that double as **in-engine** splash content, transcode first — Summer Engine has no MP4 or WebM loader, and `.ogv` (Ogg Theora) is the only video container it can open. `summer_import_from_url` runs Godot's import pipeline and rejects the file if it never becomes a loadable resource, so importing the `.mp4` fails outright rather than half-working.
|
|
111
118
|
|
|
112
119
|
```
|
|
113
|
-
|
|
120
|
+
ffmpeg -i hero_boss_reveal.mp4 -c:v libtheora -q:v 8 -an hero_boss_reveal.ogv
|
|
121
|
+
summer_import_from_url(url="<hosted .ogv url>", path="res://assets/video/trailers/hero_boss_reveal.ogv")
|
|
114
122
|
```
|
|
115
123
|
|
|
116
124
|
For pure trailer use (DaVinci / Premiere), the user can grab the `fileUrl` and download directly.
|
|
@@ -142,7 +150,7 @@ Pattern: `<archetype framing> + <subject> + <action verb> + <camera move> + <lig
|
|
|
142
150
|
| Vertical social hero | `kling` | `vertical close-up of a young witch raising hands, magical wind, hair flowing, candle-warm key, cinematic, framed for 9:16` | $0.50 | 5s |
|
|
143
151
|
| Pitch-deck premium shot | `veo3` | `wide cinematic of a fleet of airships emerging through cloud cover at dawn, slow truck forward, golden god-rays, soaring orchestral cinematic` | $1.00 | 5s |
|
|
144
152
|
| Cheap B-roll iteration | `ltx` | `mid shot of a knight walking through fog, slow truck backward, dawn light, cinematic` | $0.10 | 5s |
|
|
145
|
-
| Anime style hero | `minimax` | `anime-style hero girl draws a katana in slow motion, sakura petals swirling, dramatic side-light, dynamic camera, Ghibli painterly` | $0.
|
|
153
|
+
| Anime style hero | `minimax` | `anime-style hero girl draws a katana in slow motion, sakura petals swirling, dramatic side-light, dynamic camera, Ghibli painterly` | $0.25 | 5s |
|
|
146
154
|
|
|
147
155
|
### Bad prompts and why
|
|
148
156
|
|
|
@@ -160,7 +168,8 @@ Pattern: `<archetype framing> + <subject> + <action verb> + <camera move> + <lig
|
|
|
160
168
|
- **Skipping the reference image for the hero shot.** The boss in the Steam capsule must look like the boss in the game. Always lock identity with `imageUrl`.
|
|
161
169
|
- **Using `veo3` for B-roll.** Burn $0.10 on `ltx` for blocking and B-roll; reserve `veo3` for the one shot that has to be perfect.
|
|
162
170
|
- **Generating shots without composing the trailer first.** Make a 6-shot list before generating shot 1. Otherwise you'll generate shots that don't intercut.
|
|
163
|
-
- **
|
|
171
|
+
- **Assuming `aspectRatio="9:16"` reframed an image-to-video call.** It is ignored whenever `imageUrl` is set — the reference image decides the framing. Pillarboxed 16:9 on TikTok / Reels / Shorts reads as a desktop YouTube embed and gets demoted by the algorithm, so fix the reference, not the argument.
|
|
172
|
+
- **Treating `summer_generate_video` as synchronous.** It returns `{ queued: true, jobId }` and no URL. Poll `summer_check_job` before handing the user a link.
|
|
164
173
|
- **Forgetting that Studio doesn't cut video.** The user has to take the shots into an NLE. Tell them, don't pretend Studio can stitch.
|
|
165
174
|
- **Asking for "the camera does X then Y then Z".** Pick one camera move per shot.
|
|
166
175
|
|
|
@@ -168,7 +177,7 @@ Pattern: `<archetype framing> + <subject> + <action verb> + <camera move> + <lig
|
|
|
168
177
|
|
|
169
178
|
- **Steam capsule animated header (Steam asset).** Steam wants `.webm` at 616x353 or 1920x1080, ≤6s, 30fps, no audio, ≤4MB. Generate at 16:9, transcode in DaVinci, export `.webm` with VP9. The video model gives you the source; format conversion is on you.
|
|
170
179
|
- **Pitch deck for investors.** One shot, `veo3`, money composition (low-angle hero or wide establishing). Worth the $1.00.
|
|
171
|
-
- **Vertical for TikTok / Shorts.**
|
|
180
|
+
- **Vertical for TikTok / Shorts.** The reference image must genuinely be portrait — `aspectRatio` is ignored once `imageUrl` is set. Frame the subject in the upper-middle so titles can sit at the bottom.
|
|
172
181
|
- **Subject is a UGC environment the player built.** Take a screenshot of the in-engine view, run it through `summer_generate_image` as `referenceImageUrl` to "upgrade" the look, then use that as the video reference. The model can stylize a screenshot; it can't invent the user's level.
|
|
173
182
|
- **Logo splash with motion graphics.** Generate a static logo card in `summer_generate_image` (or use the user's existing logo PNG), then prompt video as `static composition of <logo>, only background particles drifting, cinematic, room for title text` — keep the foreground motionless.
|
|
174
183
|
|
|
@@ -178,7 +187,7 @@ If the Studio MCP server isn't running, route the user to the Studio web dashboa
|
|
|
178
187
|
|
|
179
188
|
1. Image tab → generate the reference still.
|
|
180
189
|
2. Video tab → image-to-video with the reference URL, model `kling`, duration 5s, aspect ratio per platform.
|
|
181
|
-
3. Download the `.mp4` directly into the user's editing project (DaVinci / Premiere / CapCut).
|
|
190
|
+
3. Download the `.mp4` directly into the user's editing project (DaVinci / Premiere / CapCut). No transcode needed for an NLE — only in-engine playback requires `.ogv`.
|
|
182
191
|
|
|
183
192
|
Print the exact prompt + model + duration + aspect ratio so the user can paste it into the dashboard verbatim.
|
|
184
193
|
|
|
@@ -200,4 +209,4 @@ Once the shots are generated:
|
|
|
200
209
|
- `audio/music-track` — trailer score.
|
|
201
210
|
- `audio/sound-effect` — cut SFX (whooshes, impacts, stingers).
|
|
202
211
|
- `2d-assets/concept-art` — generate the reference image axis when no asset exists yet.
|
|
203
|
-
-
|
|
212
|
+
- `../../../references/mcp-tools-reference.md` — `summer_generate_video` parameter schema and error codes.
|