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.
Files changed (150) hide show
  1. package/.claude-plugin/plugin.json +2 -1
  2. package/.codex-plugin/plugin.json +3 -2
  3. package/.cursor-plugin/plugin.json +2 -1
  4. package/.opencode/INSTALL.md +1 -1
  5. package/.opencode/plugins/summer.js +1 -1
  6. package/AGENTS.md +4 -4
  7. package/CHANGELOG.md +10 -0
  8. package/GEMINI.md +5 -4
  9. package/README.md +58 -19
  10. package/assets/autopilot/README.md +51 -0
  11. package/assets/autopilot/autopilot.gd +222 -0
  12. package/assets/autopilot/probe_base.gd +262 -0
  13. package/assets/autopilot/run.sh +78 -0
  14. package/commands/gameskill.md +11 -2
  15. package/dist/bin/summer.js +8 -0
  16. package/dist/commands/config.d.ts +2 -0
  17. package/dist/commands/config.js +53 -0
  18. package/dist/commands/create.d.ts +1 -0
  19. package/dist/commands/create.js +38 -6
  20. package/dist/commands/list.js +1 -1
  21. package/dist/commands/login.d.ts +19 -0
  22. package/dist/commands/login.js +123 -36
  23. package/dist/commands/logout.js +3 -16
  24. package/dist/commands/logs.d.ts +2 -0
  25. package/dist/commands/logs.js +19 -0
  26. package/dist/commands/mcp.js +7 -2
  27. package/dist/commands/open.js +1 -1
  28. package/dist/commands/publish.d.ts +2 -0
  29. package/dist/commands/publish.js +20 -0
  30. package/dist/commands/releases.d.ts +2 -0
  31. package/dist/commands/releases.js +20 -0
  32. package/dist/commands/run.js +1 -1
  33. package/dist/lib/api-client.d.ts +4 -2
  34. package/dist/lib/api-client.js +28 -4
  35. package/dist/lib/auth.d.ts +40 -12
  36. package/dist/lib/auth.js +173 -37
  37. package/dist/lib/cloud/engine-bridge.d.ts +17 -4
  38. package/dist/lib/cloud/engine-bridge.js +32 -6
  39. package/dist/lib/config.d.ts +20 -0
  40. package/dist/lib/config.js +142 -0
  41. package/dist/lib/creator.d.ts +93 -0
  42. package/dist/lib/creator.js +393 -0
  43. package/dist/lib/engine.d.ts +35 -2
  44. package/dist/lib/engine.js +240 -6
  45. package/dist/lib/public-surface-paths.d.ts +13 -0
  46. package/dist/lib/public-surface-paths.js +42 -0
  47. package/dist/lib/skills-registry.d.ts +8 -0
  48. package/dist/lib/skills-registry.js +9 -0
  49. package/dist/lib/store.d.ts +14 -0
  50. package/dist/lib/store.js +145 -0
  51. package/dist/lib/summer-compatibility.d.ts +6 -0
  52. package/dist/lib/summer-compatibility.js +22 -0
  53. package/dist/mcp/server.d.ts +8 -1
  54. package/dist/mcp/server.js +25 -4
  55. package/dist/mcp/tools/creator-tools.d.ts +2 -0
  56. package/dist/mcp/tools/creator-tools.js +105 -0
  57. package/dist/mcp/tools/generate-tools.js +16 -6
  58. package/dist/mcp/tools/project-tools.js +12 -7
  59. package/dist/mcp/tools/scene-tools.js +6 -6
  60. package/dist/mcp/tools/visual-tools.js +4 -3
  61. package/hooks/pre-commit-doctor.sh +0 -0
  62. package/hooks/run-hook.cmd +0 -0
  63. package/hooks/session-start.sh +5 -5
  64. package/package.json +3 -1
  65. package/references/collaborative-protocol.md +50 -0
  66. package/references/gd-style.md +121 -0
  67. package/references/godot-version.md +51 -0
  68. package/references/mcp-tools-reference.md +199 -0
  69. package/references/public-surface-language.md +30 -0
  70. package/references/summer-folder.md +90 -0
  71. package/references/template-registry.md +73 -0
  72. package/skills/2d-assets/character-portrait/SKILL.md +17 -12
  73. package/skills/2d-assets/concept-art/SKILL.md +10 -9
  74. package/skills/2d-assets/pixel-art/SKILL.md +36 -20
  75. package/skills/2d-assets/skybox-panorama/SKILL.md +32 -37
  76. package/skills/2d-assets/sprite-sheet/SKILL.md +40 -35
  77. package/skills/2d-assets/tileable-texture/SKILL.md +28 -22
  78. package/skills/2d-assets/ui-graphics/SKILL.md +46 -32
  79. package/skills/2d-assets/use-widget-asset/SKILL.md +8 -6
  80. package/skills/3d-assets/character-model/SKILL.md +34 -19
  81. package/skills/3d-assets/environment-kit/SKILL.md +11 -5
  82. package/skills/3d-assets/organic-model/SKILL.md +8 -5
  83. package/skills/3d-assets/prop-model/SKILL.md +9 -3
  84. package/skills/3d-assets/vehicle-model/SKILL.md +32 -19
  85. package/skills/README.md +1 -1
  86. package/skills/ai-and-npcs/design-npc/SKILL.md +31 -13
  87. package/skills/animation/animation-tree/SKILL.md +39 -15
  88. package/skills/animation/facial-and-lipsync/SKILL.md +25 -8
  89. package/skills/animation/generate-motion/SKILL.md +47 -15
  90. package/skills/animation/procedural-animation/SKILL.md +31 -13
  91. package/skills/animation/retarget/SKILL.md +127 -79
  92. package/skills/audio/adaptive-music/SKILL.md +24 -20
  93. package/skills/audio/ambient-bed/SKILL.md +22 -16
  94. package/skills/audio/audio-direction/SKILL.md +15 -10
  95. package/skills/audio/music-track/SKILL.md +18 -12
  96. package/skills/audio/sound-effect/SKILL.md +17 -12
  97. package/skills/audio/voice-line/SKILL.md +42 -42
  98. package/skills/character-controllers/fps-controller/SKILL.md +26 -16
  99. package/skills/debugging/debug/SKILL.md +52 -20
  100. package/skills/deployment/export-and-ship/SKILL.md +105 -38
  101. package/skills/deployment/remote-deploy/SKILL.md +56 -23
  102. package/skills/gameplay-mechanics/auto-fire-targeting/SKILL.md +26 -1
  103. package/skills/gameplay-mechanics/design-mechanic/SKILL.md +23 -15
  104. package/skills/level-design/design-level/SKILL.md +22 -8
  105. package/skills/level-design/scene-to-level/SKILL.md +13 -7
  106. package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +8 -8
  107. package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +2 -7
  108. package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +26 -18
  109. package/skills/performance/tune-performance/SKILL.md +51 -32
  110. package/skills/rendering-and-lighting/3d-lighting/SKILL.md +34 -5
  111. package/skills/rendering-and-lighting/art-direction/SKILL.md +6 -8
  112. package/skills/scene-and-project/brainstorm-game/SKILL.md +3 -5
  113. package/skills/scene-and-project/make-game/SKILL.md +2 -1
  114. package/skills/scene-and-project/play/SKILL.md +10 -4
  115. package/skills/scene-and-project/scene-composition/SKILL.md +21 -8
  116. package/skills/scene-and-project/summer-cloud/SKILL.md +1 -1
  117. package/skills/ui-and-ux/ui-basics/SKILL.md +16 -7
  118. package/skills/video/animated-loop/SKILL.md +63 -39
  119. package/skills/video/cinematic-cutscene/SKILL.md +66 -30
  120. package/skills/video/trailer-shot/SKILL.md +30 -21
  121. package/skills/visual-effects/_building-blocks/additive-billboard-particles.md +25 -16
  122. package/skills/visual-effects/_building-blocks/trauma-shake-snippet.md +5 -3
  123. package/skills/visual-effects/game-feel/SKILL.md +51 -33
  124. package/skills/visual-effects/recipes/dissolve/SKILL.md +51 -9
  125. package/skills/visual-effects/recipes/fire/SKILL.md +136 -49
  126. package/skills/visual-effects/recipes/hit-spark/SKILL.md +45 -8
  127. package/skills/visual-effects/recipes/lightning/SKILL.md +59 -27
  128. package/skills/visual-effects/recipes/magic-glow/SKILL.md +59 -26
  129. package/skills/visual-effects/recipes/muzzle-flash/SKILL.md +68 -25
  130. package/skills/visual-effects/recipes/smoke/SKILL.md +89 -28
  131. package/skills/visual-effects/recipes/water-ripple/SKILL.md +83 -23
  132. package/skills/workflow/brainstorming/SKILL.md +1 -1
  133. package/skills/workflow/brainstorming/scripts/start-server.sh +0 -0
  134. package/skills/workflow/brainstorming/scripts/stop-server.sh +0 -0
  135. package/skills/workflow/debugging-game-feel/SKILL.md +29 -9
  136. package/skills/workflow/diagnosing-perf-regressions/SKILL.md +46 -21
  137. package/skills/workflow/gameskill/SKILL.md +11 -2
  138. package/skills/workflow/headless-scripting/SKILL.md +407 -0
  139. package/skills/workflow/investigating-bugs/SKILL.md +4 -2
  140. package/skills/workflow/investigating-bugs/find-polluter.sh +0 -0
  141. package/skills/workflow/mcpupdate/SKILL.md +3 -3
  142. package/skills/workflow/playtesting-a-feature/SKILL.md +94 -21
  143. package/skills/workflow/skill-create/SKILL.md +7 -7
  144. package/skills/workflow/skill-test/SKILL.md +3 -3
  145. package/skills/workflow/using-summer/SKILL.md +12 -2
  146. package/skills/workflow/verification-before-completion/SKILL.md +2 -0
  147. package/skills/workflow/writing-plans/SKILL.md +7 -7
  148. package/skills/workflow/writing-skills/SKILL.md +7 -5
  149. package/skills/workflow/writing-skills/render-graphs.js +0 -0
  150. 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 Godot 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 vs inline styling. Trigger on "UI", "HUD", "menu", "health bar", "Control", "anchors", "VBoxContainer", "main menu", "pause menu".
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 Godot's Control nodes. Follow these patterns for layout, buttons, and responsive design.
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 is on a resource. For `theme_override_constants/margin_left`, it may be a direct node property—check Godot docs. Some constants are set via `add_theme_constant_override`. If `summer_set_prop` accepts `theme_override_constants/margin_left`, use it; otherwise the UI may need a script or theme resource.
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="1") # Top-left
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 (Godot 4):
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`?". See `../../references/collaborative-protocol.md`.
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 — 3-5 Second Seamless Background 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: keep the duration short (3-5s), 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.
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 3-5s clip designed to loop.
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 keep it 3-5s and prompt for ambient motion (drift, flicker, shimmer) rather than a narrative beat. OK?
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
- | Model | Cost | Speed | When |
48
- |---|---|---|---|
49
- | `ltx` | ~$0.10 | ~30s | Default. Use this. |
50
- | `kling` | ~$0.50 | 2-4 min | Only if the loop is the centerpiece of a premium splash and quality is visibly lacking on `ltx` |
51
- | `kling-turbo` | ~$0.30 | 1-2 min | Same as `kling` but faster |
52
- | `veo3` | ~$1.00 | 3-5 min | Almost never — `veo3` shines on dialogue/identity, neither matters for ambient loops |
53
- | `minimax` | ~$0.40 | 2-3 min | Stylized / anime aesthetic loops |
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
- For vertical menus (mobile portrait splash), generate at portrait and use `aspectRatio="9:16"` on the video call.
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=4,
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. The negative prompt rules out narrative drift.
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 duration was too long. Drop from 5s to 3s and regenerate.
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="<fileUrl>", path="assets/video/loops/title_screen_bg.ogv")
125
+ summer_import_from_url(url="<hosted .ogv url>", path="res://assets/video/loops/title_screen_bg.ogv")
104
126
  ```
