Wiki 9Minecraft Wiki 9Minecraft

Entity Events Reference

How to mutate entity state, swap component groups, and update properties using JSON events.

6Sections
4Code examples
4Known errors

Entity events are the primary state-machine mechanism inside a Bedrock Edition behavior pack entity file. They allow an entity to respond to gameplay triggers by adding or removing component groups, modifying synced entity properties, or executing slash commands. You reach for events whenever an entity needs to change its behavior dynamically after spawning, such as growing from a baby into an adult, becoming enraged when attacked, or transforming into a different variant.

Core Event Actions

All entity events live under the top-level "events" object inside a behavior pack entity definition (under "minecraft:entity"). An event does nothing on its own until something triggers it—either the game engine via a built-in lifecycle hook, a behavior component inside the entity, a slash command like /event, or the Script API.

When an event fires, it evaluates its internal action blocks. The most common use of an event is swapping component groups to alter the entity's active components. In newer format versions, events are also where you update entity properties and run direct commands or sound effects without needing an animation controller.

KeyWhat it doesNotes
addAttaches one or more component groups to the entity.Takes a "component_groups" string array.
removeStrips one or more component groups from the entity.Components in the removed group revert to the base "components" state, or disappear if not in the base.
sequenceExecutes an array of event nodes in strict top-to-bottom order.Each array entry can have its own "filters" block.
randomizePicks and runs exactly one node from an array of weighted options.Uses integer or float "weight" keys on each entry.
filtersGates the event or sub-node behind entity filter tests.If the filter evaluates to false, the node is skipped.
triggerFires another named event from within the current event.Useful for keeping complex logic modular and DRY.
set_propertyAssigns a new value to a declared entity property.Accepts literal booleans, numbers, strings, or Molang expressions.
queue_commandRuns one or more slash commands with the entity as the execution context.Takes a "command" string or array of strings. Replaces the older "run_command" syntax in modern format versions.

Built-in Engine Events

While you can name custom events whatever you like (prefixed with your namespace, such as "my_pack:enrage"), Minecraft automatically fires several reserved event names during an entity's lifecycle. You do not need to set up any component to call these; you simply define them in your "events" block and the engine will invoke them when the situation occurs.

The most important built-in event is "minecraft:entity_spawned", which fires the moment an entity enters the world naturally, via a spawn egg, or through the /summon command. Other standard lifecycle events include "minecraft:entity_born" (fired on the offspring when two entities breed) and "minecraft:entity_transformed" (fired on the new entity when another entity transforms into it). If you leave "minecraft:entity_spawned" out of your file, the entity will simply spawn with whatever is inside its base "components" block.

Swapping Component Groups

To change an entity's behavior at runtime, you bundle components into named "component_groups" and use an event's "add" and "remove" blocks to swap them in and out. When you add a group, its components merge with the base "components" block, overriding any duplicate components. When you remove a group, those specific overrides are stripped away.

It is good practice to always remove conflicting state groups in the same event where you add a new one. If an entity has a "calm" group and an "angry" group that both modify "minecraft:movement", adding "angry" without removing "calm" leaves the entity's state ambiguous if it later tries to revert.

BP/entities/custom_guard.json
{
  "format_version": "1.20.80",
  "minecraft:entity": {
    "description": {
      "identifier": "my_pack:custom_guard",
      "is_spawnable": true,
      "is_summonable": true
    },
    "component_groups": {
      "my_pack:guard_calm": {
        "minecraft:movement": {
          "value": 0.25
        }
      },
      "my_pack:guard_hostile": {
        "minecraft:movement": {
          "value": 0.38
        },
        "minecraft:behavior.melee_attack": {
          "priority": 1,
          "speed_multiplier": 1.2
        },
        "minecraft:behavior.nearest_attackable_target": {
          "priority": 2,
          "entity_types": [
            {
              "filters": {
                "test": "is_family",
                "subject": "other",
                "value": "monster"
              },
              "max_dist": 16
            }
          ]
        }
      }
    },
    "components": {
      "minecraft:type_family": {
        "family": [ "guard", "mob" ]
      },
      "minecraft:health": {
        "value": 30,
        "max": 30
      },
      "minecraft:physics": {},
      "minecraft:movement.basic": {},
      "minecraft:navigation.walk": {
        "can_path_over_water": true
      }
    },
    "events": {
      "minecraft:entity_spawned": {
        "add": {
          "component_groups": [
            "my_pack:guard_calm"
          ]
        }
      },
      "my_pack:become_hostile": {
        "remove": {
          "component_groups": [
            "my_pack:guard_calm"
          ]
        },
        "add": {
          "component_groups": [
            "my_pack:guard_hostile"
          ]
        }
      }
    }
  }
}

