How Bedrock Handles Entity Death
Entity death in Bedrock Edition is split between the Resource Pack (visuals) and the Behavior Pack (actual removal from the world). On the client side, the game automatically plays a hard-coded rotation that rolls the entity's root bone 90 degrees over roughly one second. This happens even if you have no animations defined in your client entity file.
On the server side, an entity whose health drops to 0 enters a dying state. It waits for a fixed internal timer (roughly 20 ticks, or 1 second) before deleting the entity actor and spawning the death smoke particles. If your custom animation is merely 0.8 seconds long, you only need to touch the Resource Pack. If your animation is a three-second boss collapse, the entity will vanish mid-animation unless you intercept the death in the Behavior Pack.
Canceling the Default Death Tilt
The side-tumble is controlled by a shared vanilla animation logic that applies to the root of the geometry when `!query.is_alive` is true. Because this tilt is applied at the model root level, simply playing a custom keyframe animation on the legs and arms will result in those bones animating while the entire creature still tips onto its side.
To stop the default tilt, your custom death animation must either override the root bone's rotation directly, or you must cancel out the vanilla rotation using Molang in an auxiliary animation. The cleanest approach when animating in Blockbench is to parent your entire model under a single root bone (often named `root` or `body`), and ensure your death animation explicitly keyframes that root bone's rotation at `[0, 0, 0]` (or whatever orientation your animation requires) on frame 0.0.
{
"format_version": "1.8.0",
"animations": {
"animation.custom_golem.death": {
"loop": "hold_on_last_frame",
"animation_length": 2.5,
"bones": {
"root": {
"rotation": {
"0.0": [0.0, 0.0, 0.0],
"1.2": [15.0, 0.0, 0.0],
"1.5": [-85.0, 0.0, 0.0]
},
"position": {
"0.0": [0.0, 0.0, 0.0],
"1.5": [0.0, -4.0, 0.0]
}
}
}
}
}
}Triggering the Animation on the Client
Notice that the animation above uses `"loop": "hold_on_last_frame"`. This is critical for death animations. If you leave `"loop": false`, the entity will snap back to its default idle pose for a split second right before it despawns.
To play the animation when the entity dies, set up an animation controller or a script in your client entity definition (`RP/entity/`). Using `query.is_alive` is the standard approach when relying on the normal health system. However, if you are extending the death timer via the Behavior Pack (covered in the next section), you will usually trigger the animation using a custom state such as `query.is_sheared`, `query.skin_id`, or an entity property, because the entity will technically remain "alive" at 1 health during its fake death sequence.
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.custom_golem.base": {
"initial_state": "alive",
"states": {
"alive": {
"animations": ["walk", "look_at_target"],
"transitions": [
{
"dying": "!query.is_alive || query.skin_id == 99"
}
]
},
"dying": {
"animations": ["death"],
"blend_transition": 0.1
}
}
}
}
}Extending the Death Duration (Behavior Pack)
Because Bedrock does not provide a simple `death_time` slider in the health component, playing an animation longer than one second requires keeping the entity alive artificially. The standard pattern uses `minecraft:damage_sensor` to intercept fatal damage, cancel the actual death, and switch the entity into a dummy "dying" component group.
Inside this dying component group, you strip away movement and AI goals, lock the entity in place, set a `minecraft:skin_id` (or entity property) so the Resource Pack knows to play the death animation, and start a `minecraft:timer` for the exact length of your animation. When the timer finishes, it triggers an event containing `minecraft:instant_despawn` to cleanly remove the entity without the vanilla smoke puff.
{
"format_version": "1.16.0",
"minecraft:entity": {
"description": {
"identifier": "wiki:custom_golem",
"is_spawnable": true,
"is_summonable": true
},
"component_groups": {
"wiki:dying_state": {
"minecraft:skin_id": {
"value": 99
},
"minecraft:movement": {
"value": 0.0
},
"minecraft:damage_sensor": {
"triggers": [
{
"cause": "all",
"deals_damage": false
}
]
},
"minecraft:timer": {
"looping": false,
"time": 2.5,
"time_down_event": {
"event": "wiki:despawn_self"
}
}
},
"wiki:despawn_group": {
"minecraft:instant_despawn": {}
}
},
"components": {
"minecraft:health": {
"value": 50,
"max": 50
},
"minecraft:damage_sensor": {
"triggers": [
{
"on_damage": {
"filters": {
"test": "is_fatal",
"subject": "self",
"value": true
},
"event": "wiki:start_death"
},
"deals_damage": false
}
]
}
},
"events": {
"wiki:start_death": {
"add": {
"component_groups": ["wiki:dying_state"]
}
},
"wiki:despawn_self": {
"add": {
"component_groups": ["wiki:despawn_group"]
}
}
}
}
}Handling Loot and Experience Drops
There is one major side effect to using `minecraft:instant_despawn` at the end of a custom death timer: the entity never officially dies, so its standard `minecraft:loot` table will not drop and it will not yield experience orbs.
To get around this, use `minecraft:spawn_entity` inside the `wiki:dying_state` component group with a `0.0` wait time to drop a loot table or spawn an XP orb right as the death animation finishes, or run a `/loot` command via an animation timeline event if your pack format supports behavior pack animations. Comparing the two main death techniques helps decide which trade-off fits your mob:
| Method | Max Duration | Notes |
|---|---|---|
| Vanilla Death (`!query.is_alive`) | ~1.0 second | Drops loot and XP naturally; shows red damage overlay and white death smoke. |
| Intercepted Death (`is_fatal` filter) | Unlimited | Full control over particles and length; requires manual loot spawning before `minecraft:instant_despawn`. |
Which versions this applies to
Applies to Bedrock Edition 1.16.0 and newer. No experimental toggles are required for the damage sensor, timer, or animation controller methods shown here.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| The entity plays the custom animation AND rotates 90 degrees into the floor at the same time. | You used normal death (`!query.is_alive`) without overriding the vanilla death rotation, or your root bone has no rotation keyframes at frame 0.0. | Ensure the top-level parent bone in your geometry has an explicit rotation keyframe (such as `[0, 0, 0]`) in your death animation, or switch to the intercepted death method so the entity remains technically alive while playing the animation. |
| The entity disappears in a puff of smoke halfway through a long death animation. | The entity actually reached 0 health, triggering Bedrock's hardcoded 20-tick removal timer. | Use `minecraft:damage_sensor` with the `is_fatal` filter and `"deals_damage": false` to catch the killing blow before health hits 0. |
| The entity stands back up for one frame right before vanishing. | The animation finished slightly before the `minecraft:timer` component fired, and the animation was not set to hold its pose. | Set `"loop": "hold_on_last_frame"` inside the death animation definition in your Resource Pack. |
| [Animation][error]-controller.animation.custom_golem.base |Animation 'death' not found | The short name `death` used in the animation controller was not mapped to the full animation identifier in the client entity file (`RP/entity/`). | Open your `RP/entity/*.entity.json` file and add `"death": "animation.custom_golem.death"` under the `description.animations` object. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
