summer-engine 2.6.6 → 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 (168) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +4 -1
  3. package/.codex-plugin/plugin.json +6 -2
  4. package/.cursor-plugin/plugin.json +5 -1
  5. package/.opencode/INSTALL.md +1 -1
  6. package/.opencode/plugins/summer.js +2 -2
  7. package/AGENTS.md +11 -7
  8. package/CHANGELOG.md +40 -0
  9. package/GEMINI.md +9 -7
  10. package/README.md +63 -21
  11. package/_persona/summer/SKILL.md +1 -0
  12. package/assets/autopilot/README.md +51 -0
  13. package/assets/autopilot/autopilot.gd +222 -0
  14. package/assets/autopilot/probe_base.gd +262 -0
  15. package/assets/autopilot/run.sh +78 -0
  16. package/commands/gameskill.md +11 -2
  17. package/commands/summer.md +13 -0
  18. package/dist/bin/summer.js +12 -0
  19. package/dist/commands/config.d.ts +2 -0
  20. package/dist/commands/config.js +53 -0
  21. package/dist/commands/create.d.ts +1 -0
  22. package/dist/commands/create.js +38 -6
  23. package/dist/commands/debug.d.ts +2 -0
  24. package/dist/commands/debug.js +44 -0
  25. package/dist/commands/doctor.js +112 -8
  26. package/dist/commands/list.js +1 -1
  27. package/dist/commands/login.d.ts +19 -0
  28. package/dist/commands/login.js +123 -36
  29. package/dist/commands/logout.js +3 -16
  30. package/dist/commands/logs.d.ts +2 -0
  31. package/dist/commands/logs.js +19 -0
  32. package/dist/commands/mcp.js +7 -2
  33. package/dist/commands/open.js +1 -1
  34. package/dist/commands/publish.d.ts +2 -0
  35. package/dist/commands/publish.js +20 -0
  36. package/dist/commands/releases.d.ts +2 -0
  37. package/dist/commands/releases.js +20 -0
  38. package/dist/commands/run.js +1 -1
  39. package/dist/commands/skills.js +1 -1
  40. package/dist/lib/api-client.d.ts +15 -4
  41. package/dist/lib/api-client.js +138 -13
  42. package/dist/lib/async-op-lifecycle.d.ts +7 -2
  43. package/dist/lib/async-op-lifecycle.js +32 -9
  44. package/dist/lib/auth.d.ts +40 -12
  45. package/dist/lib/auth.js +173 -37
  46. package/dist/lib/cloud/engine-bridge.d.ts +17 -4
  47. package/dist/lib/cloud/engine-bridge.js +32 -6
  48. package/dist/lib/config.d.ts +20 -0
  49. package/dist/lib/config.js +142 -0
  50. package/dist/lib/creator.d.ts +93 -0
  51. package/dist/lib/creator.js +393 -0
  52. package/dist/lib/debug-report.d.ts +50 -0
  53. package/dist/lib/debug-report.js +308 -0
  54. package/dist/lib/engine.d.ts +35 -2
  55. package/dist/lib/engine.js +240 -6
  56. package/dist/lib/game-task-plan.js +4 -4
  57. package/dist/lib/mcp-boot-notice.d.ts +3 -0
  58. package/dist/lib/mcp-boot-notice.js +7 -0
  59. package/dist/lib/mcp-log.d.ts +3 -0
  60. package/dist/lib/mcp-log.js +72 -0
  61. package/dist/lib/public-surface-paths.d.ts +13 -0
  62. package/dist/lib/public-surface-paths.js +42 -0
  63. package/dist/lib/skills-registry.d.ts +33 -1
  64. package/dist/lib/skills-registry.js +55 -0
  65. package/dist/lib/store.d.ts +14 -0
  66. package/dist/lib/store.js +145 -0
  67. package/dist/lib/summer-compatibility.d.ts +6 -0
  68. package/dist/lib/summer-compatibility.js +22 -0
  69. package/dist/mcp/server.d.ts +10 -3
  70. package/dist/mcp/server.js +104 -11
  71. package/dist/mcp/tools/asset-tools.js +33 -12
  72. package/dist/mcp/tools/cloud-tools.js +15 -15
  73. package/dist/mcp/tools/creator-tools.d.ts +2 -0
  74. package/dist/mcp/tools/creator-tools.js +105 -0
  75. package/dist/mcp/tools/debug-tools.js +44 -1
  76. package/dist/mcp/tools/file-tools.d.ts +2 -0
  77. package/dist/mcp/tools/file-tools.js +154 -0
  78. package/dist/mcp/tools/generate-tools.js +159 -11
  79. package/dist/mcp/tools/project-tools.js +37 -27
  80. package/dist/mcp/tools/scene-tools.js +106 -29
  81. package/dist/mcp/tools/visual-tools.js +4 -3
  82. package/dist/mcp/tools/with-engine.js +4 -4
  83. package/hooks/session-start.sh +5 -5
  84. package/package.json +3 -1
  85. package/references/collaborative-protocol.md +50 -0
  86. package/references/gd-style.md +121 -0
  87. package/references/godot-version.md +51 -0
  88. package/references/mcp-tools-reference.md +199 -0
  89. package/references/public-surface-language.md +30 -0
  90. package/references/summer-folder.md +90 -0
  91. package/references/template-registry.md +73 -0
  92. package/skills/2d-assets/character-portrait/SKILL.md +17 -12
  93. package/skills/2d-assets/concept-art/SKILL.md +10 -9
  94. package/skills/2d-assets/create-asset-sheet/SKILL.md +17 -15
  95. package/skills/2d-assets/pixel-art/SKILL.md +36 -20
  96. package/skills/2d-assets/skybox-panorama/SKILL.md +32 -37
  97. package/skills/2d-assets/sprite-sheet/SKILL.md +40 -35
  98. package/skills/2d-assets/tileable-texture/SKILL.md +28 -22
  99. package/skills/2d-assets/ui-graphics/SKILL.md +46 -32
  100. package/skills/2d-assets/use-widget-asset/SKILL.md +8 -6
  101. package/skills/3d-assets/character-model/SKILL.md +34 -19
  102. package/skills/3d-assets/environment-kit/SKILL.md +11 -5
  103. package/skills/3d-assets/organic-model/SKILL.md +8 -5
  104. package/skills/3d-assets/prop-model/SKILL.md +9 -3
  105. package/skills/3d-assets/vehicle-model/SKILL.md +32 -19
  106. package/skills/README.md +1 -1
  107. package/skills/ai-and-npcs/design-npc/SKILL.md +31 -13
  108. package/skills/animation/animation-tree/SKILL.md +39 -15
  109. package/skills/animation/facial-and-lipsync/SKILL.md +25 -8
  110. package/skills/animation/generate-motion/SKILL.md +47 -15
  111. package/skills/animation/procedural-animation/SKILL.md +31 -13
  112. package/skills/animation/retarget/SKILL.md +127 -79
  113. package/skills/audio/adaptive-music/SKILL.md +24 -20
  114. package/skills/audio/ambient-bed/SKILL.md +22 -16
  115. package/skills/audio/audio-direction/SKILL.md +15 -10
  116. package/skills/audio/music-track/SKILL.md +18 -12
  117. package/skills/audio/sound-effect/SKILL.md +17 -12
  118. package/skills/audio/voice-line/SKILL.md +42 -42
  119. package/skills/character-controllers/fps-controller/SKILL.md +26 -16
  120. package/skills/debugging/debug/SKILL.md +74 -20
  121. package/skills/deployment/export-and-ship/SKILL.md +105 -38
  122. package/skills/deployment/remote-deploy/SKILL.md +140 -0
  123. package/skills/gameplay-mechanics/auto-fire-targeting/SKILL.md +26 -1
  124. package/skills/gameplay-mechanics/design-mechanic/SKILL.md +23 -15
  125. package/skills/level-design/design-level/SKILL.md +22 -8
  126. package/skills/level-design/scene-to-level/SKILL.md +13 -7
  127. package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +8 -8
  128. package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +2 -7
  129. package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +26 -18
  130. package/skills/performance/tune-performance/SKILL.md +51 -32
  131. package/skills/rendering-and-lighting/3d-lighting/SKILL.md +34 -5
  132. package/skills/rendering-and-lighting/art-direction/SKILL.md +6 -8
  133. package/skills/scene-and-project/brainstorm-game/SKILL.md +7 -9
  134. package/skills/scene-and-project/make-game/SKILL.md +2 -1
  135. package/skills/scene-and-project/play/SKILL.md +10 -4
  136. package/skills/scene-and-project/scene-composition/SKILL.md +21 -8
  137. package/skills/scene-and-project/summer-cloud/SKILL.md +92 -0
  138. package/skills/scripting-patterns/gdscript-patterns/SKILL.md +1 -1
  139. package/skills/ui-and-ux/ui-basics/SKILL.md +16 -7
  140. package/skills/video/animated-loop/SKILL.md +63 -39
  141. package/skills/video/cinematic-cutscene/SKILL.md +66 -30
  142. package/skills/video/trailer-shot/SKILL.md +30 -21
  143. package/skills/visual-effects/_building-blocks/additive-billboard-particles.md +25 -16
  144. package/skills/visual-effects/_building-blocks/trauma-shake-snippet.md +5 -3
  145. package/skills/visual-effects/game-feel/SKILL.md +51 -33
  146. package/skills/visual-effects/recipes/dissolve/SKILL.md +51 -9
  147. package/skills/visual-effects/recipes/fire/SKILL.md +136 -49
  148. package/skills/visual-effects/recipes/hit-spark/SKILL.md +45 -8
  149. package/skills/visual-effects/recipes/lightning/SKILL.md +59 -27
  150. package/skills/visual-effects/recipes/magic-glow/SKILL.md +59 -26
  151. package/skills/visual-effects/recipes/muzzle-flash/SKILL.md +68 -25
  152. package/skills/visual-effects/recipes/smoke/SKILL.md +89 -28
  153. package/skills/visual-effects/recipes/water-ripple/SKILL.md +83 -23
  154. package/skills/workflow/brainstorming/SKILL.md +1 -1
  155. package/skills/workflow/debugging-game-feel/SKILL.md +29 -9
  156. package/skills/workflow/diagnosing-perf-regressions/SKILL.md +46 -21
  157. package/skills/workflow/gameskill/SKILL.md +11 -2
  158. package/skills/workflow/headless-scripting/SKILL.md +407 -0
  159. package/skills/workflow/investigating-bugs/SKILL.md +4 -2
  160. package/skills/workflow/mcpupdate/SKILL.md +9 -9
  161. package/skills/workflow/playtesting-a-feature/SKILL.md +94 -21
  162. package/skills/workflow/skill-create/SKILL.md +7 -7
  163. package/skills/workflow/skill-test/SKILL.md +3 -3
  164. package/skills/workflow/using-summer/SKILL.md +32 -3
  165. package/skills/workflow/verification-before-completion/SKILL.md +2 -0
  166. package/skills/workflow/writing-plans/SKILL.md +7 -7
  167. package/skills/workflow/writing-skills/SKILL.md +7 -5
  168. package/skills/workflow/writing-skills/testing-skills-with-subagents.md +1 -1
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: scene-composition
3
- description: Use when building or organizing scenes in Godot — node hierarchy conventions, when to extract sub-scenes, reusable prefab patterns, instance vs add-node decisions. Trigger on "scene", "sub-scene", "instance", "prefab", "node hierarchy", "scene structure", "PackedScene".
3
+ description: Use when building or organizing Summer Engine scenes: node hierarchy conventions, when to extract sub-scenes, reusable prefab patterns, and instance-versus-add-node decisions. Trigger on "scene", "sub-scene", "instance", "prefab", "node hierarchy", "scene structure", "PackedScene".
4
4
  license: MIT