Branching with Sequence and Randomize

Events are not limited to flat add and remove actions. By nesting "sequence" and "randomize" arrays, you can build decision trees directly inside an event. A "sequence" block runs every child object in order from index 0 to the end. If you place a "filters" block inside a sequence entry, that specific step only runs if the filter passes, while the rest of the sequence continues unaffected.

A "randomize" block selects only one child entry to execute based on its relative "weight" value. The weights do not need to add up to 100; the engine sums all weights in the array and rolls against the total. You can nest a "sequence" inside a "randomize" option, or a "randomize" inside a "sequence" step, allowing complex spawn setups.

BP/entities/bandit.json
{
  "format_version": "1.20.80",
  "minecraft:entity": {
    "description": {
      "identifier": "my_pack:bandit",
      "is_spawnable": true,
      "is_summonable": true
    },
    "component_groups": {
      "my_pack:bandit_melee": {
        "minecraft:equipment": {
          "table": "loot_tables/entities/bandit_sword.json"
        }
      },
      "my_pack:bandit_ranged": {
        "minecraft:equipment": {
          "table": "loot_tables/entities/bandit_bow.json"
        }
      },
      "my_pack:cold_weather_gear": {
        "minecraft:mark_variant": {
          "value": 1
        }
      }
    },
    "components": {
      "minecraft:health": {
        "value": 20
      },
      "minecraft:physics": {}
    },
    "events": {
      "minecraft:entity_spawned": {
        "sequence": [
          {
            "randomize": [
              {
                "weight": 70,
                "add": {
                  "component_groups": [ "my_pack:bandit_melee" ]
                }
              },
              {
                "weight": 30,
                "add": {
                  "component_groups": [ "my_pack:bandit_ranged" ]
                }
              }
            ]
          },
          {
            "filters": {
              "test": "has_biome_tag",
              "value": "cold"
            },
            "add": {
              "component_groups": [ "my_pack:cold_weather_gear" ]
            }
          }
        ]
      }
    }
  }
}

Triggering Events from Components

Most custom events are called by components located inside the entity's "components" or "component_groups" sections. Trigger objects inside components generally share a standard structure containing three keys: "event" (the string name of the event to fire), "target" (who the event runs on, usually "self" or "other"), and an optional "filters" block.

Components like "minecraft:environment_sensor", "minecraft:damage_sensor", "minecraft:timer", and "minecraft:interact" are the workhorses of event-driven entities. When you configure a trigger with "target": "other"—for example, inside an interact or attack sensor—the game attempts to run that named event on the interacting player or the attacked target rather than on the entity itself.

BP/entities/timed_bomb.json
{
  "format_version": "1.20.80",
  "minecraft:entity": {
    "description": {
      "identifier": "my_pack:timed_bomb",
      "is_spawnable": true,
      "is_summonable": true
    },
    "component_groups": {
      "my_pack:exploding": {
        "minecraft:explode": {
          "fuse_length": 1.5,
          "power": 4.0,
          "causes_fire": false
        }
      }
    },
    "components": {
      "minecraft:physics": {},
      "minecraft:timer": {
        "looping": false,
        "time": 5.0,
        "time_down_event": {
          "event": "my_pack:start_fuse",
          "target": "self"
        }
      }
    },
    "events": {
      "my_pack:start_fuse": {
        "add": {
          "component_groups": [
            "my_pack:exploding"
          ]
        }
      }
    }
  }
}

