summer-engine 3.7.0 → 4.0.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 (501) hide show
  1. package/.claude-plugin/marketplace.json +2 -13
  2. package/.claude-plugin/plugin.json +25 -22
  3. package/.codex-plugin/plugin.json +8 -14
  4. package/.cursor-plugin/plugin.json +7 -13
  5. package/.factory-plugin/plugin.json +7 -13
  6. package/AGENTS.md +19 -12
  7. package/CHANGELOG.md +112 -0
  8. package/GEMINI.md +3 -3
  9. package/README.md +111 -31
  10. package/assets/icon.png +0 -0
  11. package/commands/start.md +71 -0
  12. package/commands/summer.md +5 -3
  13. package/dist/cli/banner.js +3 -0
  14. package/dist/cli/commands/login.d.ts +27 -0
  15. package/dist/cli/commands/login.js +58 -12
  16. package/dist/cli/commands/ops.d.ts +47 -0
  17. package/dist/cli/commands/ops.js +301 -0
  18. package/dist/cli/commands/setup.d.ts +2 -0
  19. package/dist/cli/commands/setup.js +37 -12
  20. package/dist/cli/commands/skills.js +11 -7
  21. package/dist/cli/index.js +7 -0
  22. package/dist/core/agent-host.d.ts +65 -0
  23. package/dist/core/agent-host.js +193 -0
  24. package/dist/core/capabilities/agent-playbook.d.ts +3 -0
  25. package/dist/core/capabilities/agent-playbook.js +54 -2
  26. package/dist/core/capabilities/apps.d.ts +341 -0
  27. package/dist/core/capabilities/apps.js +353 -0
  28. package/dist/core/capabilities/doctor.d.ts +3 -0
  29. package/dist/core/capabilities/doctor.js +20 -15
  30. package/dist/core/capabilities/enable-plugin.d.ts +27 -0
  31. package/dist/core/capabilities/enable-plugin.js +75 -0
  32. package/dist/core/capabilities/fabricate-mesh.d.ts +2 -2
  33. package/dist/core/capabilities/game-task-plan.d.ts +12 -6
  34. package/dist/core/capabilities/game-task-plan.js +80 -5
  35. package/dist/core/capabilities/motion-generation.js +2 -2
  36. package/dist/core/capabilities/navigation/open.d.ts +6 -2
  37. package/dist/core/capabilities/navigation/open.js +3 -0
  38. package/dist/core/capabilities/publish-build.js +2 -0
  39. package/dist/core/capabilities/runtime-control.d.ts +4 -4
  40. package/dist/core/capabilities/scene-script-target.d.ts +17 -0
  41. package/dist/core/capabilities/scene-script-target.js +70 -0
  42. package/dist/core/capabilities/sfx-choices.d.ts +4 -0
  43. package/dist/core/capabilities/sfx-choices.js +13 -6
  44. package/dist/core/capabilities/tool-dispatch.d.ts +12 -3
  45. package/dist/core/capabilities/tool-dispatch.js +130 -46
  46. package/dist/core/capability-skew.js +4 -0
  47. package/dist/core/embeddings.d.ts +2 -0
  48. package/dist/core/embeddings.js +1 -1
  49. package/dist/core/error-codes.d.ts +62 -0
  50. package/dist/core/error-codes.js +97 -0
  51. package/dist/core/format.d.ts +2 -0
  52. package/dist/core/format.js +2 -1
  53. package/dist/core/hosted-mcp.d.ts +22 -0
  54. package/dist/core/hosted-mcp.js +56 -1
  55. package/dist/core/library-read.js +5 -0
  56. package/dist/core/library-search.js +2 -1
  57. package/dist/core/oauth.js +4 -0
  58. package/dist/core/ops/catalog.d.ts +41 -0
  59. package/dist/core/ops/catalog.js +145 -0
  60. package/dist/core/ops/cloud.d.ts +56 -0
  61. package/dist/core/ops/cloud.js +175 -0
  62. package/dist/core/ops/contract.d.ts +119 -0
  63. package/dist/core/ops/contract.js +142 -0
  64. package/dist/core/ops/engine-answer.d.ts +25 -0
  65. package/dist/core/ops/engine-answer.js +117 -0
  66. package/dist/core/ops/engine.d.ts +55 -0
  67. package/dist/core/ops/engine.js +649 -0
  68. package/dist/core/ops/save-files.d.ts +78 -0
  69. package/dist/core/ops/save-files.js +419 -0
  70. package/dist/core/ops/search.d.ts +9 -0
  71. package/dist/core/ops/search.js +55 -0
  72. package/dist/core/skills-registry.d.ts +16 -1
  73. package/dist/core/skills-registry.js +35 -2
  74. package/dist/core/telemetry.d.ts +32 -0
  75. package/dist/core/telemetry.js +38 -10
  76. package/dist/core/tool-profiles.d.ts +25 -0
  77. package/dist/core/tool-profiles.js +41 -0
  78. package/dist/installer/agent-config.d.ts +17 -4
  79. package/dist/installer/agent-config.js +22 -6
  80. package/dist/installer/agent-table.d.ts +3 -0
  81. package/dist/installer/agent-table.js +10 -7
  82. package/dist/installer/setup.d.ts +2 -0
  83. package/dist/installer/setup.js +9 -4
  84. package/dist/installer/version-check.d.ts +29 -9
  85. package/dist/installer/version-check.js +81 -28
  86. package/dist/mcp/command.js +7 -0
  87. package/dist/mcp/hosted-mount.d.ts +27 -2
  88. package/dist/mcp/hosted-mount.js +66 -24
  89. package/dist/mcp/legacy-toolset.d.ts +27 -0
  90. package/dist/mcp/legacy-toolset.js +43 -0
  91. package/dist/mcp/ops-surface.d.ts +59 -0
  92. package/dist/mcp/ops-surface.js +443 -0
  93. package/dist/mcp/server.d.ts +35 -11
  94. package/dist/mcp/server.js +236 -89
  95. package/dist/mcp/tool-results.d.ts +26 -0
  96. package/dist/mcp/tool-results.js +81 -0
  97. package/dist/mcp/tool-surface.d.ts +65 -0
  98. package/dist/mcp/tool-surface.js +317 -0
  99. package/dist/mcp/tools/app-tools.d.ts +2 -0
  100. package/dist/mcp/tools/app-tools.js +71 -0
  101. package/dist/mcp/tools/asset-tools.js +55 -53
  102. package/dist/mcp/tools/audit-tools.js +21 -21
  103. package/dist/mcp/tools/debug-tools.js +6 -6
  104. package/dist/mcp/tools/fabricate-tools.js +6 -6
  105. package/dist/mcp/tools/generate-tools.js +76 -70
  106. package/dist/mcp/tools/project-tools.d.ts +9 -4
  107. package/dist/mcp/tools/project-tools.js +16 -10
  108. package/dist/mcp/tools/scene-tools.js +12 -23
  109. package/dist/mcp/tools/script-tools.js +9 -5
  110. package/dist/mcp/tools/with-engine.d.ts +6 -0
  111. package/dist/mcp/tools/with-engine.js +19 -0
  112. package/gemini-extension.json +6 -12
  113. package/hooks/pre-commit-doctor.sh +5 -4
  114. package/hooks/session-start.sh +24 -28
  115. package/integrations/claude-desktop/README.md +1 -1
  116. package/integrations/copilot-jetbrains/README.md +1 -1
  117. package/integrations/junie/README.md +1 -1
  118. package/integrations/lm-studio/README.md +1 -1
  119. package/integrations/trae/README.md +1 -1
  120. package/integrations/visual-studio/README.md +1 -1
  121. package/library/references/mcp-tools-reference/mcp-tools-reference.md +85 -35
  122. package/library/references/mcp-tools-reference/resource.yaml +1 -1
  123. package/library/references/product-map/resource.yaml +2 -2
  124. package/library/skills/3d-lighting/SKILL.md +53 -28
  125. package/library/skills/3d-lighting/resource.yaml +1 -1
  126. package/library/skills/README.md +126 -116
  127. package/library/skills/adaptive-music/SKILL.md +19 -23
  128. package/library/skills/adaptive-music/resource.yaml +1 -1
  129. package/library/skills/agent-playtesting/SKILL.md +1 -1
  130. package/library/skills/agent-playtesting/resource.yaml +1 -1
  131. package/library/skills/ai-characters-in-games/SKILL.md +1 -1
  132. package/library/skills/ai-characters-in-games/resource.yaml +1 -1
  133. package/library/skills/ambient-bed/SKILL.md +22 -13
  134. package/library/skills/ambient-bed/resource.yaml +1 -1
  135. package/library/skills/animated-loop/SKILL.md +41 -32
  136. package/library/skills/animated-loop/resource.yaml +1 -1
  137. package/library/skills/animation-tree/SKILL.md +1 -1
  138. package/library/skills/animation-tree/resource.yaml +1 -1
  139. package/library/skills/art-direction/SKILL.md +3 -3
  140. package/library/skills/art-direction/resource.yaml +1 -1
  141. package/library/skills/asset-strategy/SKILL.md +21 -4
  142. package/library/skills/asset-strategy/resource.yaml +2 -1
  143. package/library/skills/audio-direction/SKILL.md +10 -10
  144. package/library/skills/audio-direction/resource.yaml +1 -1
  145. package/library/skills/auto-fire-targeting/SKILL.md +1 -1
  146. package/library/skills/auto-fire-targeting/resource.yaml +1 -1
  147. package/library/skills/bounded-engine-runs/SKILL.md +1 -1
  148. package/library/skills/bounded-engine-runs/resource.yaml +1 -1
  149. package/library/skills/brainstorm-game/SKILL.md +1 -1
  150. package/library/skills/brainstorm-game/resource.yaml +1 -1
  151. package/library/skills/brainstorming/SKILL.md +1 -1
  152. package/library/skills/brainstorming/resource.yaml +1 -1
  153. package/library/skills/browse-templates/SKILL.md +1 -1
  154. package/library/skills/browse-templates/resource.yaml +1 -1
  155. package/library/skills/camera-rigs/SKILL.md +2 -2
  156. package/library/skills/camera-rigs/resource.yaml +1 -1
  157. package/library/skills/celeste-momentum-platforming/resource.yaml +1 -0
  158. package/library/skills/character-animation-wiring/SKILL.md +4 -4
  159. package/library/skills/character-animation-wiring/resource.yaml +1 -1
  160. package/library/skills/character-model/SKILL.md +55 -47
  161. package/library/skills/character-model/resource.yaml +1 -1
  162. package/library/skills/character-movement/SKILL.md +3 -3
  163. package/library/skills/character-movement/resource.yaml +1 -1
  164. package/library/skills/character-portrait/SKILL.md +24 -19
  165. package/library/skills/character-portrait/resource.yaml +1 -1
  166. package/library/skills/cinematic-cutscene/SKILL.md +58 -46
  167. package/library/skills/cinematic-cutscene/resource.yaml +1 -1
  168. package/library/skills/combat-basics/SKILL.md +1 -1
  169. package/library/skills/combat-basics/resource.yaml +1 -1
  170. package/library/skills/compatibility-renderer-traps/SKILL.md +1 -1
  171. package/library/skills/compatibility-renderer-traps/resource.yaml +1 -1
  172. package/library/skills/concept-art/SKILL.md +16 -12
  173. package/library/skills/concept-art/resource.yaml +1 -1
  174. package/library/skills/concept-to-level/SKILL.md +239 -0
  175. package/library/skills/concept-to-level/references/technical-rules.md +150 -0
  176. package/library/skills/concept-to-level/resource.yaml +44 -0
  177. package/library/skills/create-asset-sheet/SKILL.md +19 -13
  178. package/library/skills/create-asset-sheet/resource.yaml +1 -1
  179. package/library/skills/debug/SKILL.md +2 -2
  180. package/library/skills/debug/resource.yaml +1 -1
  181. package/library/skills/debugging-game-feel/SKILL.md +1 -1
  182. package/library/skills/debugging-game-feel/resource.yaml +1 -1
  183. package/library/skills/design-level/SKILL.md +23 -35
  184. package/library/skills/design-level/resource.yaml +1 -1
  185. package/library/skills/design-mechanic/SKILL.md +1 -1
  186. package/library/skills/design-mechanic/resource.yaml +1 -1
  187. package/library/skills/design-npc/SKILL.md +22 -24
  188. package/library/skills/design-npc/resource.yaml +1 -1
  189. package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
  190. package/library/skills/diagnosing-perf-regressions/resource.yaml +1 -1
  191. package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
  192. package/library/skills/driving-the-editor-ui/resource.yaml +1 -1
  193. package/library/skills/environment-kit/SKILL.md +20 -16
  194. package/library/skills/environment-kit/resource.yaml +1 -1
  195. package/library/skills/export-and-ship/SKILL.md +6 -6
  196. package/library/skills/export-and-ship/resource.yaml +1 -1
  197. package/library/skills/fabricating-assets/SKILL.md +7 -7
  198. package/library/skills/fabricating-assets/resource.yaml +3 -3
  199. package/library/skills/facial-and-lipsync/SKILL.md +14 -15
  200. package/library/skills/facial-and-lipsync/resource.yaml +1 -1
  201. package/library/skills/fps-controller/SKILL.md +33 -41
  202. package/library/skills/fps-controller/resource.yaml +1 -1
  203. package/library/skills/game-feel/SKILL.md +8 -8
  204. package/library/skills/game-feel/resource.yaml +1 -1
  205. package/library/skills/gameskill/SKILL.md +4 -4
  206. package/library/skills/gameskill/resource.yaml +1 -1
  207. package/library/skills/gdscript-patterns/SKILL.md +1 -1
  208. package/library/skills/gdscript-patterns/resource.yaml +1 -1
  209. package/library/skills/generate-motion/SKILL.md +30 -21
  210. package/library/skills/generate-motion/resource.yaml +1 -1
  211. package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
  212. package/library/skills/godogen-visual-proof-game-generation/resource.yaml +1 -0
  213. package/library/skills/grow-analytics/SKILL.md +3 -3
  214. package/library/skills/grow-analytics/resource.yaml +1 -1
  215. package/library/skills/headless-scripting/SKILL.md +1 -1
  216. package/library/skills/headless-scripting/resource.yaml +1 -1
  217. package/library/skills/in-game-purchases/SKILL.md +1 -1
  218. package/library/skills/in-game-purchases/resource.yaml +1 -1
  219. package/library/skills/instantiate-asset-pack/SKILL.md +2 -2
  220. package/library/skills/instantiate-asset-pack/resource.yaml +1 -1
  221. package/library/skills/lumera-single-image-scene-reconstruction/resource.yaml +1 -0
  222. package/library/skills/make-game/SKILL.md +4 -4
  223. package/library/skills/make-game/references/2d-platformer.md +1 -1
  224. package/library/skills/make-game/references/3d-fps.md +1 -1
  225. package/library/skills/make-game/references/3d-horror.md +1 -1
  226. package/library/skills/make-game/references/3d-third-person.md +2 -2
  227. package/library/skills/make-game/resource.yaml +1 -1
  228. package/library/skills/multiplayer/SKILL.md +1 -1
  229. package/library/skills/multiplayer/resource.yaml +1 -1
  230. package/library/skills/multiplayer-movement/SKILL.md +1 -1
  231. package/library/skills/multiplayer-movement/resource.yaml +1 -1
  232. package/library/skills/multiplayer-project/SKILL.md +1 -1
  233. package/library/skills/multiplayer-project/resource.yaml +1 -1
  234. package/library/skills/multiplayer-publish/SKILL.md +8 -7
  235. package/library/skills/multiplayer-publish/resource.yaml +3 -3
  236. package/library/skills/multiplayer-state/SKILL.md +1 -1
  237. package/library/skills/multiplayer-state/resource.yaml +1 -1
  238. package/library/skills/multiplayer-testing/SKILL.md +1 -1
  239. package/library/skills/multiplayer-testing/resource.yaml +1 -1
  240. package/library/skills/music-track/SKILL.md +22 -13
  241. package/library/skills/music-track/resource.yaml +1 -1
  242. package/library/skills/navigate-summer/SKILL.md +11 -9
  243. package/library/skills/navigate-summer/resource.yaml +1 -1
  244. package/library/skills/new-project/SKILL.md +1 -1
  245. package/library/skills/new-project/resource.yaml +1 -1
  246. package/library/skills/organic-model/SKILL.md +24 -18
  247. package/library/skills/organic-model/resource.yaml +1 -1
  248. package/library/skills/pixel-art/SKILL.md +27 -23
  249. package/library/skills/pixel-art/resource.yaml +1 -1
  250. package/library/skills/play/SKILL.md +1 -1
  251. package/library/skills/play/resource.yaml +1 -1
  252. package/library/skills/playtesting-a-feature/SKILL.md +1 -1
  253. package/library/skills/playtesting-a-feature/resource.yaml +1 -1
  254. package/library/skills/procedural-animation/SKILL.md +20 -16
  255. package/library/skills/procedural-animation/resource.yaml +1 -1
  256. package/library/skills/prop-model/SKILL.md +25 -19
  257. package/library/skills/prop-model/resource.yaml +1 -1
  258. package/library/skills/psx-retro-rendering/resource.yaml +1 -0
  259. package/library/skills/publish-your-game/SKILL.md +16 -6
  260. package/library/skills/publish-your-game/resource.yaml +3 -3
  261. package/library/skills/realtime-wet-surfaces/resource.yaml +1 -0
  262. package/library/skills/release-readiness/SKILL.md +1 -1
  263. package/library/skills/release-readiness/resource.yaml +1 -1
  264. package/library/skills/remote-deploy/SKILL.md +1 -1
  265. package/library/skills/remote-deploy/resource.yaml +1 -1
  266. package/library/skills/retarget/SKILL.md +23 -20
  267. package/library/skills/retarget/resource.yaml +1 -1
  268. package/library/skills/running-in-the-cloud/SKILL.md +1 -1
  269. package/library/skills/running-in-the-cloud/resource.yaml +1 -1
  270. package/library/skills/save-load/SKILL.md +1 -1
  271. package/library/skills/save-load/resource.yaml +1 -1
  272. package/library/skills/scene-composition/SKILL.md +1 -1
  273. package/library/skills/scene-composition/resource.yaml +1 -1
  274. package/library/skills/scene-hierarchy-design/SKILL.md +2 -2
  275. package/library/skills/scene-hierarchy-design/resource.yaml +1 -1
  276. package/library/skills/scene-scripting/SKILL.md +66 -636
  277. package/library/skills/scene-scripting/references/ctx-api.md +184 -0
  278. package/library/skills/scene-scripting/references/recipes-2d-ui.md +193 -0
  279. package/library/skills/scene-scripting/references/recipes-3d.md +280 -0
  280. package/library/skills/scene-scripting/resource.yaml +4 -4
  281. package/library/skills/scene-to-level/SKILL.md +2 -2
  282. package/library/skills/scene-to-level/resource.yaml +1 -1
  283. package/library/skills/skill-create/resource.yaml +1 -0
  284. package/library/skills/skill-improve/resource.yaml +1 -0
  285. package/library/skills/skill-test/SKILL.md +2 -2
  286. package/library/skills/skill-test/resource.yaml +1 -0
  287. package/library/skills/skintokens-auto-rigging/resource.yaml +1 -0
  288. package/library/skills/skybox-panorama/SKILL.md +27 -21
  289. package/library/skills/skybox-panorama/resource.yaml +1 -1
  290. package/library/skills/sound-effect/SKILL.md +31 -20
  291. package/library/skills/sound-effect/resource.yaml +1 -1
  292. package/library/skills/spatial-placement/SKILL.md +14 -9
  293. package/library/skills/spatial-placement/resource.yaml +1 -1
  294. package/library/skills/sprite-sheet/SKILL.md +32 -27
  295. package/library/skills/sprite-sheet/resource.yaml +1 -1
  296. package/library/skills/store-art/SKILL.md +3 -3
  297. package/library/skills/store-art/resource.yaml +2 -2
  298. package/library/skills/store-listing/SKILL.md +3 -3
  299. package/library/skills/store-listing/resource.yaml +2 -2
  300. package/library/skills/summer-analytics/SKILL.md +7 -5
  301. package/library/skills/summer-analytics/resource.yaml +2 -2
  302. package/library/skills/summer-apps/SKILL.md +168 -0
  303. package/library/skills/summer-apps/manifest.md +57 -0
  304. package/library/skills/summer-apps/minimal-app.md +183 -0
  305. package/library/skills/summer-apps/resource.yaml +36 -0
  306. package/library/skills/summer-apps/sdk-reference.md +135 -0
  307. package/library/skills/summer-apps-design/SKILL.md +197 -0
  308. package/library/skills/summer-apps-design/resource.yaml +23 -0
  309. package/library/skills/summer-assets/SKILL.md +56 -0
  310. package/library/skills/summer-assets/resource.yaml +34 -0
  311. package/library/skills/summer-store/SKILL.md +1 -1
  312. package/library/skills/text-to-motion/SKILL.md +30 -23
  313. package/library/skills/text-to-motion/prompts-and-controls.md +5 -5
  314. package/library/skills/text-to-motion/resource.yaml +1 -1
  315. package/library/skills/text-to-motion/rigging-for-text-motion.md +2 -2
  316. package/library/skills/tileable-texture/SKILL.md +19 -15
  317. package/library/skills/tileable-texture/resource.yaml +1 -1
  318. package/library/skills/trailer-shot/SKILL.md +28 -24
  319. package/library/skills/trailer-shot/resource.yaml +1 -1
  320. package/library/skills/tune-performance/SKILL.md +6 -6
  321. package/library/skills/tune-performance/resource.yaml +1 -1
  322. package/library/skills/ui-basics/SKILL.md +41 -36
  323. package/library/skills/ui-basics/resource.yaml +1 -1
  324. package/library/skills/ui-graphics/SKILL.md +47 -38
  325. package/library/skills/ui-graphics/resource.yaml +1 -1
  326. package/library/skills/use-widget-asset/SKILL.md +1 -1
  327. package/library/skills/use-widget-asset/resource.yaml +1 -1
  328. package/library/skills/using-summer/SKILL.md +7 -5
  329. package/library/skills/using-summer/resource.yaml +1 -1
  330. package/library/skills/vehicle-model/SKILL.md +65 -57
  331. package/library/skills/vehicle-model/resource.yaml +1 -1
  332. package/library/skills/verification-before-completion/SKILL.md +1 -1
  333. package/library/skills/verification-before-completion/resource.yaml +1 -1
  334. package/library/skills/verifying-scenes/SKILL.md +2 -2
  335. package/library/skills/verifying-scenes/resource.yaml +1 -1
  336. package/library/skills/vfx-dissolve/SKILL.md +2 -2
  337. package/library/skills/vfx-dissolve/resource.yaml +1 -1
  338. package/library/skills/vfx-fire/SKILL.md +15 -41
  339. package/library/skills/vfx-fire/resource.yaml +1 -1
  340. package/library/skills/vfx-hit-spark/SKILL.md +1 -1
  341. package/library/skills/vfx-hit-spark/resource.yaml +1 -1
  342. package/library/skills/vfx-lightning/SKILL.md +7 -16
  343. package/library/skills/vfx-lightning/resource.yaml +1 -1
  344. package/library/skills/vfx-magic-glow/SKILL.md +23 -32
  345. package/library/skills/vfx-magic-glow/resource.yaml +1 -1
  346. package/library/skills/vfx-muzzle-flash/SKILL.md +20 -35
  347. package/library/skills/vfx-muzzle-flash/resource.yaml +1 -1
  348. package/library/skills/vfx-smoke/SKILL.md +13 -31
  349. package/library/skills/vfx-smoke/resource.yaml +1 -1
  350. package/library/skills/vfx-water-ripple/SKILL.md +12 -31
  351. package/library/skills/vfx-water-ripple/resource.yaml +1 -1
  352. package/library/skills/voice-line/SKILL.md +71 -40
  353. package/library/skills/voice-line/resource.yaml +1 -1
  354. package/library/skills/web-and-touch-input/SKILL.md +1 -1
  355. package/library/skills/web-and-touch-input/resource.yaml +1 -1
  356. package/library/skills/web-compatibility-look/SKILL.md +1 -1
  357. package/library/skills/web-compatibility-look/resource.yaml +1 -1
  358. package/library/skills/world-building-3d/SKILL.md +1 -1
  359. package/library/skills/world-building-3d/resource.yaml +1 -1
  360. package/library/skills/writing-skills/resource.yaml +1 -0
  361. package/library/tools/add-node/GUIDE.md +14 -0
  362. package/library/tools/align-distribute-3d/GUIDE.md +7 -0
  363. package/library/tools/app-call/resource.yaml +59 -0
  364. package/library/tools/app-create/resource.yaml +67 -0
  365. package/library/tools/app-data/resource.yaml +74 -0
  366. package/library/tools/app-dock/resource.yaml +59 -0
  367. package/library/tools/app-events/resource.yaml +68 -0
  368. package/library/tools/app-get/resource.yaml +46 -0
  369. package/library/tools/app-guide/resource.yaml +55 -0
  370. package/library/tools/app-list/resource.yaml +48 -0
  371. package/library/tools/app-page/resource.yaml +74 -0
  372. package/library/tools/app-publish/resource.yaml +90 -0
  373. package/library/tools/app-report-gap/resource.yaml +58 -0
  374. package/library/tools/app-screenshot/resource.yaml +103 -0
  375. package/library/tools/app-tools/resource.yaml +46 -0
  376. package/library/tools/app-update/resource.yaml +68 -0
  377. package/library/tools/attach-to-surface/GUIDE.md +15 -0
  378. package/library/tools/batch/GUIDE.md +27 -0
  379. package/library/tools/camera-bookmark/GUIDE.md +12 -0
  380. package/library/tools/capture-gameplay/GUIDE.md +3 -0
  381. package/library/tools/capture-gameplay/resource.yaml +3 -3
  382. package/library/tools/check-job/resource.yaml +1 -1
  383. package/library/tools/clear-console/GUIDE.md +3 -0
  384. package/library/tools/connect-ports/GUIDE.md +9 -0
  385. package/library/tools/connect-signal/GUIDE.md +14 -0
  386. package/library/tools/create-debug-report/GUIDE.md +10 -0
  387. package/library/tools/create-scene/GUIDE.md +10 -0
  388. package/library/tools/debug-views/GUIDE.md +7 -0
  389. package/library/tools/enable-plugin/GUIDE.md +3 -0
  390. package/library/tools/enable-plugin/resource.yaml +53 -0
  391. package/library/tools/export-game/GUIDE.md +3 -0
  392. package/library/tools/export-game/resource.yaml +3 -3
  393. package/library/tools/export-templates/GUIDE.md +3 -0
  394. package/library/tools/fabricate-3d/GUIDE.md +19 -0
  395. package/library/tools/frame-nodes/GUIDE.md +9 -0
  396. package/library/tools/frame-shot/GUIDE.md +9 -0
  397. package/library/tools/game-control/GUIDE.md +9 -0
  398. package/library/tools/game-input/GUIDE.md +9 -0
  399. package/library/tools/game-probe/GUIDE.md +9 -0
  400. package/library/tools/generate-3d/resource.yaml +3 -3
  401. package/library/tools/generate-motion/resource.yaml +2 -2
  402. package/library/tools/get-console/GUIDE.md +9 -0
  403. package/library/tools/get-console/resource.yaml +5 -0
  404. package/library/tools/get-debugger-errors/GUIDE.md +7 -0
  405. package/library/tools/get-debugger-errors/resource.yaml +5 -0
  406. package/library/tools/get-debugger-warnings/GUIDE.md +7 -0
  407. package/library/tools/get-debugger-warnings/resource.yaml +5 -0
  408. package/library/tools/get-diagnostics/GUIDE.md +13 -0
  409. package/library/tools/get-project-context/GUIDE.md +25 -0
  410. package/library/tools/get-runtime-tree/GUIDE.md +7 -0
  411. package/library/tools/get-runtime-tree/resource.yaml +5 -0
  412. package/library/tools/get-scene-tree/GUIDE.md +11 -0
  413. package/library/tools/get-scene-tree/resource.yaml +5 -0
  414. package/library/tools/get-script-errors/GUIDE.md +5 -0
  415. package/library/tools/grep/GUIDE.md +11 -0
  416. package/library/tools/import-asset/GUIDE.md +8 -0
  417. package/library/tools/import-asset-by-id/GUIDE.md +12 -0
  418. package/library/tools/import-from-url/GUIDE.md +10 -0
  419. package/library/tools/import-from-url-batch/GUIDE.md +3 -0
  420. package/library/tools/import-hdri/GUIDE.md +16 -0
  421. package/library/tools/input-map-bind/GUIDE.md +11 -0
  422. package/library/tools/inspect-asset/GUIDE.md +14 -0
  423. package/library/tools/inspect-asset/resource.yaml +5 -0
  424. package/library/tools/inspect-node/GUIDE.md +11 -0
  425. package/library/tools/inspect-node/resource.yaml +5 -0
  426. package/library/tools/inspect-resource/GUIDE.md +7 -0
  427. package/library/tools/inspect-resource/resource.yaml +5 -0
  428. package/library/tools/inspect-runtime-node/GUIDE.md +7 -0
  429. package/library/tools/inspect-runtime-node/resource.yaml +5 -0
  430. package/library/tools/instantiate-scene/GUIDE.md +12 -0
  431. package/library/tools/is-running/GUIDE.md +3 -0
  432. package/library/tools/measure/GUIDE.md +8 -0
  433. package/library/tools/navigation-probe/GUIDE.md +9 -0
  434. package/library/tools/open/resource.yaml +2 -2
  435. package/library/tools/open-main-scene/GUIDE.md +6 -0
  436. package/library/tools/open-scene/GUIDE.md +8 -0
  437. package/library/tools/place-adjacent/GUIDE.md +7 -0
  438. package/library/tools/play/GUIDE.md +13 -0
  439. package/library/tools/project-setting/GUIDE.md +9 -0
  440. package/library/tools/publish-build/resource.yaml +6 -6
  441. package/library/tools/raycast/GUIDE.md +7 -0
  442. package/library/tools/read-file/GUIDE.md +10 -0
  443. package/library/tools/read-library/resource.yaml +5 -0
  444. package/library/tools/recent-events/GUIDE.md +7 -0
  445. package/library/tools/remove-node/GUIDE.md +3 -0
  446. package/library/tools/repeat-along/GUIDE.md +5 -0
  447. package/library/tools/replace-node/GUIDE.md +9 -0
  448. package/library/tools/replace-text/GUIDE.md +5 -0
  449. package/library/tools/run-editor-script/GUIDE.md +16 -0
  450. package/library/tools/run-script/GUIDE.md +30 -0
  451. package/library/tools/run-script/resource.yaml +6 -3
  452. package/library/tools/runtime-animate/GUIDE.md +7 -0
  453. package/library/tools/runtime-call/GUIDE.md +7 -0
  454. package/library/tools/runtime-set/GUIDE.md +9 -0
  455. package/library/tools/runtime-spawn/GUIDE.md +9 -0
  456. package/library/tools/save-scene/GUIDE.md +3 -0
  457. package/library/tools/scene-audit/GUIDE.md +29 -0
  458. package/library/tools/screenshot/GUIDE.md +17 -0
  459. package/library/tools/select-node/GUIDE.md +3 -0
  460. package/library/tools/set-prop/GUIDE.md +23 -0
  461. package/library/tools/set-resource-property/GUIDE.md +8 -0
  462. package/library/tools/shot-sheet/GUIDE.md +7 -0
  463. package/library/tools/snap-to-surface/GUIDE.md +17 -0
  464. package/library/tools/snapshot-diff/GUIDE.md +7 -0
  465. package/library/tools/starcast/GUIDE.md +12 -0
  466. package/library/tools/stop/GUIDE.md +3 -0
  467. package/library/tools/test-placement/GUIDE.md +7 -0
  468. package/library/tools/ui-actions/GUIDE.md +12 -0
  469. package/library/tools/ui-activate/GUIDE.md +11 -0
  470. package/library/tools/ui-screenshot/GUIDE.md +9 -0
  471. package/library/tools/ui-tree/GUIDE.md +10 -0
  472. package/library/tools/wait-for-event/GUIDE.md +11 -0
  473. package/library/tools/world-snapshot/GUIDE.md +9 -0
  474. package/library/tools/write-file/GUIDE.md +5 -0
  475. package/library/tools/zoom/GUIDE.md +5 -0
  476. package/package.json +6 -4
  477. package/registry/generated/aliases.json +15 -0
  478. package/registry/generated/counts.json +3 -3
  479. package/registry/generated/gemini-extension.json +6 -12
  480. package/registry/generated/index.json +1155 -408
  481. package/registry/generated/marketplace.claude.json +2 -13
  482. package/registry/generated/plugin.claude.json +25 -22
  483. package/registry/generated/plugin.codex.json +8 -14
  484. package/registry/generated/plugin.cursor.json +7 -13
  485. package/registry/generated/plugin.factory.json +7 -13
  486. package/registry/generated/server.json +34 -0
  487. package/registry/generated/skills-index.md +126 -116
  488. package/registry/generated/skills-registry.json +178 -113
  489. package/registry/operations/fixtures/invalid-deprecated-without-replacement.json +60 -0
  490. package/registry/operations/fixtures/invalid-name.json +60 -0
  491. package/registry/operations/fixtures/invalid-publish-without-owner.json +82 -0
  492. package/registry/operations/fixtures/invalid-spend-without-estimate.json +42 -0
  493. package/registry/operations/fixtures/invalid-unknown-field.json +61 -0
  494. package/registry/operations/fixtures/valid-player-facing.json +82 -0
  495. package/registry/operations/fixtures/valid-read.json +60 -0
  496. package/registry/operations/fixtures/valid-spend.json +43 -0
  497. package/registry/operations/legacy-names.json +1206 -0
  498. package/registry/schemas/allowed-hosts.json +4 -2
  499. package/registry/schemas/operation.schema.json +318 -0
  500. package/registry/schemas/skill.schema.json +4 -0
  501. package/CLAUDE.md +0 -7
