summer-engine 1.5.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/{marketplace.json → .claude-plugin/marketplace.json} +3 -3
  2. package/.claude-plugin/plugin.json +52 -11
  3. package/.codex-plugin/plugin.json +69 -8
  4. package/.cursor-plugin/plugin.json +53 -12
  5. package/.factory-plugin/plugin.json +20 -0
  6. package/.opencode/INSTALL.md +75 -0
  7. package/.opencode/plugins/summer.js +9 -6
  8. package/AGENTS.md +51 -0
  9. package/CHANGELOG.md +31 -1
  10. package/CLAUDE.md +5 -0
  11. package/GEMINI.md +56 -0
  12. package/README.md +409 -80
  13. package/_persona/summer/SKILL.md +113 -0
  14. package/dist/bin/summer.js +0 -0
  15. package/dist/commands/assets.d.ts +2 -0
  16. package/dist/commands/assets.js +189 -0
  17. package/dist/commands/create.js +55 -17
  18. package/dist/commands/debug.d.ts +2 -0
  19. package/dist/commands/debug.js +127 -0
  20. package/dist/commands/install.js +2 -2
  21. package/dist/commands/list.js +24 -5
  22. package/dist/commands/project.d.ts +2 -0
  23. package/dist/commands/project.js +170 -0
  24. package/dist/commands/scene.d.ts +2 -0
  25. package/dist/commands/scene.js +290 -0
  26. package/dist/lib/banner.js +2 -2
  27. package/dist/lib/log-filters.d.ts +53 -0
  28. package/dist/lib/log-filters.js +130 -0
  29. package/dist/lib/plugin-manifests.test.d.ts +1 -0
  30. package/dist/lib/plugin-manifests.test.js +134 -0
  31. package/dist/lib/remote-templates.d.ts +25 -0
  32. package/dist/lib/remote-templates.js +86 -0
  33. package/dist/lib/skills-registry.d.ts +283 -3
  34. package/dist/lib/skills-registry.js +522 -2
  35. package/dist/lib/telemetry.d.ts +13 -0
  36. package/dist/lib/telemetry.js +63 -0
  37. package/dist/lib/with-engine.d.ts +14 -0
  38. package/dist/lib/with-engine.js +109 -0
  39. package/dist/mcp/tools/asset-tools.js +12 -13
  40. package/dist/mcp/tools/debug-tools.js +32 -9
  41. package/dist/mcp/tools/generate-tools.js +101 -0
  42. package/dist/mcp/tools/with-engine.js +4 -0
  43. package/gemini-extension.json +2 -2
  44. package/hooks/pre-commit-doctor.sh +0 -0
  45. package/hooks/run-hook.cmd +0 -0
  46. package/hooks/session-start.sh +0 -0
  47. package/package.json +11 -5
  48. package/skills/2d-assets/character-portrait/SKILL.md +196 -0
  49. package/skills/2d-assets/concept-art/SKILL.md +152 -0
  50. package/skills/2d-assets/pixel-art/SKILL.md +180 -0
  51. package/skills/2d-assets/skybox-panorama/SKILL.md +207 -0
  52. package/skills/2d-assets/sprite-sheet/SKILL.md +239 -0
  53. package/skills/2d-assets/tileable-texture/SKILL.md +205 -0
  54. package/skills/2d-assets/ui-graphics/SKILL.md +210 -0
  55. package/skills/3d-assets/character-model/SKILL.md +225 -0
  56. package/skills/3d-assets/environment-kit/SKILL.md +164 -0
  57. package/skills/3d-assets/organic-model/SKILL.md +192 -0
  58. package/skills/3d-assets/prop-model/SKILL.md +133 -0
  59. package/skills/3d-assets/vehicle-model/SKILL.md +202 -0
  60. package/skills/README.md +1 -1
  61. package/skills/_meta/skill-create/SKILL.md +1 -1
  62. package/skills/_meta/skill-improve/SKILL.md +1 -1
  63. package/skills/_meta/skill-test/SKILL.md +1 -1
  64. package/skills/_meta/using-summer/SKILL.md +130 -0
  65. package/skills/ai-and-npcs/design-npc/SKILL.md +3 -1
  66. package/skills/animation/animation-tree/SKILL.md +260 -0
  67. package/skills/animation/facial-and-lipsync/SKILL.md +282 -0
  68. package/skills/animation/generate-motion/SKILL.md +129 -0
  69. package/skills/animation/procedural-animation/SKILL.md +234 -0
  70. package/skills/animation/retarget/SKILL.md +172 -0
  71. package/skills/asset-pipeline/asset-strategy/SKILL.md +102 -212
  72. package/skills/audio/adaptive-music/SKILL.md +326 -0
  73. package/skills/audio/ambient-bed/SKILL.md +278 -0
  74. package/skills/audio/music-track/SKILL.md +268 -0
  75. package/skills/audio/sound-effect/SKILL.md +237 -0
  76. package/skills/audio/voice-line/SKILL.md +253 -0
  77. package/skills/catalog.yaml +266 -5
  78. package/skills/character-controllers/fps-controller/SKILL.md +1 -1
  79. package/skills/debugging/debug/SKILL.md +102 -82
  80. package/skills/rendering-and-lighting/3d-lighting/SKILL.md +1 -1
  81. package/skills/scene-and-project/browse-templates/SKILL.md +105 -0
  82. package/skills/scene-and-project/make-game/SKILL.md +159 -346
  83. package/skills/scene-and-project/new-project/SKILL.md +106 -0
  84. package/skills/scene-and-project/scene-composition/SKILL.md +1 -1
  85. package/skills/scripting-patterns/gdscript-patterns/SKILL.md +1 -1
  86. package/skills/ui-and-ux/ui-basics/SKILL.md +1 -1
  87. package/skills/video/animated-loop/SKILL.md +200 -0
  88. package/skills/video/cinematic-cutscene/SKILL.md +204 -0
  89. package/skills/video/trailer-shot/SKILL.md +203 -0
  90. package/skills/visual-effects/_building-blocks/additive-billboard-particles.md +28 -0
  91. package/skills/visual-effects/_building-blocks/noise-3d-fbm.gdshaderinc +45 -0
  92. package/skills/visual-effects/_building-blocks/trauma-shake-snippet.md +51 -0
  93. package/skills/visual-effects/{vfx → game-feel}/SKILL.md +1 -1
  94. package/skills/visual-effects/recipes/dissolve/SKILL.md +349 -0
  95. package/skills/visual-effects/recipes/fire/SKILL.md +387 -0
  96. package/skills/visual-effects/recipes/hit-spark/SKILL.md +330 -0
  97. package/skills/visual-effects/recipes/lightning/SKILL.md +372 -0
  98. package/skills/visual-effects/recipes/magic-glow/SKILL.md +377 -0
  99. package/skills/visual-effects/recipes/muzzle-flash/SKILL.md +326 -0
  100. package/skills/visual-effects/recipes/smoke/SKILL.md +381 -0
  101. package/skills/visual-effects/recipes/water-ripple/SKILL.md +340 -0
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: generate-motion
3
+ description: Use when the user needs an animation clip on a rigged character — idle/walk/run/attack from the curated Meshy library. Picks the right curated motion, attaches the resulting clip to an AnimationPlayer. Trigger on "animation", "animate", "idle", "walk", "run", "attack animation", "motion", "mocap", "dance", "death animation".
4
+ license: MIT
5
+ compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
+ category: animation
7
+ user-invocable: false
8
+ allowed-tools: Read Grep summer_search_assets summer_generate_motion summer_inspect_resource summer_get_scene_tree summer_add_node summer_set_prop summer_set_resource_property summer_save_scene
9
+ paths: ["**/*.tscn", "**/*.tres", "**/*.gd"]
10
+ ---
11
+
12
+ # Generate Motion — Curated Meshy Library
13
+
14
+ Picks a clip from a **curated mocap library** by name (`idle`, `walk`, `run`, `attack_sword`, ~70 standard names) and wires it onto a Meshy-rigged humanoid. Fast (~30s) and cheap (~$0.10) and looks great because it's real mocap.
15
+
16
+ The target must be a **Meshy-rigged humanoid** — a `rigAssetId` from a prior `summer_generate_3d({ kind: "image-to-3d", imageUrl: "...", options: { rig: true } })` call. The result job includes `rigAssetId`. If the user points at a non-rigged mesh, stop and route to `summer:asset-pipeline/asset-strategy` (or directly call `summer_generate_3d` with `options.rig: true`) before generating motion.
17
+
18
+ > **Custom prompt-driven motion** (e.g. "drops to one knee, draws bow") is on the roadmap but not shipped yet. For one-off signature moves not on the curated list, fall back to hand-authoring in the Godot editor or importing from Mixamo. See the Edge cases section.
19
+
20
+ ## When to use this skill
21
+
22
+ - "Add a walk animation to the goblin."
23
+ - "I need an idle, a run, and an attack on this character."
24
+ - "Death animation for the enemy when HP hits zero."
25
+ - The user has a rigged character and zero animations on it.
26
+
27
+ ## When NOT to use this skill
28
+
29
+ - The user wants to apply an *existing* animation to a *new* model — use `summer:animation/retarget` instead. Don't regenerate.
30
+ - The user wants state-machine wiring (idle → walk → run blend) — generate the clips here, then hand off to `summer:animation/animation-tree`.
31
+ - The user wants facial / lipsync animation — that's `summer:animation/facial-and-lipsync`.
32
+ - The mesh isn't rigged. Rig first; never call `summer_generate_motion` on a static `.glb`.
33
+ - The user wants procedural look-at, IK, foot placement — that's `summer:animation/procedural-animation`.
34
+ - The user described a **custom signature move** that isn't on the curated list. Today, route to the manual-authoring fallback below.
35
+
36
+ ## Steps
37
+
38
+ ### 1. Verify the target is a rigged humanoid
39
+
40
+ ```
41
+ summer_search_assets(query="<character name>", kind="model")
42
+ ```
43
+
44
+ The result must include `rigAssetId: <id>` on a Meshy rig. If it shows `rigAssetId: null`, the model isn't rigged — stop, propose `summer_generate_3d({ kind: "image-to-3d", imageUrl: "...", options: { rig: true } })` first (the result includes `rigAssetId`), or route to `summer:asset-pipeline/asset-strategy`.
45
+
46
+ ### 2. Confirm with the user before spending
47
+
48
+ > I'm about to generate a "run" animation on `goblin_rigged` via meshy-library — about 30s, ~$0.10. OK?
49
+
50
+ ### 3. Call the tool
51
+
52
+ ```
53
+ summer_generate_motion(
54
+ rigAssetId: "<id>",
55
+ backend: "meshy-library", // only option today
56
+ motionName: "run" // exact name from the curated list — see Reference card
57
+ )
58
+ ```
59
+
60
+ Returns `{ animationAssetId, durationSeconds, previewUrl }`.
61
+
62
+ ### 4. Attach to the character's AnimationPlayer
63
+
64
+ ```
65
+ summer_inspect_node("./World/Goblin") // confirm it has an AnimationPlayer child
66
+ summer_add_node(parent="./World/Goblin", type="AnimationPlayer", name="AnimationPlayer") // only if missing
67
+ summer_set_resource_property(
68
+ nodePath="./World/Goblin/AnimationPlayer",
69
+ resourceProperty="libraries/default",
70
+ subProperty="<motion_name>",
71
+ value="<animationAssetId>"
72
+ )
73
+ summer_save_scene
74
+ ```
75
+
76
+ If the character will use multiple clips, leave the AnimationPlayer in place — every subsequent generation appends to the same library. State-machine wiring belongs to `summer:animation/animation-tree`, not here.
77
+
78
+ ## Confirmation gates
79
+
80
+ - **Before generation:** state the motion name and est. cost (~$0.10). Wait for OK.
81
+ - **Before attaching:** state which AnimationPlayer and which library slot. Wait for OK.
82
+ - **After generation:** if the user hasn't seen the preview, link `previewUrl` and ask "land or regenerate?" before wiring it into the scene.
83
+
84
+ ## Reference card
85
+
86
+ ### Curated motion library — top 30 names (Meshy, exact strings)
87
+
88
+ `idle`, `idle_alert`, `idle_combat`, `walk`, `walk_strafe_left`, `walk_strafe_right`, `walk_back`, `run`, `run_strafe_left`, `run_strafe_right`, `sprint`, `jump`, `jump_loop`, `jump_land`, `crouch_idle`, `crouch_walk`, `attack_sword`, `attack_punch`, `attack_kick`, `attack_bow`, `attack_cast`, `block`, `dodge_left`, `dodge_right`, `hit_react`, `death`, `death_back`, `wave`, `dance`, `sit_idle`.
89
+
90
+ The full list is ~70 names. If the user asks for something not on the top-30, try the closest curated name first; if nothing fits, route to the manual-authoring fallback.
91
+
92
+ ### Pitfalls
93
+
94
+ - **`motionName` typos silently match nothing.** `"run_fast"` is not on the list — the call returns an error. Always check the curated list first. Use exact strings from the list above.
95
+ - **Locomotion clips have a forward bias.** Meshy's `run` translates the root forward by ~5m. If you're driving root motion in code, set `root_motion_track` correctly or strip the translation in an AnimationPlayer Edit. See the Godot 4.5 root motion docs.
96
+ - **Rig pose mismatch.** If your rig was rigged with a non-T-pose reference image, the limbs may bend wrong. Re-rig from a T-pose mannequin (see `summer:asset-pipeline/asset-strategy`) before re-generating.
97
+ - **Rig still preparing.** New rigs need ~3 minutes after the rig job completes before the animation library is ready. The MCP route returns 425 "animations_preparing" if you call too early. Wait and retry.
98
+
99
+ ## Anti-patterns
100
+
101
+ - Calling `summer_generate_motion` on a `.glb` that wasn't rigged — wastes a generation; the API errors but only after 30s.
102
+ - Generating the same clip twice because you forgot to save the `animationAssetId` from the first call. Search the asset library first: `summer_search_assets(query: "goblin run", kind: "animation")`.
103
+ - Wiring clips into an AnimationTree inside this skill. That's the next skill's job. Generate, attach, hand off.
104
+ - Asking the model to invent a `motionName` that isn't on the list. Quote from the list verbatim, or fall back to manual authoring.
105
+
106
+ ## Edge cases
107
+
108
+ - **Custom signature move** (e.g. "drops to one knee, draws bow"). The custom prompt-driven backend is on the roadmap but not shipped today. Workarounds: (a) hand-author the clip in the Godot editor's animation panel; (b) record/buy from Mixamo and import as `AnimationLibrary`; (c) compose two curated clips in an `AnimationTree`'s `OneShot` blend.
109
+ - **Quadruped rig.** Meshy library is humanoid-only. For quadrupeds, hand-author or import a Mixamo-style external library (out of scope for this skill).
110
+ - **Character is < 1m tall (child / dwarf).** Library clips assume a ~1.8m humanoid. Apply the clip; the proportions retarget but stride length looks long. Either accept it or tune `playback_speed` on the AnimationPlayer track.
111
+ - **Character has wings / tail.** The library ignores the extra bones — they sag. Hand-author additive overlays for the extra bones, or accept the visual hit.
112
+
113
+ ## Fallback (no MCP)
114
+
115
+ The user can upload to Meshy directly at meshy.ai, generate via the dashboard, download `.glb`, and import as an `AnimationLibrary` in the Godot editor. Slower, but identical output.
116
+
117
+ ## Handoff
118
+
119
+ - After generating locomotion clips, suggest `summer:animation/animation-tree` to wire idle → walk → run.
120
+ - After generating a one-shot (death, hit-react), suggest `summer:ai-and-npcs/design-npc` to fire it from the behavior state machine.
121
+ - For first-person hand animations on a player, use this skill on a *hands-only rig* and then `summer:character-controllers/fps-controller` for the wiring.
122
+ - If the user wants to apply these clips to a second character, hand off to `summer:animation/retarget`.
123
+
124
+ ## See also
125
+
126
+ - `_shared/mcp-tools-reference.md` — `summer_generate_motion` parameter schema, error codes.
127
+ - `summer:asset-pipeline/asset-strategy` — how to get a Meshy-rigged character in the first place.
128
+ - `summer:animation/animation-tree` — wire the generated clips into a state machine.
129
+ - `summer:animation/retarget` — re-use one library across many characters without regenerating.
@@ -0,0 +1,234 @@
1
+ ---
2
+ name: procedural-animation
3
+ description: Use when the user needs runtime-driven bone modification on top of clips — head look-at, foot IK on uneven ground, hand-grabs-prop, additive lean, hit-direction recoil. Code-and-modifier patterns, not generation. Trigger on "look at", "IK", "foot placement", "foot IK", "lean", "additive layer", "feet floating", "hand penetration", "head tracks player", "ragdoll".
4
+ license: MIT
5
+ compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
+ category: animation
7
+ user-invocable: false
8
+ allowed-tools: Read Grep Edit Write summer_get_scene_tree summer_inspect_node summer_inspect_resource summer_add_node summer_set_prop summer_set_resource_property summer_save_scene summer_get_script_errors
9
+ paths: ["**/*.gd", "**/*.tscn", "**/*.tres"]
10
+ ---
11
+
12
+ # Procedural Animation — Bones Driven by Code
13
+
14
+ Generated clips give you 80% of a character. The remaining 20% — the eye contact when an NPC speaks, feet that plant on slopes, hands that wrap a sword grip, the lean into a sprint, the recoil from a hit on the left shoulder — is procedural. In Godot 4.5 this is done via the `SkeletonModifier3D` family attached to the `Skeleton3D`, plus tween-driven additive blend layers on the `AnimationTree`. None of it is generative; this skill is a recipe set.
15
+
16
+ Honest limit: Godot 4.5's IK is good enough for look-at, foot-snap, and simple two-bone arm/leg chains. It is NOT good enough for full-body IK with weight redistribution (a la UE5 Control Rig). For combat-grappling or contact-heavy interactions, hand-author the contact frame and accept some clipping.
17
+
18
+ ## When to use this skill
19
+
20
+ - Feet clip into / float over uneven terrain.
21
+ - NPC head doesn't track the player during conversation — feels dead-eyed.
22
+ - Character's hand doesn't actually hold the sword — pen-through.
23
+ - Body doesn't lean into turns / aiming.
24
+ - Hit reactions need to come from the hit *direction* (recoil left when struck left), not just one canned animation.
25
+ - Ragdoll on death.
26
+
27
+ ## When NOT to use this skill
28
+
29
+ - The clip already covers it. Don't IK what mocap already nailed — adds CPU cost and rounding error.
30
+ - The character is far from the camera (LOD2+). Procedural cost outpaces visual benefit. Disable modifiers past 15m.
31
+ - You need facial animation. That's `summer:animation/facial-and-lipsync`.
32
+ - You haven't generated base clips yet. Skeleton modifiers compose ON TOP of clips; without a base pose they'll stack on T-pose and look wrong.
33
+
34
+ ## The three patterns
35
+
36
+ Almost every procedural request maps to one of these three. Pick the right one before writing code.
37
+
38
+ ### Pattern A — SkeletonModifier3D (post-clip bone overrides)
39
+
40
+ Attached as a child of `Skeleton3D`. Runs after the AnimationTree writes the pose, modifies specific bones in-place. Includes `LookAtModifier3D`, `SkeletonIK3D` (legacy, still supported), and the new (4.4+) `LookAtModifier3D` chain. Cheap, deterministic, no animation graph dependency.
41
+
42
+ ### Pattern B — Additive AnimationNodeAdd2 layer in the tree
43
+
44
+ A clip recorded as a *delta from base pose* (e.g., a "lean left" clip that's 0 at center, fully leaned at +1) added on top of locomotion. Driven by writing `parameters/Add/blend_amount` from script. Use for stylistic overlays — turning lean, aiming offset, breathing.
45
+
46
+ ### Pattern C — PhysicalBoneSimulator3D (ragdoll)
47
+
48
+ The skeleton hands off to physics on death. Bones become `PhysicalBone3D` rigid bodies that fall under gravity and collide with the world. One-way: once ragdoll fires, you can't easily blend back to clip-driven without snapping.
49
+
50
+ ## Pattern A recipes
51
+
52
+ ### A1 — Head look-at the player
53
+
54
+ The bread-and-butter NPC liveliness fix. Three lines of scene + one script function.
55
+
56
+ ```
57
+ summer_inspect_node "./World/NPC/Skeleton3D" # confirm bone names
58
+ summer_add_node parent="./World/NPC/Skeleton3D" type="LookAtModifier3D" name="HeadLookAt"
59
+ summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="bone_name" value="Head"
60
+ summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="forward_axis" value=2 # +Z forward (Meshy default)
61
+ summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="primary_rotation_axis" value=1 # Y-up
62
+ summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="use_secondary_rotation" value=true
63
+ summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="secondary_rotation_axis" value=0
64
+ summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="symmetry_limit" value=1.4 # ~80°, prevents the Exorcist
65
+ ```
66
+
67
+ Drive the target each frame:
68
+
69
+ ```gdscript
70
+ @onready var head_look: LookAtModifier3D = $Skeleton3D/HeadLookAt
71
+
72
+ func _process(_delta: float) -> void:
73
+ var player := get_tree().get_first_node_in_group("player")
74
+ if player == null:
75
+ head_look.influence = 0.0
76
+ return
77
+ var to_player := player.global_position - global_position
78
+ var dist := to_player.length()
79
+ # Disable look-at past 8m — feels uncanny at long range.
80
+ head_look.target_node = player.get_path() if dist < 8.0 else NodePath("")
81
+ head_look.influence = clamp(1.0 - (dist - 6.0) / 2.0, 0.0, 1.0) # fade out 6→8m
82
+ ```
83
+
84
+ The `symmetry_limit` is the production trick — without it, the head can rotate 180° and the model looks possessed. ~80° matches a human's neck-only range; for a "whole-body turn" use it with the spine chain (next recipe).
85
+
86
+ ### A2 — Spine + head chain (look-at with body turn)
87
+
88
+ Multiple `LookAtModifier3D` nodes on the same chain — one for `Spine1` (limit 0.4 rad), one for `Spine2` (limit 0.4 rad), one for `Head` (limit 1.0 rad). Total reach: ~110°, distributed naturally. Without the spine contribution, big angles look like the head detaches.
89
+
90
+ ### A3 — Foot IK (slopes & uneven terrain)
91
+
92
+ The clip has the foot at Y=0; on a slope the ground is at Y=0.15. Without IK, foot floats. Use `SkeletonIK3D` (Godot 4.5 legacy IK still works for two-bone chains; the new chain modifier is preferred for production):
93
+
94
+ ```gdscript
95
+ @onready var skel: Skeleton3D = $Skeleton3D
96
+ @onready var ik_left: SkeletonIK3D = $Skeleton3D/IKLeft
97
+ @onready var ik_right: SkeletonIK3D = $Skeleton3D/IKRight
98
+ @onready var ray: RayCast3D = $FootRay # cast straight down
99
+
100
+ func _physics_process(_delta: float) -> void:
101
+ _solve_foot(ik_left, "LeftFoot")
102
+ _solve_foot(ik_right, "RightFoot")
103
+
104
+ func _solve_foot(ik: SkeletonIK3D, bone_name: String) -> void:
105
+ var bone_idx := skel.find_bone(bone_name)
106
+ var foot_world := skel.get_bone_global_pose(bone_idx).origin
107
+ ray.global_position = foot_world + Vector3.UP * 0.5
108
+ ray.target_position = Vector3.DOWN * 1.0
109
+ ray.force_raycast_update()
110
+ if ray.is_colliding():
111
+ var ground := ray.get_collision_point()
112
+ if ground.y > foot_world.y - 0.05: # only lift, never drop into the ground
113
+ ik.target_node = NodePath("../IKTarget" + bone_name)
114
+ (get_node("Skeleton3D/IKTarget" + bone_name) as Node3D).global_position = ground + Vector3.UP * 0.05
115
+ ik.start()
116
+ else:
117
+ ik.stop()
118
+ else:
119
+ ik.stop()
120
+ ```
121
+
122
+ The 0.5m up-offset on the ray prevents self-occlusion. The "only lift, never drop" rule is the production fix — letting IK push feet into the ground breaks knee bends.
123
+
124
+ Limits: this works for stairs and gentle slopes. On 45°+ slopes, use a pelvis lowering pass first (drop the root by `min(left_offset, right_offset)`) so the body squats and the legs don't over-extend.
125
+
126
+ ### A4 — Hand grab on prop (sword grip, rifle stock)
127
+
128
+ `SkeletonIK3D` on the arm chain (Shoulder → UpperArm → LowerArm → Hand), with `target_node` set to a Marker3D parented to the prop. The clip drives the body; IK pins the hand to the grip. For a rifle held two-handed, do the right hand from clip and IK the left hand to a foregrip Marker3D — locks them together regardless of recoil.
129
+
130
+ ## Pattern B — Additive layer
131
+
132
+ In the AnimationTree, wrap Locomotion in an `AnimationNodeAdd2`:
133
+
134
+ ```
135
+ [parent: AnimationNodeStateMachine.Locomotion]
136
+ AnimationNodeAdd2
137
+ in: BlendSpace1D (idle/walk/run) # the base
138
+ add: AnimationNodeAnimation # an additive clip — must be authored as delta
139
+ ```
140
+
141
+ Drive `parameters/Locomotion/Add/blend_amount` (0..1) from script. Use cases: turn-lean (lean amount = clamp(turn_rate, -1, 1)), aim offset (lean while aiming up/down), breathing-while-idle. The "lean" clip must be exported with `track_type = additive` from Blender, or you'll see a 2x-pose stacked on the base.
142
+
143
+ ## Pattern C — Ragdoll on death
144
+
145
+ ```gdscript
146
+ @onready var sim: PhysicalBoneSimulator3D = $Skeleton3D/PhysicalBoneSimulator
147
+
148
+ func die(impulse_world: Vector3) -> void:
149
+ $AnimationTree.active = false
150
+ sim.physical_bones_start_simulation()
151
+ var pelvis := $Skeleton3D/PhysicalBoneSimulator/PelvisPhysicalBone as PhysicalBone3D
152
+ pelvis.apply_central_impulse(impulse_world * 4.0)
153
+ ```
154
+
155
+ You need PhysicalBone3D children matching every major bone (set up once via the Skeleton3D context menu → "Create Physical Skeleton"). The impulse parameter sells the death — without directional impulse the body just collapses straight down.
156
+
157
+ ## Confirmation gates
158
+
159
+ - **Before adding modifiers:** state which bones, which axes. Bone-name typos are a top failure.
160
+ - **Before driving from script:** confirm influence will fade out at distance and the target node is correct.
161
+ - **Before enabling ragdoll:** confirm physical bones exist; without them, simulation is a no-op.
162
+
163
+ ## Reference card
164
+
165
+ ### Bone names (Meshy humanoid skeleton, exact strings)
166
+
167
+ `Hips`, `Spine`, `Spine1`, `Spine2`, `Neck`, `Head`, `LeftShoulder`, `LeftArm`, `LeftForeArm`, `LeftHand`, `RightShoulder`, `RightArm`, `RightForeArm`, `RightHand`, `LeftUpLeg`, `LeftLeg`, `LeftFoot`, `LeftToeBase`, `RightUpLeg`, `RightLeg`, `RightFoot`, `RightToeBase`. (Meshy uses Mixamo-compatible naming with no `mixamorig:` prefix.)
168
+
169
+ ### Axis conventions
170
+
171
+ | Setting | Value (Meshy default) |
172
+ |---|---|
173
+ | Forward axis (head/spine) | Z+ |
174
+ | Up axis | Y+ |
175
+ | Right axis | X+ |
176
+ | Foot down | Y- |
177
+
178
+ ### Influence fade-out distances (tuned defaults)
179
+
180
+ | Modifier | Disable past |
181
+ |---|---|
182
+ | Head look-at | 8m |
183
+ | Foot IK | 15m (snap-to-ground only matters when player can see) |
184
+ | Hand-on-prop IK | always on (cheap, breaks if disabled) |
185
+ | Additive lean | always on |
186
+ | Ragdoll | one-shot, never disabled |
187
+
188
+ ### Pitfalls
189
+
190
+ - **LookAt rotates wildly past the symmetry_limit.** You set the limit too high. ~80° (1.4 rad) for a head-only modifier; ~25° (0.4 rad) for a single spine bone.
191
+ - **IK pops on the first frame.** Solver hasn't been initialized. Call `ik.start()` after the AnimationTree's first tick, not in `_ready()` — the bone pose is identity until the tree runs.
192
+ - **Foot IK pushes the body up on stairs but the camera doesn't follow.** Camera is parented to the root, not the head. Either parent the camera to a chest bone via `BoneAttachment3D`, or accept that the camera doesn't bob with foot IK.
193
+ - **Additive layer doubles the clip.** The "additive" clip wasn't authored as a delta. Re-export from Blender with `Pose Mode → bake additive`.
194
+ - **Ragdoll just collapses, no spread.** Missing per-bone impulse + missing collision shapes on hands/feet PhysicalBone3D children. Auto-generate via Skeleton3D inspector → "Create Physical Skeleton" with the "Add collisions" option.
195
+ - **Modifiers run before the AnimationTree, not after.** Modifier order is set by tree-position in the scene. SkeletonModifier3D nodes must be CHILDREN of Skeleton3D and appear AFTER any nodes that drive the pose. AnimationTree itself doesn't sit under Skeleton3D — it sits at the character root and writes into Skeleton3D's pose every frame.
196
+ - **Look-at influence flickers at fade boundary.** Use `lerp(current_influence, target, 5 * delta)` instead of an instant assignment. Avoids the sub-pixel oscillation when the player walks the threshold.
197
+
198
+ ### Performance budget
199
+
200
+ - Each `LookAtModifier3D`: ~5 µs/frame. Cheap; have many.
201
+ - Each `SkeletonIK3D` two-bone solve: ~30 µs/frame. ~30 active solves per frame on mid-range desktop is fine; budget more conservatively on Steam Deck.
202
+ - Ragdoll with full physical skeleton: ~200 µs/frame *while simulating*. Cap concurrent ragdolls at 5–8 before culling oldest.
203
+
204
+ ## Anti-patterns
205
+
206
+ - Writing `skel.set_bone_pose_position(...)` in `_process`. Bypasses the AnimationTree, fights it next frame, results in jitter. Use modifiers instead — they integrate with the pipeline.
207
+ - Putting IK targets in worldspace and forgetting they don't follow the character. Parent IK targets under the character root or bone — IK target is in the modifier's local space.
208
+ - Procedural look-at without a fade-out at distance. Distant NPCs all snap to player every frame, looks like a hivemind.
209
+ - Foot IK on flying / floating characters. Disable when `is_on_floor() == false`.
210
+
211
+ ## Edge cases
212
+
213
+ - **Character is mounted (riding a horse).** Disable foot IK on the rider; ride animation already sells the contact. Enable upper-body additive sway driven by horse acceleration.
214
+ - **First-person hands.** Same modifier set, but only the arm chain is visible — disable head/spine modifiers, keep hand-on-prop IK.
215
+ - **Character is a quadruped.** All four legs need foot IK. The bone names are different (`FrontLeftLeg`, `BackRightLeg`, etc.); inspect first.
216
+ - **Network-synced ragdoll.** Don't simulate on every client. Simulate on the host, send bone transforms via `MultiplayerSynchronizer`, blend on receivers. Out of scope; see `summer:multiplayer-and-networking`.
217
+
218
+ ## Fallback (no MCP)
219
+
220
+ Add modifiers in the Godot editor under Skeleton3D, set bone names from the inspector dropdown (Godot autocompletes from the rig). Hand-write the GDScript driving them. Foot raycasts can be set up visually with a RayCast3D child.
221
+
222
+ ## Handoff
223
+
224
+ - For the AnimationTree these procedural layers compose with, `summer:animation/animation-tree`.
225
+ - For the source clips that procedural overlays modify, `summer:animation/generate-motion`.
226
+ - For face / lipsync (a different modifier family — BlendShapes, not bones), `summer:animation/facial-and-lipsync`.
227
+ - For NPC behavior triggering ragdoll on death, `summer:ai-and-npcs/design-npc`.
228
+ - For first-person aim sway / ADS, `summer:character-controllers/fps-controller`.
229
+
230
+ ## See also
231
+
232
+ - `_shared/gd-style.md` — typed GDScript conventions in the snippets.
233
+ - `_shared/mcp-tools-reference.md` — `summer_set_prop` enum-int conventions for axis settings.
234
+ - Godot 4.5 docs: `SkeletonModifier3D`, `LookAtModifier3D`, `SkeletonIK3D`, `PhysicalBoneSimulator3D`.
@@ -0,0 +1,172 @@
1
+ ---
2
+ name: retarget
3
+ description: Use when the user wants to apply existing animation clips from one rigged character to a different rigged character — same library, multiple models, no regeneration. Trigger on "retarget", "reuse animation", "apply to other character", "same animations on different model", "share animation library".
4
+ license: MIT
5
+ compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
+ category: animation
7
+ user-invocable: false
8
+ allowed-tools: Read Grep summer_search_assets summer_inspect_resource summer_retarget_motion summer_get_scene_tree summer_set_resource_property summer_save_scene
9
+ paths: ["**/*.tscn", "**/*.tres"]
10
+ ---
11
+
12
+ # Retarget Motion — One Library, Many Characters
13
+
14
+ Generating a "run" clip costs ~$0.10 and 30s. If you have ten enemies, regenerating ten runs is ten generations of wasted money and clock time when one Meshy retarget call would cost ~$0.05 and take ~10s. Retarget is the right answer the moment a project has more than one rigged humanoid character.
15
+
16
+ The Meshy retarget pipeline takes a source `animationAssetId` and a target `rigAssetId`, both of which must be **Meshy-rigged humanoids**. It re-projects the animation onto the target's bone hierarchy, preserves timing and root motion, and emits a new `animationAssetId` against the target rig. The source clip is unchanged.
17
+
18
+ ## When to use this skill
19
+
20
+ - "I bought (or generated) one animation library — apply all clips to my five enemies."
21
+ - "Goblin and orc have the same combat moves — share the library."
22
+ - "I have 30 NPCs with the same idle / walk / talk loop."
23
+ - The user generated motion on character A and now needs it on character B.
24
+
25
+ ## When NOT to use this skill
26
+
27
+ - Source and target are not both Meshy-rigged humanoids — retarget will fail. Route to `summer:animation/generate-motion` to regenerate, or to `summer:asset-pipeline/asset-strategy` to re-rig.
28
+ - Target is a quadruped or non-humanoid (wings-only, mech, blob). Meshy retarget is humanoid-skeleton-locked. Hand-author or regenerate.
29
+ - The user wants ONE new clip on ONE character — just call `summer:animation/generate-motion`. Retarget is for fan-out.
30
+ - The user wants to retime, edit, or layer the animation — that's `summer:animation/animation-tree` and the `summer:animation/procedural-animation` additive layers.
31
+
32
+ ## The compatibility check (do this BEFORE calling retarget)
33
+
34
+ The dominant failure mode is retargeting between rigs that look humanoid but have different bone counts, names, or hierarchies. Meshy auto-rigs use a fixed 52-bone humanoid skeleton — every Meshy rig is interchangeable. Mixamo / VRoid / hand-rigged FBX imports are NOT — even if they're "humanoid", the bone names differ and the retarget call rejects them.
35
+
36
+ Before calling `summer_retarget_motion`, verify:
37
+
38
+ ```
39
+ summer_inspect_resource(<source_rigAssetId>)
40
+ summer_inspect_resource(<target_rigAssetId>)
41
+ ```
42
+
43
+ Both responses should include `rig_provider: "meshy"` and `bone_count: 52`. If either is missing those fields or shows a different provider, **stop**. Tell the user: "Target rig isn't Meshy-rigged — retarget will fail. Either re-rig the target via `summer_generate_3d({ kind: \"image-to-3d\", imageUrl: \"...\", options: { rig: true } })` or regenerate motion directly on it via `summer:animation/generate-motion`. Which?"
44
+
45
+ If both are Meshy-rigged but the target's mesh has wildly different proportions (e.g., source is a 1.8m human, target is a 2.5m ogre with arms-down-to-knees), retarget will succeed but the *result* will look wrong — clipping, foot-floating, or limb-twisting. Warn the user before spending: "Proportions differ a lot — retarget will run but you'll likely need procedural foot IK on the result. Continue?" Hand off to `summer:animation/procedural-animation` after.
46
+
47
+ ## Steps
48
+
49
+ ### 1. Find the source library
50
+
51
+ ```
52
+ summer_search_assets(query: "<source character>", kind: "animation")
53
+ ```
54
+
55
+ Returns a list of `{ animationAssetId, name, durationSeconds }`. Cache the IDs.
56
+
57
+ ### 2. Find the target rig
58
+
59
+ ```
60
+ summer_search_assets(query: "<target character>", kind: "model")
61
+ ```
62
+
63
+ Confirm `rigAssetId` is present and Meshy-provider.
64
+
65
+ ### 3. Confirm with user before spending
66
+
67
+ Always batch-ask. Retargets are cheap individually but $0.05 × 30 clips × 5 enemies = $7.50, which deserves consent.
68
+
69
+ > I'm about to retarget 12 clips (idle, walk, run, attack, ...) from `goblin_rigged` onto `orc_rigged` — about 12 × $0.05 = $0.60, ~2 minutes total. OK?
70
+
71
+ ### 4. Loop the retarget calls
72
+
73
+ ```
74
+ for clip in source_clips:
75
+ summer_retarget_motion(
76
+ sourceAnimationAssetId: clip.animationAssetId,
77
+ targetRigAssetId: <target_rigAssetId>,
78
+ name: clip.name // preserve the slot name (idle, walk, run...)
79
+ )
80
+ // returns { animationAssetId, durationSeconds }
81
+ ```
82
+
83
+ Save the returned IDs as a map `{ name: animationAssetId }` for the target.
84
+
85
+ ### 5. Attach to the target's AnimationPlayer
86
+
87
+ Same pattern as `summer:animation/generate-motion`: ensure an `AnimationPlayer` child exists, then write each clip into `libraries/default`.
88
+
89
+ ```
90
+ summer_set_resource_property(
91
+ nodePath: "./World/Orc/AnimationPlayer",
92
+ resourceProperty: "libraries/default",
93
+ subProperty: "<clip_name>",
94
+ value: "<retargeted_animationAssetId>"
95
+ )
96
+ ```
97
+
98
+ `summer_save_scene` once at the end, not per clip.
99
+
100
+ ## Confirmation gates
101
+
102
+ - **Before any retarget call:** show the full list and total cost.
103
+ - **After the first retarget:** preview the result. If it looks wrong, stop the loop and re-evaluate (proportions, T-pose, missing bones).
104
+ - **Before saving the scene:** confirm the AnimationPlayer additions you're about to write.
105
+
106
+ ## Reference card
107
+
108
+ ### When retarget fails — the 5 common causes
109
+
110
+ | Symptom | Cause | Fix |
111
+ |---|---|---|
112
+ | API returns `incompatible_rig` | Target isn't Meshy-rigged | Re-rig target via `summer_generate_3d({ kind: "image-to-3d", options: { rig: true } })` |
113
+ | API returns `bone_mismatch` | Source rigged with custom bones (extra wings, etc.) | Strip extras or regenerate motion natively on target |
114
+ | Clip plays but limbs twist 180° | T-pose vs A-pose mismatch | Re-rig source from T-pose reference |
115
+ | Feet float / clip into ground | Target is much taller/shorter | Apply foot IK — see `summer:animation/procedural-animation` |
116
+ | Root motion drifts | Source had baked root translation, target scale differs | Strip root track in AnimationPlayer or scale `playback_speed` |
117
+
118
+ ### Cost math (decision rule)
119
+
120
+ | Scenario | Generate fresh | Retarget |
121
+ |---|---|---|
122
+ | 1 character, 1 clip | $0.10 | n/a |
123
+ | 1 character, 12 clips | $1.20 | n/a |
124
+ | 5 characters, same 12 clips | $6.00 (5 × $1.20) | $1.80 ($1.20 + 4 × $0.60 retarget) |
125
+ | 30 NPCs, same 8-clip set | $24.00 | $6.40 ($0.80 + 29 × $0.40) |
126
+
127
+ The break-even is two characters. Past that, retarget is always cheaper.
128
+
129
+ ### Pitfalls
130
+
131
+ - **Not preserving clip names.** If you don't pass `name:` to `summer_retarget_motion`, the target gets clips named `retargeted_001`, `retargeted_002` and your AnimationTree state machine breaks. Always pass the source name.
132
+ - **Retargeting one clip at a time interactively.** Batch the loop; each call has a few seconds of overhead. Sequential is fine; parallel via `summer_batch` is faster if the project supports it.
133
+ - **Forgetting the source library still owns the clips.** Source character's AnimationPlayer is unchanged. Don't accidentally re-attach the *source* IDs to the target.
134
+ - **Retargeting then regenerating "to clean it up".** If retarget produced bad output, the fix is procedural foot IK or a bone-correction modifier — not regeneration. Regeneration only makes sense if the source itself is bad.
135
+ - **Mixing Meshy and Mixamo libraries on the same character.** They have different bone-naming conventions; the AnimationPlayer tries to play tracks against bones that don't exist. Pick one rig provider per character and stick with it.
136
+
137
+ ### Quality bar
138
+
139
+ - Library was originally generated on a 1.8m humanoid → target between 1.5m and 2.2m: retarget is production-ready.
140
+ - Target is 2.2m–3m: retarget runs, expect foot-clipping; layer foot IK.
141
+ - Target is < 1.5m or has cartoon proportions (big head, short limbs): retarget runs, expect noticeable limb-pop; consider regenerating natively.
142
+
143
+ ## Anti-patterns
144
+
145
+ - Calling `summer_retarget_motion` without first verifying both rigs are Meshy-provider.
146
+ - Retargeting from a hand-authored animation library (Mixamo `.fbx`, etc.). The MCP wraps Meshy's retarget, which only accepts Meshy-rig source clips. For external libraries, use Godot's built-in `BoneMap` retargeting in the editor — out of scope for this skill.
147
+ - Retargeting on every gameplay session. Retarget once, persist the resulting `animationAssetId`, and reference from the scene file. The asset library survives session restarts.
148
+ - Generating motion on each enemy separately because you forgot retarget existed. The first time the project has two rigged characters, point at this skill.
149
+
150
+ ## Edge cases
151
+
152
+ - **Source library uses additive blend tracks.** Additive clips (e.g., a "lean left" overlay) retarget but the additive flag is preserved only on Meshy-native rigs. Verify the `track_type` survived: `summer_inspect_resource(<retargeted_animationAssetId>)`.
153
+ - **Source has facial blendshape tracks.** Meshy retarget only handles skeleton. Facial tracks are stripped. Hand off to `summer:animation/facial-and-lipsync` to re-author per character.
154
+ - **Target rig was generated months ago and Meshy updated their skeleton schema.** Rare but happens. Symptom: bone-count mismatch even though both rigs are Meshy. Re-rig the target with a fresh `summer_generate_3d({ kind: "image-to-3d", options: { rig: true } })` call.
155
+ - **The user wants to retarget *to* the source rig as a sanity test.** Allowed and useful — round-trips should be near-identical.
156
+
157
+ ## Fallback (no MCP)
158
+
159
+ Open the source `.glb` in Blender, export the animation, then in Godot 4.5 use the BoneMap-based humanoid retargeting workflow (Project → Tools → Bone Map). Set both source and target as humanoid profile, configure the bone mapping if names differ, save the retargeted clip into the target's `AnimationLibrary`. ~5 minutes per clip vs ~10 seconds via MCP. Documented in the Godot 4.5 character animation docs.
160
+
161
+ ## Handoff
162
+
163
+ - After retarget, the wiring is identical to a freshly-generated clip — hand off to `summer:animation/animation-tree` for state-machine integration.
164
+ - If retarget produced foot-clipping or hand-pen-through-prop issues, hand off to `summer:animation/procedural-animation` for IK correction.
165
+ - For NPC behavior driving these clips, hand off to `summer:ai-and-npcs/design-npc`.
166
+
167
+ ## See also
168
+
169
+ - `summer:animation/generate-motion` — to create the source library.
170
+ - `summer:asset-pipeline/asset-strategy` — to ensure all characters are Meshy-rigged before retargeting.
171
+ - `summer:animation/animation-tree` — wire the retargeted clips into a state machine.
172
+ - `summer:animation/procedural-animation` — fix proportional mismatches with foot IK after retarget.