5
5
  compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
6
  category: scene-and-project
@@ -80,8 +80,8 @@ Use `./` for paths relative to the scene root:
80
80
 
81
81
  1. Build the hierarchy in the main scene
82
82
  2. Select the root of what you want to extract
83
- 3. Save as scene: `summer_save_scene(path="res://scenes/player.tscn")`. SaveScene saves the current open scene, so build reusable scenes in their own open scene and save them there. Do not handwrite `.tscn` files as the preferred path.
84
- 4. In the main scene, add it with `summer_instantiate_scene(parent="./World", scene="res://scenes/player.tscn", name="Player")`
83
+ 3. Save as scene: `summer_save_scene(scenePath="res://scenes/source.tscn", path="res://scenes/player.tscn")`. `scenePath` names the scene being saved and is **required**; `path` is the optional save-as target. There is no "current scene" default.
84
+ 4. In the main scene, add it with `summer_instantiate_scene(scenePath="res://main.tscn", parent="./World", scene="res://scenes/player.tscn", name="Player")`
85
85
 
86
86
  **Practical approach:** Create reusable scenes (player.tscn, enemy.tscn) as separate scene files, then instantiate them into levels.
87
87
 
@@ -97,9 +97,9 @@ Use `./` for paths relative to the scene root:
97
97
 
