Minecraft Bedrock Animation Controllers Guide (2026)

Turn Blockbench keyframes into reliable idle, walk, attack, and special states by wiring the animation, controller, client entity, and Molang conditions correctly.

Current controller modelThis guide was checked against Microsoft's animation, controller, and Molang documentation in July 2026. It focuses on visual entity controllers in the Resource Pack.

Animation vs animation controller

An animation describes movement: bone rotations, positions, scales, keyframes, loop behavior, and animation length. An animation controller describes logic: states, transitions, conditions, blends, and which animations should run inside each state.

Think of the animation as the clip and the controller as the state machine. An idle clip cannot decide when the entity starts walking. The controller observes a Molang condition and moves from idle to walk.

Files involved

Resource Pack map
Mossling_RP/
  entity/
    mossling.entity.json
  models/entity/
    mossling.geo.json
  animations/
    mossling.animation.json
  animation_controllers/
    mossling.animation_controller.json
  textures/entity/
    mossling.png

The geometry defines bones. The animation moves those bone names. The controller selects animations. The client entity connects every identifier to the entity that uses them.

Step 1: create and export the animations

  1. Open the Bedrock entity model in Blockbench.
  2. Switch to Animate mode.
  3. Create separate clips such as animation.mossling.idle and animation.mossling.walk.
  4. Keep bone names identical to the geometry.
  5. Set loop behavior intentionally. Idle and walk normally loop; a one-time attack usually does not.
  6. Export the Bedrock animation JSON into the Resource Pack animations/ folder.
Build the smallest useful setStart with idle and walk. If those two states transition correctly, attack and ability states become an extension of a working controller instead of four unknown systems failing together.

Step 2: create the controller

Create animation_controllers/mossling.animation_controller.json. This controller starts idle, switches to walk when movement passes a small threshold, and returns to idle when movement stops.

mossling.animation_controller.json
{
  "format_version": "1.10.0",
  "animation_controllers": {
    "controller.animation.mossling.movement": {
      "initial_state": "idle",
      "states": {
        "idle": {
          "animations": ["idle"],
          "transitions": [
            {
              "walk": "query.modified_move_speed > 0.05"
            }
          ],
          "blend_transition": 0.15
        },
        "walk": {
          "animations": ["walk"],
          "transitions": [
            {
              "idle": "query.modified_move_speed <= 0.05"
            }
          ],
          "blend_transition": 0.15
        }
      }
    }
  }
}

What the controller is doing

  • initial_state selects the state used when the controller starts.
  • states contains every named mode in the state machine.
  • animations uses aliases that the client entity will define.
  • transitions are evaluated in order and move to the first state whose condition becomes true.
  • blend_transition softens the visual change between state outputs.

The movement threshold prevents tiny speed changes from rapidly toggling the controller. Tune the value against the entity's actual navigation rather than copying it blindly.

Step 3: wire it into the client entity

Inside the client entity description, map short aliases to the full animation and controller identifiers. Then run the controller from scripts.animate.

Client entity additions
"animations": {
  "idle": "animation.mossling.idle",
  "walk": "animation.mossling.walk",
  "movement_controller": "controller.animation.mossling.movement"
},
"scripts": {
  "animate": [
    "movement_controller"
  ]
}

This is the most commonly missed layer. A valid animation file and valid controller file do nothing until the client entity references and runs the controller.

Write Molang conditions you can debug

Molang queries expose entity state to the Resource Pack. Useful conditions include movement, ground state, health, variants, properties, timers, and many other values available in the current reference.

Keep transitions mutually understandable

For two states, use opposite conditions. If walk begins above 0.05, idle should resume at or below 0.05. Gaps leave the controller in its current state; overlapping conditions can cause rapid switching.

Use entity properties for authored states

Movement is observable automatically. A custom state such as sleeping, charged, angry, or transformed is often clearer as an entity property synchronized to the client. The controller can then render and animate directly from that property.

Do not hide complex gameplay in a visual controller

Use the Behavior Pack or Script API as the authority for gameplay. Let the Resource Pack controller represent that state visually. This keeps multiplayer behavior and visuals aligned.

Add a one-shot attack state

An attack controller needs a reliable trigger and a reliable way to leave the state. Do not transition back only because the attack condition becomes false if that can happen before the clip finishes.

A common pattern is to enter on an attack-related query or property and return when the animation has completed. The exact query depends on the entity behavior and current API. Test the timing at different attack speeds and network conditions.

Avoid hard-coded timing driftIf gameplay cooldown, animation length, and controller transition all use unrelated numbers, they will eventually fall out of sync. Drive visuals from authoritative entity state whenever possible.

Layer animations without fighting over bones

A state can play more than one animation. This is useful when one clip controls legs and another controls a head, tail, held item, or ambient effect. It becomes unstable when several full-body clips write different values to the same bones.

  • Separate upper-body and lower-body responsibilities where possible.
  • Use additive or override behavior only when you understand the exported animation output.
  • Keep controller responsibilities narrow: movement, combat, expression, or special state.
  • Test combinations, not only each controller in isolation.

A controller test that finds real faults

  1. Summon the entity in a flat, well-lit test world.
  2. Verify the initial idle clip.
  3. Make the entity walk continuously and watch the transition both ways.
  4. Force rapid start-stop movement to expose flickering thresholds.
  5. Test slopes, water edges, knockback, and pathfinding turns.
  6. Trigger attack or special states repeatedly.
  7. Test several entities at once and in multiplayer.
  8. Check the Content Log after each failed load.

Why an animation controller does not work

No animation plays at all

Verify scripts.animate runs the controller alias. Then match the alias to the controller identifier and confirm the controller file is in animation_controllers/.

The controller runs but a clip is missing

Match the state animation alias to the client entity animations mapping, then match that mapping to the exported animation identifier.

The mob is permanently walking

Inspect the transition back to idle and the actual value of the movement query. Raise or lower the threshold and make the two conditions complementary.

The animation snaps between states

Add a short blend transition and inspect the first/last poses of both clips. A blend cannot fully hide incompatible root positions or wildly different rotations.

Only some bones move

Check bone names against the geometry, including capitalization. Blockbench can export an animation that references a bone no longer present after a model rename.

The controller works in Blockbench but not in game

Blockbench previews animation data, not the complete in-game wiring. Validate the exported identifiers, client entity aliases, controller state machine, Molang queries, and pack activation.

Frequently asked questions

Do animations belong in the Behavior Pack or Resource Pack?

Visual entity animations and their normal client-side controllers belong in the Resource Pack. Behavior-side animation controllers exist for different data-driven purposes; do not mix the two workflows without checking the relevant reference.

Can one entity use multiple animation controllers?

Yes. Add multiple controller aliases to scripts.animate. Keep their bone and state responsibilities clear so their outputs combine predictably.

Do I need Blockbench?

You can author animation JSON by hand, but Blockbench makes bone selection, keyframes, curves, pivots, and timing much easier to inspect. You still need to understand the exported identifiers and controller wiring.

Official sources checked