summer-engine 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +102 -0
- package/README.md +18 -3
- package/assets/audit/scene_audit.gd +4136 -0
- package/assets/seeing/seeing_probe.gd +1873 -0
- package/dist/cli/commands/skills.js +20 -2
- 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 +18 -2
- 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/installer/agent-config.js +5 -3
- package/dist/installer/agent-table.d.ts +16 -0
- package/dist/installer/agent-table.js +52 -17
- 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/amp/README.md +1 -1
- package/integrations/crush/README.md +1 -1
- package/integrations/grok-build/README.md +1 -1
- package/integrations/hermes/README.md +1 -1
- package/integrations/kimi-code/README.md +1 -1
- package/integrations/mistral-vibe/README.md +1 -1
- package/integrations/opencode/README.md +1 -1
- package/integrations/rovo-dev/README.md +1 -1
- package/integrations/vscode-copilot/README.md +1 -1
- package/integrations/warp/README.md +1 -1
- package/integrations/windsurf/README.md +1 -1
- 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 +36 -14
- 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 +1 -1
- 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 +36 -14
- package/registry/generated/skills-registry.json +421 -124
- 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
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: summer-world-saves
|
|
3
|
+
description: "Keep a persistent Summer World between restarts: checkpoint saves, restore before join, the final save."
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: multiplayer-and-networking
|
|
7
|
+
user-invocable: true
|
|
8
|
+
allowed-tools: Read Grep Edit Write summer_get_script_errors summer_project_setting summer_play summer_stop summer_get_diagnostics
|
|
9
|
+
paths: ["**/*.gd", "world.json", "summer.build.json"]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# /summer-world-saves — a World that is still there tomorrow
|
|
13
|
+
|
|
14
|
+
> **Preview.**
|
|
15
|
+
> - Verified in Local Play: restore of a new World, commit and receipt.
|
|
16
|
+
> - **Not** verified: restoring after a real restart. Local Play keeps saves in memory only, so only hosted play proves it.
|
|
17
|
+
> - Persistent Worlds need hosting support for your game. Check that it is available before you promise it to players.
|
|
18
|
+
|
|
19
|
+
## Overview
|
|
20
|
+
|
|
21
|
+
Most Summer Worlds are **match-scoped**: the match ends and its state is gone.
|
|
22
|
+
A **persistent** World is a place players come back to, such as a shared
|
|
23
|
+
base, a farm or a realm. Its authority can stop for maintenance, a crash or
|
|
24
|
+
a move. A new authority then restores the World from its last save.
|
|
25
|
+
|
|
26
|
+
| Keep | Use |
|
|
27
|
+
|---|---|
|
|
28
|
+
| What belongs to the place: built walls, chests, the coins left on the ground | **World save** (this skill) |
|
|
29
|
+
| What belongs to a player: their coins, unlocks, level | **Player data** (`skill/summer-player-data`) |
|
|
30
|
+
|
|
31
|
+
The engine never serializes nodes for you. The game decides what one save
|
|
32
|
+
holds. It must be **one consistent cut**: if an item moves from a chest into
|
|
33
|
+
an inventory, both sides go in the same save.
|
|
34
|
+
|
|
35
|
+
This skill extends the Courtyard game from `skill/multiplayer-state`: its
|
|
36
|
+
`match_doc` (the coins still on the ground, and the scoreboard) becomes the
|
|
37
|
+
World's saved state.
|
|
38
|
+
|
|
39
|
+
## Steps
|
|
40
|
+
|
|
41
|
+
### 1. Declare a persistent World
|
|
42
|
+
|
|
43
|
+
In `world.json`, change these fields and keep everything else:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"lifetime": "persistent",
|
|
48
|
+
"settlement": { "mode": "none" },
|
|
49
|
+
"persistence": {
|
|
50
|
+
"mode": "checkpoint",
|
|
51
|
+
"recovery_point_seconds": 60,
|
|
52
|
+
"snapshot_schemas": ["courtyard.v1"],
|
|
53
|
+
"migration_ids": []
|
|
54
|
+
},
|
|
55
|
+
"lifecycle": {
|
|
56
|
+
"reconnect_seconds": 30,
|
|
57
|
+
"drain_seconds": 120,
|
|
58
|
+
"transfer": "disabled",
|
|
59
|
+
"completion_owner": "world"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- `recovery_point_seconds` (1 to 3600) is the most play you accept losing in a crash. Commit at least that often.
|
|
65
|
+
- `snapshot_schemas`: exactly one name for your save format in this release. There are no migrations.
|
|
66
|
+
- `drain_seconds`: 60 to 300.
|
|
67
|
+
- A save holds at most **16 MiB**.
|
|
68
|
+
|
|
69
|
+
### 2. Restore before anyone joins
|
|
70
|
+
|
|
71
|
+
Restore runs right after `Summer.initialize`, **before** waiting for
|
|
72
|
+
`binding_ready`. Players are admitted only after `finish_restore` succeeds,
|
|
73
|
+
so restore is part of becoming ready. Add to `authority/main.gd`:
|
|
74
|
+
|
|
75
|
+
```gdscript
|
|
76
|
+
const SAVE_SCHEMA := "courtyard.v1" # the WorldDefinition's snapshot_schemas entry
|
|
77
|
+
const CHECKPOINT_SECONDS := 30.0 # at most the WorldDefinition's recovery_point_seconds
|
|
78
|
+
var saves: SummerAuthorityWorld # Summer.authority.world: this World's save slot
|
|
79
|
+
var save_revision := "0"
|
|
80
|
+
var save_sequence := 0
|
|
81
|
+
var save_op: SummerWorldSaveOperation # the commit in flight, if any
|
|
82
|
+
var restored := false
|
|
83
|
+
var world_dirty := false
|
|
84
|
+
var acknowledged: Array[String] = []
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
In `_ready()`, between `Summer.initialize` and the `binding_ready` wait:
|
|
88
|
+
|
|
89
|
+
```gdscript
|
|
90
|
+
# Restore before waiting for binding_ready: players are admitted only
|
|
91
|
+
# after the World confirms its restore.
|
|
92
|
+
if not await _restore_world():
|
|
93
|
+
push_error("could not restore this World; not starting")
|
|
94
|
+
return
|
|
95
|
+
var checkpoints := Timer.new()
|
|
96
|
+
checkpoints.wait_time = CHECKPOINT_SECONDS
|
|
97
|
+
checkpoints.timeout.connect(_on_checkpoint_timer)
|
|
98
|
+
add_child(checkpoints)
|
|
99
|
+
checkpoints.start()
|
|
100
|
+
if not world.is_ready():
|
|
101
|
+
await world.binding_ready
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Create the shared `match` State group **after** the restore, so it starts
|
|
105
|
+
from the restored document.
|
|
106
|
+
|
|
107
|
+
```gdscript
|
|
108
|
+
## Loads the World's last checkpoint, or starts fresh when it has none.
|
|
109
|
+
func _restore_world() -> bool:
|
|
110
|
+
saves = Summer.authority.world
|
|
111
|
+
saves.save_requested.connect(_on_save_requested)
|
|
112
|
+
# Local Play binds the World on the frame after initialize; let that
|
|
113
|
+
# frame pass before loading.
|
|
114
|
+
await get_tree().process_frame
|
|
115
|
+
var loading := saves.load_save()
|
|
116
|
+
var result: SummerResult = await loading.get_result_or_completed_signal()
|
|
117
|
+
if not result.ok:
|
|
118
|
+
return false # never treat a failed load as an empty World
|
|
119
|
+
var saved := loading.get_save()
|
|
120
|
+
if saved.has_save():
|
|
121
|
+
var doc: Variant = JSON.parse_string(saved.get_data().get_string_from_utf8())
|
|
122
|
+
if not doc is Dictionary or not doc.has_all(["coins", "scores"]):
|
|
123
|
+
return false
|
|
124
|
+
match_doc = doc
|
|
125
|
+
save_revision = saved.get_revision()
|
|
126
|
+
save_sequence = int(saved.get_state_sequence())
|
|
127
|
+
result = await saves.finish_restore(saved).get_result_or_completed_signal()
|
|
128
|
+
if not result.ok:
|
|
129
|
+
return false
|
|
130
|
+
restored = true
|
|
131
|
+
# A save request may have arrived before this point.
|
|
132
|
+
var pending := saves.get_snapshot_request_id()
|
|
133
|
+
if not pending.is_empty():
|
|
134
|
+
_on_save_requested(pending, saves.get_snapshot_deadline_unix_msec())
|
|
135
|
+
return true
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**A failed or corrupt load must stop the World.** Starting fresh instead
|
|
139
|
+
would overwrite the players' place with an empty one on the next save.
|
|
140
|
+
|
|
141
|
+
### 3. Checkpoint while playing
|
|
142
|
+
|
|
143
|
+
Mark the World dirty wherever saved state changes. Here that is after
|
|
144
|
+
`match_group.reset(...)` in `_collect`:
|
|
145
|
+
|
|
146
|
+
```gdscript
|
|
147
|
+
world_dirty = true
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```gdscript
|
|
151
|
+
func _on_checkpoint_timer() -> void:
|
|
152
|
+
if world_dirty:
|
|
153
|
+
_checkpoint()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
## Commits one consistent copy of the World. One save at a time; a retry
|
|
157
|
+
## resends exactly the same five arguments.
|
|
158
|
+
func _checkpoint() -> SummerWorldSaveReceipt:
|
|
159
|
+
while save_op != null:
|
|
160
|
+
await save_op.get_result_or_completed_signal()
|
|
161
|
+
world_dirty = false
|
|
162
|
+
save_sequence += 1
|
|
163
|
+
var sequence := str(save_sequence)
|
|
164
|
+
var save_id := "cut-" + sequence
|
|
165
|
+
var bytes := JSON.stringify(match_doc).to_utf8_buffer()
|
|
166
|
+
var expected := save_revision
|
|
167
|
+
for attempt in 3:
|
|
168
|
+
save_op = saves.commit_save(expected, save_id, SAVE_SCHEMA, bytes, sequence)
|
|
169
|
+
var result: SummerResult = await save_op.get_result_or_completed_signal()
|
|
170
|
+
var receipt := save_op.get_receipt()
|
|
171
|
+
save_op = null
|
|
172
|
+
if result.ok:
|
|
173
|
+
save_revision = receipt.get_revision()
|
|
174
|
+
return receipt
|
|
175
|
+
if not result.retryable:
|
|
176
|
+
# Conflict, corrupt, incompatible or fenced: stop, never overwrite.
|
|
177
|
+
push_error("world save failed: %s" % result.code)
|
|
178
|
+
break
|
|
179
|
+
world_dirty = true
|
|
180
|
+
return null
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The rules behind it:
|
|
184
|
+
|
|
185
|
+
- **One save at a time.** `commit_save` takes the revision you expect to replace, so two overlapping saves would conflict.
|
|
186
|
+
- **Capture once, retry exactly.**
|
|
187
|
+
- On retryable `world_save_unavailable`, resend the same expected revision, `save_id`, schema, bytes and sequence.
|
|
188
|
+
- A lost reply may hide a commit that already succeeded.
|
|
189
|
+
- **The sequence only grows.** It continues from the restored save's `state_sequence`, so `save_id`s never repeat across restarts.
|
|
190
|
+
- **Stop on non-retryable codes.** `world_save_conflict`, `world_save_corrupt`, `world_save_incompatible`, `world_restore_required` and `runtime_fenced` mean this authority must not keep writing.
|
|
191
|
+
|
|
192
|
+
### 4. Answer the final save request
|
|
193
|
+
|
|
194
|
+
Before Summer stops, restarts or moves the World, it emits `save_requested`
|
|
195
|
+
with a deadline. Commit a fresh cut, then acknowledge it with that receipt:
|
|
196
|
+
|
|
197
|
+
```gdscript
|
|
198
|
+
## The platform asks for a final save before it stops or moves this World.
|
|
199
|
+
## Commit a fresh cut, then acknowledge it. Never wait for timers or frames
|
|
200
|
+
## here: gameplay is frozen while the final save runs.
|
|
201
|
+
func _on_save_requested(request_id: String, _deadline_unix_msec: int) -> void:
|
|
202
|
+
if not restored or request_id in acknowledged:
|
|
203
|
+
return
|
|
204
|
+
acknowledged.append(request_id)
|
|
205
|
+
var receipt := await _checkpoint()
|
|
206
|
+
if receipt == null:
|
|
207
|
+
return # never acknowledge a save that did not commit
|
|
208
|
+
await saves.finish_snapshot(request_id, receipt).get_result_or_completed_signal()
|
|
209
|
+
# This runtime may stop right here. Put nothing important after it.
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
- During the final save, scene processing and timers are frozen; only save operations complete. Never `await` a timer or a frame in this path.
|
|
213
|
+
- A crash delivers no request, so periodic checkpoints are still required.
|
|
214
|
+
- For a planned shutdown, `saves.shutdown_notice_changed` gives advance notice; a `null` notice means it was cancelled. Use it to warn players ("Server restarts in 5 minutes") and to finish events that are in progress.
|
|
215
|
+
|
|
216
|
+
### 5. Bring players back to the same World
|
|
217
|
+
|
|
218
|
+
A player returns to a persistent World by its id:
|
|
219
|
+
|
|
220
|
+
```gdscript
|
|
221
|
+
var join := Summer.client.join(SummerJoinTarget.world(world_id))
|
|
222
|
+
var joined: SummerResult = await join.get_result_or_completed_signal()
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Read the id with `Summer.get_world().world_id` after the first join, and keep
|
|
226
|
+
it, for example in the player's public player data. A sleeping World wakes
|
|
227
|
+
and restores before the player is admitted.
|
|
228
|
+
|
|
229
|
+
Never call `saves.complete()` to "save and stop". It ends the World
|
|
230
|
+
permanently.
|
|
231
|
+
|
|
232
|
+
### 6. Test in Local Play
|
|
233
|
+
|
|
234
|
+
Local Play runs a persistent World with an **in-memory** save store:
|
|
235
|
+
|
|
236
|
+
- Every run starts with no save, so `has_save()` is false.
|
|
237
|
+
- Commits succeed and return receipts.
|
|
238
|
+
- Nothing survives the run.
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
summer_project_setting name="summer/local_play/players" value=2
|
|
242
|
+
summer_play
|
|
243
|
+
summer_get_diagnostics
|
|
244
|
+
summer_stop
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Add a marker after restore, such as `print("WORLD_RESTORED has_save=", saved.has_save())`,
|
|
248
|
+
and one after each successful commit. Then check:
|
|
249
|
+
|
|
250
|
+
- the restore marker appears before any player joins;
|
|
251
|
+
- a checkpoint commits after state changes;
|
|
252
|
+
- there are no `world_save_*` errors.
|
|
253
|
+
|
|
254
|
+
Restoring after a real restart can only be proven hosted.
|
|
255
|
+
|
|
256
|
+
## Checklist
|
|
257
|
+
|
|
258
|
+
- [ ] `world.json` declares `lifetime: persistent` and a `checkpoint` persistence block with one schema.
|
|
259
|
+
- [ ] The authority restores before awaiting `binding_ready`, and a failed load stops it.
|
|
260
|
+
- [ ] Checkpoints run at least every `recovery_point_seconds` while the World changes.
|
|
261
|
+
- [ ] Only one `commit_save` is in flight; retries reuse all five arguments.
|
|
262
|
+
- [ ] `save_requested` commits a fresh cut, then calls `finish_snapshot` with that receipt, without awaiting timers.
|
|
263
|
+
- [ ] Player progress lives in player data, not in the World save.
|
|
264
|
+
|
|
265
|
+
## Common mistakes
|
|
266
|
+
|
|
267
|
+
| Don't | Do | Why |
|
|
268
|
+
|---|---|---|
|
|
269
|
+
| Await `binding_ready` before restoring | Restore first, then await `binding_ready` | Readiness waits for the restore, so the World never becomes ready |
|
|
270
|
+
| Call `load_save()` in the same frame as `initialize` | Await one `process_frame` first | Local Play binds the World a frame later; the load fails with `world_save_unavailable` ("no active SummerNetworkWorld binding") |
|
|
271
|
+
| Start an empty World when the load fails | Stop and report | The next checkpoint would overwrite the real World |
|
|
272
|
+
| Save only on shutdown | Checkpoint every `recovery_point_seconds` | Crashes deliver no save request |
|
|
273
|
+
| Start a second save while one is pending | Serialize saves | Both expect the same revision; one conflicts |
|
|
274
|
+
| Recapture or mint a new `save_id` after a lost reply | Retry the same five arguments | The first commit may have succeeded |
|
|
275
|
+
| Await a timer inside the final save | Await only save operations | Timers are frozen during final saving |
|
|
276
|
+
| Put player progress in the World save | Player data | It must follow the player to other Worlds |
|
|
277
|
+
| Call `complete()` to sleep the World | Let the platform stop it after the final save | `complete()` ends the World forever |
|
|
278
|
+
|
|
279
|
+
## See also
|
|
280
|
+
|
|
281
|
+
- `skill/summer-player-data` — progress that follows a player
|
|
282
|
+
- `skill/multiplayer-state` — the shared document this skill saves
|
|
283
|
+
- `skill/multiplayer-project` — `world.json` and the authority scene
|
|
284
|
+
- `skill/multiplayer-testing` — Local Play runs and markers
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
id: skill/summer-world-saves
|
|
2
|
+
kind: skill
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
summary: "Keep a persistent Summer World between restarts: checkpoint saves, restore before join, the final save."
|
|
5
|
+
use_when:
|
|
6
|
+
- "building a persistent World, shared base, farm or realm in a Summer game that must survive server restarts"
|
|
7
|
+
- "saving and restoring World state with commit_save, load_save, finish_restore, save_requested or finish_snapshot"
|
|
8
|
+
- "deciding whether progress belongs in a World save or in player data"
|
|
9
|
+
facets:
|
|
10
|
+
lifecycle:
|
|
11
|
+
- build
|
|
12
|
+
domains:
|
|
13
|
+
- multiplayer
|
|
14
|
+
- scripting
|
|
15
|
+
modalities:
|
|
16
|
+
- scripts
|
|
17
|
+
compatibility:
|
|
18
|
+
engine: ">=4.6"
|
|
19
|
+
related:
|
|
20
|
+
skills:
|
|
21
|
+
- skill/multiplayer
|
|
22
|
+
- skill/multiplayer-project
|
|
23
|
+
- skill/multiplayer-state
|
|
24
|
+
- skill/summer-player-data
|
|
25
|
+
- skill/summer-match-results
|
|
26
|
+
source: official
|
|
27
|
+
license: MIT
|
|
28
|
+
status: preview
|
|
29
|
+
recommended: false
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: text-to-motion
|
|
3
|
+
description: "Custom 2-second animation clips from text prompts on any of the user's own rigged models — humanoids, animals, creatures, cartoon plants, props."
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: animation
|
|
7
|
+
user-invocable: false
|
|
8
|
+
allowed-tools: Read summer_list_my_assets summer_generate_motion summer_check_job summer_get_asset summer_import_asset_by_id
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Text to Motion
|
|
12
|
+
|
|
13
|
+
Summer-hosted text-to-motion turns a text prompt into a 2-second (60 frames) skeletal
|
|
14
|
+
clip for the user's **own** rigged model. One model covers every skeleton with 5-70 bones:
|
|
15
|
+
humanoids, animals, creatures, cartoon plants, turrets, props.
|
|
16
|
+
|
|
17
|
+
The tool is `summer_generate_motion` with `backend: "text-to-motion"`. It returns a
|
|
18
|
+
`jobId`; poll `summer_check_job`. The finished job's `result.assets` lists one `animation`
|
|
19
|
+
asset per prompt x take (`id`, `fileUrl`, `animationName`, `prompt`, `take`); each is a GLB
|
|
20
|
+
of the whole model carrying one animation named after its prompt.
|
|
21
|
+
|
|
22
|
+
Trigger on: "make the flower nod", "animate my creature", "custom animation from text",
|
|
23
|
+
"a bow / shrug / wave with the right arm", "animate this uploaded rig", "the library
|
|
24
|
+
doesn't have that move", any animation request for a non-humanoid rig.
|
|
25
|
+
|
|
26
|
+
## Choose the right route
|
|
27
|
+
|
|
28
|
+
| Situation | Use |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| Summer-rigged humanoid needs idle / walk / run / jump / attack | `generate-motion` (`backend: "meshy-library"`) |
|
|
31
|
+
| Custom action, specific arm or side, emotional gesture | this skill |
|
|
32
|
+
| Non-humanoid rig: flower, animal, creature, turret, prop | this skill |
|
|
33
|
+
| Uploaded or custom-rigged GLB/FBX | this skill |
|
|
34
|
+
| Existing clips onto a second character | `retarget` |
|
|
35
|
+
| Unrigged mesh | rig first (`rigging-for-text-motion.md`; humanoids via `character-model`), then this skill |
|
|
36
|
+
|
|
37
|
+
## The order
|
|
38
|
+
|
|
39
|
+
1. **Confirm the rig.** The asset must be the user's own `3d_model` GLB/FBX with one
|
|
40
|
+
skinned armature and 5-70 bones (`summer_list_my_assets` / `summer_get_asset`). If it
|
|
41
|
+
is unrigged or has odd bone names, read `rigging-for-text-motion.md` in this directory.
|
|
42
|
+
2. **Agree the clip list and cost.** Each prompt x take is one billed clip. Show the list
|
|
43
|
+
and the estimated cost and wait for the user's OK before submitting.
|
|
44
|
+
3. **Submit once.** Up to 8 prompts per call, `takes` 1-4. For rooted characters pass
|
|
45
|
+
`lockJoints` with the base bones:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
summer_generate_motion(
|
|
49
|
+
rigAssetId: "<id>",
|
|
50
|
+
backend: "text-to-motion",
|
|
51
|
+
prompts: ["nods happily", "waves hello with the right leaf"],
|
|
52
|
+
lockJoints: ["Hips", "Spine"], // rooted flower; omit for characters that move
|
|
53
|
+
cfgScale: 5, // default 3; 5 for clearer gestures on stylized rigs
|
|
54
|
+
wait: false
|
|
55
|
+
)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Pass a stable `idempotencyKey` if you might retry the same request. Prompt writing and
|
|
59
|
+
every control: `prompts-and-controls.md` in this directory.
|
|
60
|
+
4. **Poll to completion.** `summer_check_job(jobId)`. A job takes about 1-2 minutes. Do not
|
|
61
|
+
resubmit while it runs. (With the default `wait: true` the tool polls for you.)
|
|
62
|
+
5. **Review, then import.** Import the chosen clip assets with
|
|
63
|
+
`summer_import_asset_by_id(assetId, parent, scenePath)`. Offer to regenerate weak takes
|
|
64
|
+
with a rephrased prompt or a higher `cfgScale`; keep the good ones.
|
|
65
|
+
|
|
66
|
+
## Hard rules
|
|
67
|
+
|
|
68
|
+
- **Only the user's own rigged models.** Never animate assets owned by someone else.
|
|
69
|
+
- **Clips are 2 seconds and not guaranteed to loop.** For longer actions chain several
|
|
70
|
+
prompts ("raises both arms", "holds the pose", "lowers the arms") or loop a good take.
|
|
71
|
+
- **Locomotion moves the root.** Walk/run/jump clips may translate the character; gameplay
|
|
72
|
+
code owns movement, so strip or ignore root translation for in-place controllers.
|
|
73
|
+
- **Never lock joints on characters that walk or jump**; the root would be pinned.
|
|
74
|
+
- **Report failures with their code.** Job failures starting `text_motion:` (no skinned
|
|
75
|
+
armature, too many or too few joints, multiple armatures, unknown lock joint) are input
|
|
76
|
+
problems and the charge is refunded. Fix the rig or the request; do not retry unchanged.
|
|
77
|
+
- **`backend_unavailable` means text-to-motion is not enabled on this server yet.** Fall
|
|
78
|
+
back to `generate-motion` (meshy-library) for humanoid clips and say so; do not retry.
|
|
79
|
+
- **Do not promise facial animation, finger detail or lip sync.** The model animates the
|
|
80
|
+
skeleton only; blendshapes stay untouched (`facial-and-lipsync` covers faces).
|
|
81
|
+
|
|
82
|
+
## Request errors
|
|
83
|
+
|
|
84
|
+
| Code | Meaning | Do |
|
|
85
|
+
| --- | --- | --- |
|
|
86
|
+
| `backend_unavailable` | Server flag off | Use `generate-motion`; do not retry |
|
|
87
|
+
| `prompt_required` | No prompt | Pass `prompt` or `prompts` (1-8, each 1-300 chars) |
|
|
88
|
+
| `invalid_takes` | `takes` outside 1-4 | Fix and resubmit |
|
|
89
|
+
| `invalid_cfg_scale` | `cfgScale` outside 1.5-8 | Fix and resubmit |
|
|
90
|
+
| `invalid_lock_joints` | Bone names wrong | Use bone names that exist in the rig |
|
|
91
|
+
| `rig_asset_not_found` | Not the caller's asset | Find the user's own asset id |
|
|
92
|
+
| `rig_asset_invalid` | Not a rigged GLB/FBX `3d_model` | Rig it first |
|
|
93
|
+
| `insufficient_credits` (402) | Not enough credits | Fewer prompts/takes, or the user tops up |
|
|
94
|
+
|
|
95
|
+
## Do not stop early
|
|
96
|
+
|
|
97
|
+
Done means the chosen clips are imported and playing on the model in the scene. For a
|
|
98
|
+
playable character continue with `character-animation-wiring`; for state machines,
|
|
99
|
+
`animation-tree`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Prompts and controls
|
|
2
|
+
|
|
3
|
+
## Prompts
|
|
4
|
+
|
|
5
|
+
- Describe one action as a verb phrase: "waves hello with the right arm", "nods happily",
|
|
6
|
+
"bows politely", "jumps up and down excitedly", "looks around curiously".
|
|
7
|
+
The service normalizes to its training style ("An object waves ...").
|
|
8
|
+
- Name the side and body part for asymmetric actions ("with the right arm", "raises the
|
|
9
|
+
left leaf").
|
|
10
|
+
- Keep it to one action per clip; 2 seconds fits one gesture, not a sequence.
|
|
11
|
+
- Style words that map to motion work ("happily", "slowly", "tiredly"); story or
|
|
12
|
+
appearance words do not.
|
|
13
|
+
|
|
14
|
+
## Controls (`summer_generate_motion`, `backend: "text-to-motion"`)
|
|
15
|
+
|
|
16
|
+
| Field | Default | Use |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| `prompt` / `prompts` | - | One action, or 1-8 actions (each 1-300 chars); one clip each. Pass one of the two, not both |
|
|
19
|
+
| `takes` | 1 | 1-4; 2-3 when choosing a hero clip. Every take is billed |
|
|
20
|
+
| `cfgScale` | 3 | 1.5-8; 5 for bigger, clearer gestures on stylized rigs; above 6 gets unstable |
|
|
21
|
+
| `lockJoints` | none | Base bones of rooted characters (plants, turrets, statues), e.g. `["Hips","Spine"]` |
|
|
22
|
+
| `idempotencyKey` | none | Stable key so a retried request is not billed twice |
|
|
23
|
+
| `wait` | true | `false` returns the `jobId` at once; poll `summer_check_job` |
|
|
24
|
+
|
|
25
|
+
Clip count = prompts x takes; each clip is billed. The queued response reports
|
|
26
|
+
`clipCount` and `estimatedCost`.
|
|
27
|
+
|
|
28
|
+
## Judging results
|
|
29
|
+
|
|
30
|
+
- Good: the named body part does the action, the base stays put, no mesh tearing.
|
|
31
|
+
- Tipping over or collapsing on rooted rigs: add or extend `lockJoints`.
|
|
32
|
+
- Barely moving: rephrase with a clearer verb, raise `cfgScale` to 5, or rename bones to
|
|
33
|
+
human names (see `rigging-for-text-motion.md`).
|
|
34
|
+
- Mesh warping at a joint: a weighting problem in the rig, not the motion; fix the rig.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
id: skill/text-to-motion
|
|
2
|
+
kind: skill
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
summary: "Custom 2-second animation clips from text prompts on any of the user's own rigged models — humanoids, animals, creatures, cartoon plants, props."
|
|
5
|
+
use_when:
|
|
6
|
+
- a custom action the curated motion library lacks — nod, bow, shrug, wave with a specific arm, an emotional gesture
|
|
7
|
+
- animating a non-humanoid rig — a talking flower, animal, creature, turret or prop
|
|
8
|
+
- adding clips to an uploaded or custom-rigged GLB/FBX model
|
|
9
|
+
- '"make the flower nod" / "animate my creature from a text description"'
|
|
10
|
+
do_not_use_when:
|
|
11
|
+
- a Summer-rigged humanoid needs standard idle/walk/run/jump/attack clips — generate-motion (meshy-library)
|
|
12
|
+
- the model is not rigged yet — rig it first
|
|
13
|
+
- facial animation, finger detail or lip sync — facial-and-lipsync
|
|
14
|
+
facets:
|
|
15
|
+
lifecycle:
|
|
16
|
+
- build
|
|
17
|
+
domains:
|
|
18
|
+
- animation
|
|
19
|
+
- generate
|
|
20
|
+
- 3d
|
|
21
|
+
modalities:
|
|
22
|
+
- animation
|
|
23
|
+
compatibility:
|
|
24
|
+
engine: ">=4.6"
|
|
25
|
+
related:
|
|
26
|
+
tools:
|
|
27
|
+
- tool/generate-motion
|
|
28
|
+
- tool/check-job
|
|
29
|
+
- tool/import-asset-by-id
|
|
30
|
+
skills:
|
|
31
|
+
- skill/generate-motion
|
|
32
|
+
- skill/character-model
|
|
33
|
+
- skill/retarget
|
|
34
|
+
- skill/asset-strategy
|
|
35
|
+
source: official
|
|
36
|
+
license: MIT
|
|
37
|
+
status: preview
|
|
38
|
+
recommended: false
|
|
39
|
+
aliases:
|
|
40
|
+
- text-motion
|
|
41
|
+
- animate-from-text
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Rigging for text-to-motion
|
|
2
|
+
|
|
3
|
+
The motion model reads the skeleton's rest pose, hierarchy **and bone names**. Names carry
|
|
4
|
+
meaning: a bone called `LeftArm` borrows everything the model learned from human arms.
|
|
5
|
+
Rigs named like a human skeleton therefore animate far better than freeform names, even
|
|
6
|
+
on non-humans. Measured on cartoon flowers (2026-09-29): with plant names (`Stem1`,
|
|
7
|
+
`LeafL1`) most prompts barely moved; the same rig with human names nodded, bowed,
|
|
8
|
+
gestured and looked around on cue.
|
|
9
|
+
|
|
10
|
+
## Limits the service enforces
|
|
11
|
+
|
|
12
|
+
- One skinned armature driving the mesh; GLB or FBX; at most 100 MB.
|
|
13
|
+
- 5-70 bones total (helper, twist and finger bones count). Remove extras before submitting.
|
|
14
|
+
- Existing animations are ignored; the service adds its own reference clip.
|
|
15
|
+
- Facing is detected from a left/right limb pair (`RightUpLeg`/`LeftUpLeg`, else arms).
|
|
16
|
+
|
|
17
|
+
## Humanoids
|
|
18
|
+
|
|
19
|
+
Meshy, Mixamo-style (`mixamorig:*`) and Summer auto-rig skeletons work as-is.
|
|
20
|
+
Summer character packages (`character-model`) can use text-to-motion for extra custom
|
|
21
|
+
clips; keep the package's canonical idle/walk/run/jump from `generate-motion`.
|
|
22
|
+
|
|
23
|
+
## Non-humanoids: map the body plan to human bone names
|
|
24
|
+
|
|
25
|
+
| Body part | Bone names |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| Base / pelvis / root of a plant | `Hips` |
|
|
28
|
+
| Torso, stem, trunk, neck chain (bottom to top) | `Spine`, `Spine1`, `Spine2`, `Neck` |
|
|
29
|
+
| Head, bloom, face | `Head`, then `HeadTop_End` |
|
|
30
|
+
| Arms, leaves, fins, wings | `LeftShoulder` > `LeftArm` > `LeftForeArm` > `LeftHand` (and `Right*`) |
|
|
31
|
+
| Legs, roots, lower fins | `LeftUpLeg` > `LeftLeg` > `LeftFoot` (and `Right*`) |
|
|
32
|
+
| Petals, ears, antennae, tails | own names (`Petal0`, `Tail1`), parented to the nearest body bone |
|
|
33
|
+
|
|
34
|
+
## Talking-flower recipe (validated)
|
|
35
|
+
|
|
36
|
+
- Stem = `Hips` > `Spine` > `Spine1` > `Spine2` > `Neck` > `Head`; petals parented to `Head`.
|
|
37
|
+
- Leaf-arms on the upper-middle stem, parented to `Spine1`/`Spine2`, pointing sideways.
|
|
38
|
+
- **Keep the arms clear of the petals and face.** Hands that touch the lower petals get
|
|
39
|
+
their weights mixed and the mesh warps when the arm moves; arms lower on the stem
|
|
40
|
+
deform cleanly.
|
|
41
|
+
- Submit with `lockJoints: ["Hips","Spine"]` so the flower stays planted, and
|
|
42
|
+
`cfgScale: 5` for readable gestures.
|
|
43
|
+
|
|
44
|
+
## Rigging an unrigged mesh
|
|
45
|
+
|
|
46
|
+
- Humanoid: the Summer auto-rig (`character-model`, `summer_generate_3d` with
|
|
47
|
+
`options.rig: true`).
|
|
48
|
+
- Other body plans: rig in the user's own Blender (`fabricating-assets`) or offline
|
|
49
|
+
(`skintokens-auto-rigging`), using the human bone names above where the body plan allows
|
|
50
|
+
(stem as spine, leaves as arms).
|
|
51
|
+
|
|
52
|
+
Check the weights around every joint that will move before animating. A rig with bad
|
|
53
|
+
weights produces bad clips regardless of the motion; mesh warping at a joint is a rig
|
|
54
|
+
problem, not a motion problem.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tileable-texture
|
|
3
|
-
description:
|
|
3
|
+
description: "Generate a seamless tileable texture for walls, floors, or terrain — repeats cleanly on all four edges, wired as a StandardMaterial3D albedo."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: 2d-assets
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: trailer-shot
|
|
3
|
-
description:
|
|
3
|
+
description: "Generate marketing or trailer footage — slow-mo combat, establishing shots, hero beats, splash screens, pitch-deck B-roll — max punch in 5-10 seconds."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: video
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tune-performance
|
|
3
|
-
description:
|
|
3
|
+
description: "Profile a slow game via summer_get_diagnostics, identify rendering/physics/scripting hotspots, propose fixes with before/after metric expectations."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: performance
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ui-basics
|
|
3
|
-
description: "
|
|
3
|
+
description: "Build Summer Engine UI — HUDs, menus, health bars, dialogue boxes, Control trees — anchors, containers, responsive layout, theme vs inline styling."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: ui-and-ux
|
|
@@ -130,6 +130,15 @@ For UI that scales with window size:
|
|
|
130
130
|
|
|
131
131
|
For simple cases, CenterContainer + fixed-size children works. For complex layouts, a Theme resource or script may be needed.
|
|
132
132
|
|
|
133
|
+
## Text, fonts and symbols
|
|
134
|
+
|
|
135
|
+
The default font only has letters, digits and common punctuation. Anything else renders as an empty box with a hex code in it (for example a box reading `25 B2` for ▲, or `25 C0` for ◀), and on the web there is no system font to fall back to.
|
|
136
|
+
|
|
137
|
+
- Never put emoji or Unicode symbols in Label, Button or RichTextLabel text: arrows (▲ ▼ ◀ ▶ ← →), stars, hearts, check marks, music notes, keycap symbols. Write the words instead ("Up", "Next"), or show an icon.
|
|
138
|
+
- Draw icons as nodes: a TextureRect with a small texture, a Polygon2D triangle for arrows, or a `_draw()` shape. Key prompts are a rounded StyleBoxFlat panel with the key's letter in it.
|
|
139
|
+
- If the game really needs symbols or another script (Japanese, Arabic, Cyrillic), add a font file that contains them: import a TTF/OTF that covers the characters, set it as the theme's default font, and add it to the fallbacks of any other font you use.
|
|
140
|
+
- After adding text, take one screenshot and look for boxes with hex codes; fix any you find before moving on.
|
|
141
|
+
|
|
133
142
|
## Fallback (no MCP — edit `.tscn` directly)
|
|
134
143
|
|
|
135
144
|
If Summer MCP isn't connected, write the menu hierarchy by hand:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ui-graphics
|
|
3
|
-
description:
|
|
3
|
+
description: "Generate game-UI elements — icons, buttons, panels, frames, HUD widgets, badges — flat design, transparent background, wired via TextureRect/NinePatchRect."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: 2d-assets
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: use-widget-asset
|
|
3
|
-
description:
|
|
3
|
+
description: "Wire a widget slice from a create-asset-sheet pack (panel, button, slider, bar, toggle) into NinePatchRect, TextureProgressBar, or TextureRect via sliceMeta."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: 2d-assets
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: using-summer
|
|
3
|
-
description:
|
|
3
|
+
description: "Session bootstrap for Summer projects — establishes how to find and use Summer skills and the summer-engine MCP before any response."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Codex, Windsurf, Gemini, OpenCode, Factory, Copilot]
|
|
6
6
|
category: _meta
|
|
@@ -111,7 +111,7 @@ When multiple Summer skills could apply, run them in this order:
|
|
|
111
111
|
|
|
112
112
|
1. **Process skills first** — `brainstorm-game`, `debug`, `play`. These determine HOW to approach the task.
|
|
113
113
|
2. **Discipline skills second** — `gdscript-patterns`, `scene-composition`, `art-direction`, `audio-direction`. These shape the content.
|
|
114
|
-
3. **Build skills third** — `fps-controller`, `design-mechanic`, `design-level`, `
|
|
114
|
+
3. **Build skills third** — `fps-controller`, `design-mechanic`, `design-level`, `multiplayer`. These produce the artifacts.
|
|
115
115
|
|
|
116
116
|
> "I want to make a game" → `brainstorm-game` first, then build skills.
|
|
117
117
|
> "Fix this crash" → `debug` first, then domain skills.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
id: skill/using-summer
|
|
2
2
|
kind: skill
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.5
|
|
4
4
|
summary: Session bootstrap for Summer projects — establishes how to find and use Summer skills and the summer-engine MCP before any response.
|
|
5
5
|
use_when:
|
|
6
6
|
- starting any conversation in a Summer Engine project
|
|
@@ -25,7 +25,7 @@ related:
|
|
|
25
25
|
- skill/debug
|
|
26
26
|
- skill/design-mechanic
|
|
27
27
|
- skill/design-level
|
|
28
|
-
- skill/
|
|
28
|
+
- skill/multiplayer
|
|
29
29
|
- skill/art-direction
|
|
30
30
|
- skill/brainstorm-game
|
|
31
31
|
- skill/play
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vehicle-model
|
|
3
|
-
description:
|
|
3
|
+
description: "Generate a hard-surface vehicle — car, spaceship, mech, boat, tank — static mesh with optional detail-texture pass, wired as Vehicle3D or MeshInstance3D."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
6
|
category: 3d-assets
|