Modifying Properties and Running Commands

When you just need to sync a state flag to the resource pack for animations or rendering, swapping an entire component group is unnecessary overhead. Instead, declare an entity property inside "description" -> "properties" and mutate it inside an event using "set_property". Property updates can evaluate Molang expressions at the moment the event runs, allowing you to increment counters or toggle booleans cleanly.

Events can also execute slash commands directly on the entity via "queue_command". The command runs at the end of the current tick with the entity as "@s". Keep in mind that running commands frequently across dozens of entities can hurt tick performance, so prefer native components or entity properties whenever possible.

BP/entities/counter_golem.json
{
  "format_version": "1.20.80",
  "minecraft:entity": {
    "description": {
      "identifier": "my_pack:counter_golem",
      "is_spawnable": true,
      "is_summonable": true,
      "properties": {
        "my_pack:hit_count": {
          "type": "int",
          "default": 0,
          "range": [ 0, 10 ],
          "client_sync": true
        }
      }
    },
    "components": {
      "minecraft:health": {
        "value": 50
      },
      "minecraft:physics": {},
      "minecraft:damage_sensor": {
        "triggers": [
          {
            "on_damage": {
              "event": "my_pack:register_hit",
              "target": "self"
            }
          }
        ]
      }
    },
    "events": {
      "my_pack:register_hit": {
        "set_property": {
          "my_pack:hit_count": "math.min(q.property('my_pack:hit_count') + 1, 10)"
        },
        "queue_command": {
          "command": [
            "particle minecraft:villager_angry ~ ~2 ~"
          ]
        }
      }
    }
  }
}

Which versions this applies to

Core event structures (add, remove, sequence, randomize, filters, trigger) apply to all modern Bedrock versions (1.16.0+) without experimental toggles. Using "set_property" and "queue_command" inside events is stable in format_version 1.20.40 and newer without any experimental toggles.

When it does not work

What you seeWhyThe fix
Running /event entity @e[type=my_pack:custom_guard] my_pack:become_hostile in chat returns "Event 'my_pack:become_hostile' could not be executed on..." or the event appears in autocomplete but nothing happens when triggered.Either the event name is misspelled, or a typo exists in the component group name listed inside the event's "add" or "remove" array. Minecraft silently ignores unknown component group names inside events without failing the whole file.Check that every string inside "add": { "component_groups": [...] } exactly matches a key declared under the top-level "component_groups" object, including any namespace prefix.
The game freezes or crashes the moment the entity spawns or takes an action.You created an infinite event loop. This happens when Event A triggers Event B, which triggers Event A on the same tick, or when an event adds a component group containing an "environment_sensor" that immediately fires an event removing and re-adding that same sensor without a cooldown or filter change.Trace the chain of "trigger" calls and sensor events. Ensure that when an event swaps states, the new state's sensor filters no longer match the condition that just triggered the swap.
Content Log shows an error regarding "set_property" failing to set a value, or the property remains stuck at its default value.The value assigned in "set_property" violates the "type", "range", or "values" array defined in the entity's "description" -> "properties" block, or you attempted to set an integer property to a float result from a Molang math expression.Wrap Molang math inside "math.floor()" or "math.round()" and clamp it with "math.clamp()" so the output strictly stays within the declared integer bounds.
A filter inside an event's "sequence" fails, and none of the "add" or "remove" blocks in the event run at all.You placed the "filters" block at the root of the event instead of inside the specific "sequence" entry, or you put "add" and "remove" on the same level as "sequence" expecting them to wait for the sequence filter.Move the conditional "filters", "add", and "remove" keys inside a dedicated object element within the "sequence" array so the filter only gates that single step.

Reference, straight from the game files

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