@@ -0,0 +1,184 @@
1
+ # scene-scripting: the extended ctx API
2
+
3
+ The second and later tiers of the `ctx` object that `summer_run_script` hands to `func run(ctx):`. The core tier (creation helpers, `find`, `save_scene`, `summary`) is in the `scene-scripting` skill. Call results from `ctx` are untyped: write `var wall = ctx.add_mesh(...)`, never `var wall := ...` (GDScript cannot infer a type from an untyped call and refuses to compile).
4
+
5
+ ## The geometry & authoring stdlib (geometry tier)
6
+
7
+ Newer engines extend ctx with a second tier: real geometry (booleans, lathe, sweep, terrain), mesh post-processing (smooth, decimate, UVs, mirror, collision), keyframe animation, and text shaders. Frozen signatures:
8
+
9
+ ```gdscript
10
+ boolean(a: Node, b: Node, op: String = "union") -> MeshInstance3D
11
+ # op: union|difference|intersection. Manifold-exact CSG, baked to a plain
12
+ # ArrayMesh — no live CSG nodes remain. a and b are CONSUMED (freed) by
13
+ # default; pass keep_inputs: bool = true as the final param to keep them.
14
+ extrude_polygon(points: PackedVector2Array, depth: float, name: String,
15
+ parent: Node = null) -> MeshInstance3D # 2D footprint -> prism, baked
16
+ lathe(points: PackedVector2Array, name: String, parent: Node = null,
17
+ spin_degrees: float = 360.0, sides: int = 32) -> MeshInstance3D # revolve a profile, baked
18
+ sweep(points: PackedVector2Array, path_points: PackedVector3Array,
19
+ name: String, parent: Node = null) -> MeshInstance3D # profile swept along a 3D path, baked
20
+ # add_mesh shapes extended: torus | text (props.text: String, TextMesh)
21
+ set_smooth(node: Node, angle_deg: float = 30.0) -> bool # shade smooth by angle
22
+ terrain(size: Vector2, height: float, seed: int, name: String,
23
+ parent: Node = null, image_path: String = "") -> MeshInstance3D
24
+ # noise heightfield (or heightmap image via image_path); adds
25
+ # HeightMapShape3D collision under a StaticBody3D child automatically
26
+ decimate(node: Node, ratio: float) -> bool # simplify mesh to ~ratio of triangles
27
+ convex_collision(node: Node, decompose: bool = false) -> Node
28
+ # single convex hull, or multi-shape convex decomposition when decompose;
29
+ # ALL created bodies are owned — they survive the save
30
+ uv_planar(node: Node, axis: String = "y", scale: float = 1.0) -> bool
31
+ uv_box(node: Node, scale: float = 1.0) -> bool # make textures land on generated geometry
32
+ mirror(node: Node, axis: String = "x") -> Node # mirrored duplicate
33
+ animate(node: Node, property: String, keys: Array, anim_name: String = "",
34
+ loop: bool = false, player: AnimationPlayer = null) -> AnimationPlayer
35
+ # keys: [[time_s, value], ...]; gets-or-creates the AnimationPlayer and
36
+ # library; position/rotation/scale get dedicated 3D tracks (rotation keys
37
+ # are converted for you — never hand-build quaternion tracks)
38
+ make_shader(code: String, params: Dictionary = {}) -> ShaderMaterial
39
+ # builds Shader + ShaderMaterial from source and sets shader parameters;
40
+ # compile errors come back VERBATIM in the result (the `make_shader_errors`
41
+ # report entry, plus errors[]) — read them
42
+ ```
43
+
44
+ Conventions, same as the rest of the stdlib: creation helpers set the owner and return the created node; bad input produces a per-helper `report` entry plus a `null`/`false` return, never a crash; every baked mesh carries generated normals (and tangents where UVs exist). On an older engine these helpers are missing — the CSG-node fallback recipe in `recipes-3d.md` (next to this file) still works everywhere.
45
+
46
+ ## The animation stdlib (animation tier)
47
+
48
+ Character-animation USAGE on top of `animate()` — state machines, method tracks, bone poses, head tracking. Same conventions. Frozen signatures:
49
+
50
+ ```gdscript
51
+ animate(...) v2 — additive extensions, signature unchanged:
52
+ # keys entries also accept {time, value, interpolation: "nearest"|"linear"|"cubic"}
53
+ # property may target bones: "<skeleton_node>:<bone_name>/position|rotation|scale"
54
+ # -> creates bone position_3d/rotation_3d/scale_3d tracks (path "Skeleton:bone")
55
+ animate_method(node: Node, calls: Array, anim_name: String = "",
56
+ loop: bool = false, player: AnimationPlayer = null) -> AnimationPlayer
57
+ # calls: [[time_s, method_name, args_array], ...] -> one method-call track
58
+ anim_state_machine(target: Node, spec: Dictionary,
59
+ player: AnimationPlayer = null) -> AnimationTree
60
+ # spec: { states: {name: clip_name}, transitions: [[from, to, {auto?: bool,
61
+ # blend_s?: float}], ...], start: name }
62
+ # get-or-create AnimationTree wired to the (found or given) player,
63
+ # AnimationNodeStateMachine, active=true; unknown clip names -> report
64
+ # entry listing the player's actual clips (never silent)
65
+ bone_pose(skeleton: Node, bone: String, pose: Dictionary) -> bool
66
+ # pose keys position/rotation/scale -> set_bone_pose_* on Skeleton3D;
67
+ # unknown bone -> false + report listing bone names (capped 64)
68
+ look_at_modifier(node: Node, target: Node, props: Dictionary = {}) -> Node
69
+ # LookAtModifier3D under the skeleton/node, owned
70
+ ```
71
+
72
+ Blend shapes key through plain `animate()` with property `"blend_shapes/<name>"` (value tracks) — no separate helper. The end-to-end recipe (inspect an imported rig's real clips/bones, locomotion wiring, footstep method tracks, root motion, the raw-GDScript fallback for engines without these helpers) lives in `character-animation-wiring` — one hop, not duplicated here.
73
+
74
+ ## The game-completeness stdlib (game-completeness tier: 2D, UI, gameplay code)
75
+
76
+ Everything a script needs to produce a GAME, not just a 3D scene: 2D levels, Control trees, persisted signal connections, attached scripts, prefabs, project settings. Same conventions (owner-by-default, return the node, `prop_warnings`, structured report entries on failure — never silent). 2D helpers work in any edited scene (root may be `Node2D` or `Node`); Control helpers parent under the edited root unless a parent is given. Frozen signatures:
77
+
78
+ ```gdscript
79
+ # 2D
80
+ add_sprite(texture_path: String, name: String, parent: Node = null,
81
+ props: Dictionary = {}) -> Sprite2D # missing texture -> report + null
82
+ add_animated_sprite(frames: Dictionary, name: String, parent: Node = null,
83
+ autoplay: String = "") -> AnimatedSprite2D
84
+ # frames: { anim_name: { frames: [texture_paths], fps: float, loop: bool } } -> SpriteFrames
85
+ add_tilemap(tileset_path: String, name: String, parent: Node = null) -> TileMapLayer
86
+ paint_tiles(layer: TileMapLayer, cells: Array, source_id: int,
87
+ atlas_coords: Vector2i = Vector2i.ZERO) -> int # cells: [Vector2i]; returns count
88
+ paint_rect(layer: TileMapLayer, rect: Rect2i, source_id: int,
89
+ atlas_coords: Vector2i = Vector2i.ZERO) -> int
90
+ add_body_2d(kind: String, name: String, parent: Node = null,
91
+ shape: Dictionary = {}, props: Dictionary = {}) -> Node
92
+ # kind: static|rigid|character|area ; shape: {type: rect|circle|capsule, size|radius|height}
93
+ # -> body + owned CollisionShape2D child. Empty shape = a 32x32 rect (confessed in
94
+ # prop_warnings); size may be a float (square); props try the body, then the shape
95
+ add_camera_2d(position: Vector2, zoom: Vector2 = Vector2.ONE, make_current: bool = true,
96
+ limits: Rect2i = Rect2i()) -> Camera2D # empty limits = unlimited
97
+ # Camera2D has no saved "current" flag: make_current persists as `enabled` (+ a live
98
+ # make_current()); make_current: false saves the camera disabled
99
+ add_parallax(layers: Array, name: String, parent: Node = null) -> Node
100
+ # layers: [{texture: path, motion_scale: Vector2, repeat: Vector2i}] -> one Parallax2D per
101
+ # layer under one Node2D group; repeat -> repeat_size. Parallax2D is in the engine tree
102
+ # (no ParallaxBackground fallback); a layer whose texture fails to load is skipped + reported
103
+
104
+ # UI (Control)
105
+ add_ui(kind: String, name: String, parent: Node = null, props: Dictionary = {}) -> Control
106
+ # kind: label|button|panel|vbox|hbox|grid|margin|texture_rect|progress_bar|line_edit|
107
+ # rich_text|color_rect|center ; panel -> PanelContainer (container semantics for HUD
108
+ # layouts; a plain Panel is add_node("Panel", ...)). props.anchor: full_rect|center|
109
+ # top_left|top_right|bottom_left|bottom_right|top_wide|bottom_wide (+ the other
110
+ # Control::PRESET_* names) -> set_anchors_and_offsets_preset, applied BEFORE the other
111
+ # props so an explicit size/position wins; props.text/custom_minimum_size/etc via set();
112
+ # props.texture as a "res://" path is loaded for you. A Control parented under a Node2D
113
+ # gets a prop_warning (it scrolls with the camera — HUDs go under add_canvas_layer)
114
+ add_canvas_layer(name: String, layer: int = 1, parent: Node = null) -> CanvasLayer
115
+ set_theme_overrides(control: Control, overrides: Dictionary) -> int
116
+ # {font_size: int, font_color: Color, <theme_item>: value} -> add_theme_*_override; count applied
117
+ # dispatch by value: Color or "#hex" -> color; int/float -> font_size when the key is/ends with
118
+ # font_size, else constant; StyleBox/Font/Texture2D (or a "res://" path) -> style/font/icon.
119
+ # An item the control's theme type does not define is stored but confessed in prop_warnings
120
+ connect_signal(emitter: Node, signal_name: String, target: Node, method: String,
121
+ binds: Array = []) -> bool # PERSIST flag so it saves in .tscn;
122
+ # unknown signal/method -> report, false
123
+ # NOT `connect` — a ctx method of that name would shadow Object.connect on the ctx object,
124
+ # so nothing named `connect` is bound. Method gate: target.has_method, else its script
125
+ # has_method, else the script SOURCE declares `func <method>(` (attached this run, not yet
126
+ # compiled). Already connected -> true (+ already_connected in the report). Both ends must
127
+ # be owned by the edited root for the .tscn to carry the connection (prop_warning otherwise)
128
+
129
+ # Gameplay-code lane
130
+ attach_script(node: Node, source: String, path: String = "") -> Script
131
+ # compile-validate first (GDScriptLanguage::validate; parse errors -> `attach_script_errors`
132
+ # report entry {node, path, errors: [{line, column, message}]}, null, nothing written);
133
+ # path empty -> res://scripts/<SceneName>/<NodeName>.gd (dirs created; the root node's name
134
+ # when the scene was never saved, prop_warning); writes the file, FS rescan, set_script.
135
+ # An existing file at path IS overwritten; its previous sha is recorded in the report (the
136
+ # pre-run checkpoint covers rollback). Gate: the script's native base (`extends`) must be an
137
+ # ancestor of the node's class — else the file is written but NOT attached (report, null)
138
+ make_prefab(node: Node, path: String, replace_with_instance: bool = true) -> Node
139
+ # pack the subtree to res:// path as a PackedScene (owner fix-up first), save; when
140
+ # replace_with_instance the node is swapped for an instance of the new file (same
141
+ # name/transform/parent; outgoing persisted connections re-established) and the instance
142
+ # is returned; else returns node. REFUSES the scene root and a path open in an editor tab.
143
+ # The node's own position is zeroed for the pack (prefab authored at its origin, like the
144
+ # editor's Save Branch) and restored / copied onto the instance; rotation and scale stay in
145
+ # the prefab. A failure AFTER the file was written keeps + returns the original node (report)
146
+ add_autoload(name: String, path: String) -> bool # ProjectSettings autoload/<name>="*res://…"
147
+ # same gates as the editor's autoload dock: valid identifier, no engine/global-class
148
+ # collision, existing res:// path to a Script or PackedScene
149
+ add_input_action(action: String, events: Array) -> bool
150
+ # events: [{type: key, keycode: String|int} | {type: mouse_button, button_index: int} |
151
+ # {type: joypad_button, button_index: int} | {type: joypad_axis, axis:int, value:float}]
152
+ # writes input/<action> = {deadzone, events} in ProjectSettings + saves; every event is
153
+ # built BEFORE anything is written — unknown shape -> report, false, nothing half-written.
154
+ # New action: deadzone = the engine default 0.2. Existing action: keeps its deadzone and
155
+ # gains only the events it does not already match. Keycode strings go through
156
+ # find_keycode ("Space", "Left", "Ctrl+S" — modifiers become the event's modifier flags)
157
+ set_main_scene(path: String) -> bool # application/run/main_scene + save
158
+ # path must exist and be a PackedScene
159
+ # Project settings are written in the res:// PATH form ("*res://…", "res://…"); the editor UI
160
+ # writes uid:// forms — both resolve. Do not "fix" one into the other.
161
+ ```
162
+
163
+ **Engine posture. Read before relying on any of this.** The game-completeness tier is a frozen contract that not every engine build exposes yet; treat it with the same preview posture as `summer_run_script` itself (which returns `engine_lacks_op` on engines without RunSceneScript). On an engine that has RunSceneScript but predates this tier, a missing helper is a plain GDScript error (`Invalid call to method 'add_ui'…`) and, under the default `undo: "action"`, the whole run rolls back. Fall back to what works everywhere:
164
+
165
+ | Game-completeness helper | Works on every engine |
166
+ |---|---|
167
+ | `add_tilemap` / `paint_tiles` / `paint_rect` | `TileMapLayer.new()` + `layer.tile_set = load(path)`, then `layer.set_cell(coords, source_id, atlas_coords)` in a loop — the GridMap recipe, in 2D |
168
+ | `add_sprite` / `add_animated_sprite` / `add_body_2d` / `add_camera_2d` / `add_parallax` | manual `.new()` + `add_child` + `ctx.set_owner_recursive` |
169
+ | `add_ui` / `add_canvas_layer` / `set_theme_overrides` | `.new()` + `set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)` + `add_theme_constant_override(...)`, owned as above — the `ui-basics` skill's plain-node script |
170
+ | `connect_signal` | `summer_connect_signal` (persists in the `.tscn`); a raw `emitter.pressed.connect(...)` inside the run script does NOT persist |
171
+ | `attach_script` | `summer_write_file` the source, `summer_get_script_errors` on it, then `node.set_script(load(path))` in a script |
172
+ | `make_prefab` | `PackedScene.new().pack(node)` + `ResourceSaver.save(...)` (pack includes only OWNED descendants — owner rules again), then `summer_instantiate_scene` |
173
+ | `add_input_action` / `add_autoload` / `set_main_scene` | `summer_input_map_bind`; `summer_project_setting` (`autoload/<Name>`, `application/run/main_scene`) |
174
+
175
+ **Undo posture.** File-writing helpers (`attach_script`, `make_prefab`) and project-settings helpers (`add_autoload`, `add_input_action`, `set_main_scene`) are covered by the pre-run checkpoint, NOT by the packed-scene undo action — a `rolled_back: true` result has reverted the scene but not those files or settings. The result's `undo_action` note says so whenever any of them ran (`files_written: [paths]`, `project_settings_changed: [keys]`): read it, and surface `no_rewind_point: true` to the user before more work of this kind.
176
+
177
+ ## Pitfalls
178
+
179
+ | Pitfall | Reality |
180
+ |---|---|
181
+ | Calling a geometry, animation or game-completeness helper on an engine that predates it | `Invalid call to method` — the run rolls back. Use the fallback table above. |
182
+ | Reading `rolled_back: true` as "nothing happened" after `attach_script` / `add_autoload` / `set_main_scene` | Files and `project.godot` sit outside the undo action. Read `files_written` / `project_settings_changed`; the checkpoint is the rollback. |
183
+ | `ctx.connect(button, "pressed", hud, "_on_pressed")` | That is `Object.connect` on the ctx object, not the helper — wrong-signature error. The helper is `ctx.connect_signal(...)`. |
184
+ | `var node := ctx.add_node(...)` | `ctx` is untyped, so the type cannot be inferred and the script does not compile. Write `var node = ctx.add_node(...)`. |
@@ -0,0 +1,193 @@
1
+ # scene-scripting: 2D, UI and gameplay-code recipes
2
+
3
+ Every recipe below is the `source` of one call: `summer_run_script(scenePath="res://<the scene>.tscn", source=<the recipe>)`. Name the scene every time; it is opened first when it is not the edited one, and the person's tab comes back after the run. The core helpers (`add_node`, `find`, `add_mesh`, `make_material`, `save_scene` ...) are in the `scene-scripting` skill itself.
4
+ These use the game-completeness tier (`ctx-api.md`, next to this file); on an engine that predates it, use the fallback table there.
5
+
6
+ ## 2D platformer level — tilemap paint, character body, camera limits, parallax (game-completeness tier)
7
+
8
+ One script lays down the level: paint the ground, drop a character body with collision, bound the camera to the level, stack parallax behind it. Tile coordinates are cells; camera limits are pixels (cells × tile size — 32 here).
9
+
10
+ ```gdscript
11
+ func run(ctx):
12
+ const TILE := 32
13
+ var ground = ctx.add_tilemap("res://tilesets/grass.tres", "Ground")
14
+ var painted = ctx.paint_rect(ground, Rect2i(0, 12, 64, 4), 0, Vector2i(0, 0)) # floor: 64 wide, 4 deep
15
+ painted += ctx.paint_rect(ground, Rect2i(20, 8, 6, 1), 0, Vector2i(1, 0)) # a floating platform
16
+ painted += ctx.paint_tiles(ground, [Vector2i(10, 11), Vector2i(11, 11), Vector2i(12, 11)], 0, Vector2i(2, 0)) # a step
17
+ ctx.report("tiles_painted", painted)
18
+
19
+ var player = ctx.add_body_2d("character", "Player", null,
20
+ {"type": "capsule", "radius": 14.0, "height": 60.0},
21
+ {"position": Vector2(3 * TILE, 11 * TILE)})
22
+ ctx.add_sprite("res://sprites/player_idle.png", "Sprite", player)
23
+
24
+ var cam = ctx.add_camera_2d(player.position, Vector2(2, 2), true, Rect2i(0, 0, 64 * TILE, 16 * TILE))
25
+ cam.reparent(player, false) # follow the body...
26
+ cam.position = Vector2.ZERO
27
+ ctx.set_owner_recursive(cam) # ...and re-stamp the owner after ANY reparent
28
+
29
+ ctx.add_parallax([
30
+ {"texture": "res://backgrounds/sky.png", "motion_scale": Vector2(0.1, 0.1), "repeat": Vector2i(1024, 0)},
31
+ {"texture": "res://backgrounds/hills.png", "motion_scale": Vector2(0.4, 0.4), "repeat": Vector2i(1024, 0)},
32
+ ], "Background")
33
+ ctx.report("level", ctx.summary())
34
+ ```
35
+
36
+ Compare `tiles_painted` with the cell areas you asked for (256 + 6 + 3 here) — a short count means cells were skipped. Then `summer_snapshot_diff`: `added` must list `Ground`, `Player` **with its `CollisionShape2D` child**, the camera under `Player`, and the `Background` group with one `Parallax2D` per layer. Screenshot `target:"scene" nodePath:"Player"` to see the body standing on the floor row, then the whole scene to see the platform is reachable. Movement needs the controller script and the input actions — two recipes below. Want a working baseline instead of a blank scene? The `2d-platformer` template already has tilemap + `CharacterBody2D` + parallax wired.
37
+
38
+ ## Animated sprite (game-completeness tier)
39
+
40
+ `add_animated_sprite` builds the `SpriteFrames` resource from per-frame texture paths — one entry per animation, `fps` and `loop` per clip — and optionally autoplays one. Cut a sheet into frames first (`assets.slice_sheet`, or the `sprite-sheet` skill when generating them).
41
+
42
+ ```gdscript
43
+ func run(ctx):
44
+ var player = ctx.find("Player")
45
+ if player == null:
46
+ ctx.report("error", "Player not found")
47
+ return
48
+ var anim = ctx.add_animated_sprite({
49
+ "idle": {"frames": ["res://sprites/player/idle_0.png", "res://sprites/player/idle_1.png"], "fps": 4.0, "loop": true},
50
+ "run": {"frames": ["res://sprites/player/run_0.png", "res://sprites/player/run_1.png",
51
+ "res://sprites/player/run_2.png", "res://sprites/player/run_3.png"], "fps": 12.0, "loop": true},
52
+ "jump": {"frames": ["res://sprites/player/jump_0.png"], "fps": 1.0, "loop": false},
53
+ }, "Anim", player, "idle")
54
+ ctx.report("animations", anim.sprite_frames.get_animation_names())
55
+ ```
56
+
57
+ A missing texture path comes back as a report entry — read it before wondering why a clip is short. Which clip plays when is gameplay code (`anim.play("run")` from the controller's `_physics_process`), not scene setup. Verify by playing: `summer_play`, move, `summer_screenshot target:"game"` — an edit-time preview shows frame 0 only.
58
+
59
+ ## HUD — canvas layer, margin, vbox, label/progress/button, anchors, theme overrides (game-completeness tier)
60
+
61
+ ```gdscript
62
+ func run(ctx):
63
+ var hud = ctx.add_canvas_layer("HUD", 1)
64
+ var margin = ctx.add_ui("margin", "Margin", hud, {"anchor": "full_rect"})
65
+ ctx.set_theme_overrides(margin, {"margin_left": 24, "margin_top": 24, "margin_right": 24, "margin_bottom": 24})
66
+
67
+ var column = ctx.add_ui("vbox", "TopLeft", margin)
68
+ var score = ctx.add_ui("label", "Score", column, {"text": "Score: 0"})
69
+ ctx.set_theme_overrides(score, {"font_size": 28, "font_color": Color(1, 1, 1)})
70
+ var health = ctx.add_ui("progress_bar", "Health", column,
71
+ {"min_value": 0, "max_value": 100, "value": 100, "show_percentage": false,
72
+ "custom_minimum_size": Vector2(240, 18)})
73
+
74
+ var pause = ctx.add_ui("button", "PauseButton", hud, {"text": "Pause", "anchor": "top_right"})
75
+ pause.process_mode = Node.PROCESS_MODE_ALWAYS # still clickable while the tree is paused
76
+ ctx.report("hud", ctx.summary())
77
+ ```
78
+
79
+ `props.anchor` runs `set_anchors_and_offsets_preset` — the right way to pin a Control; hand-set `anchor_*`/`offset_*` values drift the moment the window resizes. The preset is applied before the other props, so an explicit `size`/`position` in the same dict wins. `add_ui("panel", …)` is a **PanelContainer** (it sizes to its child — a backdrop for a vbox/hbox); a plain `Panel` is `add_node("Panel", …)`. `set_theme_overrides` returns how many overrides it applied — compare with what you passed (an `int` on a key that is not `font_size` becomes a *constant* override, as with the margins above). Unknown `props` keys land in `prop_warnings` as always (use real property names: `custom_minimum_size`, not `min_size` or a guess). HUD Controls belong under a `CanvasLayer` — a Control parented under a `Node2D` scrolls with the camera and gets a `prop_warning`. For the layout and theme *design* — which container for which job, theme vs inline styling — use `ui-basics`; this is its one-script form.
80
+
81
+ ## Wire a button with connect_signal() (game-completeness tier)
82
+
83
+ `ctx.connect_signal` makes a **persisted** connection (`CONNECT_PERSIST`) — it survives in the `.tscn`, exactly what the editor's ConnectionsDock writes. The target needs a method to call, so attach the script first; a script attached in the same run has not compiled yet, and `connect_signal` accepts it because the source declares `func _on_pause_pressed(` (the method gate):
84
+
85
+ ```gdscript
86
+ func run(ctx):
87
+ var hud = ctx.find("HUD")
88
+ var button = ctx.find("PauseButton")
89
+ if ctx.attach_script(hud, """
90
+ extends CanvasLayer
91
+
92
+ func _on_pause_pressed() -> void:
93
+ get_tree().paused = not get_tree().paused
94
+ """) == null:
95
+ return # parse errors are in the report — fix, re-run
96
+ if not ctx.connect_signal(button, "pressed", hud, "_on_pause_pressed"):
97
+ return # the report names the unknown signal or method
98
+ ctx.report("wired", "PauseButton.pressed -> HUD._on_pause_pressed")
99
+ ```
100
+
101
+ Never wire with a bare `button.pressed.connect(...)` inside the run script: that connection lives only in the editor process and is not saved. And the helper is `connect_signal`, not `connect` — `ctx.connect(...)` is `Object.connect` on the ctx object itself and fails with a wrong-signature error. `true` from `ctx.connect_signal` says the connection was made and flagged persistent (an already-connected pair also returns `true`, with `already_connected` in the report); both ends must be owned by the edited root or the `.tscn` cannot carry it. The proof is `summer_play`, click, `summer_screenshot target:"game"`.
102
+
103
+ ## attach_script — behavior with the parse-error loop (game-completeness tier)
104
+
105
+ `attach_script` validates the source **before** writing anything: a parse error comes back as a report entry (with the line) and the return is `null` — no half-written file, no broken node. Empty `path` → `res://scripts/<SceneName>/<NodeName>.gd`.
106
+
107
+ ```gdscript
108
+ func run(ctx):
109
+ var player = ctx.find("Player")
110
+ var script = ctx.attach_script(player, """
111
+ extends CharacterBody2D
112
+
113
+ const SPEED := 220.0
114
+ const JUMP_VELOCITY := -420.0
115
+
116
+ @onready var anim: AnimatedSprite2D = $Anim
117
+
118
+ func _physics_process(delta: float) -> void:
119
+ if not is_on_floor():
120
+ velocity += get_gravity() * delta
121
+ if Input.is_action_just_pressed("jump") and is_on_floor():
122
+ velocity.y = JUMP_VELOCITY
123
+ var dir := Input.get_axis("move_left", "move_right")
124
+ velocity.x = dir * SPEED
125
+ if dir != 0.0:
126
+ anim.flip_h = dir < 0.0
127
+ anim.play("jump" if not is_on_floor() else ("run" if dir != 0.0 else "idle"))
128
+ move_and_slide()
129
+ """)
130
+ if script == null:
131
+ return # read the report: line + message; fix THAT line; re-run
132
+ ctx.report("script", script.resource_path)
133
+ ```
134
+
135
+ The loop: read the exact parse error (line and identifier) from the report → fix that line → re-run. Do not guess-and-mutate. An existing file at `path` is overwritten and its previous sha recorded in the report — the pre-run checkpoint is the rollback for that, not the undo action. Idioms (typed declarations, signals, `_ready` vs `_process`): `gdscript-patterns`. Later edits to a script already on disk: `summer_write_file` + `summer_get_script_errors`.
136
+
137
+ ## make_prefab — turn a built subtree into a reusable .tscn (game-completeness tier)
138
+
139
+ Build the thing once in-scene, then pack it. With `replace_with_instance` (the default) the inline subtree is swapped for an instance of the new file — same name, transform, parent — and the instance is returned.
140
+
141
+ ```gdscript
142
+ func run(ctx):
143
+ var torch = ctx.find("Torch") # Sprite2D + PointLight2D + Area2D you built above
144
+ if torch == null:
145
+ return
146
+ var first = ctx.make_prefab(torch, "res://prefabs/torch.tscn")
147
+ for i in range(3):
148
+ var t = ctx.instance_scene("res://prefabs/torch.tscn", null, "Torch%d" % (i + 2))
149
+ t.position = first.position + Vector2(160 * (i + 1), 0)
150
+ ctx.report("prefab", first.scene_file_path)
151
+ ```
152
+
153
+ The owner fix-up runs before packing, so a child you forgot to own is included instead of silently dropped. The prefab is authored at its origin — the node's position is zeroed for the pack (the editor's Save Branch default) and copied back onto the instance, so `first.position` above is still where the torch stood; rotation and scale stay in the prefab. `make_prefab` refuses the scene root (pack a child subtree, never `ctx.get_scene_root()`) and a path that is open in an editor tab. The receipt: `res://prefabs/torch.tscn` in the result's `files_written`, `Torch` now reporting a `scene_file_path`, and the copies in the diff's `added`. From here on, edit the prefab file, not the instances.
154
+
155
+ ## Input actions, autoload, main scene (game-completeness tier)
156
+
157
+ Project-level wiring in one run — the platformer controller above already reads these actions:
158
+
159
+ ```gdscript
160
+ func run(ctx):
161
+ ctx.add_input_action("move_left", [{"type": "key", "keycode": "A"}, {"type": "key", "keycode": "Left"},
162
+ {"type": "joypad_axis", "axis": 0, "value": -1.0}])
163
+ ctx.add_input_action("move_right", [{"type": "key", "keycode": "D"}, {"type": "key", "keycode": "Right"},
164
+ {"type": "joypad_axis", "axis": 0, "value": 1.0}])
165
+ ctx.add_input_action("jump", [{"type": "key", "keycode": "Space"}, {"type": "joypad_button", "button_index": 0}])
166
+ ctx.add_autoload("GameState", "res://scripts/autoload/game_state.gd") # the file must exist — write it first
167
+ if ctx.save_scene("res://levels/level_01.tscn"):
168
+ ctx.set_main_scene("res://levels/level_01.tscn")
169
+ ```
170
+
171
+ An unknown event shape → report + `false`, never a half-written action (every event is built before anything is written). A new action gets the engine's default deadzone, 0.2; re-running on an existing action keeps its deadzone and appends only the events it does not already match, so the recipe is safe to re-run. Keycode strings are `find_keycode` names (`"Space"`, `"Left"`, `"Ctrl+S"` — modifiers become the event's modifier flags). Write the autoload's script before registering it (`summer_write_file`, or `attach_script` on a node you then `make_prefab`) — `add_autoload` applies the editor dock's gates (valid identifier, no class-name collision, an existing `res://` Script or PackedScene). These helpers write the `res://` path form (`"*res://…"`, `"res://…"`); the editor UI writes `uid://` forms and both resolve — leave them be. They write `project.godot`, not the scene: the result's `undo_action` note lists them under `project_settings_changed`, outside the scene undo — checkpoint territory. Proof: `summer_play` → `summer_get_runtime_tree` shows `/root/GameState`; the keys move the body in a `target:"game"` capture.
172
+
173
+ ## Verifying 2D and UI work
174
+
175
+ Same loop, different framing:
176
+
177
+ - **Diff first.** `added` must carry the bodies' `CollisionShape2D` children, the `CanvasLayer` with its Controls, one `Parallax2D` per layer. Anchors and theme overrides show up as `changed` properties on the Controls.
178
+ - **2D scene captures.** `summer_screenshot target:"scene"` on a 2D scene synthesizes a `Camera2D` and auto-fits the `CanvasItem` bounds — the 3D presets do not apply, and `framing:"camera"` errors on a scene with no 3D content. `nodePath:"Player"` frames one node (its 2D rect, children included); `size:[1280, 720]` sets the resolution that anchors resolve against.
179
+ - **UI and anything input-driven** is only proven in the running game: `summer_play`, then `summer_screenshot target:"game"`. An edit-time preview of a HUD approximates a viewport the editor does not have.
180
+ - Read the confession fields in every capture (synthetic camera, no camera, project mismatch). A capture you did not receive is not evidence — `verifying-scenes` has the full discipline.
181
+
182
+ ## Pitfalls
183
+
184
+ | Pitfall | Reality |
185
+ |---|---|
186
+ | Painting tiles with `summer_set_prop`, or hand-editing `tile_map_data` | `ctx.paint_rect` / `paint_tiles` (or `set_cell` in a loop) — cells are packed data. |
187
+ | Building a HUD with a dozen `summer_add_node`/`summer_set_prop` calls | One script: `add_canvas_layer` → `add_ui` → `set_theme_overrides`. |
188
+ | `button.pressed.connect(...)` inside the run script | Not persisted — gone when the script ends. `ctx.connect_signal` (or `summer_connect_signal`) saves it in the `.tscn`. |
189
+ | `{"min_size": ...}` in `add_ui` props | Not a Control property — lands in `prop_warnings` and does nothing. The property is `custom_minimum_size`. |
190
+ | `ctx.make_prefab(ctx.get_scene_root(), ...)` | Refused. Pack a child subtree; the scene itself is `save_scene`. |
191
+ | Re-running a failed `attach_script` with a guessed fix | The parse error is in the report with the line. Read it, fix that line. |
192
+ | Judging a HUD from an edit-time scene preview | Anchors resolve against the real viewport. `summer_play` + `target:"game"`. |
193
+