summer-engine 3.1.0 → 3.2.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 (366) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +27 -5
  3. package/.codex-plugin/plugin.json +28 -6
  4. package/.cursor-plugin/plugin.json +27 -5
  5. package/.factory-plugin/plugin.json +27 -5
  6. package/.opencode/plugins/summer.js +1 -1
  7. package/CHANGELOG.md +102 -0
  8. package/README.md +18 -3
  9. package/assets/audit/scene_audit.gd +4136 -0
  10. package/assets/seeing/seeing_probe.gd +1873 -0
  11. package/dist/cli/commands/skills.js +20 -2
  12. package/dist/core/api-client.d.ts +9 -1
  13. package/dist/core/api-client.js +21 -4
  14. package/dist/core/capabilities/agent-playbook.js +46 -0
  15. package/dist/core/capabilities/audit/accept.d.ts +55 -0
  16. package/dist/core/capabilities/audit/accept.js +147 -0
  17. package/dist/core/capabilities/audit/args.d.ts +95 -0
  18. package/dist/core/capabilities/audit/args.js +89 -0
  19. package/dist/core/capabilities/audit/audit.d.ts +56 -0
  20. package/dist/core/capabilities/audit/audit.js +287 -0
  21. package/dist/core/capabilities/audit/frame.d.ts +14 -0
  22. package/dist/core/capabilities/audit/frame.js +35 -0
  23. package/dist/core/capabilities/audit/gaps.d.ts +96 -0
  24. package/dist/core/capabilities/audit/gaps.js +257 -0
  25. package/dist/core/capabilities/audit/judge.d.ts +162 -0
  26. package/dist/core/capabilities/audit/judge.js +1134 -0
  27. package/dist/core/capabilities/audit/math.d.ts +110 -0
  28. package/dist/core/capabilities/audit/math.js +263 -0
  29. package/dist/core/capabilities/audit/summary.d.ts +74 -0
  30. package/dist/core/capabilities/audit/summary.js +212 -0
  31. package/dist/core/capabilities/board.d.ts +31 -0
  32. package/dist/core/capabilities/board.js +43 -0
  33. package/dist/core/capabilities/camera-view.d.ts +4 -2
  34. package/dist/core/capabilities/camera-view.js +6 -3
  35. package/dist/core/capabilities/connect-signal.d.ts +85 -0
  36. package/dist/core/capabilities/connect-signal.js +285 -0
  37. package/dist/core/capabilities/engine-fallbacks.d.ts +5 -0
  38. package/dist/core/capabilities/engine-fallbacks.js +5 -0
  39. package/dist/core/capabilities/engine-ops.d.ts +5 -1
  40. package/dist/core/capabilities/engine-ops.js +0 -3
  41. package/dist/core/capabilities/engine-receipt.d.ts +12 -0
  42. package/dist/core/capabilities/engine-receipt.js +26 -0
  43. package/dist/core/capabilities/file-read.d.ts +64 -0
  44. package/dist/core/capabilities/file-read.js +325 -0
  45. package/dist/core/capabilities/game-task-plan.js +4 -2
  46. package/dist/core/capabilities/grep.d.ts +60 -0
  47. package/dist/core/capabilities/grep.js +190 -0
  48. package/dist/core/capabilities/inspect-node.d.ts +56 -0
  49. package/dist/core/capabilities/inspect-node.js +225 -0
  50. package/dist/core/capabilities/inspect-resource.d.ts +61 -0
  51. package/dist/core/capabilities/inspect-resource.js +376 -0
  52. package/dist/core/capabilities/math3d.d.ts +28 -0
  53. package/dist/core/capabilities/math3d.js +88 -0
  54. package/dist/core/capabilities/motion-generation.d.ts +62 -0
  55. package/dist/core/capabilities/motion-generation.js +138 -0
  56. package/dist/core/capabilities/placement-batch.d.ts +102 -0
  57. package/dist/core/capabilities/placement-batch.js +483 -0
  58. package/dist/core/capabilities/placement-math.d.ts +70 -0
  59. package/dist/core/capabilities/placement-math.js +209 -0
  60. package/dist/core/capabilities/placement-script.d.ts +42 -0
  61. package/dist/core/capabilities/placement-script.js +1096 -0
  62. package/dist/core/capabilities/placement.d.ts +485 -0
  63. package/dist/core/capabilities/placement.js +1731 -0
  64. package/dist/core/capabilities/project-context.d.ts +33 -2
  65. package/dist/core/capabilities/project-context.js +87 -4
  66. package/dist/core/capabilities/replace-node.d.ts +91 -0
  67. package/dist/core/capabilities/replace-node.js +423 -0
  68. package/dist/core/capabilities/runtime-control.d.ts +18 -2
  69. package/dist/core/capabilities/runtime-control.js +67 -2
  70. package/dist/core/capabilities/scene-batch.d.ts +63 -0
  71. package/dist/core/capabilities/scene-batch.js +394 -0
  72. package/dist/core/capabilities/scene-readback.d.ts +36 -0
  73. package/dist/core/capabilities/scene-readback.js +54 -0
  74. package/dist/core/capabilities/seeing/args.d.ts +348 -0
  75. package/dist/core/capabilities/seeing/args.js +178 -0
  76. package/dist/core/capabilities/seeing/candidates.d.ts +127 -0
  77. package/dist/core/capabilities/seeing/candidates.js +282 -0
  78. package/dist/core/capabilities/seeing/math.d.ts +134 -0
  79. package/dist/core/capabilities/seeing/math.js +269 -0
  80. package/dist/core/capabilities/seeing/probe.d.ts +62 -0
  81. package/dist/core/capabilities/seeing/probe.js +188 -0
  82. package/dist/core/capabilities/seeing/scoring.d.ts +235 -0
  83. package/dist/core/capabilities/seeing/scoring.js +639 -0
  84. package/dist/core/capabilities/seeing/seeing.d.ts +233 -0
  85. package/dist/core/capabilities/seeing/seeing.js +1341 -0
  86. package/dist/core/capabilities/seeing/shot-store.d.ts +52 -0
  87. package/dist/core/capabilities/seeing/shot-store.js +204 -0
  88. package/dist/core/capabilities/surface-snap-mesh.d.ts +88 -0
  89. package/dist/core/capabilities/surface-snap-mesh.js +425 -0
  90. package/dist/core/capabilities/surface-snap.d.ts +77 -0
  91. package/dist/core/capabilities/surface-snap.js +461 -0
  92. package/dist/core/capabilities/tool-dispatch.js +231 -72
  93. package/dist/core/capabilities/tscn.d.ts +85 -0
  94. package/dist/core/capabilities/tscn.js +391 -0
  95. package/dist/core/capabilities/world-snapshot.d.ts +58 -0
  96. package/dist/core/capabilities/world-snapshot.js +150 -0
  97. package/dist/core/capability-skew.d.ts +5 -5
  98. package/dist/core/capability-skew.js +14 -6
  99. package/dist/core/headless/worker-engine-client.d.ts +1 -1
  100. package/dist/core/headless/worker-engine-client.js +2 -2
  101. package/dist/core/library-read.d.ts +37 -5
  102. package/dist/core/library-read.js +264 -33
  103. package/dist/core/library-search.d.ts +2 -2
  104. package/dist/installer/agent-config.js +5 -3
  105. package/dist/installer/agent-table.d.ts +16 -0
  106. package/dist/installer/agent-table.js +52 -17
  107. package/dist/mcp/server.js +9 -3
  108. package/dist/mcp/tools/asset-tools.js +21 -3
  109. package/dist/mcp/tools/audit-tools.d.ts +23 -0
  110. package/dist/mcp/tools/audit-tools.js +60 -0
  111. package/dist/mcp/tools/debug-tools.js +3 -1
  112. package/dist/mcp/tools/file-tools.js +17 -4
  113. package/dist/mcp/tools/generate-tools.js +74 -66
  114. package/dist/mcp/tools/library-tools.js +2 -0
  115. package/dist/mcp/tools/perception-tools.js +6 -19
  116. package/dist/mcp/tools/placement-tools.d.ts +24 -0
  117. package/dist/mcp/tools/placement-tools.js +91 -0
  118. package/dist/mcp/tools/project-tools.js +18 -15
  119. package/dist/mcp/tools/scene-tools.js +71 -83
  120. package/dist/mcp/tools/seeing-tools.d.ts +24 -0
  121. package/dist/mcp/tools/seeing-tools.js +64 -0
  122. package/dist/mcp/tools/spatial-tools.js +17 -9
  123. package/dist/mcp/tools/visual-tools.js +59 -7
  124. package/gemini-extension.json +26 -4
  125. package/integrations/amp/README.md +1 -1
  126. package/integrations/crush/README.md +1 -1
  127. package/integrations/grok-build/README.md +1 -1
  128. package/integrations/hermes/README.md +1 -1
  129. package/integrations/kimi-code/README.md +1 -1
  130. package/integrations/mistral-vibe/README.md +1 -1
  131. package/integrations/opencode/README.md +1 -1
  132. package/integrations/rovo-dev/README.md +1 -1
  133. package/integrations/vscode-copilot/README.md +1 -1
  134. package/integrations/warp/README.md +1 -1
  135. package/integrations/windsurf/README.md +1 -1
  136. package/library/references/mcp-tools-reference/mcp-tools-reference.md +59 -15
  137. package/library/references/mcp-tools-reference/resource.yaml +1 -1
  138. package/library/references/summer-folder/resource.yaml +1 -1
  139. package/library/references/summer-folder/summer-folder.md +1 -1
  140. package/library/skills/3d-lighting/SKILL.md +1 -1
  141. package/library/skills/README.md +36 -14
  142. package/library/skills/adaptive-music/SKILL.md +1 -1
  143. package/library/skills/agent-playtesting/SKILL.md +1 -1
  144. package/library/skills/ai-characters-in-games/SKILL.md +220 -0
  145. package/library/skills/ai-characters-in-games/resource.yaml +30 -0
  146. package/library/skills/ambient-bed/SKILL.md +1 -1
  147. package/library/skills/animated-loop/SKILL.md +1 -1
  148. package/library/skills/animation-tree/SKILL.md +1 -1
  149. package/library/skills/art-direction/SKILL.md +1 -1
  150. package/library/skills/asset-strategy/SKILL.md +2 -1
  151. package/library/skills/asset-strategy/resource.yaml +2 -1
  152. package/library/skills/audio-direction/SKILL.md +1 -1
  153. package/library/skills/auto-fire-targeting/SKILL.md +1 -1
  154. package/library/skills/brainstorm-game/SKILL.md +1 -1
  155. package/library/skills/brainstorming/SKILL.md +1 -1
  156. package/library/skills/browse-templates/SKILL.md +3 -3
  157. package/library/skills/browse-templates/resource.yaml +1 -1
  158. package/library/skills/camera-rigs/SKILL.md +128 -0
  159. package/library/skills/camera-rigs/resource.yaml +29 -0
  160. package/library/skills/celeste-momentum-platforming/SKILL.md +1 -1
  161. package/library/skills/character-animation-wiring/SKILL.md +1 -1
  162. package/library/skills/character-model/SKILL.md +1 -1
  163. package/library/skills/character-movement/SKILL.md +326 -0
  164. package/library/skills/character-movement/references/default-third-person-controller.gd +201 -0
  165. package/library/skills/character-movement/references/default-third-person-verification-probe.gd +154 -0
  166. package/library/skills/character-movement/references/movement-3d.md +136 -0
  167. package/library/skills/character-movement/references/platformer-feel.md +83 -0
  168. package/library/skills/character-movement/resource.yaml +40 -0
  169. package/library/skills/character-portrait/SKILL.md +1 -1
  170. package/library/skills/cinematic-cutscene/SKILL.md +1 -1
  171. package/library/skills/combat-basics/SKILL.md +159 -0
  172. package/library/skills/combat-basics/references/projectiles-and-aoe.md +100 -0
  173. package/library/skills/combat-basics/resource.yaml +34 -0
  174. package/library/skills/concept-art/SKILL.md +1 -1
  175. package/library/skills/create-asset-sheet/SKILL.md +1 -1
  176. package/library/skills/debug/SKILL.md +1 -1
  177. package/library/skills/debugging-game-feel/SKILL.md +1 -1
  178. package/library/skills/design-level/SKILL.md +1 -1
  179. package/library/skills/design-mechanic/SKILL.md +1 -1
  180. package/library/skills/design-npc/SKILL.md +1 -1
  181. package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
  182. package/library/skills/dispatching-parallel-agents/SKILL.md +1 -1
  183. package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
  184. package/library/skills/environment-kit/SKILL.md +1 -1
  185. package/library/skills/export-and-ship/SKILL.md +1 -1
  186. package/library/skills/fabricating-assets/SKILL.md +1 -1
  187. package/library/skills/facial-and-lipsync/SKILL.md +1 -1
  188. package/library/skills/fps-controller/SKILL.md +9 -7
  189. package/library/skills/fps-controller/resource.yaml +4 -1
  190. package/library/skills/game-feel/SKILL.md +1 -1
  191. package/library/skills/gameskill/SKILL.md +1 -1
  192. package/library/skills/gdscript-patterns/SKILL.md +1 -1
  193. package/library/skills/generate-motion/SKILL.md +9 -9
  194. package/library/skills/generate-motion/resource.yaml +2 -1
  195. package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
  196. package/library/skills/headless-scripting/SKILL.md +1 -1
  197. package/library/skills/in-game-purchases/SKILL.md +254 -0
  198. package/library/skills/in-game-purchases/resource.yaml +29 -0
  199. package/library/skills/instantiate-asset-pack/SKILL.md +1 -1
  200. package/library/skills/investigating-bugs/SKILL.md +1 -1
  201. package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +1 -1
  202. package/library/skills/make-game/SKILL.md +25 -3
  203. package/library/skills/make-game/references/2d-platformer-polish.md +93 -0
  204. package/library/skills/make-game/references/2d-platformer.md +117 -0
  205. package/library/skills/make-game/references/2d-rpg-content.md +234 -0
  206. package/library/skills/make-game/references/2d-rpg.md +241 -0
  207. package/library/skills/make-game/references/2d-survivors-progression.md +201 -0
  208. package/library/skills/make-game/references/2d-survivors.md +237 -0
  209. package/library/skills/make-game/references/3d-fps-systems.md +216 -0
  210. package/library/skills/make-game/references/3d-fps.md +177 -0
  211. package/library/skills/make-game/references/3d-horror-systems.md +186 -0
  212. package/library/skills/make-game/references/3d-horror.md +201 -0
  213. package/library/skills/make-game/references/3d-third-person-systems.md +220 -0
  214. package/library/skills/make-game/references/3d-third-person.md +215 -0
  215. package/library/skills/make-game/resource.yaml +6 -1
  216. package/library/skills/multiplayer/SKILL.md +150 -0
  217. package/library/skills/multiplayer/resource.yaml +33 -0
  218. package/library/skills/multiplayer-movement/SKILL.md +510 -0
  219. package/library/skills/multiplayer-movement/files.md +501 -0
  220. package/library/skills/multiplayer-movement/resource.yaml +30 -0
  221. package/library/skills/multiplayer-project/SKILL.md +521 -0
  222. package/library/skills/multiplayer-project/files.md +448 -0
  223. package/library/skills/multiplayer-project/resource.yaml +36 -0
  224. package/library/skills/multiplayer-publish/SKILL.md +229 -0
  225. package/library/skills/multiplayer-publish/export-errors.md +89 -0
  226. package/library/skills/multiplayer-publish/resource.yaml +28 -0
  227. package/library/skills/multiplayer-state/SKILL.md +438 -0
  228. package/library/skills/multiplayer-state/files.md +592 -0
  229. package/library/skills/multiplayer-state/resource.yaml +35 -0
  230. package/library/skills/multiplayer-testing/SKILL.md +236 -0
  231. package/library/skills/multiplayer-testing/resource.yaml +39 -0
  232. package/library/skills/music-track/SKILL.md +1 -1
  233. package/library/skills/navigate-summer/SKILL.md +1 -1
  234. package/library/skills/new-project/SKILL.md +1 -1
  235. package/library/skills/organic-model/SKILL.md +1 -1
  236. package/library/skills/pixel-art/SKILL.md +1 -1
  237. package/library/skills/play/SKILL.md +1 -1
  238. package/library/skills/playtesting-a-feature/SKILL.md +1 -1
  239. package/library/skills/procedural-animation/SKILL.md +2 -2
  240. package/library/skills/procedural-animation/resource.yaml +1 -1
  241. package/library/skills/prop-model/SKILL.md +1 -1
  242. package/library/skills/psx-retro-rendering/SKILL.md +1 -1
  243. package/library/skills/realtime-wet-surfaces/SKILL.md +2 -2
  244. package/library/skills/remote-deploy/SKILL.md +1 -1
  245. package/library/skills/retarget/SKILL.md +1 -1
  246. package/library/skills/running-in-the-cloud/SKILL.md +1 -1
  247. package/library/skills/save-load/SKILL.md +156 -0
  248. package/library/skills/save-load/resource.yaml +27 -0
  249. package/library/skills/scene-composition/SKILL.md +1 -1
  250. package/library/skills/scene-hierarchy-design/SKILL.md +1 -1
  251. package/library/skills/scene-scripting/SKILL.md +1 -1
  252. package/library/skills/scene-to-level/SKILL.md +1 -1
  253. package/library/skills/skill-create/SKILL.md +1 -1
  254. package/library/skills/skill-improve/SKILL.md +1 -1
  255. package/library/skills/skill-test/SKILL.md +1 -1
  256. package/library/skills/skintokens-auto-rigging/SKILL.md +1 -1
  257. package/library/skills/skybox-panorama/SKILL.md +1 -1
  258. package/library/skills/sound-effect/SKILL.md +1 -1
  259. package/library/skills/spatial-placement/SKILL.md +134 -3
  260. package/library/skills/spatial-placement/references/kit-placement-tools.md +364 -0
  261. package/library/skills/spatial-placement/resource.yaml +16 -2
  262. package/library/skills/sprite-sheet/SKILL.md +1 -1
  263. package/library/skills/summer-analytics/SKILL.md +147 -0
  264. package/library/skills/summer-analytics/resource.yaml +28 -0
  265. package/library/skills/summer-friends/SKILL.md +226 -0
  266. package/library/skills/summer-friends/resource.yaml +28 -0
  267. package/library/skills/summer-leaderboards/SKILL.md +231 -0
  268. package/library/skills/summer-leaderboards/resource.yaml +30 -0
  269. package/library/skills/summer-match-results/SKILL.md +286 -0
  270. package/library/skills/summer-match-results/resource.yaml +32 -0
  271. package/library/skills/summer-matchmaking/SKILL.md +301 -0
  272. package/library/skills/summer-matchmaking/resource.yaml +32 -0
  273. package/library/skills/summer-parties/SKILL.md +253 -0
  274. package/library/skills/summer-parties/resource.yaml +30 -0
  275. package/library/skills/summer-player-data/SKILL.md +322 -0
  276. package/library/skills/summer-player-data/resource.yaml +30 -0
  277. package/library/skills/summer-store/SKILL.md +271 -0
  278. package/library/skills/summer-store/resource.yaml +29 -0
  279. package/library/skills/summer-world-chat/SKILL.md +195 -0
  280. package/library/skills/summer-world-chat/resource.yaml +30 -0
  281. package/library/skills/summer-world-saves/SKILL.md +284 -0
  282. package/library/skills/summer-world-saves/resource.yaml +29 -0
  283. package/library/skills/text-to-motion/SKILL.md +99 -0
  284. package/library/skills/text-to-motion/prompts-and-controls.md +34 -0
  285. package/library/skills/text-to-motion/resource.yaml +41 -0
  286. package/library/skills/text-to-motion/rigging-for-text-motion.md +54 -0
  287. package/library/skills/tileable-texture/SKILL.md +1 -1
  288. package/library/skills/trailer-shot/SKILL.md +1 -1
  289. package/library/skills/tune-performance/SKILL.md +1 -1
  290. package/library/skills/ui-basics/SKILL.md +10 -1
  291. package/library/skills/ui-graphics/SKILL.md +1 -1
  292. package/library/skills/use-widget-asset/SKILL.md +1 -1
  293. package/library/skills/using-summer/SKILL.md +2 -2
  294. package/library/skills/using-summer/resource.yaml +2 -2
  295. package/library/skills/vehicle-model/SKILL.md +1 -1
  296. package/library/skills/verification-before-completion/SKILL.md +1 -1
  297. package/library/skills/verifying-scenes/SKILL.md +76 -2
  298. package/library/skills/verifying-scenes/resource.yaml +13 -2
  299. package/library/skills/vfx-dissolve/SKILL.md +1 -1
  300. package/library/skills/vfx-fire/SKILL.md +1 -1
  301. package/library/skills/vfx-hit-spark/SKILL.md +1 -1
  302. package/library/skills/vfx-lightning/SKILL.md +1 -1
  303. package/library/skills/vfx-magic-glow/SKILL.md +1 -1
  304. package/library/skills/vfx-muzzle-flash/SKILL.md +1 -1
  305. package/library/skills/vfx-smoke/SKILL.md +1 -1
  306. package/library/skills/vfx-water-ripple/SKILL.md +1 -1
  307. package/library/skills/voice-line/SKILL.md +1 -1
  308. package/library/skills/web-and-touch-input/SKILL.md +38 -0
  309. package/library/skills/web-and-touch-input/resource.yaml +28 -0
  310. package/library/skills/web-compatibility-look/SKILL.md +62 -0
  311. package/library/skills/web-compatibility-look/resource.yaml +30 -0
  312. package/library/skills/world-building-3d/SKILL.md +8 -1
  313. package/library/skills/world-building-3d/references/spatial-tools.md +1 -1
  314. package/library/skills/world-building-3d/resource.yaml +2 -1
  315. package/library/skills/writing-plans/SKILL.md +1 -1
  316. package/library/skills/writing-skills/SKILL.md +1 -1
  317. package/library/templates/3d-lan-multiplayer-starter/resource.yaml +2 -2
  318. package/library/tools/attach-to-surface/resource.yaml +142 -0
  319. package/library/tools/batch/resource.yaml +9 -3
  320. package/library/tools/connect-ports/resource.yaml +120 -0
  321. package/library/tools/connect-signal/resource.yaml +3 -2
  322. package/library/tools/debug-views/resource.yaml +94 -0
  323. package/library/tools/frame-nodes/resource.yaml +104 -0
  324. package/library/tools/frame-shot/resource.yaml +134 -0
  325. package/library/tools/generate-motion/resource.yaml +44 -9
  326. package/library/tools/get-board/resource.yaml +50 -0
  327. package/library/tools/get-project-context/resource.yaml +13 -2
  328. package/library/tools/grep/resource.yaml +77 -0
  329. package/library/tools/inspect-asset/resource.yaml +71 -0
  330. package/library/tools/inspect-node/resource.yaml +9 -2
  331. package/library/tools/inspect-resource/resource.yaml +16 -5
  332. package/library/tools/instantiate-scene/resource.yaml +27 -2
  333. package/library/tools/measure/resource.yaml +96 -0
  334. package/library/tools/place-adjacent/resource.yaml +113 -0
  335. package/library/tools/play/resource.yaml +15 -2
  336. package/library/tools/raycast/resource.yaml +101 -0
  337. package/library/tools/read-file/resource.yaml +36 -2
  338. package/library/tools/read-library/resource.yaml +2 -2
  339. package/library/tools/repeat-along/resource.yaml +129 -0
  340. package/library/tools/replace-node/resource.yaml +11 -5
  341. package/library/tools/scene-audit/resource.yaml +144 -0
  342. package/library/tools/screenshot/resource.yaml +13 -2
  343. package/library/tools/search-assets/resource.yaml +18 -0
  344. package/library/tools/shot-sheet/resource.yaml +110 -0
  345. package/library/tools/snap-to-surface/resource.yaml +4 -1
  346. package/library/tools/world-snapshot/resource.yaml +24 -3
  347. package/library/tools/zoom/resource.yaml +105 -0
  348. package/package.json +1 -1
  349. package/registry/generated/aliases.json +17 -3
  350. package/registry/generated/counts.json +3 -3
  351. package/registry/generated/gemini-extension.json +26 -4
  352. package/registry/generated/index.json +2154 -469
  353. package/registry/generated/marketplace.claude.json +2 -2
  354. package/registry/generated/plugin.claude.json +27 -5
  355. package/registry/generated/plugin.codex.json +28 -6
  356. package/registry/generated/plugin.cursor.json +27 -5
  357. package/registry/generated/plugin.factory.json +27 -5
  358. package/registry/generated/skills-index.md +36 -14
  359. package/registry/generated/skills-registry.json +421 -124
  360. package/registry/generated/templates-registry.json +2 -2
  361. package/library/skills/host-authoritative-state/SKILL.md +0 -332
  362. package/library/skills/host-authoritative-state/resource.yaml +0 -28
  363. package/library/skills/peer-to-peer-multiplayer/SKILL.md +0 -373
  364. package/library/skills/peer-to-peer-multiplayer/resource.yaml +0 -28
  365. package/library/skills/setup-multiplayer/SKILL.md +0 -336
  366. package/library/skills/setup-multiplayer/resource.yaml +0 -28
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: scene-to-level
3
- description: Use when the user wants to go from a scene reference image or concept art to a playable Summer Engine scene populated with the right assets and terrain. Orchestrates concept, asset pack, terrain, composition, and scene assembly. Trigger on "build this scene", "make this playable", "I want a level that looks like this", "from a screenshot to a game", "implement this concept".
3
+ description: "Go from a scene reference image or concept art to a playable scene — orchestrates concept, asset pack, terrain, composition, and scene assembly."
4
4
  license: MIT
