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.
- package/.claude-plugin/marketplace.json +2 -13
- package/.claude-plugin/plugin.json +25 -22
- package/.codex-plugin/plugin.json +8 -14
- package/.cursor-plugin/plugin.json +7 -13
- package/.factory-plugin/plugin.json +7 -13
- package/AGENTS.md +19 -12
- package/CHANGELOG.md +112 -0
- package/GEMINI.md +3 -3
- package/README.md +111 -31
- package/assets/icon.png +0 -0
- package/commands/start.md +71 -0
- package/commands/summer.md +5 -3
- package/dist/cli/banner.js +3 -0
- package/dist/cli/commands/login.d.ts +27 -0
- package/dist/cli/commands/login.js +58 -12
- package/dist/cli/commands/ops.d.ts +47 -0
- package/dist/cli/commands/ops.js +301 -0
- package/dist/cli/commands/setup.d.ts +2 -0
- package/dist/cli/commands/setup.js +37 -12
- package/dist/cli/commands/skills.js +11 -7
- package/dist/cli/index.js +7 -0
- package/dist/core/agent-host.d.ts +65 -0
- package/dist/core/agent-host.js +193 -0
- package/dist/core/capabilities/agent-playbook.d.ts +3 -0
- package/dist/core/capabilities/agent-playbook.js +54 -2
- package/dist/core/capabilities/apps.d.ts +341 -0
- package/dist/core/capabilities/apps.js +353 -0
- package/dist/core/capabilities/doctor.d.ts +3 -0
- package/dist/core/capabilities/doctor.js +20 -15
- package/dist/core/capabilities/enable-plugin.d.ts +27 -0
- package/dist/core/capabilities/enable-plugin.js +75 -0
- package/dist/core/capabilities/fabricate-mesh.d.ts +2 -2
- package/dist/core/capabilities/game-task-plan.d.ts +12 -6
- package/dist/core/capabilities/game-task-plan.js +80 -5
- package/dist/core/capabilities/motion-generation.js +2 -2
- package/dist/core/capabilities/navigation/open.d.ts +6 -2
- package/dist/core/capabilities/navigation/open.js +3 -0
- package/dist/core/capabilities/publish-build.js +2 -0
- package/dist/core/capabilities/runtime-control.d.ts +4 -4
- package/dist/core/capabilities/scene-script-target.d.ts +17 -0
- package/dist/core/capabilities/scene-script-target.js +70 -0
- package/dist/core/capabilities/sfx-choices.d.ts +4 -0
- package/dist/core/capabilities/sfx-choices.js +13 -6
- package/dist/core/capabilities/tool-dispatch.d.ts +12 -3
- package/dist/core/capabilities/tool-dispatch.js +130 -46
- package/dist/core/capability-skew.js +4 -0
- package/dist/core/embeddings.d.ts +2 -0
- package/dist/core/embeddings.js +1 -1
- package/dist/core/error-codes.d.ts +62 -0
- package/dist/core/error-codes.js +97 -0
- package/dist/core/format.d.ts +2 -0
- package/dist/core/format.js +2 -1
- package/dist/core/hosted-mcp.d.ts +22 -0
- package/dist/core/hosted-mcp.js +56 -1
- package/dist/core/library-read.js +5 -0
- package/dist/core/library-search.js +2 -1
- package/dist/core/oauth.js +4 -0
- package/dist/core/ops/catalog.d.ts +41 -0
- package/dist/core/ops/catalog.js +145 -0
- package/dist/core/ops/cloud.d.ts +56 -0
- package/dist/core/ops/cloud.js +175 -0
- package/dist/core/ops/contract.d.ts +119 -0
- package/dist/core/ops/contract.js +142 -0
- package/dist/core/ops/engine-answer.d.ts +25 -0
- package/dist/core/ops/engine-answer.js +117 -0
- package/dist/core/ops/engine.d.ts +55 -0
- package/dist/core/ops/engine.js +649 -0
- package/dist/core/ops/save-files.d.ts +78 -0
- package/dist/core/ops/save-files.js +419 -0
- package/dist/core/ops/search.d.ts +9 -0
- package/dist/core/ops/search.js +55 -0
- package/dist/core/skills-registry.d.ts +16 -1
- package/dist/core/skills-registry.js +35 -2
- package/dist/core/telemetry.d.ts +32 -0
- package/dist/core/telemetry.js +38 -10
- package/dist/core/tool-profiles.d.ts +25 -0
- package/dist/core/tool-profiles.js +41 -0
- package/dist/installer/agent-config.d.ts +17 -4
- package/dist/installer/agent-config.js +22 -6
- package/dist/installer/agent-table.d.ts +3 -0
- package/dist/installer/agent-table.js +10 -7
- package/dist/installer/setup.d.ts +2 -0
- package/dist/installer/setup.js +9 -4
- package/dist/installer/version-check.d.ts +29 -9
- package/dist/installer/version-check.js +81 -28
- package/dist/mcp/command.js +7 -0
- package/dist/mcp/hosted-mount.d.ts +27 -2
- package/dist/mcp/hosted-mount.js +66 -24
- package/dist/mcp/legacy-toolset.d.ts +27 -0
- package/dist/mcp/legacy-toolset.js +43 -0
- package/dist/mcp/ops-surface.d.ts +59 -0
- package/dist/mcp/ops-surface.js +443 -0
- package/dist/mcp/server.d.ts +35 -11
- package/dist/mcp/server.js +236 -89
- package/dist/mcp/tool-results.d.ts +26 -0
- package/dist/mcp/tool-results.js +81 -0
- package/dist/mcp/tool-surface.d.ts +65 -0
- package/dist/mcp/tool-surface.js +317 -0
- package/dist/mcp/tools/app-tools.d.ts +2 -0
- package/dist/mcp/tools/app-tools.js +71 -0
- package/dist/mcp/tools/asset-tools.js +55 -53
- package/dist/mcp/tools/audit-tools.js +21 -21
- package/dist/mcp/tools/debug-tools.js +6 -6
- package/dist/mcp/tools/fabricate-tools.js +6 -6
- package/dist/mcp/tools/generate-tools.js +76 -70
- package/dist/mcp/tools/project-tools.d.ts +9 -4
- package/dist/mcp/tools/project-tools.js +16 -10
- package/dist/mcp/tools/scene-tools.js +12 -23
- package/dist/mcp/tools/script-tools.js +9 -5
- package/dist/mcp/tools/with-engine.d.ts +6 -0
- package/dist/mcp/tools/with-engine.js +19 -0
- package/gemini-extension.json +6 -12
- package/hooks/pre-commit-doctor.sh +5 -4
- package/hooks/session-start.sh +24 -28
- package/integrations/claude-desktop/README.md +1 -1
- package/integrations/copilot-jetbrains/README.md +1 -1
- package/integrations/junie/README.md +1 -1
- package/integrations/lm-studio/README.md +1 -1
- package/integrations/trae/README.md +1 -1
- package/integrations/visual-studio/README.md +1 -1
- package/library/references/mcp-tools-reference/mcp-tools-reference.md +85 -35
- package/library/references/mcp-tools-reference/resource.yaml +1 -1
- package/library/references/product-map/resource.yaml +2 -2
- package/library/skills/3d-lighting/SKILL.md +53 -28
- package/library/skills/3d-lighting/resource.yaml +1 -1
- package/library/skills/README.md +126 -116
- package/library/skills/adaptive-music/SKILL.md +19 -23
- package/library/skills/adaptive-music/resource.yaml +1 -1
- package/library/skills/agent-playtesting/SKILL.md +1 -1
- package/library/skills/agent-playtesting/resource.yaml +1 -1
- package/library/skills/ai-characters-in-games/SKILL.md +1 -1
- package/library/skills/ai-characters-in-games/resource.yaml +1 -1
- package/library/skills/ambient-bed/SKILL.md +22 -13
- package/library/skills/ambient-bed/resource.yaml +1 -1
- package/library/skills/animated-loop/SKILL.md +41 -32
- package/library/skills/animated-loop/resource.yaml +1 -1
- package/library/skills/animation-tree/SKILL.md +1 -1
- package/library/skills/animation-tree/resource.yaml +1 -1
- package/library/skills/art-direction/SKILL.md +3 -3
- package/library/skills/art-direction/resource.yaml +1 -1
- package/library/skills/asset-strategy/SKILL.md +21 -4
- package/library/skills/asset-strategy/resource.yaml +2 -1
- package/library/skills/audio-direction/SKILL.md +10 -10
- package/library/skills/audio-direction/resource.yaml +1 -1
- package/library/skills/auto-fire-targeting/SKILL.md +1 -1
- package/library/skills/auto-fire-targeting/resource.yaml +1 -1
- package/library/skills/bounded-engine-runs/SKILL.md +1 -1
- package/library/skills/bounded-engine-runs/resource.yaml +1 -1
- package/library/skills/brainstorm-game/SKILL.md +1 -1
- package/library/skills/brainstorm-game/resource.yaml +1 -1
- package/library/skills/brainstorming/SKILL.md +1 -1
- package/library/skills/brainstorming/resource.yaml +1 -1
- package/library/skills/browse-templates/SKILL.md +1 -1
- package/library/skills/browse-templates/resource.yaml +1 -1
- package/library/skills/camera-rigs/SKILL.md +2 -2
- package/library/skills/camera-rigs/resource.yaml +1 -1
- package/library/skills/celeste-momentum-platforming/resource.yaml +1 -0
- package/library/skills/character-animation-wiring/SKILL.md +4 -4
- package/library/skills/character-animation-wiring/resource.yaml +1 -1
- package/library/skills/character-model/SKILL.md +55 -47
- package/library/skills/character-model/resource.yaml +1 -1
- package/library/skills/character-movement/SKILL.md +3 -3
- package/library/skills/character-movement/resource.yaml +1 -1
- package/library/skills/character-portrait/SKILL.md +24 -19
- package/library/skills/character-portrait/resource.yaml +1 -1
- package/library/skills/cinematic-cutscene/SKILL.md +58 -46
- package/library/skills/cinematic-cutscene/resource.yaml +1 -1
- package/library/skills/combat-basics/SKILL.md +1 -1
- package/library/skills/combat-basics/resource.yaml +1 -1
- package/library/skills/compatibility-renderer-traps/SKILL.md +1 -1
- package/library/skills/compatibility-renderer-traps/resource.yaml +1 -1
- package/library/skills/concept-art/SKILL.md +16 -12
- package/library/skills/concept-art/resource.yaml +1 -1
- package/library/skills/concept-to-level/SKILL.md +239 -0
- package/library/skills/concept-to-level/references/technical-rules.md +150 -0
- package/library/skills/concept-to-level/resource.yaml +44 -0
- package/library/skills/create-asset-sheet/SKILL.md +19 -13
- package/library/skills/create-asset-sheet/resource.yaml +1 -1
- package/library/skills/debug/SKILL.md +2 -2
- package/library/skills/debug/resource.yaml +1 -1
- package/library/skills/debugging-game-feel/SKILL.md +1 -1
- package/library/skills/debugging-game-feel/resource.yaml +1 -1
- package/library/skills/design-level/SKILL.md +23 -35
- package/library/skills/design-level/resource.yaml +1 -1
- package/library/skills/design-mechanic/SKILL.md +1 -1
- package/library/skills/design-mechanic/resource.yaml +1 -1
- package/library/skills/design-npc/SKILL.md +22 -24
- package/library/skills/design-npc/resource.yaml +1 -1
- package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
- package/library/skills/diagnosing-perf-regressions/resource.yaml +1 -1
- package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
- package/library/skills/driving-the-editor-ui/resource.yaml +1 -1
- package/library/skills/environment-kit/SKILL.md +20 -16
- package/library/skills/environment-kit/resource.yaml +1 -1
- package/library/skills/export-and-ship/SKILL.md +6 -6
- package/library/skills/export-and-ship/resource.yaml +1 -1
- package/library/skills/fabricating-assets/SKILL.md +7 -7
- package/library/skills/fabricating-assets/resource.yaml +3 -3
- package/library/skills/facial-and-lipsync/SKILL.md +14 -15
- package/library/skills/facial-and-lipsync/resource.yaml +1 -1
- package/library/skills/fps-controller/SKILL.md +33 -41
- package/library/skills/fps-controller/resource.yaml +1 -1
- package/library/skills/game-feel/SKILL.md +8 -8
- package/library/skills/game-feel/resource.yaml +1 -1
- package/library/skills/gameskill/SKILL.md +4 -4
- package/library/skills/gameskill/resource.yaml +1 -1
- package/library/skills/gdscript-patterns/SKILL.md +1 -1
- package/library/skills/gdscript-patterns/resource.yaml +1 -1
- package/library/skills/generate-motion/SKILL.md +30 -21
- package/library/skills/generate-motion/resource.yaml +1 -1
- package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
- package/library/skills/godogen-visual-proof-game-generation/resource.yaml +1 -0
- package/library/skills/grow-analytics/SKILL.md +3 -3
- package/library/skills/grow-analytics/resource.yaml +1 -1
- package/library/skills/headless-scripting/SKILL.md +1 -1
- package/library/skills/headless-scripting/resource.yaml +1 -1
- package/library/skills/in-game-purchases/SKILL.md +1 -1
- package/library/skills/in-game-purchases/resource.yaml +1 -1
- package/library/skills/instantiate-asset-pack/SKILL.md +2 -2
- package/library/skills/instantiate-asset-pack/resource.yaml +1 -1
- package/library/skills/lumera-single-image-scene-reconstruction/resource.yaml +1 -0
- package/library/skills/make-game/SKILL.md +4 -4
- package/library/skills/make-game/references/2d-platformer.md +1 -1
- package/library/skills/make-game/references/3d-fps.md +1 -1
- package/library/skills/make-game/references/3d-horror.md +1 -1
- package/library/skills/make-game/references/3d-third-person.md +2 -2
- package/library/skills/make-game/resource.yaml +1 -1
- package/library/skills/multiplayer/SKILL.md +1 -1
- package/library/skills/multiplayer/resource.yaml +1 -1
- package/library/skills/multiplayer-movement/SKILL.md +1 -1
- package/library/skills/multiplayer-movement/resource.yaml +1 -1
- package/library/skills/multiplayer-project/SKILL.md +1 -1
- package/library/skills/multiplayer-project/resource.yaml +1 -1
- package/library/skills/multiplayer-publish/SKILL.md +8 -7
- package/library/skills/multiplayer-publish/resource.yaml +3 -3
- package/library/skills/multiplayer-state/SKILL.md +1 -1
- package/library/skills/multiplayer-state/resource.yaml +1 -1
- package/library/skills/multiplayer-testing/SKILL.md +1 -1
- package/library/skills/multiplayer-testing/resource.yaml +1 -1
- package/library/skills/music-track/SKILL.md +22 -13
- package/library/skills/music-track/resource.yaml +1 -1
- package/library/skills/navigate-summer/SKILL.md +11 -9
- package/library/skills/navigate-summer/resource.yaml +1 -1
- package/library/skills/new-project/SKILL.md +1 -1
- package/library/skills/new-project/resource.yaml +1 -1
- package/library/skills/organic-model/SKILL.md +24 -18
- package/library/skills/organic-model/resource.yaml +1 -1
- package/library/skills/pixel-art/SKILL.md +27 -23
- package/library/skills/pixel-art/resource.yaml +1 -1
- package/library/skills/play/SKILL.md +1 -1
- package/library/skills/play/resource.yaml +1 -1
- package/library/skills/playtesting-a-feature/SKILL.md +1 -1
- package/library/skills/playtesting-a-feature/resource.yaml +1 -1
- package/library/skills/procedural-animation/SKILL.md +20 -16
- package/library/skills/procedural-animation/resource.yaml +1 -1
- package/library/skills/prop-model/SKILL.md +25 -19
- package/library/skills/prop-model/resource.yaml +1 -1
- package/library/skills/psx-retro-rendering/resource.yaml +1 -0
- package/library/skills/publish-your-game/SKILL.md +16 -6
- package/library/skills/publish-your-game/resource.yaml +3 -3
- package/library/skills/realtime-wet-surfaces/resource.yaml +1 -0
- package/library/skills/release-readiness/SKILL.md +1 -1
- package/library/skills/release-readiness/resource.yaml +1 -1
- package/library/skills/remote-deploy/SKILL.md +1 -1
- package/library/skills/remote-deploy/resource.yaml +1 -1
- package/library/skills/retarget/SKILL.md +23 -20
- package/library/skills/retarget/resource.yaml +1 -1
- package/library/skills/running-in-the-cloud/SKILL.md +1 -1
- package/library/skills/running-in-the-cloud/resource.yaml +1 -1
- package/library/skills/save-load/SKILL.md +1 -1
- package/library/skills/save-load/resource.yaml +1 -1
- package/library/skills/scene-composition/SKILL.md +1 -1
- package/library/skills/scene-composition/resource.yaml +1 -1
- package/library/skills/scene-hierarchy-design/SKILL.md +2 -2
- package/library/skills/scene-hierarchy-design/resource.yaml +1 -1
- package/library/skills/scene-scripting/SKILL.md +66 -636
- package/library/skills/scene-scripting/references/ctx-api.md +184 -0
- package/library/skills/scene-scripting/references/recipes-2d-ui.md +193 -0
- package/library/skills/scene-scripting/references/recipes-3d.md +280 -0
- package/library/skills/scene-scripting/resource.yaml +4 -4
- package/library/skills/scene-to-level/SKILL.md +2 -2
- package/library/skills/scene-to-level/resource.yaml +1 -1
- package/library/skills/skill-create/resource.yaml +1 -0
- package/library/skills/skill-improve/resource.yaml +1 -0
- package/library/skills/skill-test/SKILL.md +2 -2
- package/library/skills/skill-test/resource.yaml +1 -0
- package/library/skills/skintokens-auto-rigging/resource.yaml +1 -0
- package/library/skills/skybox-panorama/SKILL.md +27 -21
- package/library/skills/skybox-panorama/resource.yaml +1 -1
- package/library/skills/sound-effect/SKILL.md +31 -20
- package/library/skills/sound-effect/resource.yaml +1 -1
- package/library/skills/spatial-placement/SKILL.md +14 -9
- package/library/skills/spatial-placement/resource.yaml +1 -1
- package/library/skills/sprite-sheet/SKILL.md +32 -27
- package/library/skills/sprite-sheet/resource.yaml +1 -1
- package/library/skills/store-art/SKILL.md +3 -3
- package/library/skills/store-art/resource.yaml +2 -2
- package/library/skills/store-listing/SKILL.md +3 -3
- package/library/skills/store-listing/resource.yaml +2 -2
- package/library/skills/summer-analytics/SKILL.md +7 -5
- package/library/skills/summer-analytics/resource.yaml +2 -2
- package/library/skills/summer-apps/SKILL.md +168 -0
- package/library/skills/summer-apps/manifest.md +57 -0
- package/library/skills/summer-apps/minimal-app.md +183 -0
- package/library/skills/summer-apps/resource.yaml +36 -0
- package/library/skills/summer-apps/sdk-reference.md +135 -0
- package/library/skills/summer-apps-design/SKILL.md +197 -0
- package/library/skills/summer-apps-design/resource.yaml +23 -0
- package/library/skills/summer-assets/SKILL.md +56 -0
- package/library/skills/summer-assets/resource.yaml +34 -0
- package/library/skills/summer-store/SKILL.md +1 -1
- package/library/skills/text-to-motion/SKILL.md +30 -23
- package/library/skills/text-to-motion/prompts-and-controls.md +5 -5
- package/library/skills/text-to-motion/resource.yaml +1 -1
- package/library/skills/text-to-motion/rigging-for-text-motion.md +2 -2
- package/library/skills/tileable-texture/SKILL.md +19 -15
- package/library/skills/tileable-texture/resource.yaml +1 -1
- package/library/skills/trailer-shot/SKILL.md +28 -24
- package/library/skills/trailer-shot/resource.yaml +1 -1
- package/library/skills/tune-performance/SKILL.md +6 -6
- package/library/skills/tune-performance/resource.yaml +1 -1
- package/library/skills/ui-basics/SKILL.md +41 -36
- package/library/skills/ui-basics/resource.yaml +1 -1
- package/library/skills/ui-graphics/SKILL.md +47 -38
- package/library/skills/ui-graphics/resource.yaml +1 -1
- package/library/skills/use-widget-asset/SKILL.md +1 -1
- package/library/skills/use-widget-asset/resource.yaml +1 -1
- package/library/skills/using-summer/SKILL.md +7 -5
- package/library/skills/using-summer/resource.yaml +1 -1
- package/library/skills/vehicle-model/SKILL.md +65 -57
- package/library/skills/vehicle-model/resource.yaml +1 -1
- package/library/skills/verification-before-completion/SKILL.md +1 -1
- package/library/skills/verification-before-completion/resource.yaml +1 -1
- package/library/skills/verifying-scenes/SKILL.md +2 -2
- package/library/skills/verifying-scenes/resource.yaml +1 -1
- package/library/skills/vfx-dissolve/SKILL.md +2 -2
- package/library/skills/vfx-dissolve/resource.yaml +1 -1
- package/library/skills/vfx-fire/SKILL.md +15 -41
- package/library/skills/vfx-fire/resource.yaml +1 -1
- package/library/skills/vfx-hit-spark/SKILL.md +1 -1
- package/library/skills/vfx-hit-spark/resource.yaml +1 -1
- package/library/skills/vfx-lightning/SKILL.md +7 -16
- package/library/skills/vfx-lightning/resource.yaml +1 -1
- package/library/skills/vfx-magic-glow/SKILL.md +23 -32
- package/library/skills/vfx-magic-glow/resource.yaml +1 -1
- package/library/skills/vfx-muzzle-flash/SKILL.md +20 -35
- package/library/skills/vfx-muzzle-flash/resource.yaml +1 -1
- package/library/skills/vfx-smoke/SKILL.md +13 -31
- package/library/skills/vfx-smoke/resource.yaml +1 -1
- package/library/skills/vfx-water-ripple/SKILL.md +12 -31
- package/library/skills/vfx-water-ripple/resource.yaml +1 -1
- package/library/skills/voice-line/SKILL.md +71 -40
- package/library/skills/voice-line/resource.yaml +1 -1
- package/library/skills/web-and-touch-input/SKILL.md +1 -1
- package/library/skills/web-and-touch-input/resource.yaml +1 -1
- package/library/skills/web-compatibility-look/SKILL.md +1 -1
- package/library/skills/web-compatibility-look/resource.yaml +1 -1
- package/library/skills/world-building-3d/SKILL.md +1 -1
- package/library/skills/world-building-3d/resource.yaml +1 -1
- package/library/skills/writing-skills/resource.yaml +1 -0
- package/library/tools/add-node/GUIDE.md +14 -0
- package/library/tools/align-distribute-3d/GUIDE.md +7 -0
- package/library/tools/app-call/resource.yaml +59 -0
- package/library/tools/app-create/resource.yaml +67 -0
- package/library/tools/app-data/resource.yaml +74 -0
- package/library/tools/app-dock/resource.yaml +59 -0
- package/library/tools/app-events/resource.yaml +68 -0
- package/library/tools/app-get/resource.yaml +46 -0
- package/library/tools/app-guide/resource.yaml +55 -0
- package/library/tools/app-list/resource.yaml +48 -0
- package/library/tools/app-page/resource.yaml +74 -0
- package/library/tools/app-publish/resource.yaml +90 -0
- package/library/tools/app-report-gap/resource.yaml +58 -0
- package/library/tools/app-screenshot/resource.yaml +103 -0
- package/library/tools/app-tools/resource.yaml +46 -0
- package/library/tools/app-update/resource.yaml +68 -0
- package/library/tools/attach-to-surface/GUIDE.md +15 -0
- package/library/tools/batch/GUIDE.md +27 -0
- package/library/tools/camera-bookmark/GUIDE.md +12 -0
- package/library/tools/capture-gameplay/GUIDE.md +3 -0
- package/library/tools/capture-gameplay/resource.yaml +3 -3
- package/library/tools/check-job/resource.yaml +1 -1
- package/library/tools/clear-console/GUIDE.md +3 -0
- package/library/tools/connect-ports/GUIDE.md +9 -0
- package/library/tools/connect-signal/GUIDE.md +14 -0
- package/library/tools/create-debug-report/GUIDE.md +10 -0
- package/library/tools/create-scene/GUIDE.md +10 -0
- package/library/tools/debug-views/GUIDE.md +7 -0
- package/library/tools/enable-plugin/GUIDE.md +3 -0
- package/library/tools/enable-plugin/resource.yaml +53 -0
- package/library/tools/export-game/GUIDE.md +3 -0
- package/library/tools/export-game/resource.yaml +3 -3
- package/library/tools/export-templates/GUIDE.md +3 -0
- package/library/tools/fabricate-3d/GUIDE.md +19 -0
- package/library/tools/frame-nodes/GUIDE.md +9 -0
- package/library/tools/frame-shot/GUIDE.md +9 -0
- package/library/tools/game-control/GUIDE.md +9 -0
- package/library/tools/game-input/GUIDE.md +9 -0
- package/library/tools/game-probe/GUIDE.md +9 -0
- package/library/tools/generate-3d/resource.yaml +3 -3
- package/library/tools/generate-motion/resource.yaml +2 -2
- package/library/tools/get-console/GUIDE.md +9 -0
- package/library/tools/get-console/resource.yaml +5 -0
- package/library/tools/get-debugger-errors/GUIDE.md +7 -0
- package/library/tools/get-debugger-errors/resource.yaml +5 -0
- package/library/tools/get-debugger-warnings/GUIDE.md +7 -0
- package/library/tools/get-debugger-warnings/resource.yaml +5 -0
- package/library/tools/get-diagnostics/GUIDE.md +13 -0
- package/library/tools/get-project-context/GUIDE.md +25 -0
- package/library/tools/get-runtime-tree/GUIDE.md +7 -0
- package/library/tools/get-runtime-tree/resource.yaml +5 -0
- package/library/tools/get-scene-tree/GUIDE.md +11 -0
- package/library/tools/get-scene-tree/resource.yaml +5 -0
- package/library/tools/get-script-errors/GUIDE.md +5 -0
- package/library/tools/grep/GUIDE.md +11 -0
- package/library/tools/import-asset/GUIDE.md +8 -0
- package/library/tools/import-asset-by-id/GUIDE.md +12 -0
- package/library/tools/import-from-url/GUIDE.md +10 -0
- package/library/tools/import-from-url-batch/GUIDE.md +3 -0
- package/library/tools/import-hdri/GUIDE.md +16 -0
- package/library/tools/input-map-bind/GUIDE.md +11 -0
- package/library/tools/inspect-asset/GUIDE.md +14 -0
- package/library/tools/inspect-asset/resource.yaml +5 -0
- package/library/tools/inspect-node/GUIDE.md +11 -0
- package/library/tools/inspect-node/resource.yaml +5 -0
- package/library/tools/inspect-resource/GUIDE.md +7 -0
- package/library/tools/inspect-resource/resource.yaml +5 -0
- package/library/tools/inspect-runtime-node/GUIDE.md +7 -0
- package/library/tools/inspect-runtime-node/resource.yaml +5 -0
- package/library/tools/instantiate-scene/GUIDE.md +12 -0
- package/library/tools/is-running/GUIDE.md +3 -0
- package/library/tools/measure/GUIDE.md +8 -0
- package/library/tools/navigation-probe/GUIDE.md +9 -0
- package/library/tools/open/resource.yaml +2 -2
- package/library/tools/open-main-scene/GUIDE.md +6 -0
- package/library/tools/open-scene/GUIDE.md +8 -0
- package/library/tools/place-adjacent/GUIDE.md +7 -0
- package/library/tools/play/GUIDE.md +13 -0
- package/library/tools/project-setting/GUIDE.md +9 -0
- package/library/tools/publish-build/resource.yaml +6 -6
- package/library/tools/raycast/GUIDE.md +7 -0
- package/library/tools/read-file/GUIDE.md +10 -0
- package/library/tools/read-library/resource.yaml +5 -0
- package/library/tools/recent-events/GUIDE.md +7 -0
- package/library/tools/remove-node/GUIDE.md +3 -0
- package/library/tools/repeat-along/GUIDE.md +5 -0
- package/library/tools/replace-node/GUIDE.md +9 -0
- package/library/tools/replace-text/GUIDE.md +5 -0
- package/library/tools/run-editor-script/GUIDE.md +16 -0
- package/library/tools/run-script/GUIDE.md +30 -0
- package/library/tools/run-script/resource.yaml +6 -3
- package/library/tools/runtime-animate/GUIDE.md +7 -0
- package/library/tools/runtime-call/GUIDE.md +7 -0
- package/library/tools/runtime-set/GUIDE.md +9 -0
- package/library/tools/runtime-spawn/GUIDE.md +9 -0
- package/library/tools/save-scene/GUIDE.md +3 -0
- package/library/tools/scene-audit/GUIDE.md +29 -0
- package/library/tools/screenshot/GUIDE.md +17 -0
- package/library/tools/select-node/GUIDE.md +3 -0
- package/library/tools/set-prop/GUIDE.md +23 -0
- package/library/tools/set-resource-property/GUIDE.md +8 -0
- package/library/tools/shot-sheet/GUIDE.md +7 -0
- package/library/tools/snap-to-surface/GUIDE.md +17 -0
- package/library/tools/snapshot-diff/GUIDE.md +7 -0
- package/library/tools/starcast/GUIDE.md +12 -0
- package/library/tools/stop/GUIDE.md +3 -0
- package/library/tools/test-placement/GUIDE.md +7 -0
- package/library/tools/ui-actions/GUIDE.md +12 -0
- package/library/tools/ui-activate/GUIDE.md +11 -0
- package/library/tools/ui-screenshot/GUIDE.md +9 -0
- package/library/tools/ui-tree/GUIDE.md +10 -0
- package/library/tools/wait-for-event/GUIDE.md +11 -0
- package/library/tools/world-snapshot/GUIDE.md +9 -0
- package/library/tools/write-file/GUIDE.md +5 -0
- package/library/tools/zoom/GUIDE.md +5 -0
- package/package.json +6 -4
- package/registry/generated/aliases.json +15 -0
- package/registry/generated/counts.json +3 -3
- package/registry/generated/gemini-extension.json +6 -12
- package/registry/generated/index.json +1155 -408
- package/registry/generated/marketplace.claude.json +2 -13
- package/registry/generated/plugin.claude.json +25 -22
- package/registry/generated/plugin.codex.json +8 -14
- package/registry/generated/plugin.cursor.json +7 -13
- package/registry/generated/plugin.factory.json +7 -13
- package/registry/generated/server.json +34 -0
- package/registry/generated/skills-index.md +126 -116
- package/registry/generated/skills-registry.json +178 -113
- package/registry/operations/fixtures/invalid-deprecated-without-replacement.json +60 -0
- package/registry/operations/fixtures/invalid-name.json +60 -0
- package/registry/operations/fixtures/invalid-publish-without-owner.json +82 -0
- package/registry/operations/fixtures/invalid-spend-without-estimate.json +42 -0
- package/registry/operations/fixtures/invalid-unknown-field.json +61 -0
- package/registry/operations/fixtures/valid-player-facing.json +82 -0
- package/registry/operations/fixtures/valid-read.json +60 -0
- package/registry/operations/fixtures/valid-spend.json +43 -0
- package/registry/operations/legacy-names.json +1206 -0
- package/registry/schemas/allowed-hosts.json +4 -2
- package/registry/schemas/operation.schema.json +318 -0
- package/registry/schemas/skill.schema.json +4 -0
- 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
|
+
|