# Procedural Animation

> 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".

- **Type:** Skill
- **Install:** `agentstack add skill-summerengine-summer-engine-agent-procedural-animation`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [SummerEngine](https://agentstack.voostack.com/s/summerengine)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [SummerEngine](https://github.com/SummerEngine)
- **Source:** https://github.com/SummerEngine/summer-engine-agent/tree/main/skills/animation/procedural-animation
- **Website:** https://summerengine.com/

## Install

```sh
agentstack add skill-summerengine-summer-engine-agent-procedural-animation
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Procedural Animation — Bones Driven by Code

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.

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.

## When to use this skill

- Feet clip into / float over uneven terrain.
- NPC head doesn't track the player during conversation — feels dead-eyed.
- Character's hand doesn't actually hold the sword — pen-through.
- Body doesn't lean into turns / aiming.
- Hit reactions need to come from the hit *direction* (recoil left when struck left), not just one canned animation.
- Ragdoll on death.

## When NOT to use this skill

- The clip already covers it. Don't IK what mocap already nailed — adds CPU cost and rounding error.
- The character is far from the camera (LOD2+). Procedural cost outpaces visual benefit. Disable modifiers past 15m.
- You need facial animation. That's `summer:animation/facial-and-lipsync`.
- 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.

## The three patterns

Almost every procedural request maps to one of these three. Pick the right one before writing code.

### Pattern A — SkeletonModifier3D (post-clip bone overrides)

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.

### Pattern B — Additive AnimationNodeAdd2 layer in the tree

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.

### Pattern C — PhysicalBoneSimulator3D (ragdoll)

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.

## Pattern A recipes

### A1 — Head look-at the player

The bread-and-butter NPC liveliness fix. Three lines of scene + one script function.

```
summer_inspect_node "./World/NPC/Skeleton3D"   # confirm bone names
summer_add_node parent="./World/NPC/Skeleton3D" type="LookAtModifier3D" name="HeadLookAt"
summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="bone_name" value="Head"
summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="forward_axis" value=2   # +Z forward (Meshy default)
summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="primary_rotation_axis" value=1   # Y-up
summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="use_secondary_rotation" value=true
summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="secondary_rotation_axis" value=0
summer_set_prop "./World/NPC/Skeleton3D/HeadLookAt" key="symmetry_limit" value=1.4   # ~80°, prevents the Exorcist
```

Drive the target each frame:

```gdscript
@onready var head_look: LookAtModifier3D = $Skeleton3D/HeadLookAt

func _process(_delta: float) -> void:
    var player := get_tree().get_first_node_in_group("player")
    if player == null:
        head_look.influence = 0.0
        return
    var to_player := player.global_position - global_position
    var dist := to_player.length()
    # Disable look-at past 8m — feels uncanny at long range.
    head_look.target_node = player.get_path() if dist  void:
    _solve_foot(ik_left, "LeftFoot")
    _solve_foot(ik_right, "RightFoot")

func _solve_foot(ik: SkeletonIK3D, bone_name: String) -> void:
    var bone_idx := skel.find_bone(bone_name)
    var foot_world := skel.get_bone_global_pose(bone_idx).origin
    ray.global_position = foot_world + Vector3.UP * 0.5
    ray.target_position = Vector3.DOWN * 1.0
    ray.force_raycast_update()
    if ray.is_colliding():
        var ground := ray.get_collision_point()
        if ground.y > foot_world.y - 0.05:   # only lift, never drop into the ground
            ik.target_node = NodePath("../IKTarget" + bone_name)
            (get_node("Skeleton3D/IKTarget" + bone_name) as Node3D).global_position = ground + Vector3.UP * 0.05
            ik.start()
        else:
            ik.stop()
    else:
        ik.stop()
```

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.

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.

### A4 — Hand grab on prop (sword grip, rifle stock)

`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.

## Pattern B — Additive layer

In the AnimationTree, wrap Locomotion in an `AnimationNodeAdd2`:

```
[parent: AnimationNodeStateMachine.Locomotion]
  AnimationNodeAdd2
    in: BlendSpace1D (idle/walk/run)   # the base
    add: AnimationNodeAnimation         # an additive clip — must be authored as delta
```

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.

## Pattern C — Ragdoll on death

```gdscript
@onready var sim: PhysicalBoneSimulator3D = $Skeleton3D/PhysicalBoneSimulator

func die(impulse_world: Vector3) -> void:
    $AnimationTree.active = false
    sim.physical_bones_start_simulation()
    var pelvis := $Skeleton3D/PhysicalBoneSimulator/PelvisPhysicalBone as PhysicalBone3D
    pelvis.apply_central_impulse(impulse_world * 4.0)
```

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.

## Confirmation gates

- **Before adding modifiers:** state which bones, which axes. Bone-name typos are a top failure.
- **Before driving from script:** confirm influence will fade out at distance and the target node is correct.
- **Before enabling ragdoll:** confirm physical bones exist; without them, simulation is a no-op.

## Reference card

### Bone names (Meshy humanoid skeleton, exact strings)

`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.)

### Axis conventions

| Setting | Value (Meshy default) |
|---|---|
| Forward axis (head/spine) | Z+ |
| Up axis | Y+ |
| Right axis | X+ |
| Foot down | Y- |

### Influence fade-out distances (tuned defaults)

| Modifier | Disable past |
|---|---|
| Head look-at | 8m |
| Foot IK | 15m (snap-to-ground only matters when player can see) |
| Hand-on-prop IK | always on (cheap, breaks if disabled) |
| Additive lean | always on |
| Ragdoll | one-shot, never disabled |

### Pitfalls

- **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.
- **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.
- **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.
- **Additive layer doubles the clip.** The "additive" clip wasn't authored as a delta. Re-export from Blender with `Pose Mode → bake additive`.
- **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.
- **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.
- **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.

### Performance budget

- Each `LookAtModifier3D`: ~5 µs/frame. Cheap; have many.
- 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.
- Ragdoll with full physical skeleton: ~200 µs/frame *while simulating*. Cap concurrent ragdolls at 5–8 before culling oldest.

## Anti-patterns

- 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.
- 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.
- Procedural look-at without a fade-out at distance. Distant NPCs all snap to player every frame, looks like a hivemind.
- Foot IK on flying / floating characters. Disable when `is_on_floor() == false`.

## Edge cases

- **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.
- **First-person hands.** Same modifier set, but only the arm chain is visible — disable head/spine modifiers, keep hand-on-prop IK.
- **Character is a quadruped.** All four legs need foot IK. The bone names are different (`FrontLeftLeg`, `BackRightLeg`, etc.); inspect first.
- **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`.

## Fallback (no MCP)

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.

## Handoff

- For the AnimationTree these procedural layers compose with, `summer:animation/animation-tree`.
- For the source clips that procedural overlays modify, `summer:animation/generate-motion`.
- For face / lipsync (a different modifier family — BlendShapes, not bones), `summer:animation/facial-and-lipsync`.
- For NPC behavior triggering ragdoll on death, `summer:ai-and-npcs/design-npc`.
- For first-person aim sway / ADS, `summer:character-controllers/fps-controller`.

## See also

- `references/gd-style.md` — typed GDScript conventions in the snippets.
- `references/mcp-tools-reference.md` — `summer_set_prop` enum-int conventions for axis settings.
- Godot 4.5 docs: `SkeletonModifier3D`, `LookAtModifier3D`, `SkeletonIK3D`, `PhysicalBoneSimulator3D`.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [SummerEngine](https://github.com/SummerEngine)
- **Source:** [SummerEngine/summer-engine-agent](https://github.com/SummerEngine/summer-engine-agent)
- **License:** MIT
- **Homepage:** https://summerengine.com/

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-summerengine-summer-engine-agent-procedural-animation
- Seller: https://agentstack.voostack.com/s/summerengine
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