5
5
  compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
6
  category: level-design
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: skill-create
3
- description: Use when a contributor wants to add a new skill to the Summer library. Bootstraps the canonical folder (library/skills/<slug>/ with resource.yaml and SKILL.md), frontmatter, and stub sections. Trigger on "create skill", "add skill", "new skill", "skill-create".
3
+ description: "Bootstrap a new Summer library skill (library/skills/<slug>/ with resource.yaml and SKILL.md), frontmatter, and stub sections."
4
4
  license: MIT
5
5
  compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
6
  category: workflow
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: skill-improve
3
- description: Use when a contributor wants to upgrade a Summer skill that is underperforming or to fix a regression — runs the skill against a behavioral spec with and without proposed changes via parallel-eval harness and ships the version that wins. Trigger on "improve skill", "iterate on skill", "make this skill better".
3
+ description: "Upgrade an underperforming Summer skill — run it against a behavioral spec with and without changes via a parallel-eval harness; ship the winner."
4
4
  license: MIT
5
5
  compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
6
  category: workflow
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: skill-test
3
- description: Use when a contributor wants to lint a Summer skill before commit, audit the whole library, or check a behavioral spec assertion — validates against static structural rules and per-skill behavioral specs. Trigger on "skill test", "lint skill", "validate skill".
3
+ description: "Lint a Summer skill before commit, audit the whole library, or check a behavioral spec assertion — static structural rules plus behavioral specs."
4
4
  license: MIT