98
98
  ## Save Conventions
99
99
 
100
- - Always call `summer_save_scene` after changes you want to keep
101
- - For new scenes: `summer_save_scene(path="res://scenes/level1.tscn")`
102
- - For existing scenes: `summer_save_scene` (no path, uses current scene path)
100
+ - The mutation tools (`summer_add_node`, `summer_set_prop`, ...) already append one save per call, so a standalone `summer_save_scene` is only for a save-as or an explicit extra flush
101
+ - Save-as: `summer_save_scene(scenePath="res://main.tscn", path="res://scenes/level1.tscn")`
102
+ - Plain save: `summer_save_scene(scenePath="res://main.tscn")` — `scenePath` is required in both forms
103
103
 
104
104
  ## Common Mistakes
105
105
 
@@ -110,7 +110,20 @@ Use `./` for paths relative to the scene root:
110
110
 
111
111
  ## Fallback
112
112
 
113
- No fallback for this — Summer MCP required. Handwriting `.tscn` files for hierarchy mutations is error-prone (UID collisions, wrong format version, broken sub_resource refs). If MCP isn't connected, open the scene in the Godot editor and use the SceneTree dock.
113
+ MCP is the preferred path, not a requirement. Hand-written `.tscn` text loads and
114
+ instantiates fine — including `[ext_resource]` lines with **no `uid=` field**,
115
+ which the engine resolves by path (verified by loading such a scene on the
116
+ shipped 4.6.1 build). Format version 3 is current for Godot 4.
117
+
118
+ What actually goes wrong when you hand-write scenes is mundane and checkable:
119
+ a `SubResource("id")` with no matching `[sub_resource id="id"]` block, a
120
+ `parent=` path naming a node that isn't declared above it, or an
121
+ `[ext_resource path=...]` pointing at a file that hasn't been imported yet
122
+ (`--headless --import`, or `summer_import_from_url`, before it will load).
123
+
124
+ So: use MCP when it's connected because the ops are undoable as one step and the
125
+ engine validates paths for you. When it isn't, write the `.tscn` and then open it
126
+ once to confirm it loads. Do not tell the user it's impossible.
114
127
 
