Wiki 9Minecraft Wiki 9Minecraft

Running Commands on Entity Death with Animation Controllers

How to execute slash commands, entity events, or functions the moment an entity or player dies.

6Sections
3Code examples
3Known errors

In Minecraft Bedrock, entities do not have a built-in component solely dedicated to firing slash commands at the exact moment of death, and custom damage sensors often fail to catch fatal hits reliably. By attaching a behavior pack animation controller that watches the entity's life state via Molang, you can run commands, trigger events, or execute function files on the exact tick an entity dies. This pattern works for both custom mobs and players.

Why Use an Animation Controller for Death Detection

When an entity takes fatal damage, the game immediately transitions it into a dying state before removing it from the world roughly twenty ticks later (the duration of the standard death fall-over animation). If you rely on `minecraft:damage_sensor` with the `deals_damage` property enabled, the entity may die before your event fires, or you have to calculate whether the incoming damage exceeds the remaining health yourself.

Behavior pack animation controllers evaluate their Molang transition queries every tick, even while an entity is playing its death animation. By watching the `query.is_alive` Molang query, a controller can transition out of its idle state the very first tick the entity is marked dead, executing any `on_entry` slash commands at the entity's exact final coordinates.

Creating the Death Animation Controller

A behavior pack animation controller lives in the `BP/animation_controllers/` folder. Unlike resource pack controllers, which only handle visual bones, sounds, and particles, behavior pack controllers can execute slash commands, run `.mcfunction` files, and trigger entity events defined in the entity's behavior file.

For a standard mob that dies once and never comes back, the controller only needs two states: an initial waiting state and a dead state. When `!query.is_alive` evaluates to true, the state shifts to `dead` and fires the `on_entry` array once.

BP/animation_controllers/mob_death.ac.json
{
  "format_version": "1.10.0",
  "animation_controllers": {
    "controller.animation.custom_mob.death": {
      "initial_state": "alive",
      "states": {
        "alive": {
          "transitions": [
            {
              "dead": "!query.is_alive"
            }
          ]
        },
        "dead": {
          "on_entry": [
            "/summon minecraft:lightning_bolt ~ ~ ~",
            "/playsound mob.wither.death @a[r=24] ~ ~ ~ 1.0 1.0",
            "@s custom:on_death_event"
          ]
        }
      }
    }
  }
}

Handling Player Death and Respawning

If you attach the two-state controller above to `BP/entities/player.json`, it will work the first time the player dies and never again. Because a player entity persists across deaths, the controller remains stuck in the `dead` state after the player clicks the respawn button.

To make the controller reusable for players, add a transition back to the `alive` state that checks `query.is_alive`. The moment the player respawns, `query.is_alive` returns true again, resetting the state machine for their next death.

BP/animation_controllers/player_death.ac.json
{
  "format_version": "1.10.0",
  "animation_controllers": {
    "controller.animation.player.death_commands": {
      "initial_state": "alive",
      "states": {
        "alive": {
          "transitions": [
            {
              "dead": "!query.is_alive"
            }
          ]
        },
        "dead": {
          "on_entry": [
            "/title @a actionbar §cA player has fallen!",
            "/scoreboard players add @s deaths 1"
          ],
          "transitions": [
            {
              "alive": "query.is_alive"
            }
          ]
        }
      }
    }
  }
}

Linking the Controller to an Entity

Defining the animation controller file does nothing until an entity references it. Open your entity's behavior file inside `BP/entities/` and locate the `description` block. You must first assign a short name to the controller inside the `animations` object, and then tell the entity to run that short name inside the `scripts.animate` array.

Notice that `format_version` inside the entity file must be at least `1.16.0` (or `1.14.0` depending on your pack's base target) to use the `scripts.animate` block cleanly without legacy `minecraft:entity` wrapper issues.

BP/entities/custom_mob.json
{
  "format_version": "1.16.0",
  "minecraft:entity": {
    "description": {
      "identifier": "custom:skeleton_boss",
      "is_spawnable": true,
      "is_summonable": true,
      "animations": {
        "death_ctrl": "controller.animation.custom_mob.death"
      },
      "scripts": {
        "animate": [
          "death_ctrl"
        ]
      }
    },
    "components": {
      "minecraft:health": {
        "value": 100,
        "max": 100
      },
      "minecraft:type_family": {
        "family": [ "monster", "undead" ]
      }
    },
    "events": {
      "custom:on_death_event": {
        "add": {
          "component_groups": []
        }
      }
    }
  }
}

What You Can Run in on_entry

The `on_entry` and `on_exit` arrays inside a behavior pack animation controller accept three distinct types of strings. The engine determines what to do based on the first character of each string.

Commands run from an entity's animation controller execute with the dying entity as `@s` and at the entity's current position and rotation, so relative coordinates (`~ ~ ~`) and local coordinates (`^ ^ ^`) work without needing an `/execute` wrapper.

PrefixWhat it doesNotes
/Executes a standard slash command as the entity.Example: "/summon XP_orb ~ ~ ~". If executing a function via "/function my_func", keep all commands inside the function free of leading slashes.
@s Triggers an entity event defined in the entity's own behavior JSON.Example: "@s custom:explode_on_death". Must match an event name under the entity's "events" block.
v. or variable.Executes a Molang statement or assigns a Molang variable.Example: "v.death_timer = 1.0;". Statements must end with a semicolon.

Limitations When Instant Despawn Is Used

A common technique in add-ons is to remove a mob's death animation and corpse smoke by triggering an event that adds the `minecraft:instant_despawn` component. However, if an entity despawns on the exact same tick it takes fatal damage, the animation controller may not have a chance to evaluate `!query.is_alive`, or the entity context (`@s`) may vanish before queued slash commands finish.

Instead of triggering `minecraft:instant_despawn` from a damage sensor, let the entity die normally so the animation controller catches the death in `on_entry`. You can then place `"@s custom:despawn_event"` as the final line inside the `dead` state's `on_entry` array, ensuring your slash commands execute first and the entity cleanly removes itself right after.

Which versions this applies to

Applies to Bedrock Edition 1.10.0 and all newer versions, including 1.20 and 1.21. No experimental toggles are required.

When it does not work

What you seeWhyThe fix
Commands work the first time a player dies, but stop firing on subsequent deaths.The animation controller transitioned to the 'dead' state and stayed there because player entities are not destroyed when they respawn.Add a transition inside the 'dead' state back to 'alive' using the condition "query.is_alive".
Content Log Error: [Animation][error]-animation controller 'controller.animation...' not found, or commands simply never execute without any error.You either placed the animation controller inside the Resource Pack (RP/animation_controllers/) instead of the Behavior Pack, or forgot to list the short name under 'scripts.animate' in the entity's description.Move the controller file to BP/animation_controllers/ and verify that both 'animations' and 'scripts.animate' in your BP/entities/ file reference it.
Target selectors using '@s' inside the death command fail to match the dying mob.Most selector arguments (and selectors like @e) automatically ignore dead entities once their health hits zero, even while their death animation is still playing.Commands that do not require targeting the dead body—such as '/summon', '/setblock', '/particle', or '/playsound @a'—work normally at '~ ~ ~'. If you need to modify the dying entity itself, trigger an entity event using '@s event_name' instead of a slash command.

Reference, straight from the game files

Read out of the game itself, so the ids match the version you are building for.