5
5
  compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
6
  category: workflow
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: skintokens-auto-rigging
3
- description: "Use when auto-rigging a static GLB mesh offline with skin-tokens.cpp (LocalAI's C++/GGML port of VAST-AI SkinTokens/TokenRig) in SummerEngine's art pipeline: generate a skeleton and skin weights on CPU/Vulkan, then import the rigged GLB into Godot 4."
3
+ description: "Offline auto-rigging with skin-tokens.cpp (GGML SkinTokens/TokenRig port) — skeleton and skin weights from a static GLB mesh on CPU/Vulkan, into Godot 4."
4
4
  license: MIT
5
5
  category: art-pipeline
6
6
  tags:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: skybox-panorama
3
- description: Use when generating a 360° panoramic sky image for use as a Sky resource (PanoramaSkyMaterial) in a 3D scene. Equirectangular projection, 2:1 aspect. Wires into WorldEnvironment.sky. Trigger on "skybox", "sky panorama", "360 background", "environment sky", "HDRI sky", "panoramic background", "panorama sky".
3
+ description: "Generate a 360-degree equirectangular sky panorama and wire it as a PanoramaSkyMaterial Sky resource on WorldEnvironment in a 3D scene."
4
4
  license: MIT
5
5
  compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
6
  category: 2d-assets
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: sound-effect
3
- description: Use when generating short SFX one-shots — footsteps, weapon swings, UI clicks, hit impacts, environmental cues. Wires the resulting clip as an AudioStreamPlayer / 2D / 3D and auto-frees on finished. Trigger on "make a sword swing sound", "generate a UI click", "I need a footstep", "add a hit sound", "spawn an SFX".
3
+ description: "Generate short SFX one-shots — footsteps, weapon swings, UI clicks, hit impacts — wired as AudioStreamPlayer/2D/3D that auto-frees on finished."
4
4
  license: MIT