115
128
  ## Trap — Cross-scene transform leak when copying a scene as a template
116
129
 
@@ -143,4 +156,4 @@ Don't skip the player mask update. If you only move foliage to layer 9 without a
143
156
 
144
157
  ## Collaborative protocol
145
158
 
146
- This skill creates and mutates scene files. Always ask before applying: "May I create `res://scenes/player.tscn` and instantiate it under `./World`?". See `../../references/collaborative-protocol.md`.
159
+ This skill creates and mutates scene files. Always ask before applying: "May I create `res://scenes/player.tscn` and instantiate it under `./World`?".
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: summer-cloud
3
+ description: Use when the user wants to sync a Summer Engine project, move it to another machine or laptop, share the exact bytes with a collaborator, back up big generated assets that do not belong in git, restore an earlier version, or wants a safety net before a risky bulk operation. Trigger on "sync", "Summer Cloud", "cloud push", "cloud pull", "move to another machine", "other computer", "second machine", "share project", "back up assets", "big assets", "collaborator", "teammate", "restore a version", "checkpoint", "conflict".
4
+ license: MIT
5
+ compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
+ category: scene-and-project
7
+ user-invocable: true
8
+ allowed-tools: Read summer_cloud_init summer_cloud_status summer_cloud_push summer_cloud_pull summer_cloud_restore summer_cloud_checkpoints summer_cloud_conflicts
9
+ paths: ["summer-cloud.json"]
10
+ ---
11
+
12
+ # Summer Cloud: Project Sync
13
+
14
+ ## What Summer Cloud is
15
+
16
+ Summer Cloud is content-addressed sync for a whole Summer Engine project. Every tracked file is identified by its sha256 hash, so identical bytes upload once and dedupe across versions and projects. It syncs the entire project tree at once (code, scenes, resources, import sidecars, and the heavy binary assets), not a hand-picked folder. The only git-tracked cloud artifact is a tiny `summer-cloud.json` binding at the project root; all real sync state lives under `.summer/local/cloud/` and is never committed.
17
+
18
+ This is not a folder backup and it is not a git replacement. Code that lives happily in git can stay in git. What Cloud adds is a way to move the large generated binaries (models, textures, audio, video) that do not belong in a git repo, and to keep a project byte-identical across machines and collaborators. Git and Cloud can run side by side; the binding file merges trivially.
19
+
20
+ ## When to offer it (proactive triggers)
21
+
22
+ Surface Cloud, do not wait to be asked, when any of these are true:
23
+
24
+ - The project has heavy generated assets (large `.glb`, `.png`, `.wav`, `.ogg`, `.mp4` under `assets/`) that should not go into git. Cloud is how those travel.
25
+ - The user mentions a second machine, a laptop, "my other computer", or working from somewhere else. Cloud is how the same bytes show up there.
26
+ - A teammate or collaborator needs the exact same project state. Add them as a collaborator and they pull.
27
+ - A risky bulk operation is about to run (mass asset import, a large refactor, a destructive cleanup). A push first gives a restorable version to fall back to.
28
+
29
+ If none of these apply, do not push Cloud on the user. It is a tool for a real need, not a default step.
30
+
31
+ ## Command and tool surface
32
+
33
+ | Action | CLI | MCP tool |
34
+ |---|---|---|
35
+ | Enable Cloud for this project | `summer cloud init` | `summer_cloud_init` |
36
+ | Show what would push/pull | `summer cloud status` | `summer_cloud_status` |
37
+ | Upload local changes | `summer cloud push` | `summer_cloud_push` |
38
+ | Download remote changes | `summer cloud pull` | `summer_cloud_pull` |
39
+ | Restore an earlier version or a local checkpoint | `summer cloud restore --version N` / `--checkpoint <stamp>` | `summer_cloud_restore` |
40
+ | List local pre-sync checkpoints | `summer cloud checkpoints` | `summer_cloud_checkpoints` |
41
+ | List or recover conflict sets | `summer cloud conflicts list` / `restore <path>` | `summer_cloud_conflicts` |
42
+
43
+ Run `summer cloud status` before any push or pull. It reports the file counts, what would move in each direction, and whether any conflict sets are waiting. Never push blind.
44
+
45
+ ## The safety model (respect this)
46
+
47
+ The whole point of Cloud is that user data is never destroyed silently. The rules below are how that holds. Do not work around them.
48
+
49
+ - **Every push is a restorable version.** The server keeps the version history within the retention window. Version numbers are never reused. If a bad push lands, `summer cloud restore --version N` brings the project back as a new head version, then pulls it locally.
50
+ - **Local checkpoints come before destructive applies.** Before a pull modifies or deletes any existing file, the client writes a full-tree checkpoint into the project's local SummerGit repo. `summer cloud checkpoints` lists them; `summer cloud restore --checkpoint <stamp>` rolls back. Note the honest caveat the restore prints: it restores bytes but does not delete files a bad sync added, so review and remove any extras it lists.
51
+ - **Large deletions are gated.** A push that would delete many cloud files (more than 10 files, or at least 20% of the tracked tree, or the entire tree) requires `confirmDeletes: true` on the MCP tool (or `--confirm-deletes` on the CLI). Never pass it blindly. First run `summer cloud status`, read the delete count out loud to the user, and only set the flag once they confirm that count is what they intend. If the local tree reads as completely empty against a non-empty base (a wrong directory or an unmounted volume), the push aborts outright and no flag can force it.
52
+ - **Conflicts become conflict sets, never silent overwrites.** Concurrent edits to the same file are resolved deterministically: the first sync to land wins the canonical path (this is "first to sync wins", not "most recent save wins", because there are no wall clocks). The losing bytes are preserved, never discarded, in a local conflict set and backed up to the cloud. Surface them with `summer cloud conflicts list` and recover any with `summer cloud conflicts restore <path>`, which re-enters the file as a fresh edit. `project.godot` is the one file merged key by key rather than whole-file, so input actions and autoloads from both sides survive.
53
+ - **A modify always beats a delete.** If one side edited a file and the other deleted it, the edited file is kept and the deletion is dropped, with a notice. Offline work is never lost to someone else's delete.
54
+
55
+ ## First sync and the bootstrap choice
56
+
57
+ When a project already has files on both the local disk and in the cloud but this machine has no sync base (for example a fresh git clone of a project that was cloud-enabled elsewhere), auto-sync will not run. The tool returns a bootstrap choice. Present it to the user and let them pick:
58
+
59
+ - `keep-cloud` (pull): replace local divergent files with the cloud version. Local divergent files are checkpointed first.
60
+ - `keep-local` (push): make the local tree the new cloud version.
61
+ - `merge`: converge automatically where hashes already match (usually most files); the rest get normal conflict treatment.
62
+
63
+ If the project folder was moved or Finder-copied, sync blocks until you confirm whether to adopt the new path (`adoptPath: true`) or fork it into a separate cloud project. Two folders must never fight over one project.
64
+
65
+ ## Honest v1 limits
66
+
67
+ State these plainly when they are relevant; do not paper over them.
68
+
69
+ - **One linear head per project. No branches yet.** There is a single history line. If a user wants an isolated line to experiment with assets, fork to a separate cloud project: delete `summer-cloud.json` and run `summer cloud init` to create a new binding. Because storage is content-addressed and dedupes, the fork is nearly free in storage.
70
+ - **Per-file cap is 4.995 GiB.** A single file larger than that is rejected with a clear error. There is no multipart path in v1.
71
+ - **No resumable uploads.** A dropped connection mid-upload on a multi-GiB file restarts that file from zero. For large pushes, prefer a stable connection.
72
+ - **No locking or presence.** Two people editing the same binary at once produces a conflict (recoverable, never lost), not a lock.
73
+ - **Git branch switches read as edits.** Switching git branches on a cloud-synced project looks like local edits to Cloud and will push as such. Guidance: sync before and after branch operations, or keep cloud projects on one branch.
74
+ - **Storage rides the plan tiers.** Free, Pro, Pro Plus, and Ultra each have a storage cap. A push past the cap returns a quota error pointing at the upgrade path; surface that to the user rather than retrying.
75
+
76
+ ## Hard rule: drive everything through the CLI or MCP
77
+
78
+ Never hand-edit anything under `.summer/local/cloud/` (base, journal, hash cache, staging, checkpoints, conflict sets). That state is the integrity model; editing it by hand can corrupt the 3-way base and cause data loss on the next sync. The only file you ever touch directly is the tiny git-tracked `summer-cloud.json` binding, and even then only to remove `pinnedVersion` for a read-only checkout or to delete it when intentionally forking. Every real operation goes through `summer cloud ...` or the `summer_cloud_*` tools.
79
+
80
+ ## Typical flows
81
+
82
+ - **Move to a second machine.** On machine A: `summer cloud init`, then `summer cloud push`. Commit `summer-cloud.json` so it travels with git, or share the project id. On machine B: get the project (git clone or copy), then `summer cloud pull`. If both sides already had files, take the bootstrap choice.
83
+ - **Back up big assets before a bulk import.** `summer cloud status`, then `summer cloud push`. The resulting version is the restore point.
84
+ - **Recover from a bad change.** `summer cloud checkpoints` (or `summer cloud status` for cloud versions), then `summer cloud restore --checkpoint <stamp>` for local-only work or `--version N` for a pushed version. Remove any extra files the restore lists.
85
+
86
+ ## Fallback
87
+
88
+ If the MCP tools are unavailable, run the `summer cloud ...` CLI commands directly. The CLI and MCP tools are one to one and share the same engine. If neither is available, the project is not set up; point the user at `summer login` (Cloud auth comes from the login token) and `summer cloud init`.
89
+
90
+ ## Collaborative protocol
91
+
92
+ Push and pull move bytes and can replace files. Always run `summer cloud status` and say what will move before you push or pull: "Push will upload 4 files and delete 0. OK to push?" For any gated deletion, state the exact count and get explicit confirmation before setting `confirmDeletes`.
@@ -145,6 +145,6 @@ Note the field name difference too: `LabelSettings.outline_color` (Label 2D) vs
145
145
 
146
146
  ## Scene Integration
147
147
 
148
- When the AI adds a node with Summer MCP tools and attaches a script, the script path is set via `summer_set_prop(path, "script", "res://path/to/script.gd")`. The script file must exist first. Create or edit `.gd` files with the host agent's normal file-editing tools, then use Summer MCP only to attach the script and connect scene signals.
148
+ When the AI adds a node with Summer MCP tools and attaches a script, the script path is set via `summer_set_prop(path, "script", "res://path/to/script.gd")`. The script file must exist first. Create it with guarded `summer_write_file` or edit it with `summer_replace_text`, then attach the script and connect scene signals.
149
149
 
150
150
  For signal connections, the receiver must have the handler method. Create the script with the method stub before calling `summer_connect_signal`.
@@ -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.