105
127
 
106
- Note: Godot's `VideoStreamPlayer` natively plays Ogg Theora (`.ogv`); for `.mp4` you may need to transcode or rely on the engine's bundled WebM/MP4 plugin. Studio's import pipeline handles transcoding when the path extension is set explicitly — confirm the resulting resource type with `summer_inspect_resource` if playback fails.
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="./TitleScreen", type="VideoStreamPlayer", name="BackgroundLoop")
110
- summer_set_prop(path="./TitleScreen/BackgroundLoop", property="stream", value="res://assets/video/loops/title_screen_bg.ogv")
111
- summer_set_prop(path="./TitleScreen/BackgroundLoop", property="autoplay", value=true)
112
- summer_set_prop(path="./TitleScreen/BackgroundLoop", property="loop", value=true)
113
- summer_set_prop(path="./TitleScreen/BackgroundLoop", property="expand", value=true)
114
- summer_set_prop(path="./TitleScreen/BackgroundLoop", property="anchors_preset", value=15)
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="./TitleScreen/BackgroundLoop", property="volume_db", value=-80)
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 | 4s |
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 | 4s |
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 | 3s |
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 | 4s |
141
- | Title — anime sky | `minimax` | `anime style cumulus clouds drifting slowly across a pastel sunset sky, soft, painterly, looping, seamless, Ghibli` | $0.40 | 4s |
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. Cap at 5s.
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
- - **Using `aspectRatio="16:9"` for a portrait splash.** Pillarboxed loops on a vertical splash look broken. Set `9:16` and frame portrait.
162
- - **Importing without transcoding to a Godot-friendly container.** `VideoStreamPlayer` natively wants Ogg Theora; `.mp4` works with the bundled plugin but isn't guaranteed across platforms — confirm with `summer_inspect_resource`.
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.** `aspectRatio="9:16"`, reference image at portrait, anchors preset 15 still works.
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
- - `references/mcp-tools-reference.md` — `summer_generate_video` parameter schema and error codes.
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="cutscene", filter={ kind: "video" })
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
- | Model | Cost | Speed | When |
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
- Default policy: **`ltx` first** to validate the prompt and shot framing. If it lands the composition but quality is rough, escalate to `kling`. Only reach for `veo3` if dialogue lip-sync matters and the user has approved the cost.
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
- Returns `{ asset: { fileUrl } }`. Show the user the URL and ask:
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="<fileUrl>", path="assets/video/cinematics/intro_shot_01.mp4")
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
- summer_add_node(parent=".", type="Control", name="Intro")
121
- summer_add_node(parent="./Intro", type="ColorRect", name="Fade") # black, alpha 1.0 → 0.0
122
- summer_add_node(parent="./Intro", type="VideoStreamPlayer", name="Video")
123
- summer_set_prop(path="./Intro/Video", property="stream", value="res://assets/video/cinematics/intro_shot_01.mp4")
124
- summer_set_prop(path="./Intro/Video", property="autoplay", value=true)
125
- summer_set_prop(path="./Intro/Video", property="expand", value=true)
126
- summer_set_prop(path="./Intro/Fade", property="anchors_preset", value=15)
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.40 | 5s |
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
- - **Forgetting to import the file.** `summer_generate_video` returns a `fileUrl` on Cloudinary; until you call `summer_import_from_url`, it isn't in `res://` and the scene can't reference it.
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.** Set `aspectRatio="9:16"`. Reference image must also be 9:16 — generate it with `image_size: "portrait_16_9"` or the framing will crop wrong on the video.
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 it into `assets/video/cinematics/` in the project, then re-import via the Godot editor.
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
- - `references/mcp-tools-reference.md` — `summer_generate_video` parameter schema and error codes.
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
- For pure environment / abstract / VFX shots, you can skip this and prompt text-to-video directly.
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
- | Model | Cost | Speed | When |
70
- |---|---|---|---|
71
- | `kling` | ~$0.50 | 2-4 min | Default for trailer hero shots — best motion + composition |
72
- | `kling-turbo` | ~$0.30 | 1-2 min | Same look as kling, faster, slight quality dip |
73
- | `veo3` | ~$1.00 | 3-5 min | Pitch deck for investors, the one shot that has to be perfect, premium social ad |
74
- | `ltx` | ~$0.10 | ~30s | B-roll, throwaway tests, blocking the composition before committing |
75
- | `minimax` | ~$0.40 | 2-3 min | Anime / stylized trailer looks |
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
- For vertical social (TikTok, Reels, Shorts): `aspectRatio="9:16"` and frame the subject vertically in your reference image.
94
+ `duration` accepts **only 5 or 10** — anything else is coerced to 5.
92
95
 
93
- For square (Instagram feed): `aspectRatio="1:1"`.
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. But for shots that double as in-engine splash content, import:
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
- summer_import_from_url(url="<fileUrl>", path="assets/video/trailers/hero_boss_reveal.mp4")
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.40 | 5s |
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
- - **Using `aspectRatio="16:9"` for vertical social.** TikTok / Reels / Shorts are `9:16`. Pillarboxed 16:9 reads as a desktop YouTube embed and gets demoted by the algorithm.
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.** `aspectRatio="9:16"`, reference image at portrait, frame the subject in the upper-middle so titles can sit at the bottom.
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
- - `references/mcp-tools-reference.md` — `summer_generate_video` parameter schema and error codes.
212
+ - `../../../references/mcp-tools-reference.md` — `summer_generate_video` parameter schema and error codes.