5
5
  compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
6
  category: audio
@@ -1,20 +1,43 @@
1
1
  ---
2
2
  name: spatial-placement
3
- description: Use when positioning or verifying 3D objects with surrounding-scene evidence — floor and shelf support, wall gaps, collider or mesh overlap, directional clearance, alcoves, rotated props, and post-placement checks. Trigger on "place", "position", "align", "sit on", "against the wall", "inside", "overlap", "clearance", "grounded", "flush", "spatial", "Starcast".
3
+ description: "Place 3D objects and modular kit pieces from measured geometry — inspect, place, starcast, measure, correct; floor, wall, facade, pipe and alcove recipes."
4
4
  license: MIT
5
5
  compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
6
  category: scene-and-project
7
7
  user-invocable: false
8
- allowed-tools: Read Grep summer_get_scene_tree summer_inspect_node summer_set_prop summer_batch summer_starcast
8
+ allowed-tools: Read Grep summer_get_scene_tree summer_inspect_node summer_set_prop summer_batch summer_starcast summer_inspect_asset summer_instantiate_scene summer_place_adjacent summer_attach_to_surface summer_repeat_along summer_connect_ports summer_raycast summer_measure summer_test_placement summer_snap_to_surface summer_align_distribute_3d summer_world_snapshot summer_snapshot_diff summer_screenshot
9
9
  paths: ["**/*.tscn"]
10
10
  ---
11
11
 
12
12
  # Spatial Placement in Summer Engine
13
13
 
14
- Use Starcast as spatial evidence, not as an automatic placement solver. Make a
14
+ Place from measured geometry, never from guesses about size or facing. Use
15
+ Starcast as spatial evidence, not as an automatic placement solver. Make a
15
16
  reasonable transform from scene intent, inspect the result, then correct only
16
17
  the axes that the evidence shows are wrong.
17
18
 
19
+ Every tool below is already shipped. Arguments, result shapes, limits and the
20
+ engine ops behind them: [references/kit-placement-tools.md](references/kit-placement-tools.md).
21
+
22
+ ## Choose the tool
23
+
24
+ | Question | Tool |
25
+ |---|---|
26
+ | Size, origin, front/back plane, pipe ends of a piece not yet placed? | `summer_inspect_asset` |
27
+ | Place one piece at an exact pose | `summer_instantiate_scene` with `position`, `rotation_degrees` |
28
+ | Place many pieces, read the receipt | `summer_batch`, placed `InstantiateScene` ops, `receipt: "summary"` |
29
+ | Next module edge to edge, next storey on top | `summer_place_adjacent` |
30
+ | Pipe, lamp, AC unit or sign on a wall | `summer_attach_to_surface` |
31
+ | Clamps, braces, posts or windows along a line | `summer_repeat_along` |
32
+ | Pipe or duct end to end | `summer_connect_ports` |
33
+ | Surface and normal in front of a point | `summer_raycast` |
34
+ | Gap or overlap between two pieces; fronts flush? | `summer_measure` |
35
+ | What surrounds a placed piece, which side is blocked? | `summer_starcast` |
36
+ | Will this pose fit in a tight spot? | `summer_test_placement` before committing |
37
+ | Seat a prop on a floor, table or ledge | `summer_snap_to_surface` |
38
+ | Line up or space 2-16 placed pieces on one axis | `summer_align_distribute_3d` |
39
+ | Did exactly that change, does it look right? | `summer_world_snapshot` + `summer_snapshot_diff`, `summer_screenshot` |
40
+
18
41
  ## Placement loop
19
42
 
20
43
  1. Call `summer_get_scene_tree` and inspect the subject and intended anchor.
@@ -46,6 +69,94 @@ defined relative to a rotated subject; then use `directionSpace="local"`.
46
69
  - Warnings about missing collision shapes or visual bounds mean coverage is
47
70
  partial; state that limitation rather than inventing certainty.
48
71
 
