summer-engine 3.0.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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +27 -5
- package/.codex-plugin/plugin.json +28 -6
- package/.cursor-plugin/plugin.json +27 -5
- package/.factory-plugin/plugin.json +27 -5
- package/.opencode/plugins/summer.js +1 -1
- package/CHANGELOG.md +120 -0
- package/README.md +22 -7
- package/assets/audit/scene_audit.gd +4136 -0
- package/assets/seeing/seeing_probe.gd +1873 -0
- package/dist/cli/commands/setup.js +6 -19
- package/dist/cli/commands/skills.js +57 -32
- package/dist/core/api-client.d.ts +9 -1
- package/dist/core/api-client.js +21 -4
- package/dist/core/capabilities/agent-playbook.js +46 -0
- package/dist/core/capabilities/audit/accept.d.ts +55 -0
- package/dist/core/capabilities/audit/accept.js +147 -0
- package/dist/core/capabilities/audit/args.d.ts +95 -0
- package/dist/core/capabilities/audit/args.js +89 -0
- package/dist/core/capabilities/audit/audit.d.ts +56 -0
- package/dist/core/capabilities/audit/audit.js +287 -0
- package/dist/core/capabilities/audit/frame.d.ts +14 -0
- package/dist/core/capabilities/audit/frame.js +35 -0
- package/dist/core/capabilities/audit/gaps.d.ts +96 -0
- package/dist/core/capabilities/audit/gaps.js +257 -0
- package/dist/core/capabilities/audit/judge.d.ts +162 -0
- package/dist/core/capabilities/audit/judge.js +1134 -0
- package/dist/core/capabilities/audit/math.d.ts +110 -0
- package/dist/core/capabilities/audit/math.js +263 -0
- package/dist/core/capabilities/audit/summary.d.ts +74 -0
- package/dist/core/capabilities/audit/summary.js +212 -0
- package/dist/core/capabilities/board.d.ts +31 -0
- package/dist/core/capabilities/board.js +43 -0
- package/dist/core/capabilities/camera-view.d.ts +4 -2
- package/dist/core/capabilities/camera-view.js +6 -3
- package/dist/core/capabilities/connect-signal.d.ts +85 -0
- package/dist/core/capabilities/connect-signal.js +285 -0
- package/dist/core/capabilities/engine-fallbacks.d.ts +5 -0
- package/dist/core/capabilities/engine-fallbacks.js +5 -0
- package/dist/core/capabilities/engine-ops.d.ts +5 -1
- package/dist/core/capabilities/engine-ops.js +0 -3
- package/dist/core/capabilities/engine-receipt.d.ts +12 -0
- package/dist/core/capabilities/engine-receipt.js +26 -0
- package/dist/core/capabilities/file-read.d.ts +64 -0
- package/dist/core/capabilities/file-read.js +325 -0
- package/dist/core/capabilities/game-task-plan.js +4 -2
- package/dist/core/capabilities/grep.d.ts +60 -0
- package/dist/core/capabilities/grep.js +190 -0
- package/dist/core/capabilities/inspect-node.d.ts +56 -0
- package/dist/core/capabilities/inspect-node.js +225 -0
- package/dist/core/capabilities/inspect-resource.d.ts +61 -0
- package/dist/core/capabilities/inspect-resource.js +376 -0
- package/dist/core/capabilities/math3d.d.ts +28 -0
- package/dist/core/capabilities/math3d.js +88 -0
- package/dist/core/capabilities/motion-generation.d.ts +62 -0
- package/dist/core/capabilities/motion-generation.js +138 -0
- package/dist/core/capabilities/placement-batch.d.ts +102 -0
- package/dist/core/capabilities/placement-batch.js +483 -0
- package/dist/core/capabilities/placement-math.d.ts +70 -0
- package/dist/core/capabilities/placement-math.js +209 -0
- package/dist/core/capabilities/placement-script.d.ts +42 -0
- package/dist/core/capabilities/placement-script.js +1096 -0
- package/dist/core/capabilities/placement.d.ts +485 -0
- package/dist/core/capabilities/placement.js +1731 -0
- package/dist/core/capabilities/project-context.d.ts +33 -2
- package/dist/core/capabilities/project-context.js +87 -4
- package/dist/core/capabilities/replace-node.d.ts +91 -0
- package/dist/core/capabilities/replace-node.js +423 -0
- package/dist/core/capabilities/runtime-control.d.ts +20 -4
- package/dist/core/capabilities/runtime-control.js +67 -2
- package/dist/core/capabilities/scene-batch.d.ts +63 -0
- package/dist/core/capabilities/scene-batch.js +394 -0
- package/dist/core/capabilities/scene-readback.d.ts +36 -0
- package/dist/core/capabilities/scene-readback.js +54 -0
- package/dist/core/capabilities/seeing/args.d.ts +348 -0
- package/dist/core/capabilities/seeing/args.js +178 -0
- package/dist/core/capabilities/seeing/candidates.d.ts +127 -0
- package/dist/core/capabilities/seeing/candidates.js +282 -0
- package/dist/core/capabilities/seeing/math.d.ts +134 -0
- package/dist/core/capabilities/seeing/math.js +269 -0
- package/dist/core/capabilities/seeing/probe.d.ts +62 -0
- package/dist/core/capabilities/seeing/probe.js +188 -0
- package/dist/core/capabilities/seeing/scoring.d.ts +235 -0
- package/dist/core/capabilities/seeing/scoring.js +639 -0
- package/dist/core/capabilities/seeing/seeing.d.ts +233 -0
- package/dist/core/capabilities/seeing/seeing.js +1341 -0
- package/dist/core/capabilities/seeing/shot-store.d.ts +52 -0
- package/dist/core/capabilities/seeing/shot-store.js +204 -0
- package/dist/core/capabilities/surface-snap-mesh.d.ts +88 -0
- package/dist/core/capabilities/surface-snap-mesh.js +425 -0
- package/dist/core/capabilities/surface-snap.d.ts +77 -0
- package/dist/core/capabilities/surface-snap.js +461 -0
- package/dist/core/capabilities/tool-dispatch.js +231 -72
- package/dist/core/capabilities/tscn.d.ts +85 -0
- package/dist/core/capabilities/tscn.js +391 -0
- package/dist/core/capabilities/world-snapshot.d.ts +58 -0
- package/dist/core/capabilities/world-snapshot.js +150 -0
- package/dist/core/capability-skew.d.ts +5 -5
- package/dist/core/capability-skew.js +14 -6
- package/dist/core/headless/worker-engine-client.d.ts +1 -1
- package/dist/core/headless/worker-engine-client.js +2 -2
- package/dist/core/library-read.d.ts +37 -5
- package/dist/core/library-read.js +264 -33
- package/dist/core/library-search.d.ts +2 -2
- package/dist/core/skills-registry.d.ts +9 -1
- package/dist/core/skills-registry.js +25 -2
- package/dist/installer/agent-config.d.ts +9 -4
- package/dist/installer/agent-config.js +194 -392
- package/dist/installer/agent-table.d.ts +119 -0
- package/dist/installer/agent-table.js +619 -0
- package/dist/installer/setup.js +4 -2
- package/dist/installer/skill-locations.d.ts +8 -17
- package/dist/installer/skill-locations.js +22 -101
- package/dist/installer/version-check.d.ts +5 -1
- package/dist/installer/version-check.js +38 -28
- package/dist/mcp/server.js +9 -3
- package/dist/mcp/tools/asset-tools.js +21 -3
- package/dist/mcp/tools/audit-tools.d.ts +23 -0
- package/dist/mcp/tools/audit-tools.js +60 -0
- package/dist/mcp/tools/debug-tools.js +3 -1
- package/dist/mcp/tools/file-tools.js +17 -4
- package/dist/mcp/tools/generate-tools.js +74 -66
- package/dist/mcp/tools/library-tools.js +2 -0
- package/dist/mcp/tools/perception-tools.js +6 -19
- package/dist/mcp/tools/placement-tools.d.ts +24 -0
- package/dist/mcp/tools/placement-tools.js +91 -0
- package/dist/mcp/tools/project-tools.js +18 -15
- package/dist/mcp/tools/scene-tools.js +71 -83
- package/dist/mcp/tools/seeing-tools.d.ts +24 -0
- package/dist/mcp/tools/seeing-tools.js +64 -0
- package/dist/mcp/tools/spatial-tools.js +17 -9
- package/dist/mcp/tools/visual-tools.js +59 -7
- package/gemini-extension.json +26 -4
- package/integrations/README.md +48 -19
- package/integrations/amp/README.md +12 -0
- package/integrations/amp/manifest-target.json +3 -0
- package/integrations/antigravity/README.md +12 -0
- package/integrations/antigravity/manifest-target.json +3 -0
- package/integrations/claude-desktop/README.md +12 -0
- package/integrations/claude-desktop/manifest-target.json +3 -0
- package/integrations/cline/README.md +8 -9
- package/integrations/cline-cli/README.md +12 -0
- package/integrations/cline-cli/manifest-target.json +3 -0
- package/integrations/copilot-jetbrains/README.md +12 -0
- package/integrations/copilot-jetbrains/manifest-target.json +3 -0
- package/integrations/crush/README.md +12 -0
- package/integrations/crush/manifest-target.json +3 -0
- package/integrations/github-copilot/README.md +8 -8
- package/integrations/goose/README.md +12 -0
- package/integrations/goose/manifest-target.json +3 -0
- package/integrations/grok-build/README.md +12 -0
- package/integrations/grok-build/manifest-target.json +3 -0
- package/integrations/hermes/README.md +12 -0
- package/integrations/hermes/manifest-target.json +3 -0
- package/integrations/junie/README.md +12 -0
- package/integrations/junie/manifest-target.json +3 -0
- package/integrations/kilo-code/README.md +6 -10
- package/integrations/kimi-code/README.md +12 -0
- package/integrations/kimi-code/manifest-target.json +3 -0
- package/integrations/kiro/README.md +12 -0
- package/integrations/kiro/manifest-target.json +3 -0
- package/integrations/lm-studio/README.md +8 -8
- package/integrations/mistral-vibe/README.md +12 -0
- package/integrations/mistral-vibe/manifest-target.json +3 -0
- package/integrations/opencode/README.md +9 -12
- package/integrations/qoder/README.md +12 -0
- package/integrations/qoder/manifest-target.json +3 -0
- package/integrations/qwen-code/README.md +12 -0
- package/integrations/qwen-code/manifest-target.json +3 -0
- package/integrations/roo-code/README.md +8 -7
- package/integrations/rovo-dev/README.md +12 -0
- package/integrations/rovo-dev/manifest-target.json +3 -0
- package/integrations/trae/README.md +12 -0
- package/integrations/trae/manifest-target.json +3 -0
- package/integrations/visual-studio/README.md +12 -0
- package/integrations/visual-studio/manifest-target.json +3 -0
- package/integrations/vscode-copilot/README.md +9 -9
- package/integrations/warp/README.md +12 -0
- package/integrations/warp/manifest-target.json +3 -0
- package/integrations/windsurf/README.md +8 -9
- package/integrations/zed/README.md +12 -0
- package/integrations/zed/manifest-target.json +3 -0
- package/library/references/mcp-tools-reference/mcp-tools-reference.md +59 -15
- package/library/references/mcp-tools-reference/resource.yaml +1 -1
- package/library/references/summer-folder/resource.yaml +1 -1
- package/library/references/summer-folder/summer-folder.md +1 -1
- package/library/skills/3d-lighting/SKILL.md +1 -1
- package/library/skills/README.md +264 -0
- package/library/skills/adaptive-music/SKILL.md +1 -1
- package/library/skills/agent-playtesting/SKILL.md +1 -1
- package/library/skills/ai-characters-in-games/SKILL.md +220 -0
- package/library/skills/ai-characters-in-games/resource.yaml +30 -0
- package/library/skills/ambient-bed/SKILL.md +1 -1
- package/library/skills/animated-loop/SKILL.md +1 -1
- package/library/skills/animation-tree/SKILL.md +1 -1
- package/library/skills/art-direction/SKILL.md +1 -1
- package/library/skills/asset-strategy/SKILL.md +2 -1
- package/library/skills/asset-strategy/resource.yaml +2 -1
- package/library/skills/audio-direction/SKILL.md +1 -1
- package/library/skills/auto-fire-targeting/SKILL.md +1 -1
- package/library/skills/brainstorm-game/SKILL.md +1 -1
- package/library/skills/brainstorming/SKILL.md +1 -1
- package/library/skills/browse-templates/SKILL.md +3 -3
- package/library/skills/browse-templates/resource.yaml +1 -1
- package/library/skills/camera-rigs/SKILL.md +128 -0
- package/library/skills/camera-rigs/resource.yaml +29 -0
- package/library/skills/celeste-momentum-platforming/SKILL.md +1 -1
- package/library/skills/character-animation-wiring/SKILL.md +1 -1
- package/library/skills/character-model/SKILL.md +1 -1
- package/library/skills/character-movement/SKILL.md +326 -0
- package/library/skills/character-movement/references/default-third-person-controller.gd +201 -0
- package/library/skills/character-movement/references/default-third-person-verification-probe.gd +154 -0
- package/library/skills/character-movement/references/movement-3d.md +136 -0
- package/library/skills/character-movement/references/platformer-feel.md +83 -0
- package/library/skills/character-movement/resource.yaml +40 -0
- package/library/skills/character-portrait/SKILL.md +1 -1
- package/library/skills/cinematic-cutscene/SKILL.md +1 -1
- package/library/skills/combat-basics/SKILL.md +159 -0
- package/library/skills/combat-basics/references/projectiles-and-aoe.md +100 -0
- package/library/skills/combat-basics/resource.yaml +34 -0
- package/library/skills/concept-art/SKILL.md +1 -1
- package/library/skills/create-asset-sheet/SKILL.md +1 -1
- package/library/skills/debug/SKILL.md +1 -1
- package/library/skills/debugging-game-feel/SKILL.md +1 -1
- package/library/skills/design-level/SKILL.md +1 -1
- package/library/skills/design-mechanic/SKILL.md +1 -1
- package/library/skills/design-npc/SKILL.md +1 -1
- package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
- package/library/skills/dispatching-parallel-agents/SKILL.md +1 -1
- package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
- package/library/skills/environment-kit/SKILL.md +1 -1
- package/library/skills/export-and-ship/SKILL.md +1 -1
- package/library/skills/fabricating-assets/SKILL.md +1 -1
- package/library/skills/facial-and-lipsync/SKILL.md +1 -1
- package/library/skills/fps-controller/SKILL.md +9 -7
- package/library/skills/fps-controller/resource.yaml +4 -1
- package/library/skills/game-feel/SKILL.md +1 -1
- package/library/skills/gameskill/SKILL.md +1 -1
- package/library/skills/gdscript-patterns/SKILL.md +1 -1
- package/library/skills/generate-motion/SKILL.md +9 -9
- package/library/skills/generate-motion/resource.yaml +2 -1
- package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
- package/library/skills/headless-scripting/SKILL.md +1 -1
- package/library/skills/in-game-purchases/SKILL.md +254 -0
- package/library/skills/in-game-purchases/resource.yaml +29 -0
- package/library/skills/instantiate-asset-pack/SKILL.md +1 -1
- package/library/skills/investigating-bugs/SKILL.md +1 -1
- package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +1 -1
- package/library/skills/make-game/SKILL.md +25 -3
- package/library/skills/make-game/references/2d-platformer-polish.md +93 -0
- package/library/skills/make-game/references/2d-platformer.md +117 -0
- package/library/skills/make-game/references/2d-rpg-content.md +234 -0
- package/library/skills/make-game/references/2d-rpg.md +241 -0
- package/library/skills/make-game/references/2d-survivors-progression.md +201 -0
- package/library/skills/make-game/references/2d-survivors.md +237 -0
- package/library/skills/make-game/references/3d-fps-systems.md +216 -0
- package/library/skills/make-game/references/3d-fps.md +177 -0
- package/library/skills/make-game/references/3d-horror-systems.md +186 -0
- package/library/skills/make-game/references/3d-horror.md +201 -0
- package/library/skills/make-game/references/3d-third-person-systems.md +220 -0
- package/library/skills/make-game/references/3d-third-person.md +215 -0
- package/library/skills/make-game/resource.yaml +6 -1
- package/library/skills/multiplayer/SKILL.md +150 -0
- package/library/skills/multiplayer/resource.yaml +33 -0
- package/library/skills/multiplayer-movement/SKILL.md +510 -0
- package/library/skills/multiplayer-movement/files.md +501 -0
- package/library/skills/multiplayer-movement/resource.yaml +30 -0
- package/library/skills/multiplayer-project/SKILL.md +521 -0
- package/library/skills/multiplayer-project/files.md +448 -0
- package/library/skills/multiplayer-project/resource.yaml +36 -0
- package/library/skills/multiplayer-publish/SKILL.md +229 -0
- package/library/skills/multiplayer-publish/export-errors.md +89 -0
- package/library/skills/multiplayer-publish/resource.yaml +28 -0
- package/library/skills/multiplayer-state/SKILL.md +438 -0
- package/library/skills/multiplayer-state/files.md +592 -0
- package/library/skills/multiplayer-state/resource.yaml +35 -0
- package/library/skills/multiplayer-testing/SKILL.md +236 -0
- package/library/skills/multiplayer-testing/resource.yaml +39 -0
- package/library/skills/music-track/SKILL.md +1 -1
- package/library/skills/navigate-summer/SKILL.md +1 -1
- package/library/skills/new-project/SKILL.md +1 -1
- package/library/skills/organic-model/SKILL.md +1 -1
- package/library/skills/pixel-art/SKILL.md +1 -1
- package/library/skills/play/SKILL.md +1 -1
- package/library/skills/playtesting-a-feature/SKILL.md +1 -1
- package/library/skills/procedural-animation/SKILL.md +2 -2
- package/library/skills/procedural-animation/resource.yaml +1 -1
- package/library/skills/prop-model/SKILL.md +1 -1
- package/library/skills/psx-retro-rendering/SKILL.md +1 -1
- package/library/skills/realtime-wet-surfaces/SKILL.md +2 -2
- package/library/skills/remote-deploy/SKILL.md +1 -1
- package/library/skills/retarget/SKILL.md +1 -1
- package/library/skills/running-in-the-cloud/SKILL.md +1 -1
- package/library/skills/save-load/SKILL.md +156 -0
- package/library/skills/save-load/resource.yaml +27 -0
- package/library/skills/scene-composition/SKILL.md +1 -1
- package/library/skills/scene-hierarchy-design/SKILL.md +1 -1
- package/library/skills/scene-scripting/SKILL.md +1 -1
- package/library/skills/scene-to-level/SKILL.md +1 -1
- package/library/skills/skill-create/SKILL.md +1 -1
- package/library/skills/skill-improve/SKILL.md +1 -1
- package/library/skills/skill-test/SKILL.md +1 -1
- package/library/skills/skintokens-auto-rigging/SKILL.md +1 -1
- package/library/skills/skybox-panorama/SKILL.md +1 -1
- package/library/skills/sound-effect/SKILL.md +1 -1
- package/library/skills/spatial-placement/SKILL.md +134 -3
- package/library/skills/spatial-placement/references/kit-placement-tools.md +364 -0
- package/library/skills/spatial-placement/resource.yaml +16 -2
- package/library/skills/sprite-sheet/SKILL.md +1 -1
- package/library/skills/summer-analytics/SKILL.md +147 -0
- package/library/skills/summer-analytics/resource.yaml +28 -0
- package/library/skills/summer-friends/SKILL.md +226 -0
- package/library/skills/summer-friends/resource.yaml +28 -0
- package/library/skills/summer-leaderboards/SKILL.md +231 -0
- package/library/skills/summer-leaderboards/resource.yaml +30 -0
- package/library/skills/summer-match-results/SKILL.md +286 -0
- package/library/skills/summer-match-results/resource.yaml +32 -0
- package/library/skills/summer-matchmaking/SKILL.md +301 -0
- package/library/skills/summer-matchmaking/resource.yaml +32 -0
- package/library/skills/summer-parties/SKILL.md +253 -0
- package/library/skills/summer-parties/resource.yaml +30 -0
- package/library/skills/summer-player-data/SKILL.md +322 -0
- package/library/skills/summer-player-data/resource.yaml +30 -0
- package/library/skills/summer-store/SKILL.md +271 -0
- package/library/skills/summer-store/resource.yaml +29 -0
- package/library/skills/summer-world-chat/SKILL.md +195 -0
- package/library/skills/summer-world-chat/resource.yaml +30 -0
- package/library/skills/summer-world-saves/SKILL.md +284 -0
- package/library/skills/summer-world-saves/resource.yaml +29 -0
- package/library/skills/text-to-motion/SKILL.md +99 -0
- package/library/skills/text-to-motion/prompts-and-controls.md +34 -0
- package/library/skills/text-to-motion/resource.yaml +41 -0
- package/library/skills/text-to-motion/rigging-for-text-motion.md +54 -0
- package/library/skills/tileable-texture/SKILL.md +1 -1
- package/library/skills/trailer-shot/SKILL.md +1 -1
- package/library/skills/tune-performance/SKILL.md +1 -1
- package/library/skills/ui-basics/SKILL.md +10 -1
- package/library/skills/ui-graphics/SKILL.md +1 -1
- package/library/skills/use-widget-asset/SKILL.md +1 -1
- package/library/skills/using-summer/SKILL.md +2 -2
- package/library/skills/using-summer/resource.yaml +2 -2
- package/library/skills/vehicle-model/SKILL.md +1 -1
- package/library/skills/verification-before-completion/SKILL.md +1 -1
- package/library/skills/verifying-scenes/SKILL.md +76 -2
- package/library/skills/verifying-scenes/resource.yaml +13 -2
- package/library/skills/vfx-dissolve/SKILL.md +1 -1
- package/library/skills/vfx-fire/SKILL.md +1 -1
- package/library/skills/vfx-hit-spark/SKILL.md +1 -1
- package/library/skills/vfx-lightning/SKILL.md +1 -1
- package/library/skills/vfx-magic-glow/SKILL.md +1 -1
- package/library/skills/vfx-muzzle-flash/SKILL.md +1 -1
- package/library/skills/vfx-smoke/SKILL.md +1 -1
- package/library/skills/vfx-water-ripple/SKILL.md +1 -1
- package/library/skills/voice-line/SKILL.md +1 -1
- package/library/skills/web-and-touch-input/SKILL.md +38 -0
- package/library/skills/web-and-touch-input/resource.yaml +28 -0
- package/library/skills/web-compatibility-look/SKILL.md +62 -0
- package/library/skills/web-compatibility-look/resource.yaml +30 -0
- package/library/skills/world-building-3d/SKILL.md +8 -1
- package/library/skills/world-building-3d/references/spatial-tools.md +1 -1
- package/library/skills/world-building-3d/resource.yaml +2 -1
- package/library/skills/writing-plans/SKILL.md +1 -1
- package/library/skills/writing-skills/SKILL.md +1 -1
- package/library/templates/3d-lan-multiplayer-starter/resource.yaml +2 -2
- package/library/tools/attach-to-surface/resource.yaml +142 -0
- package/library/tools/batch/resource.yaml +9 -3
- package/library/tools/connect-ports/resource.yaml +120 -0
- package/library/tools/connect-signal/resource.yaml +3 -2
- package/library/tools/debug-views/resource.yaml +94 -0
- package/library/tools/frame-nodes/resource.yaml +104 -0
- package/library/tools/frame-shot/resource.yaml +134 -0
- package/library/tools/generate-motion/resource.yaml +44 -9
- package/library/tools/get-board/resource.yaml +50 -0
- package/library/tools/get-project-context/resource.yaml +13 -2
- package/library/tools/grep/resource.yaml +77 -0
- package/library/tools/inspect-asset/resource.yaml +71 -0
- package/library/tools/inspect-node/resource.yaml +9 -2
- package/library/tools/inspect-resource/resource.yaml +16 -5
- package/library/tools/instantiate-scene/resource.yaml +27 -2
- package/library/tools/measure/resource.yaml +96 -0
- package/library/tools/place-adjacent/resource.yaml +113 -0
- package/library/tools/play/resource.yaml +15 -2
- package/library/tools/raycast/resource.yaml +101 -0
- package/library/tools/read-file/resource.yaml +36 -2
- package/library/tools/read-library/resource.yaml +2 -2
- package/library/tools/repeat-along/resource.yaml +129 -0
- package/library/tools/replace-node/resource.yaml +11 -5
- package/library/tools/scene-audit/resource.yaml +144 -0
- package/library/tools/screenshot/resource.yaml +13 -2
- package/library/tools/search-assets/resource.yaml +18 -0
- package/library/tools/shot-sheet/resource.yaml +110 -0
- package/library/tools/snap-to-surface/resource.yaml +4 -1
- package/library/tools/world-snapshot/resource.yaml +24 -3
- package/library/tools/zoom/resource.yaml +105 -0
- package/package.json +3 -3
- package/registry/generated/aliases.json +17 -3
- package/registry/generated/counts.json +3 -3
- package/registry/generated/gemini-extension.json +26 -4
- package/registry/generated/index.json +2154 -469
- package/registry/generated/marketplace.claude.json +2 -2
- package/registry/generated/plugin.claude.json +27 -5
- package/registry/generated/plugin.codex.json +28 -6
- package/registry/generated/plugin.cursor.json +27 -5
- package/registry/generated/plugin.factory.json +27 -5
- package/registry/generated/skills-index.md +264 -0
- package/registry/generated/skills-registry.json +901 -206
- package/registry/generated/templates-registry.json +2 -2
- package/library/skills/host-authoritative-state/SKILL.md +0 -332
- package/library/skills/host-authoritative-state/resource.yaml +0 -28
- package/library/skills/peer-to-peer-multiplayer/SKILL.md +0 -373
- package/library/skills/peer-to-peer-multiplayer/resource.yaml +0 -28
- package/library/skills/setup-multiplayer/SKILL.md +0 -336
- package/library/skills/setup-multiplayer/resource.yaml +0 -28
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { withEngine, ToolInputError } from "./with-engine.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { executeSceneMutation } from "../../core/capabilities/engine-ops.js";
|
|
4
|
+
import { instantiateScene, runBatch } from "../../core/capabilities/placement-batch.js";
|
|
5
|
+
import { renderPlacementResult } from "./placement-tools.js";
|
|
6
|
+
import { inspectNodeFields, inspectNodeInputShape } from "../../core/capabilities/inspect-node.js";
|
|
7
|
+
import { inspectResource, inspectResourceInputShape } from "../../core/capabilities/inspect-resource.js";
|
|
8
|
+
import { rawSceneReplaceRefusal, replaceNodeInputShape, replaceNodePersisted, } from "../../core/capabilities/replace-node.js";
|
|
9
|
+
import { connectSignalInputShape, connectSignalPersisted } from "../../core/capabilities/connect-signal.js";
|
|
5
10
|
import { FALLBACK_SINGLE_ONLY_OPS, resolveSingleOnlyOps, } from "../../core/capability-skew.js";
|
|
6
11
|
// Re-exported for tests and for callers that reason about dispatch classes.
|
|
7
12
|
// executeSceneMutation is the ONE copy in core/capabilities/engine-ops.ts,
|
|
@@ -28,6 +33,8 @@ function requireSuccessfulOps(result, context) {
|
|
|
28
33
|
function minimalSceneText(rootName, rootType) {
|
|
29
34
|
return `[gd_scene format=3]\n\n[node name="${rootName}" type="${rootType}"]\n`;
|
|
30
35
|
}
|
|
36
|
+
const finiteNumber = z.number().finite();
|
|
37
|
+
const finiteVector3 = z.tuple([finiteNumber, finiteNumber, finiteNumber]);
|
|
31
38
|
// Node names reject . : @ / " %; the type must be a plain class name.
|
|
32
39
|
// Both are interpolated into quoted .tscn fields, so validate before composing.
|
|
33
40
|
const VALID_ROOT_NAME = /^[A-Za-z_][A-Za-z0-9_\- ]*$/;
|
|
@@ -194,7 +201,9 @@ Do not guess paths. Prefer:
|
|
|
194
201
|
|
|
195
202
|
The scene must already exist in the project. Use summer_import_from_url first if importing from external sources.
|
|
196
203
|
|
|
197
|
-
PASS target_size FOR IMPORTED MODELS. Downloaded/generated .glb assets arrive at arbitrary scale (a "chair" can be 40 units tall). target_size uniformly scales the instanced subtree so its largest world-AABB dimension equals that many units — commit to real-world size: chair 1.0, door 2.0, car 4.5, person 1.7, tree 6-10. The result then reports dimensions + scale_applied; verify placement afterwards (summer_world_snapshot AABBs, summer_screenshot). Older engine builds ignore target_size — when the result lacks scale_applied, this tool appends a note and you must scale the node yourself (summer_set_prop scale) and re-check
|
|
204
|
+
PASS target_size FOR IMPORTED MODELS. Downloaded/generated .glb assets arrive at arbitrary scale (a "chair" can be 40 units tall). target_size uniformly scales the instanced subtree so its largest world-AABB dimension equals that many units — commit to real-world size: chair 1.0, door 2.0, car 4.5, person 1.7, tree 6-10. The result then reports dimensions + scale_applied; verify placement afterwards (summer_world_snapshot AABBs, summer_screenshot). Older engine builds ignore target_size — when the result lacks scale_applied, this tool appends a note and you must scale the node yourself (summer_set_prop scale) and re-check.
|
|
205
|
+
|
|
206
|
+
PLACE IT IN THE SAME CALL: position, rotation_degrees and scale ([x, y, z], parent-local, like summer_set_prop), or transform (a "Transform3D(...)" string). The instance is created, then those properties are set on the exact node path the receipt reports (a name collision rename is followed), then the scene is saved: one call per piece, no window at the origin. The result adds placement {nodePath, applied, fields}. Do not combine transform with the others, or scale/transform with target_size. Measure a kit piece first with summer_inspect_asset.`, {
|
|
198
207
|
scenePath: z.string().describe("Target scene to receive the instance, e.g. 'res://main.tscn'"),
|
|
199
208
|
parent: z.string().describe("Parent node path, e.g. './World'"),
|
|
200
209
|
scene: z.string().describe("Scene/model path, e.g. 'res://player.tscn' or 'res://models/tree.glb'"),
|
|
@@ -204,30 +213,18 @@ PASS target_size FOR IMPORTED MODELS. Downloaded/generated .glb assets arrive at
|
|
|
204
213
|
.positive()
|
|
205
214
|
.optional()
|
|
206
215
|
.describe("Normalize the instance's physical size: uniformly scale it so its largest world-AABB dimension equals this many units (chair 1.0, car 4.5, person 1.7). Strongly recommended for imported .glb/.gltf models."),
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const instanced = envelope.results?.find((entry) => entry.op === "InstantiateScene" && entry.ok === true);
|
|
220
|
-
if (instanced && !("scale_applied" in instanced)) {
|
|
221
|
-
return {
|
|
222
|
-
...envelope,
|
|
223
|
-
target_size_note: `This Summer Engine build IGNORED target_size (no scale_applied in the receipt) — the instance is at the asset's raw scale, NOT normalized to ${target_size}. ` +
|
|
224
|
-
"Scale it yourself (summer_set_prop scale, or ctx code in summer_run_script), verify with summer_world_snapshot/summer_screenshot, or update Summer Engine.",
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
return result;
|
|
229
|
-
}));
|
|
230
|
-
server.tool("summer_connect_signal", `Connect a signal between two nodes. Signals are Godot's event system — they notify when something happens.
|
|
216
|
+
position: finiteVector3.optional().describe("Parent-local position [x, y, z] set right after the instance is created."),
|
|
217
|
+
rotation_degrees: finiteVector3.optional().describe("Parent-local rotation in degrees [x, y, z] (Godot rotation_degrees)."),
|
|
218
|
+
scale: finiteVector3.optional().describe("Local scale [x, y, z]. Not with target_size."),
|
|
219
|
+
transform: z
|
|
220
|
+
.string()
|
|
221
|
+
.optional()
|
|
222
|
+
.describe('Full local transform as "Transform3D(xx, xy, xz, yx, yy, yz, zx, zy, zz, ox, oy, oz)" (Godot row-major basis, then origin). Not with position/rotation_degrees/scale/target_size.'),
|
|
223
|
+
}, async (args) =>
|
|
224
|
+
// E2E: an older engine applies the op but silently drops target_size —
|
|
225
|
+
// instantiateScene appends target_size_note when scale_applied is absent.
|
|
226
|
+
withEngine(async (client) => instantiateScene(client, args)));
|
|
227
|
+
server.tool("summer_connect_signal", `Connect a signal between two nodes so the connection is SAVED in the scene. Signals are Godot's event system — they notify when something happens.
|
|
231
228
|
|
|
232
229
|
Common signals:
|
|
233
230
|
- "body_entered" / "body_exited" — Area3D/Area2D detects physics bodies
|
|
@@ -236,15 +233,9 @@ Common signals:
|
|
|
236
233
|
- "area_entered" — Area detects another area
|
|
237
234
|
- "input_event" — CollisionObject received input
|
|
238
235
|
|
|
239
|
-
The receiver
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
signal: z.string().describe("Signal name, e.g. 'body_entered'"),
|
|
243
|
-
receiver: z.string().describe("Node with the handler script, e.g. './Player'"),
|
|
244
|
-
method: z.string().describe("Method name in the receiver's script, e.g. '_on_hit_area_body_entered'"),
|
|
245
|
-
}, async ({ scenePath, emitter, signal, receiver, method }) => withEngine(async (client) => executeSceneMutation(client, scenePath, [
|
|
246
|
-
{ op: "ConnectSignal", emitter, signal, receiver, method },
|
|
247
|
-
])));
|
|
236
|
+
The receiver should have the method (a script method, or a built-in such as queue_free); a missing one is saved anyway and reported in warnings. scenePath must be a .tscn.
|
|
237
|
+
|
|
238
|
+
PERSISTENCE IS VERIFIED: the engine's ConnectSignal op connects without CONNECT_PERSIST, so its connection never reached the file. This tool connects through a RunSceneScript probe with CONNECT_PERSIST (replacing a non-persistent connection of the same pair), saves, reads the saved .tscn back and returns persisted:true / verified:true only when the [connection] line is there; otherwise an error with failure_reason not_persisted. The probe runs in the active tab: a scene in a background tab is brought forward and the user's tab restored (tab_switched). One Ctrl+Z reverts it.`, connectSignalInputShape, async (args) => withEngine(async (client) => connectSignalPersisted(client, args)));
|
|
248
239
|
server.tool("summer_select_node", "Select a node in the editor's scene tree and show it in the inspector panel. Useful for focusing the editor on a specific node.", {
|
|
249
240
|
nodePath: z.string().describe("Node path to select"),
|
|
250
241
|
scenePath: z.string().optional().describe("Open this scene first, then select the node"),
|
|
@@ -254,35 +245,29 @@ The receiver node must have a script with the specified method.`, {
|
|
|
254
245
|
op.scenePath = scenePath;
|
|
255
246
|
return client.executeOps([op]);
|
|
256
247
|
}));
|
|
257
|
-
server.tool("summer_replace_node",
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (type)
|
|
265
|
-
op.type = type;
|
|
266
|
-
if (scene)
|
|
267
|
-
op.scene = scene;
|
|
268
|
-
return executeSceneMutation(client, scenePath, [op]);
|
|
269
|
-
}));
|
|
248
|
+
server.tool("summer_replace_node", `Replace a node with a different scene/model or node type, keeping its parent, sibling index, name, transform and property overrides, and the children the scene added under it. Use it to swap a kit piece for another (a wall host for a door host), a placeholder for a prefab, or a StaticBody3D for a RigidBody3D.
|
|
249
|
+
|
|
250
|
+
Give exactly one of scene or type. The scenePath must be a .tscn.
|
|
251
|
+
|
|
252
|
+
PERSISTENCE IS VERIFIED: the tool saves, reads the saved .tscn back and checks that the node at path now instances the new scene (or has the new type), under the same parent, with every child present. persisted:true is proven from the file; a mismatch is an error with failure_reason not_persisted — never report that as done.
|
|
253
|
+
|
|
254
|
+
How: a scene swap runs as InstantiateScene (temporary name) -> SetProp each property override -> ReparentNode the children -> MoveNode to the old index -> RemoveNode the old node -> rename -> SaveScene, because the engine's own ReplaceNode keeps the OLD scene reference in the saved file. A type change of a plain node uses the engine's ReplaceNode. State that cannot travel (groups, signal connections, scene-local sub_resource values, overrides of nodes inside the old scene) is listed in not_carried_over. Undo takes one Ctrl+Z per step.`, replaceNodeInputShape, async (args) => withEngine(async (client) => replaceNodePersisted(client, args)));
|
|
270
255
|
server.tool("summer_inspect_node", `Get all editable properties of a node with their current values, types, and resource info.
|
|
271
256
|
|
|
272
257
|
Call this before modifying a node to understand its current state. Returns every property the Godot inspector would show. Each prop carries the engine's raw Variant.Type integer as "type" plus its name as "type_name" (e.g. type 5 = TYPE_VECTOR2, 20 = TYPE_COLOR, 24 = TYPE_OBJECT); resource-valued props also carry resource_type / resource_path.
|
|
273
258
|
|
|
274
259
|
Reads the currently OPEN scene — "path" is relative to its root (there is no scenePath argument; open the scene first if needed).
|
|
275
260
|
|
|
276
|
-
Example: inspect a light to see its energy, color, shadow settings before changing them
|
|
277
|
-
|
|
278
|
-
|
|
261
|
+
Example: inspect a light to see its energy, color, shadow settings before changing them.
|
|
262
|
+
|
|
263
|
+
The full read is about 5 KB. To read only what you need, pass fields: property names or globs ('position', 'surface_material_override/*'), plus derived fields: transform (local position / rotation_degrees / scale, and a Transform3D literal for 3D nodes), global_transform (world origin + Transform3D, composed from the world snapshot), scene_file_path (the scene this node instances), aabb (world bounds), warnings. Example: fields:['transform','global_transform','scene_file_path'] is a few hundred bytes. missing_fields and unavailable say what could not be read.`, inspectNodeInputShape, async (args) =>
|
|
279
264
|
// E2E 2026-09-03 F-14: the engine returns Variant.Type as a bare int.
|
|
280
|
-
withEngine(async (client) =>
|
|
281
|
-
server.tool("summer_inspect_resource", `
|
|
265
|
+
withEngine(async (client) => inspectNodeFields(client, args)));
|
|
266
|
+
server.tool("summer_inspect_resource", `Read a resource: a material, mesh, shape, texture, environment, or a scene/model file.
|
|
282
267
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
268
|
+
Two forms, pass exactly one:
|
|
269
|
+
- path: a resource FILE ('res://materials/ground.tres', a mesh 'res://kit/meshes/wall_01.res', 'res://models/player.glb'), loaded read-only in the editor. A Mesh returns its AABB, surface_count and per surface the primitive, vertex and index counts, attributes, triangles and material (class, path or embedded, albedo for standard materials), plus the unique materials and blend shapes. A scene or model (.tscn/.glb/.gltf) returns its node count, the first 40 nodes with type, instanced scene and mesh, and its meshes; summer_inspect_asset measures it (AABB, planes, ports). Every other resource (and a mesh) returns its editor properties that differ from the class default (props), with props_at_default counting the rest.
|
|
270
|
+
- nodePath + property: a resource a node of the ACTIVE scene tab holds, e.g. nodePath 'Floor', property 'mesh'. For example, summer_inspect_node tells you a MeshInstance3D has a "StandardMaterial3D" material_override — this form returns its albedo_color, metallic, roughness, etc.`, inspectResourceInputShape, async (args) => withEngine(async (client) => inspectResource(client, args)));
|
|
286
271
|
server.tool("summer_batch", `Execute multiple operations in a single call. Each op is forwarded to the engine VERBATIM, so this is also how you reach engine ops that have no dedicated tool.
|
|
287
272
|
|
|
288
273
|
UNDO: when nothing in the list forces a split (see the single-op contract below), the whole batch is ONE undo step — the user undoes everything with a single Ctrl+Z. When single-only ops are present the list is split into sequential requests and EACH chunk is its own undo step (one Ctrl+Z per chunk; the receipt shows the chunks). Use this when building something that involves multiple nodes and properties — e.g., creating a player character with collision, camera, and properties.
|
|
@@ -297,6 +282,11 @@ RAW RUNTIME OPS (interactive verification — structured failure_reason passes t
|
|
|
297
282
|
- RunVerification — spawn a hidden, disposable game instance that runs a GDScript probe and dies (never touches the editor): {"op": "RunVerification", "probe_source": "...", "max_seconds": 20}. Returns {ok, results, frames, out_dir}. Probe API: report(name, value) / save_frame(name) / press(action) / key(keycode) / finish(). save_frame REQUIRES a name argument — save_frame() with no args is a script error. Mount scenes deferred: get_tree().root.add_child.call_deferred(instance); await get_tree().process_frame; await settle() — a direct add_child in _ready can hit the parent-busy guard and capture a black frame.
|
|
298
283
|
- SimulateInput — inject an action/key/mouse/axis into the RUNNING game (summer_play first): {"op": "SimulateInput", "type": "action", "action": "jump", "pressed": true}. It MUST be sent alone (single-op batch). failure_reason "not_running" = start the game first; "unsupported" = the running game build predates the handler — fall back to RunVerification or ask the user.
|
|
299
284
|
|
|
285
|
+
A raw ReplaceNode with scene is refused (it saves the old scene reference); use summer_replace_node.
|
|
286
|
+
A raw ConnectSignal is refused (the engine connects without CONNECT_PERSIST, so the file never holds it); use summer_connect_signal.
|
|
287
|
+
|
|
288
|
+
REPARENTNODE KEEPS ITS SUBTREE AND IS VERIFIED: the engine's ReparentNode re-owns only the moved node, so its children and grandchildren were dropped from the saved file. A batch with ReparentNode saves first, reads the saved .tscn, sends each ReparentNode in its own request with an in-place ReparentNode (same parent, same index) per scene-owned descendant to give it back to the scene, then reads the saved file again: persisted:true / verified:true only when every moved node and descendant is at its new path; otherwise an error with failure_reason not_persisted. A move onto a parent that already has a child of that name is refused (failure_reason name_collision). The scenePath must be a .tscn, and Undo cannot share the batch.
|
|
289
|
+
|
|
300
290
|
Do not mix OpenScene with scene mutations in one batch. OpenScene is a UI action;
|
|
301
291
|
send it separately. scenePath selects every mutation target. The tool appends one
|
|
302
292
|
final SaveScene when the batch mutates a scene; if supplied explicitly, SaveScene
|
|
@@ -306,10 +296,21 @@ SaveScene, InstantiateScene, ReplaceNode, SimulateInput, the runtime reads
|
|
|
306
296
|
ops to travel as their own request, so this tool automatically splits your op
|
|
307
297
|
list into sequential requests around them — each split chunk is its own undo
|
|
308
298
|
step (NOT one step for the whole batch), and if a later chunk fails the receipt
|
|
309
|
-
reports exactly which earlier ops already applied
|
|
299
|
+
reports exactly which earlier ops already applied.
|
|
300
|
+
|
|
301
|
+
PLACED INSTANCES: an InstantiateScene op may also carry position, rotation_degrees, scale ([x, y, z] or "Vector3(...)") or transform ("Transform3D(...)"); the tool sets them on the created node. One op per piece. Other ops are forwarded verbatim. Cost: each InstantiateScene is its own engine request (the engine requires it); the transforms of a run of InstantiateScene ops are then sent together (up to 200 per request) before the next other op, so N placed pieces plus the save cost about N + 2 requests and N + 2 undo steps. Every later op (a SetProp, SnapToSurface, the save) sees the pieces already placed; if an InstantiateScene fails, the pieces created before it still get their transforms.
|
|
302
|
+
|
|
303
|
+
RECEIPTS: receipt "summary" returns only counts, failures [{index, op, error}] (index = position in your ops list), created node paths and renames, under 5 KB with any cut declared. Use it for any batch over a few ops; the full receipt of a large batch overflows the tool-output limit.
|
|
304
|
+
|
|
305
|
+
scenePersistence.saved means the SaveScene ran; it does not prove what the file
|
|
306
|
+
holds. verified:true is set only where the tool read the saved file back.`, {
|
|
310
307
|
scenePath: z.string().optional().describe("Required when ops contains scene mutations; exact res:// target scene path"),
|
|
311
308
|
ops: z.array(z.record(z.unknown())).describe("Array of operation objects, each with 'op' plus its parameters"),
|
|
312
|
-
|
|
309
|
+
receipt: z
|
|
310
|
+
.enum(["full", "summary"])
|
|
311
|
+
.optional()
|
|
312
|
+
.describe("full (default): every engine receipt. summary: counts, failures with op index, created node paths only (under 5 KB)."),
|
|
313
|
+
}, async ({ scenePath, ops, receipt }) => withEngine(async (client) => {
|
|
313
314
|
const rawFileMutation = ops.find((op) => {
|
|
314
315
|
const kind = String(op.op ?? "");
|
|
315
316
|
return kind === "WriteFile" || kind === "ReplaceText";
|
|
@@ -318,28 +319,15 @@ reports exactly which earlier ops already applied.`, {
|
|
|
318
319
|
throw new ToolInputError(`summer_batch does not accept raw ${String(rawFileMutation.op)} operations. ` +
|
|
319
320
|
"Use summer_write_file or summer_replace_text so project identity, content guards, and same-file ordering are enforced.");
|
|
320
321
|
}
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
//
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
const needsScenePath = containsMutation ||
|
|
333
|
-
ops.some((op) => sceneQueries.has(String(op.op ?? "")));
|
|
334
|
-
if (needsScenePath && !scenePath) {
|
|
335
|
-
throw new ToolInputError("summer_batch requires scenePath when ops targets a scene");
|
|
336
|
-
}
|
|
337
|
-
const options = { groupUndo: true, ...(scenePath ? { scenePath } : {}) };
|
|
338
|
-
if (containsMutation) {
|
|
339
|
-
return executeSceneMutation(client, scenePath, ops, options);
|
|
340
|
-
}
|
|
341
|
-
return executeOpsChunked((chunk) => needsScenePath
|
|
342
|
-
? client.executeIdentityBoundOps(chunk, options)
|
|
343
|
-
: client.executeOps(chunk, options), ops, resolveSingleOnlyOps(client));
|
|
344
|
-
}));
|
|
322
|
+
const replaceRefusal = rawSceneReplaceRefusal(ops);
|
|
323
|
+
if (replaceRefusal)
|
|
324
|
+
throw new ToolInputError(replaceRefusal);
|
|
325
|
+
// Scene mutations get one final SaveScene; read-only spatial queries
|
|
326
|
+
// (TestPlacement3D, NavigationProbe3D, Starcast3D) are identity-bound
|
|
327
|
+
// to the scene but never saved (core/capabilities/placement-batch.ts).
|
|
328
|
+
const result = await runBatch(client, { scenePath, ops: ops, receipt });
|
|
329
|
+
return receipt === "summary" ? { summaryReceipt: result } : result;
|
|
330
|
+
}, receipt === "summary"
|
|
331
|
+
? { onResult: (wrapped) => renderPlacementResult(wrapped.summaryReceipt) }
|
|
332
|
+
: undefined));
|
|
345
333
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type SeeingResult } from "../../core/capabilities/seeing/seeing.js";
|
|
3
|
+
/**
|
|
4
|
+
* Seeing tools: look at a 3D environment the way a player and an artist do.
|
|
5
|
+
* Every image comes back INLINE as an MCP image block (one grid image for a
|
|
6
|
+
* sheet, never N images), with a compact text caption (labels, poses, scores,
|
|
7
|
+
* mark -> path). Renders use the scene's REAL WorldEnvironment and lights.
|
|
8
|
+
* Implementation and the in-engine kernel: src/core/capabilities/seeing/.
|
|
9
|
+
*/
|
|
10
|
+
type ToolResultContent = {
|
|
11
|
+
type: "text";
|
|
12
|
+
text: string;
|
|
13
|
+
} | {
|
|
14
|
+
type: "image";
|
|
15
|
+
data: string;
|
|
16
|
+
mimeType: string;
|
|
17
|
+
};
|
|
18
|
+
type ToolResult = {
|
|
19
|
+
content: ToolResultContent[];
|
|
20
|
+
isError?: boolean;
|
|
21
|
+
};
|
|
22
|
+
export declare function seeingContent(result: SeeingResult): ToolResult;
|
|
23
|
+
export declare function registerSeeingTools(server: McpServer): void;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { withEngine } from "./with-engine.js";
|
|
2
|
+
import { debugViews, frameNodes, frameShot, shotSheet, zoom, } from "../../core/capabilities/seeing/seeing.js";
|
|
3
|
+
import { debugViewsShape, frameNodesShape, frameShotShape, shotSheetShape, zoomShape, } from "../../core/capabilities/seeing/args.js";
|
|
4
|
+
function wrap(result) {
|
|
5
|
+
return result.ok ? { seeing: result } : { seeing: result, failure_reason: result.failure_reason };
|
|
6
|
+
}
|
|
7
|
+
export function seeingContent(result) {
|
|
8
|
+
if (!result.ok) {
|
|
9
|
+
return {
|
|
10
|
+
isError: true,
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: JSON.stringify({
|
|
15
|
+
error: result.error,
|
|
16
|
+
failure_reason: result.failure_reason,
|
|
17
|
+
...(result.hint ? { hint: result.hint } : {}),
|
|
18
|
+
...(result.detail ? { detail: result.detail } : {}),
|
|
19
|
+
}, null, 2),
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const content = [];
|
|
25
|
+
if (result.image)
|
|
26
|
+
content.push({ type: "image", data: result.image.base64, mimeType: result.image.mime || "image/jpeg" });
|
|
27
|
+
content.push({ type: "text", text: result.caption });
|
|
28
|
+
return { content };
|
|
29
|
+
}
|
|
30
|
+
function run(op) {
|
|
31
|
+
return async (args) => withEngine(async (client) => wrap(await op(client, args)), {
|
|
32
|
+
onResult: (wrapped) => seeingContent(wrapped.seeing),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const COMMON = `Read-only: the scene file, the open tab and the undo history are never touched (the render is an offscreen copy of the SAVED scene). The image arrives inline; the caption carries poses, labels and numbers. Failures are structured (failure_reason), never a silent fallback.`;
|
|
36
|
+
export function registerSeeingTools(server) {
|
|
37
|
+
server.tool("summer_frame_nodes", `Frame one or more nodes with a camera fitted to their WORLD bounds and render it with the scene's REAL WorldEnvironment, lights, fog and tonemap (unlike summer_screenshot nodePath, which only works with the flat preview environment).
|
|
38
|
+
|
|
39
|
+
Pick the side with direction (front/back/left/right/top/iso) or an explicit from vector; fill sets how much of the frame they span. bookmark_name also saves the fitted pose so every later render (summer_shot_sheet, summer_debug_views, summer_screenshot framing:"bookmark") lines up with it. marks:true adds numbered labels mapped to node paths.
|
|
40
|
+
|
|
41
|
+
An explicit from is checked in-engine before you trust the image: if walls block the nodes, or the camera stands behind or inside a one-sided surface (its back is not drawn, so the image would look THROUGH the wall), the caption opens with a WARNING and the nearest valid from (+ fov) to pass back. With marks:true every labelled node gets an occlusion test (centre + 4 bounds points); hidden ones are noted "(hidden behind <path>)".
|
|
42
|
+
|
|
43
|
+
Returns the image + caption: the pose as Vector3 literals, the bounds, the environment used, the view check, and the mark list. ${COMMON}`, frameNodesShape, run(frameNodes));
|
|
44
|
+
server.tool("summer_shot_sheet", `Render several bookmarks and/or explicit poses into ONE labelled grid image in a single call: same tile size, same view, real lighting. Use it after every change to see all hero views at once instead of N screenshots.
|
|
45
|
+
|
|
46
|
+
compare_previous:true turns each bookmark into a row of [previous | now | difference map] and reports the share of pixels that changed and where. Each bookmark keeps exactly one previous render (its compare baseline) at res://.summer/shots/<bookmark>.jpg (JPEG, <= 1024 px; the folder is capped at 20 MB, oldest first). Only compare_previous:true or update_previous:true replaces it; a plain sheet creates a missing baseline and never overwrites one. view renders every tile as lighting/unshaded/normals/overdraw/wireframe instead of beauty.
|
|
47
|
+
|
|
48
|
+
Returns the grid + caption (tile number -> label and pose, difference stats). ${COMMON}`, shotSheetShape, run(shotSheet));
|
|
49
|
+
server.tool("summer_debug_views", `One pose rendered as a grid of debug views next to the beauty pass: beauty, lighting (light only: direction, pools, dead-dark areas), unshaded (albedo: texture quality, value grouping), normals (world-space, x red y green z blue: seams, flipped or faceted normals), overdraw (stacked transparent layers), wireframe (triangle density, floating or duplicated pieces).
|
|
50
|
+
|
|
51
|
+
Use it on the weakest shot of a sheet to see WHY it reads badly. lighting/unshaded/overdraw/wireframe are the engine's Viewport debug draw modes; normals uses an unshaded override material on a private copy (normal maps and alpha cut-outs are not applied) and works on every renderer. The caption names the method per view.
|
|
52
|
+
|
|
53
|
+
Returns the grid + caption. ${COMMON}`, debugViewsShape, run(debugViews));
|
|
54
|
+
server.tool("summer_zoom", `High-resolution close look at part of a frame: region [x, y, w, h] (fractions of the frame) or mark N from a marks render of the same pose. The camera renders the EXACT sub-frustum of that region at full output resolution, so you see real texture detail, seams, gaps and floating pieces, not upscaled pixels. A region is honoured exactly (no pad by default, never widened to an aspect ratio: the image takes the region's own aspect, with dark bars only for extreme shapes); a mark gets pad 0.15.
|
|
55
|
+
|
|
56
|
+
Use after a sheet or debug view shows something suspicious. view picks beauty or a debug view. Returns the zoomed image + caption (the real zoom factor, the rendered region, widened_because when it is larger than asked, mark -> node path and a warning when that node is hidden). ${COMMON}`, zoomShape, run(zoom));
|
|
57
|
+
server.tool("summer_frame_shot", `Smart framing: find good camera poses for a shot type automatically, measured in-engine against the real geometry.
|
|
58
|
+
|
|
59
|
+
shot: establishing (wide), eye_level (from a spawn node at player eye height), low_angle (hero, near the ground looking up: the camera moves closer and widens its FOV instead of sinking into the ground), detail (close-up), corridor (down a lane or corridor found inside the subject by a free-space scan, preferring the view in from its open end, walls on both sides).
|
|
60
|
+
|
|
61
|
+
How: candidate poses on a ring/hemisphere (or along the corridor line) at the distance where the subject fills the shot's target share of the frame; each is checked with a THICK sphere sweep to points on the subject (thin rays miss corners), a near-lens sphere (camera inside or touching geometry is nudged forward or rejected), a ray grid through the frame, and a small beauty render per pose. Walls/terrain blocking the subject reject a pose, and so does a camera behind or inside a one-sided surface (a sight line or a quarter of the frame meeting a wall from behind: its back is not drawn, so the image would look through it). Foliage, fences, props and pipes in front are allowed (wanted, up to a limit) as framing; transparent materials (alpha, scissor, glass, foliage cards) are see-through cover at partial weight. Scored on rule-of-thirds placement, frame fill, level horizon, sky share, depth behind the subject (no flat wall right behind it), empty or featureless areas, near-wall clearance, near/far value contrast, foreground framing, surfaces seen from behind, the key light's direction (side or front-side beats a flat front-lit face) and the world edge (sky or void below the horizon).
|
|
62
|
+
|
|
63
|
+
Returns the top 3 with score breakdowns and poses — three different views (one per side of the subject while the score allows, at least 25 degrees apart) — saves the best as a bookmark (default <shot>_<subject>), and renders the 3 as one sheet with real lighting (render:"best" or "none" to save context). ${COMMON} Saving the bookmark writes res://.summer/camera_bookmarks.json.`, frameShotShape, run(frameShot));
|
|
64
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { withEngine, missingEngineOpResult, ToolInputError, withOldEngineHint } from "./with-engine.js";
|
|
3
3
|
import { executeSceneMutation } from "./scene-tools.js";
|
|
4
|
+
import { SNAP_LIFT_MARGIN, SNAP_MAX_AUTO_LIFT, snapToSurface } from "../../core/capabilities/surface-snap.js";
|
|
4
5
|
// engine_lacks_op fallbacks: ONE copy for every face (E2E 2026-09-03 F-16).
|
|
5
6
|
import { ALIGN_DISTRIBUTE_FALLBACK, NAVIGATION_PROBE_FALLBACK, SNAP_TO_SURFACE_FALLBACK, STARCAST_FALLBACK, TEST_PLACEMENT_FALLBACK, } from "../../core/capabilities/engine-fallbacks.js";
|
|
6
7
|
/** Hard budget for one tool's model-visible result. These ops are designed to
|
|
@@ -244,9 +245,14 @@ Use the default downward direction to seat props on floors, ramps, tables, or sh
|
|
|
244
245
|
|
|
245
246
|
EVIDENCE BOUNDARY:
|
|
246
247
|
- physics means Godot swept the subject's enabled collider shapes against body colliders and refined the first-contact bracket.
|
|
247
|
-
- visual_aabb is
|
|
248
|
+
- visual_aabb is the engine's broad-phase fallback for mesh-only geometry (no collider on the subject or the support): AABBs swept against AABBs. It does not prove triangle contact, and alignUp is not applied from that approximate normal.
|
|
249
|
+
- visual_mesh: whenever the engine answers with visual_aabb (overlap_recovery_exceeded, gap_exceeds_hit_travel, surface_not_found, or a seat), a read-only probe measures the move from visible triangles instead: the subject's vertices cast along the direction onto the triangles of the meshes below (a surface cutting through the subject counts as sunk), plus the support's vertices under it cast back. One SetProp places the subject, a second read verifies the gap (the move is undone if it disagrees by more than 5 mm), and the scene is saved. The receipt says evidence visual_mesh, the engine's own answer under engine, verify {final_gap, ok}, and evidenceDetails (samples, triangles, whether the subject and the support have colliders). Meshes whose shader writes POSITION (screen-space quads) are not surfaces. When the triangles find no support either, the engine's failure is returned with mesh_fallback saying why.
|
|
248
250
|
- initiallyOverlapping and backoffDistance expose bounded pre-sweep recovery. The tool fails instead of teleporting when the subject cannot be cleared within maxDistance.
|
|
249
251
|
|
|
252
|
+
SUNK PROPS: when the subject starts inside its support (gap_exceeds_hit_travel with a start overlap), the tool lifts it against the cast direction by the overlap depth plus ${SNAP_LIFT_MARGIN} m (at most ${SNAP_MAX_AUTO_LIFT} m and the subject's own extent), snaps again from there, and keeps that only if it settles on a node it was sunk into; the receipt then carries recovery (lifted_by, original_local_position) and 'before' is the lifted pose. Otherwise the original position is restored.
|
|
253
|
+
|
|
254
|
+
FAILURES EXPLAIN THEMSELVES: after gap_exceeds_hit_travel or overlap_recovery_exceeded a read-only starcast at the current pose adds start_overlap, blocking (the nodes it touches or sits inside), below, and a concrete next_step.
|
|
255
|
+
|
|
250
256
|
The normal result is bounded below 5 KB and returns before/after transforms, supportPath, finalGap with an error bound, slopeDeg, evidence, and warnings. scenePath and subjectPath are always required; there is no editor-selection fallback. On an engine build that predates SnapToSurface the result is a structured engine_lacks_op failure naming the fallback.`, {
|
|
251
257
|
scenePath: exactScenePath.describe("Exact scene containing the subject, e.g. 'res://levels/market.tscn'"),
|
|
252
258
|
subjectPath: exactNodePath.describe("Exact Node3D path relative to the scene root, e.g. './Props/Crate'"),
|
|
@@ -286,14 +292,16 @@ The normal result is bounded below 5 KB and returns before/after transforms, sup
|
|
|
286
292
|
// Cross-field: a raw zod shape cannot express it, so it stays here.
|
|
287
293
|
if (gap > maxDistance)
|
|
288
294
|
throw new ToolInputError("gap must not exceed maxDistance.");
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
295
|
+
// ONE implementation for both faces (core/capabilities/surface-snap.ts):
|
|
296
|
+
// the snap, a starcast diagnosis on failure, and the sunk-prop lift.
|
|
297
|
+
const receipt = await snapToSurface(client, {
|
|
298
|
+
scenePath: exactScene,
|
|
299
|
+
subjectPath: exactSubject,
|
|
300
|
+
direction: direction,
|
|
301
|
+
maxDistance,
|
|
302
|
+
gap,
|
|
303
|
+
alignUp,
|
|
304
|
+
});
|
|
297
305
|
return withOldEngineHint(receipt, "SnapToSurface", SNAP_TO_SURFACE_FALLBACK);
|
|
298
306
|
}, compactResult({
|
|
299
307
|
op: "SnapToSurface",
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { withEngine, missingEngineOpResult, withOldEngineHint } from "./with-engine.js";
|
|
2
|
+
import { withEngine, missingEngineOpResult, withOldEngineHint, ToolInputError } from "./with-engine.js";
|
|
3
3
|
import { withFailureReasonHint } from "./perception-tools.js";
|
|
4
4
|
import { analyzedSnapshot, captureGame, captureScene, captureViewport, VIEWPORT_RECAPTURE_DELAY_MS, } from "../../core/capabilities/capture.js";
|
|
5
5
|
import { describeFlatFrame } from "../../core/capabilities/frame-quality.js";
|
|
6
6
|
import { CAMERA_BOOKMARK_ACTIONS, CAMERA_BOOKMARK_FALLBACK, SCREENSHOT_FRAMINGS, MAX_MARKS_CAP, buildCameraBookmarkOp, buildScenePreviewInput, formatSceneMarks, isFixedPoseFraming, readCameraPose, readSceneMarks, } from "../../core/capabilities/camera-view.js";
|
|
7
|
+
import { checkMarkOcclusion, formatMarksWithOcclusion, rememberBookmarkRender, shotSheet, slotPolicy, } from "../../core/capabilities/seeing/seeing.js";
|
|
8
|
+
import { parseVector3 } from "../../core/capabilities/seeing/math.js";
|
|
9
|
+
import { seeingContent } from "./seeing-tools.js";
|
|
7
10
|
// The capture path (content check, single viewport recapture, scene-kind read
|
|
8
11
|
// for the no-camera confession) is ONE copy in core/capabilities/capture.ts,
|
|
9
12
|
// shared with the CLI face; re-exported so tests and callers keep this door.
|
|
@@ -170,7 +173,7 @@ Static frame only — one moment, not motion. For a SEQUENCE of frames over time
|
|
|
170
173
|
marks: z
|
|
171
174
|
.boolean()
|
|
172
175
|
.optional()
|
|
173
|
-
.describe('target:"scene" only, 3D scenes. Draw a Set-of-Mark overlay: numbered tags + box outlines over the largest visible VisualInstance3D nodes (lights excluded), ranked by projected screen area. The caption lists label -> node path (scene-root-relative) so you can name what you see. Works with every framing. 2D scenes return marks_unsupported. Default false.'),
|
|
176
|
+
.describe('target:"scene" only, 3D scenes. Draw a Set-of-Mark overlay: numbered tags + box outlines over the largest visible VisualInstance3D nodes (lights excluded), ranked by projected screen area. The caption lists label -> node path (scene-root-relative) so you can name what you see, and an occlusion test (centre + 4 bounds points from the rendered camera) notes "(hidden behind <path>)" on labels whose node is hidden: ignore those. Works with every framing. 2D scenes return marks_unsupported. Default false.'),
|
|
174
177
|
max_marks: z
|
|
175
178
|
.number()
|
|
176
179
|
.int()
|
|
@@ -178,10 +181,36 @@ Static frame only — one moment, not motion. For a SEQUENCE of frames over time
|
|
|
178
181
|
.max(MAX_MARKS_CAP)
|
|
179
182
|
.optional()
|
|
180
183
|
.describe(`marks:true only. Cap on numbered labels (engine default 32, at most ${MAX_MARKS_CAP}). The caption says when the cap truncated the list.`),
|
|
181
|
-
|
|
184
|
+
compare_previous: z
|
|
185
|
+
.boolean()
|
|
186
|
+
.optional()
|
|
187
|
+
.describe('framing:"bookmark" only. Return ONE image of [previous render | now | difference map] for the bookmark, with the share of changed pixels (summer_shot_sheet compare_previous with this one bookmark); this render then replaces the bookmark\'s previous image in res://.summer/shots/<bookmark>.jpg. A plain bookmark render (no marks, at most 1024 px) only creates that image when it is missing and never overwrites the compare baseline.'),
|
|
188
|
+
update_previous: z
|
|
189
|
+
.boolean()
|
|
190
|
+
.optional()
|
|
191
|
+
.describe('framing:"bookmark" only. Replace the bookmark\'s previous image (its compare baseline) with this clean render. Default false: an existing baseline is kept.'),
|
|
192
|
+
}, async ({ target, scenePath, framing, bookmark_name, size, nodePath, camera_path, camera_position, camera_look_at, fov, marks, max_marks, compare_previous, update_previous, }) => {
|
|
193
|
+
if (compare_previous) {
|
|
194
|
+
// Same implementation as summer_shot_sheet: one bookmark row of
|
|
195
|
+
// [previous | now | difference].
|
|
196
|
+
return withEngine(async (client) => {
|
|
197
|
+
if (target !== "scene" || !bookmark_name || (framing !== undefined && framing !== "bookmark")) {
|
|
198
|
+
throw new ToolInputError('compare_previous needs target:"scene" with framing:"bookmark" and bookmark_name. Nothing was sent.');
|
|
199
|
+
}
|
|
200
|
+
const result = await shotSheet(client, {
|
|
201
|
+
scenePath,
|
|
202
|
+
shots: [{ bookmark_name, ...(fov !== undefined ? { fov } : {}) }],
|
|
203
|
+
compare_previous: true,
|
|
204
|
+
max_size: 1536,
|
|
205
|
+
});
|
|
206
|
+
return { seeing: result, ...(result.ok ? {} : { failure_reason: result.failure_reason }) };
|
|
207
|
+
}, { onResult: (wrapped) => seeingContent(wrapped.seeing) });
|
|
208
|
+
}
|
|
182
209
|
// Resolved inside the engine closure so a contradictory framing is a
|
|
183
210
|
// classified invalid_input (nothing sent), never a transport failure.
|
|
184
211
|
let preview;
|
|
212
|
+
let slotNotes = [];
|
|
213
|
+
let markOcclusion;
|
|
185
214
|
return withEngine(async (client) => {
|
|
186
215
|
if (target === "game")
|
|
187
216
|
return captureGame(client);
|
|
@@ -199,7 +228,27 @@ Static frame only — one moment, not motion. For a SEQUENCE of frames over time
|
|
|
199
228
|
marks,
|
|
200
229
|
max_marks,
|
|
201
230
|
});
|
|
202
|
-
|
|
231
|
+
const snap = teachPreviewFailure(await captureScene(client, preview));
|
|
232
|
+
// One before/after slot per bookmark: a clean render creates it
|
|
233
|
+
// when missing; only update_previous replaces an existing one.
|
|
234
|
+
const bookmark = preview.framing?.startsWith("bookmark:") ? preview.framing.slice("bookmark:".length) : undefined;
|
|
235
|
+
if (snap.ok && snap.base64 && bookmark && snap.framing === preview.framing) {
|
|
236
|
+
slotNotes = await rememberBookmarkRender(typeof client.getProjectRoot === "function" ? client.getProjectRoot() : undefined, bookmark, { base64: snap.base64, width: snap.width, height: snap.height }, preview.marks === true, slotPolicy({ updatePrevious: update_previous === true }));
|
|
237
|
+
}
|
|
238
|
+
// Labels on hidden nodes: test each labelled node from the
|
|
239
|
+
// rendered camera (centre + 4 bounds points).
|
|
240
|
+
const meta = snap.metadata;
|
|
241
|
+
const marked = snap.ok && preview.marks ? readSceneMarks(meta) : null;
|
|
242
|
+
const camera = readCameraPose(meta)?.position;
|
|
243
|
+
if (marked?.marks.length && camera) {
|
|
244
|
+
try {
|
|
245
|
+
markOcclusion = await checkMarkOcclusion(client, scenePath, parseVector3(camera, "camera_pose.position"), marked.marks);
|
|
246
|
+
}
|
|
247
|
+
catch (err) {
|
|
248
|
+
markOcclusion = { occlusion: new Map(), note: `NOTE: the mark occlusion check could not run (${err instanceof Error ? err.message : String(err)}).` };
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return snap;
|
|
203
252
|
}
|
|
204
253
|
return captureViewport(client);
|
|
205
254
|
}, {
|
|
@@ -367,11 +416,14 @@ Static frame only — one moment, not motion. For a SEQUENCE of frames over time
|
|
|
367
416
|
details.push(`camera pose: ${parts.join(", ")}`);
|
|
368
417
|
}
|
|
369
418
|
const marksSummary = readSceneMarks(meta);
|
|
370
|
-
if (marksSummary)
|
|
371
|
-
marksBlock = formatSceneMarks(marksSummary);
|
|
419
|
+
if (marksSummary) {
|
|
420
|
+
marksBlock = markOcclusion ? formatMarksWithOcclusion(marksSummary, markOcclusion.occlusion) : formatSceneMarks(marksSummary);
|
|
421
|
+
if (markOcclusion?.note)
|
|
422
|
+
marksBlock.push(markOcclusion.note);
|
|
423
|
+
}
|
|
372
424
|
}
|
|
373
425
|
const detailNote = details.length ? `; ${details.join(", ")}` : "";
|
|
374
|
-
const trailer = [...warnings, ...notes];
|
|
426
|
+
const trailer = [...warnings, ...notes, ...slotNotes];
|
|
375
427
|
const caption = `${label} (${dims}${detailNote}). Saved to ${snap.localPath ?? "n/a"}.${frameCheck} Describe only what is visibly in the image above.` +
|
|
376
428
|
(marksBlock.length ? `\n\n${marksBlock.join("\n")}` : "") +
|
|
377
429
|
(trailer.length ? `\n\n${trailer.join("\n")}` : "");
|
package/gemini-extension.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_generated": "GENERATED from integrations/gemini — do not edit; npm run generate:registry",
|
|
3
3
|
"name": "summer",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.2.0",
|
|
5
5
|
"description": "Agent tooling for Summer Engine: MCP bridge, context primer, and game-dev skills. Use with the npm CLI for skill files on disk.",
|
|
6
6
|
"contextFileName": "GEMINI.md",
|
|
7
7
|
"mcpServers": {
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"./library/skills/3d-lighting/",
|
|
28
28
|
"./library/skills/adaptive-music/",
|
|
29
29
|
"./library/skills/agent-playtesting/",
|
|
30
|
+
"./library/skills/ai-characters-in-games/",
|
|
30
31
|
"./library/skills/ambient-bed/",
|
|
31
32
|
"./library/skills/animated-loop/",
|
|
32
33
|
"./library/skills/animation-tree/",
|
|
@@ -37,11 +38,14 @@
|
|
|
37
38
|
"./library/skills/brainstorm-game/",
|
|
38
39
|
"./library/skills/brainstorming/",
|
|
39
40
|
"./library/skills/browse-templates/",
|
|
41
|
+
"./library/skills/camera-rigs/",
|
|
40
42
|
"./library/skills/celeste-momentum-platforming/",
|
|
41
43
|
"./library/skills/character-animation-wiring/",
|
|
42
44
|
"./library/skills/character-model/",
|
|
45
|
+
"./library/skills/character-movement/",
|
|
43
46
|
"./library/skills/character-portrait/",
|
|
44
47
|
"./library/skills/cinematic-cutscene/",
|
|
48
|
+
"./library/skills/combat-basics/",
|
|
45
49
|
"./library/skills/concept-art/",
|
|
46
50
|
"./library/skills/create-asset-sheet/",
|
|
47
51
|
"./library/skills/debug/",
|
|
@@ -63,16 +67,21 @@
|
|
|
63
67
|
"./library/skills/generate-motion/",
|
|
64
68
|
"./library/skills/godogen-visual-proof-game-generation/",
|
|
65
69
|
"./library/skills/headless-scripting/",
|
|
66
|
-
"./library/skills/
|
|
70
|
+
"./library/skills/in-game-purchases/",
|
|
67
71
|
"./library/skills/instantiate-asset-pack/",
|
|
68
72
|
"./library/skills/investigating-bugs/",
|
|
69
73
|
"./library/skills/lumera-single-image-scene-reconstruction/",
|
|
70
74
|
"./library/skills/make-game/",
|
|
75
|
+
"./library/skills/multiplayer/",
|
|
76
|
+
"./library/skills/multiplayer-movement/",
|
|
77
|
+
"./library/skills/multiplayer-project/",
|
|
78
|
+
"./library/skills/multiplayer-publish/",
|
|
79
|
+
"./library/skills/multiplayer-state/",
|
|
80
|
+
"./library/skills/multiplayer-testing/",
|
|
71
81
|
"./library/skills/music-track/",
|
|
72
82
|
"./library/skills/navigate-summer/",
|
|
73
83
|
"./library/skills/new-project/",
|
|
74
84
|
"./library/skills/organic-model/",
|
|
75
|
-
"./library/skills/peer-to-peer-multiplayer/",
|
|
76
85
|
"./library/skills/pixel-art/",
|
|
77
86
|
"./library/skills/play/",
|
|
78
87
|
"./library/skills/playtesting-a-feature/",
|
|
@@ -83,11 +92,11 @@
|
|
|
83
92
|
"./library/skills/remote-deploy/",
|
|
84
93
|
"./library/skills/retarget/",
|
|
85
94
|
"./library/skills/running-in-the-cloud/",
|
|
95
|
+
"./library/skills/save-load/",
|
|
86
96
|
"./library/skills/scene-composition/",
|
|
87
97
|
"./library/skills/scene-hierarchy-design/",
|
|
88
98
|
"./library/skills/scene-scripting/",
|
|
89
99
|
"./library/skills/scene-to-level/",
|
|
90
|
-
"./library/skills/setup-multiplayer/",
|
|
91
100
|
"./library/skills/skill-create/",
|
|
92
101
|
"./library/skills/skill-improve/",
|
|
93
102
|
"./library/skills/skill-test/",
|
|
@@ -96,6 +105,17 @@
|
|
|
96
105
|
"./library/skills/sound-effect/",
|
|
97
106
|
"./library/skills/spatial-placement/",
|
|
98
107
|
"./library/skills/sprite-sheet/",
|
|
108
|
+
"./library/skills/summer-analytics/",
|
|
109
|
+
"./library/skills/summer-friends/",
|
|
110
|
+
"./library/skills/summer-leaderboards/",
|
|
111
|
+
"./library/skills/summer-match-results/",
|
|
112
|
+
"./library/skills/summer-matchmaking/",
|
|
113
|
+
"./library/skills/summer-parties/",
|
|
114
|
+
"./library/skills/summer-player-data/",
|
|
115
|
+
"./library/skills/summer-store/",
|
|
116
|
+
"./library/skills/summer-world-chat/",
|
|
117
|
+
"./library/skills/summer-world-saves/",
|
|
118
|
+
"./library/skills/text-to-motion/",
|
|
99
119
|
"./library/skills/tileable-texture/",
|
|
100
120
|
"./library/skills/trailer-shot/",
|
|
101
121
|
"./library/skills/tune-performance/",
|
|
@@ -115,6 +135,8 @@
|
|
|
115
135
|
"./library/skills/vfx-smoke/",
|
|
116
136
|
"./library/skills/vfx-water-ripple/",
|
|
117
137
|
"./library/skills/voice-line/",
|
|
138
|
+
"./library/skills/web-and-touch-input/",
|
|
139
|
+
"./library/skills/web-compatibility-look/",
|
|
118
140
|
"./library/skills/world-building-3d/",
|
|
119
141
|
"./library/skills/writing-plans/",
|
|
120
142
|
"./library/skills/writing-skills/"
|