72
+ ## Modular kit placement
73
+
74
+ 1. `summer_inspect_asset` every piece type once and read its `summary` first:
75
+ size, where the origin sits (`origin.label`), the two largest opposite plane
76
+ pairs (a large `+z` plane at the max z offset means the visible face looks
77
+ along +z and the back is `-z`; a `one_sided` sheet with no opposite plane
78
+ is invisible from behind), port-like loops (pipe and duct ends), anchors
79
+ and colliders. Read the kit's own notes too, but trust the
80
+ measurement.
81
+ 2. `summer_world_snapshot`; keep the `snapshot_id`.
82
+ 3. Place the first piece of a line with `summer_instantiate_scene` and its
83
+ `position` / `rotation_degrees`. Place the rest relative to it:
84
+ `summer_place_adjacent` along the line, again along `y` for the next storey.
85
+ For many pieces at known poses use one `summer_batch` with
86
+ `receipt: "summary"`.
87
+ 4. Mount wall pieces with `summer_attach_to_surface`, using the back axis from
88
+ step 1. Instance each at its mount height first: the tool keeps the height
89
+ and pushes the piece's back face onto the wall, and refuses (putting the
90
+ piece back) when the seat lands on another node. Join pipe and duct runs
91
+ with `summer_connect_ports`; its `other_ports` says where a bend's free end
92
+ now points. Add clamps and braces with `summer_repeat_along`.
93
+ 5. Check: `summer_measure` plane mode on each facade line (every front on one
94
+ plane), pair mode on joints you doubt, `summer_starcast` with
95
+ `directionSpace: "local"` on mounted pieces, `summer_test_placement` before
96
+ committing a piece in a tight spot. Starcast's local names follow Godot:
97
+ `forward` is -Z, `back` is +Z. A piece with a -Z back should read
98
+ `forward` blocked by the wall at about the standoff (or the wall in
99
+ `contacts` when flush) and `back` open.
100
+ 6. `summer_snapshot_diff` against the id from step 2, then `summer_screenshot`
101
+ and look at it. Fix facing from the measurement, not by eye.
102
+
103
+ ### Worked example: two-storey facade wall with a downpipe and a lamp
104
+
105
+ Pieces (measured in step 1): `wall_double` is 2 x 3 x 0.2 m, origin bottom
106
+ centre, front `+z`; `window_double` the same size; `gutter_section` is 1 m tall
107
+ with its back `-z` and open loops at both ends; `wall_lamp` has its back `-z`;
108
+ `wall_clamp` is small with its back `-z`. Scene `res://facade_test.tscn` with a
109
+ `Facade` Node3D at the origin.
110
+
111
+ ```text
112
+ summer_instantiate_scene {scenePath:"res://facade_test.tscn", parent:"./Facade",
113
+ scene:"res://kit/wall_double.tscn", name:"G1", position:[0,0,0]}
114
+ summer_instantiate_scene {..., scene:"res://kit/window_double.tscn", name:"G2", position:[2,0,0]}
115
+ summer_place_adjacent {scenePath:"res://facade_test.tscn", subject:"./Facade/G2",
116
+ reference:"./Facade/G1", axis:"x", side:"max", alignOtherAxes:{y:"min", z:"max"}}
117
+ -> verify {gap:0, residuals:{y:0, z:0}}
118
+ summer_instantiate_scene {..., scene:"res://kit/window_double.tscn", name:"U1", position:[0,3,0]}
119
+ summer_place_adjacent {..., subject:"./Facade/U1", reference:"./Facade/G1",
120
+ axis:"y", side:"max", alignOtherAxes:{x:"min", z:"max"}}
121
+ summer_instantiate_scene {..., scene:"res://kit/window_double.tscn", name:"U2", position:[2,3,0]}
122
+ summer_place_adjacent {..., subject:"./Facade/U2", reference:"./Facade/U1",
123
+ axis:"x", side:"max", alignOtherAxes:{y:"min", z:"max"}}
124
+ summer_measure {scenePath:"res://facade_test.tscn", mode:"plane",
125
+ nodes:["./Facade/G1","./Facade/G2","./Facade/U1","./Facade/U2"], face:"+z"}
126
+ -> coplanar:true, spread 0
127
+
128
+ summer_raycast {scenePath:"res://facade_test.tscn", origin:[2.15,0.5,1], direction:[0,0,-1]}
129
+ -> hit ./Facade/G2, normal [0,0,1]: the wall front, by physics
130
+ summer_instantiate_scene {..., scene:"res://kit/gutter_section.tscn", name:"Pipe_1", position:[2.15,0.1,0.5]}
131
+ summer_attach_to_surface {scenePath:"res://facade_test.tscn", subject:"./Facade/Pipe_1",
132
+ ray:{origin:[2.15,0.5,1], direction:[0,0,-1]}, backAxis:"-z", upAxis:"+y", standoff:0.02}
133
+ -> seated_on "Facade/G2", final_gap 0.02, back_face_gap 0.02; the pipe keeps y 0.1
134
+ summer_instantiate_scene {..., scene:"res://kit/gutter_section.tscn", name:"Pipe_2", position:[2.15,1.1,0.1]}
135
+ summer_connect_ports {scenePath:"res://facade_test.tscn", subject:"./Facade/Pipe_2", subjectPort:"-Y",
136
+ target:"./Facade/Pipe_1", targetPort:"+Y"}
137
+ -> tilt_degrees 0, verify {distance:0, angle_degrees:0}, other_ports [{id:"+Y", direction:[0,1,0]}]
138
+ summer_repeat_along {scenePath:"res://facade_test.tscn", template:"res://kit/wall_clamp.tscn",
139
+ parent:"./Facade", start:[2.15,0.3,0.02], end:[2.15,1.9,0.02], spacing:0.45}
140
+ -> count 4, created ["Facade/wall_clamp_1", ...]
141
+
142
+ summer_instantiate_scene {..., scene:"res://kit/wall_lamp.tscn", name:"Lamp", position:[1,2.6,0.5]}
143
+ summer_attach_to_surface {scenePath:"res://facade_test.tscn", subject:"./Facade/Lamp",
144
+ surface:"./Facade/G1", backAxis:"-z", standoff:0}
145
+ summer_starcast {scenePath:"res://facade_test.tscn", path:"./Facade/Lamp", directionSpace:"local"}
146
+ -> contacts ["Facade/G1"], forward (-Z, the lamp's back) blocked at 0, back (+Z) open
147
+ summer_snapshot_diff {from_id:"<id>"} then summer_screenshot
148
+ ```
149
+
150
+ Loop ids come from the section's `open_loops` in step 1 (its
151
+ `summary.port_like_loops`): `+Y` is the outermost loop facing +Y in the
152
+ piece's own axes (here the top end), `-Y` the bottom; a second loop facing the
153
+ same way is `+Y#2`. The ids do not depend on radius or pose.
154
+ On the target pick the loop whose `direction` points where the run continues;
155
+ on the subject, the one that points back at the target. A join that would tilt
156
+ the piece more than 5 degrees is refused and lists the ports that fit; pass
157
+ `allowTilt: true` only for an intended tilt. With kits that ship Marker3D
158
+ anchors, pass their names instead.
159
+
49
160
  ## Placement recipes
50
161
 
51
162
  - **Floor/platform:** require downward support, no unintended contacts, and open
@@ -60,6 +171,17 @@ defined relative to a rotated subject; then use `directionSpace="local"`.
60
171
  refers to the object's orientation; use world directions for level axes.
61
172
  - **Overlap repair:** move along the clearest axis with the shortest correction,
62
173
  then rerun. Do not resize the asset unless the user asked for that.
174
+ - **Facade line:** modules edge to edge with `summer_place_adjacent`
175
+ (`alignOtherAxes` `{y: "min", z: "max"}` for a +z front), then
176
+ `summer_measure` plane mode on the fronts. A module reported `proud` or
177
+ `recessed` is moved along the face axis by its `deviation`.
178
+ - **Pipes and gutters:** back on the wall's front plane (`summer_attach_to_surface`
179
+ with the measured back axis), runs joined with `summer_connect_ports`, clamps
180
+ with `summer_repeat_along`. Starcast in local space: the back-axis direction
181
+ (`forward` for a -Z back) blocked at about the standoff.
182
+ - **Wall fixtures (lamps, AC units, signs):** `summer_raycast` to find the
183
+ wall point, `summer_test_placement` if the spot is crowded, then
184
+ `summer_attach_to_surface`.
63
185
 
64
186
  ## Guardrails
65
187
 
@@ -72,3 +194,12 @@ defined relative to a rotated subject; then use `directionSpace="local"`.
72
194
  - Cameras, lights, audio, navigation nodes, scripts, and plain Nodes are not
73
195
  obstacles unless they own collision or renderable geometry.
74
196
  - Prefer two useful summary calls around one correction over repeated full calls.
197
+ - Never infer a piece's facing from its file name or a screenshot alone.
198
+ Measure it (`summer_inspect_asset`), place it, then confirm with Starcast
199
+ (local) and a screenshot.
200
+ - Batch receipts over a few ops: always `receipt: "summary"`.
201
+ - `visual_aabb` measurements (measure, place_adjacent) are box bounds: an
202
+ overhang or a lip sets the face. Say so when it matters.
203
+ - A piece seated flush against a single-sided wall can read `open` in the
204
+ wall's direction while `contacts` lists the wall: Starcast's one ray per
205
+ direction starts at the touching face. Read `contacts` too.
@@ -0,0 +1,364 @@
1
+ # Kit placement tools
2
+
3
+ Reference for the tools that place modular kit pieces from measured geometry.
4
+ Read it before the first call in a task. The workflow that uses them is in
5
+ [`SKILL.md`](../SKILL.md).
6
+
7
+ ## Shared rules
8
+
9
+ - **Exact paths.** `scenePath` is an exact `res://...tscn`; node paths are
10
+ relative to the scene root (`./Facade/Wall_01` or `Facade/Wall_01`). Editor
11
+ selection is never used.
12
+ - **The scene must be open** in the editor (any tab). A scene mutation with
13
+ `scenePath` opens it; `summer_open_scene` does too. A closed scene answers
14
+ `scene_not_open`.
15
+ - **Physics needs the active tab.** Only the active scene's bodies are in the
16
+ editor's physics space. Ray queries on another tab fall back to visual AABBs
17
+ and say so.
18
+ - **Scene space.** Points, normals and bounds in results are in the scene
19
+ root's frame (world space in the editor). `position` / `start` / `end` that
20
+ you pass for new instances are parent-local, like `summer_set_prop`.
21
+ - **Evidence** is named in every result:
22
+ - `visual_aabb`: bounds of visible `GeometryInstance3D` nodes (the definition
23
+ `summer_align_distribute_3d` uses). In `space: "local"` the mesh boxes are
24
+ projected onto the node's own axes, so a rotated facade measures tightly.
25
+ Never triangle contact.
26
+ - `physics`: a collider query (exact shapes, needs the active tab).
27
+ - `mesh_triangles`: computed from the mesh triangles themselves.
28
+ - `markers`: Marker3D anchors shipped with the kit.
29
+ - **Compact results.** Every result is under 5 KB. A list cut to fit is
30
+ declared in `truncated: {list: {shown, total}}`.
31
+ - **No silent fallback.** A missing op answers `engine_lacks_op`; a measurement
32
+ that cannot be made answers a named `failure_reason`.
33
+ - **Engine ops.** No new engine op. Reads run one read-only GDScript probe
34
+ through `RunSceneScript` (the op behind `summer_run_script`: in-process, no
35
+ child editor, `undo: "none"`, no checkpoint). Mutations are ordinary
36
+ `SetProp`, `SnapToSurface` and `InstantiateScene` ops: one undo step per
37
+ request and one final `SaveScene`.
38
+ - **Side effects of the probe.** It blocks the editor for the few milliseconds
39
+ it runs, and the engine marks the *active* tab as unsaved after any
40
+ `RunSceneScript`, even a read-only one. Nothing in the scene changes.
41
+
42
+ ## Which tool answers which question
43
+
44
+ | Question | Tool |
45
+ |---|---|
46
+ | How big is this piece, where is its origin, which face is its back, where are its pipe ends? | `summer_inspect_asset` |
47
+ | Place a piece at an exact pose in one call | `summer_instantiate_scene` with `position` / `rotation_degrees` / `scale` / `transform` |
48
+ | Place many pieces in one call and read the receipt | `summer_batch` with placed `InstantiateScene` ops and `receipt: "summary"` |
49
+ | Next facade module edge to edge, next storey on top | `summer_place_adjacent` |
50
+ | Downpipe, lamp, AC unit or sign on the wall | `summer_attach_to_surface` |
51
+ | Clamps every 0.45 m, a row of posts or windows | `summer_repeat_along` |
52
+ | Pipe or duct end to end | `summer_connect_ports` |
53
+ | What is in front of this point, and its normal? | `summer_raycast` |
54
+ | Gap or overlap between two pieces; is the facade front flat? | `summer_measure` |
55
+ | What surrounds a placed piece, which side is blocked? | `summer_starcast` (existing) |
56
+ | Will a pose fit before I commit it in a tight spot? | `summer_test_placement` (existing) |
57
+ | Seat a prop on a floor, table or ledge | `summer_snap_to_surface` (existing) |
58
+ | Line up or equally space 2-16 placed pieces on one axis | `summer_align_distribute_3d` (existing) |
59
+ | Did exactly that change, and does it look right? | `summer_world_snapshot` + `summer_snapshot_diff`, then `summer_screenshot` (existing) |
60
+
61
+ ## `summer_inspect_asset`
62
+
63
+ Measure an asset file without adding it to a scene. The probe loads the file,
64
+ instances it off the scene tree, measures, and frees it.
65
+
66
+ - **Use when:** before placing any kit piece you have not measured.
67
+ - **Arguments:** `path` (`res://` `.tscn` `.scn` `.glb` `.gltf` `.res`
68
+ `.tres` `.mesh` `.obj`), `maxTriangles` (100-300000, default 60000) for the
69
+ face and loop analysis, `detail` (`summary`, the default, or `full`).
70
+ - **Result:** `{ok, tool, detail, summary {aabb, origin, plane_pairs,
71
+ port_like_loops, triangles, mesh_count, anchor_count, collision_count,
72
+ warnings?}, frame: "asset_root", root_class, root_transform_identity,
73
+ aabb {min, max, size}, origin {fraction [x,y,z], label}, mesh_count,
74
+ meshes [{path, tris, min, max, hidden?}], triangles,
75
+ planes [{normal, offset, area, tris, cull_back, one_sided}] (top 6 by area),
76
+ open_loop_count, open_loops [{id, index, mesh, center, direction, radius,
77
+ vertices, max_dev, direction_ambiguous?}], open_loops_listed?,
78
+ open_loops_omitted?, open_chains, anchor_count, anchors [{name, path,
79
+ position, forward, up}], collision_count, collision [{path, shape,
80
+ size|radius|height|faces|points, center, min, max, disabled?}], analysis
81
+ {triangles_analyzed, triangle_budget, truncated, weld_m, plane_bin},
82
+ evidence: "mesh_triangles"}`.
83
+ - **The summary block** comes first and holds the facing evidence:
84
+ - `plane_pairs`: the two largest pairs of opposite planes (a pair under 1% of
85
+ the largest one's area is left out), each `{larger, opposite, separation}`.
86
+ `opposite` is `null` for a single sheet. Every plane is `{axis?, normal,
87
+ offset, area, one_sided}`; `axis` (such as `+z`) is given only when the
88
+ normal is within about 1 degree of it, so a baked yaw or a 45-degree corner
89
+ face shows its exact normal with no label. `separation` is the distance
90
+ between the two planes (the thickness; 0 for a sheet modelled with both
91
+ faces).
92
+ - `one_sided: true` means the plane's material culls back faces: it is
93
+ invisible from behind its normal. A one-sided sheet with no opposite plane
94
+ faces along its normal, and its back is the opposite axis.
95
+ - `port_like_loops`: ids of the open loops that look like pipe or duct
96
+ ends: radius over 2 cm, a decided direction, and either a partner loop of
97
+ similar radius facing more than 60 degrees away (the other end of a
98
+ straight run or a bend) or, for an end piece with one opening (an outlet's
99
+ socket, a funnel's mouth), the only loop opening on the bounding-box face
100
+ it points through, with the piece reaching at least two radii behind it.
101
+ - `warnings`: says when the triangle budget cut the analysis and which
102
+ `maxTriangles` covers the whole mesh.
103
+ - **`detail`:** `summary` lists in `open_loops` only the port-like loops (with
104
+ their ids and indices, which `summer_connect_ports` accepts) and says how
105
+ many it omitted. `full` lists every loop, including the outline and holes of
106
+ flat sheets.
107
+ - **Loop ids and order:** loops are grouped by the piece axis their outward
108
+ direction is nearest (`+X`, `-X`, `+Y`, `-Y`, `+Z`, `-Z`, then `~X`, `~Y`,
109
+ `~Z` for loops whose direction is undecided), the outermost along that axis
110
+ first, then by centre x, y, z (in millimetres); the radius only breaks exact
111
+ ties. The `id` follows that order: `+Y` is the outermost loop facing +Y,
112
+ `+Y#2` the next one. `index` is the position in the same order. Both are
113
+ computed in the piece's own frame, so they name the same loop on the placed
114
+ node in `summer_connect_ports`, whatever its pose. A loop 30 degrees off +Y
115
+ still groups under `+Y`: read its `direction`.
116
+ - **Reading it:** the asset frame is the root's own frame (its own transform
117
+ excluded), the frame `position` and `rotation_degrees` apply in. `origin.label`
118
+ such as `x:center y:min z:center` means bottom centre. Plane normals follow
119
+ triangle winding, so they point out of the visible side. The largest planes
120
+ with normals along one axis are usually the front and back: a wall with a
121
+ large `+z` plane at the max z offset faces +z and its back is `-z`. The tool
122
+ reports planes; you decide which is the front. Open loops are holes in the
123
+ mesh: pipe and duct ends (`direction` points out of the piece), and also the
124
+ open edge of single-sided geometry. `max_dev` is how far the loop is from
125
+ flat.
126
+ - **Limits:** planes are binned at about 1.4 degrees and 1 cm. Vertices are
127
+ welded at 0.1 mm, so UV seams do not count as holes; double-sided or capped
128
+ ends have no loop. Hidden meshes are listed but not analysed. `one_sided`
129
+ reads `cull_mode` of a `BaseMaterial3D`, or `cull_disabled` / `cull_front`
130
+ in a shader's code; a mesh with no material counts as one-sided (the default
131
+ material culls back faces).
132
+ - **Ops:** `RunSceneScript` (read-only probe).
133
+
134
+ ## `summer_instantiate_scene` (placed)
135
+
136
+ - **Arguments added:** `position`, `rotation_degrees`, `scale` (`[x, y, z]`,
137
+ parent-local) or `transform` (`"Transform3D(xx, xy, xz, yx, yy, yz, zx, zy,
138
+ zz, ox, oy, oz)"`). Not `transform` with the others; not `scale` or
139
+ `transform` with `target_size`.
140
+ - **Behaviour:** `InstantiateScene` (its own request, as the engine requires),
141
+ then one `SetProp` request on the node path the receipt reports (a name
142
+ collision rename is followed), then `SaveScene`. Without the new fields it is
143
+ unchanged.
144
+ - **Result:** the merged receipt (`results` holds every op; the per-request
145
+ `receipts` copies are kept only when something failed) plus
146
+ `placement {nodePath, applied, fields, space: "parent_local"}`.
147
+ - **Ops:** `InstantiateScene`, `SetProp`, `SaveScene`.
148
+
149
+ ## `summer_batch` additions
150
+
151
+ - `InstantiateScene` ops may carry the same placement fields (arrays or
152
+ `"Vector3(...)"` strings). Each piece is one op; its `SetProp`s are sent right
153
+ after it is created. Other ops are forwarded verbatim.
154
+ - `receipt: "summary"` returns `{ok, receipt, ops, requests, applied, failed,
155
+ not_sent, saved, error?, failures [{index, op, step?, failure_reason?,
156
+ error}], created_total, created [paths], renamed [{index, requested,
157
+ actual}]}`. `index` is the position in your `ops` list. Use it for every batch
158
+ over a few ops: a full receipt for about 30 or more ops overflows the tool
159
+ output limit.
160
+ - **Cost:** the engine runs each `InstantiateScene` as its own request. The
161
+ transforms of a run of `InstantiateScene` ops are held back and sent
162
+ together (up to 200 `SetProp`s per request) just before the next op that is
163
+ not an `InstantiateScene`, riding along with it when it can. A batch of N
164
+ placed pieces is therefore about N + 2 requests and N + 2 undo steps (it was
165
+ 2N + 1). Every later op in the list (a `SetProp`, `SnapToSurface`, a query,
166
+ the save) runs after the transforms land. If an `InstantiateScene` fails,
167
+ the pieces created before it still get their transforms; nothing is saved.
168
+
169
+ ## `summer_place_adjacent`
170
+
171
+ - **Use when:** facade modules edge to edge, a storey on the storey below, a
172
+ cornice on a wall, a pier beside a bay.
173
+ - **Arguments:** `subject` (moves), `reference` (stays), `axis` (`x|y|z`),
174
+ `side` (`max`: subject on the reference's +axis side; `min`: the -axis side),
175
+ `gap` (default 0; negative overlaps), `alignOtherAxes` (`min|center|max|none`
176
+ for both other axes, or per axis `{y: "min", z: "max"}`), `space`
177
+ (`world`, or `local` for the reference's own axes).
178
+ - **Result:** `{subject, reference, evidence: "visual_aabb", space, moved,
179
+ moved_by [world], position [parent-local], saved, reference_excludes_subject?,
180
+ verify {gap, residuals}}`. `verify` is a fresh read after the move.
181
+ - **Limits:** bounds are visible-mesh AABBs; a piece with an overhang (a
182
+ cornice lip) meets at its outermost point. If the subject is inside the
183
+ reference, its geometry is left out of the reference's bounds. A reference
184
+ inside the subject is refused.
185
+ - **Ops:** `RunSceneScript` (read, verify), `SetProp` (position),
186
+ `SaveScene`.
187
+
188
+ ## `summer_attach_to_surface`
189
+
190
+ - **Use when:** mounting downpipes, gutters, lamps, AC units, signs, fire
191
+ escapes on a wall (or anything on a ceiling or floor) with the right side
192
+ against it.
193
+ - **Arguments:** `subject`; `surface` (node: the ray runs from the subject's
194
+ origin to the nearest point of the node's bounds) and/or `ray {origin,
195
+ direction}` (with both, hits on other nodes are skipped); `backAxis` (the
196
+ subject's local axis that faces into the surface, default `-z`); `upAxis`
197
+ (default `+y`); `worldUp` (default `[0,1,0]`); `standoff` (default 0);
198
+ `placeAt` (`current`, the default, or `hit`); `maxMove` (default 2);
199
+ `maxDistance` (ray length, default 20); `collisionMask`.
200
+ - **Place the piece near its mount first** (`summer_instantiate_scene` with
201
+ `position`): this tool turns it and pushes it onto the surface.
202
+ - **Behaviour:** the probe reads the piece's visible bounds along its own axes
203
+ and casts the ray (physics first, visual AABB fallback declared). The piece is
204
+ turned so `backAxis` points along -normal and `upAxis` follows `worldUp`
205
+ projected onto the surface (on a floor or ceiling, where that is undefined,
206
+ the current up is kept and a warning says so). The planned seat puts its
207
+ **back face** (the extreme of its visible bounds along `backAxis`, not its
208
+ origin) at `standoff` in front of the plane through the hit point:
209
+ - `placeAt: "current"`: the piece keeps its height and its place along the
210
+ surface and moves only along the surface normal.
211
+ - `placeAt: "hit"`: it also slides so the centre of its back face lands on
212
+ the hit point (its height then follows the ray).
213
+ One `SetProp` turns it and puts its back face 5 cm in front of the planned
214
+ seat; `SnapToSurface` sweeps it along -normal (at most `standoff` + 0.3) and
215
+ seats it at `standoff` by its own evidence.
216
+ - **Checked before saving:**
217
+ - a planned move longer than `maxMove` is refused before anything changes
218
+ (`move_exceeds_max_move`, `mutationApplied: false`), and so is, with
219
+ `placeAt: "current"`, a ray hit farther than `maxMove` along the surface
220
+ from the piece's back face (`hit_far_from_piece`: aim the ray at the piece,
221
+ or pass `placeAt: "hit"` to move it there);
222
+ - with `surface`, the seat must be on that node or inside it; with a ray
223
+ only, a seat on another node is accepted only when it lies on the hit plane
224
+ (a coplanar neighbour module, warned `seated_on_coplanar_<path>`). Anything
225
+ else is refused as `seated_on_other_node`;
226
+ - a failed seat (`overlap_recovery_exceeded`, `gap_exceeds_hit_travel`,
227
+ `surface_not_found`, `subject_not_ready`) is reported with `blockers
228
+ {evidence, overlapping, overlaps, first_contact {path, distance}}`, read
229
+ where the seat started, and a `next_step`.
230
+
231
+ A refusal or failure puts the piece back exactly where it started
232
+ (`restored: true`), saves nothing and answers `ok: false` with `seated_on`,
233
+ `intended_surface`, `in_front_of_plan` (how far in front of the planned seat
234
+ it stopped) and `next_step`.
235
+ - **Result:** `{subject, placed_at, seated_on, final_gap (the collider gap
236
+ from SnapToSurface), back_face_gap (visible back face to the hit plane),
237
+ moved_by, surface_hit {evidence, path, point, normal, distance}, orientation
238
+ {backAxis, upAxis, world_back, world_up}, back_face_offset (origin to back
239
+ face along backAxis), seat {ok, evidence, supportPath, finalGap,
240
+ gapErrorBound, initiallyOverlapping, backoffDistance, hitTravel, origin,
241
+ warnings}, standoff, saved, warnings}`.
242
+ - **Warnings worth acting on:** `visible_back_X_into_surface` (the collider
243
+ sits X behind the visible back face, so the mesh pokes into the wall: add X
244
+ to `standoff`); `surface_not_flat_under_piece` (it seated on the surface but
245
+ in front of the hit plane); `hit_normal_pointed_away_from_the_ray_flipped`
246
+ (the ray hit a back face; the piece still mounts on the ray's side).
247
+ - **Check after:** `summer_starcast` with `directionSpace: "local"`. Its local
248
+ names follow Godot (`forward` = -Z, `back` = +Z), so a -Z back reads
249
+ `forward` blocked (or the surface in `contacts` when seated flush) and `back`
250
+ open.
251
+ - **Limits:** the back face is the visible-mesh AABB in the piece's own axes;
252
+ the seat itself is collider-exact when the piece has colliders. A mesh-only
253
+ wall gives an AABB face normal (axis-aligned), and SnapToSurface's own
254
+ evidence is then `visual_aabb`. A mirrored (negative-scale) piece is refused.
255
+ Pass `backAxis` from `summer_inspect_asset`, never a guess.
256
+ - **Ops:** `RunSceneScript` (bounds and ray; the blockers read after a failed
257
+ seat), `SetProp` (transform; the restore), `SnapToSurface`, `SaveScene`.
258
+
259
+ ## `summer_repeat_along`
260
+
261
+ - **Use when:** clamps every 0.45 m up a pipe, braces every 0.8 m along a duct,
262
+ fence posts, bollards, a row of window modules.
263
+ - **Arguments:** `template` (scene), `parent`, `start`; then `end` with
264
+ `spacing` (as many as fit) or `count` (spread start to end), or `direction`
265
+ with `count` and `spacing`. `align` (`start|center|end`) places the leftover
266
+ length with `end` + `spacing`. `rotationDegrees`, `scale`, `namePrefix`
267
+ (copies are `<prefix>_<n>`, default the template file name). Coordinates are
268
+ parent-local. At most 64 copies per call.
269
+ - **Result:** the batch summary plus `{template, parent, count, spacing,
270
+ direction, first, last}`.
271
+ - **Ops:** `InstantiateScene` (one request per copy), `SetProp` (every copy's
272
+ transform in one request), `SaveScene`: N copies cost N + 2 requests.
273
+
274
+ ## `summer_connect_ports`
275
+
276
+ - **Use when:** pipe to pipe, duct to duct, gutter section to funnel or outlet,
277
+ any two pieces with named anchors.
278
+ - **Arguments:** `subject` (moves), `subjectPort`, `target` (stays),
279
+ `targetPort`, `gap` (default 0), `rollDegrees` (default 0),
280
+ `maxTiltDegrees` (0-180, default 5), `allowTilt` (default false),
281
+ `maxTriangles`. A port is an open-loop id from `summer_inspect_asset` on
282
+ that node's scene (`+Y`, `-Z#2`; case does not matter, `+Y#1` is `+Y`), a
283
+ Marker3D (or any Node3D) name under the node whose -Z axis points out of the
284
+ port, or an open-loop index in the same stable order. A string shaped like
285
+ an id is always read as an id.
286
+ - **Behaviour:** the subject turns by the shortest rotation that makes its port
287
+ direction the opposite of the target's, then by `rollDegrees` about the
288
+ joined axis, then moves so the ports meet, `gap` apart along the target port
289
+ direction.
290
+ - **`rollDegrees` exactly:**
291
+ - axis: the target port's direction reversed, pointing from the joint into
292
+ the target (`roll_axis` in the receipt);
293
+ - sign: right-hand rule about that axis; positive turns counter-clockwise
294
+ when you look back along the axis from inside the target toward the
295
+ subject;
296
+ - zero: the shortest turn from the subject's current orientation, so the same
297
+ value gives different results from different start poses. Once the ports
298
+ are joined, a second call turns by exactly `rollDegrees` about the joint:
299
+ 180 flips a bend's free end to the other side.
300
+ - **Tilt guard:** the tilt is how far the join turns the subject's up axis
301
+ (its local +Y); a turn about the up axis is no tilt. Over `maxTiltDegrees`
302
+ the join is refused before anything changes: `failure_reason:
303
+ "tilt_exceeds_limit"`, `tilt_degrees` (predicted), `max_tilt_degrees`,
304
+ `subject_port`, `target_port`, `ports_within_limit [{id|name, index,
305
+ tilt_degrees, direction}]` (the subject's ports that would join within the
306
+ limit, least tilt first) and `saved: false`. Pass `allowTilt: true` when the
307
+ tilt is intended (a bend laid on its side, a sloped run); the receipt then
308
+ warns `tilt_allowed`.
309
+ - **Result:** `{evidence (markers|mesh_triangles), subject_port, target_port,
310
+ roll_axis, roll_degrees, rotated_degrees, tilt_degrees, max_tilt_degrees,
311
+ moved_by, other_ports [{kind, id|name, index?, position, direction,
312
+ radius?, direction_ambiguous?}], other_ports_total?, other_ports_predicted?,
313
+ saved, verify {distance, angle_degrees, tilt_degrees}, warnings}`. A port
314
+ that is not found answers `port_not_found` with the node's loops by id
315
+ (`subject_ports` or `target_ports`).
316
+ - **`other_ports`:** every other port of the subject (its other Marker3D
317
+ anchors for a marker port, its other open loops for an open-loop port, up to
318
+ 8) with world position and outward direction after the move, measured by the
319
+ verify read (`other_ports_predicted: true` when that read failed and they
320
+ were computed from the move). Read where a bend's free end now points
321
+ instead of measuring it; if it points the wrong way, call again with the
322
+ `rollDegrees` that turns it about `roll_axis`.
323
+ - **Limits:** open-loop ports are only as exact as the mesh; an end whose
324
+ direction cannot be decided is flagged `direction_ambiguous`.
325
+ - **Ops:** `RunSceneScript` (read, verify), `SetProp` (transform),
326
+ `SaveScene`.
327
+
328
+ ## `summer_raycast`
329
+
330
+ - **Use when:** you need a surface and its normal at an arbitrary point before
331
+ anything is placed. (`summer_starcast` casts from an existing node.)
332
+ - **Arguments:** `origin`, `direction`, `maxDistance` (default 100),
333
+ `collisionMask`, `collideWithAreas`, `evidence` (`auto|physics|visual_aabb`),
334
+ `exclude` (up to 16 nodes).
335
+ - **Result:** `{hit, evidence, path, point, normal, distance, fallback?,
336
+ fallback_reason?, nearer_visual_only?, origin, direction, physics_available,
337
+ physics_unavailable_reason?, warnings}`.
338
+ - **Limits:** visual AABB hits ignore boxes that contain the origin (counted in
339
+ `warnings`); their normal is a box face normal.
340
+ - **Ops:** `RunSceneScript` (read-only).
341
+
342
+ ## `summer_measure`
343
+
344
+ - **Use when:** checking a placement numerically: facade gaps, overlaps,
345
+ modules standing proud. (`summer_starcast` reports clearance around one node
346
+ in 26 directions; this compares named nodes.)
347
+ - **Arguments:** `mode` (`pair` with `a`, `b`, optional `axis`; `plane` with
348
+ `nodes` (2-32) and `face` such as `+z`), `space` (`world`, or `local` for the
349
+ axes of `a` / `nodes[0]`), `tolerance` (default 0.005).
350
+ - **Result, pair:** `{axes {x|y|z: {gap, relation: gap|touching|overlap, a,
351
+ b, delta_min, delta_max, delta_center}}, boxes_overlap}`; `gap < 0` is the
352
+ overlap depth, `delta_*` is b minus a.
353
+ - **Result, plane:** `{coplanar, plane, spread, off_plane_count, nodes [{path,
354
+ face, deviation, off_plane: proud|recessed}], no_geometry?}`.
355
+ - **Ops:** `RunSceneScript` (read-only).
356
+
357
+ ## What belongs in the engine later
358
+
359
+ These tools compose existing ops. Natively they would be faster and exact:
360
+ an `InstantiateScene` that takes a transform (one request, one undo step per
361
+ piece), a compact `summer_batch` receipt mode in the ops executor, a raycast and
362
+ a measure op that need no script and do not mark the active tab unsaved, an
363
+ asset-geometry op that reads the import cache without instancing, and an
364
+ oriented-bounds (OBB) query so rotated pieces stop needing `space: "local"`.
@@ -1,12 +1,15 @@
1
1
  id: skill/spatial-placement
2
2
  kind: skill
3
- version: 1.0.1
4
- summary: Place and verify 3D objects with Starcast evidence — inspect, place, starcast, correct, verify; floor, shelf, wall, alcove recipes and overlap repair.
3
+ version: 1.1.0
4
+ summary: Place 3D objects and modular kit pieces from measured geometry — inspect, place, starcast, measure, correct; floor, wall, facade, pipe and alcove recipes.
5
5
  use_when:
6
6
  - positioning a prop, character, collider, or platform so it sits flush, avoids overlap, or keeps clearance
7
7
  - placing something against a wall, inside an alcove, or on a shelf and needing to know which side is blocked and by how much
8
8
  - repairing an overlap or a floating object after a placement
9
9
  - post-placement checks on a rotated prop using its own local axes
10
+ - placing modular kit pieces — facade or wall modules edge to edge, storeys stacked, pipes, gutters and lamps on a wall, clamps along a pipe
11
+ - measuring a kit piece's size, origin and which way it faces before placing it
12
+ - checking that a facade line is flush, with no gaps and no module standing proud
10
13
  do_not_use_when:
11
14
  - the scene is 2D — Starcast reads Node3D bounds, 3D physics, and visual AABBs
12
15
  - you want the engine to seat or align for you — skill/world-building-3d (summer_snap_to_surface, summer_align_distribute_3d)
@@ -27,6 +30,17 @@ compatibility:
27
30
  related:
28
31
  tools:
29
32
  - tool/starcast
33
+ - tool/inspect-asset
34
+ - tool/place-adjacent
35
+ - tool/attach-to-surface
36
+ - tool/repeat-along
37
+ - tool/connect-ports
38
+ - tool/raycast
39
+ - tool/measure
40
+ - tool/instantiate-scene
41
+ - tool/test-placement
42
+ - tool/snap-to-surface
43
+ - tool/align-distribute-3d
30
44
  - tool/get-scene-tree
31
45
  - tool/inspect-node
32
46
  - tool/set-prop