Events

Events use advancements to detect player/entity actions and dispatch them to function tags. Multiple handlers can be registered for the same event - they all fire together.

This makes events a convenient bridge between vanilla triggers and OOP-style gameplay code: you register interest once, then let the generated dispatchers call your handlers when Minecraft reports the action.

Registering events

Event helpers only need a DataPack in scope, so you can register them straight in the datapack { } block, without wrapping them in a function { }:

datapack("my_pack") {
  val player = player("Steve")
  player.onKill { say("Kill!") }
}
Kotlin

Registering them inside a function { } still works (the surrounding datapack is in scope there too), which is handy when you want to mix event registration with other commands.

Handler receives the entity

Each handler is invoked with the entity/player handle it was registered on, so you can keep chaining the OOP API without re-declaring the handle:

datapack("my_pack") {
  val player = player("Steve")
  player.onKill { self ->
    self.setScore("kills", 1)
    say("Kill counted!")
  }
}
Kotlin

Minecraft runs reward functions as the player, so the handle you get back is always the player/entity the event was registered on. The other entity involved (the mob you killed, the attacker, etc.) is not exposed by the game and cannot be passed in.

Player events

val player = player("Steve")

player.onBlockUse { say("Interacted with a block!") }
player.onConsumeItem(Items.GOLDEN_APPLE) { say("Golden apple!") }
player.onFishingRodHooked { say("Got a bite!") }
player.onRecipeCrafted(Recipes.CRAFTING_TABLE) { say("Crafted a recipe!") }
player.onRightClick(Items.STICK) { say("Right click with stick!") }
player.onUsedTotem { say("Cheated death!") }
Kotlin

Available player events (alphabetical):

Function Trigger
onBlockUse Right-click any block
onBredAnimals Breed two animals
onBrewedPotion Take a potion out of a brewing stand
onChangeDimension Change dimension
onConsumeItem Consume any item (food, potion, etc.)
onConsumeItem(item) Consume a specific item
onEffectsChanged Effects on the player change
onEnchantItem Enchant an item
onEntityHurtPlayer A player is hurt by an entity
onFallFromHeight Fall from a height
onFilledBucket Fill a bucket
onFishingRodHooked Hook something with a fishing rod
onHurtEntity Deal damage to an entity
onInteractWithEntity Right-click an entity
onInventoryChange Inventory contents change
onItemUsedOnBlock Use an item on a block
onKill Kill an entity
onKilledByArrow Get killed by an arrow
onPlaceBlock Place a block
onRecipeCrafted Craft a recipe
onRightClick(item) Right-click while holding an item
onShotCrossbow Shoot a crossbow
onSleptInBed Sleep in a bed
onStartRiding Start riding an entity
onTameAnimal Tame an animal
onTargetHit Hit a target block
onTick Every tick (per player)
onUsedEnderEye Use an eye of ender
onUsedTotem Trigger a totem of undying

Typical workflow

  1. Declare the entity or player handle that should receive the event helpers.
  2. Register one or more event handlers, either directly in the datapack or inside a function.
  3. Keep the handler bodies focused on gameplay reactions such as score updates, messaging, or spawning.

This pattern works well for mini-games where multiple systems need to react to the same player action.

Entity events

val zombie = entity(EntityTypes.ZOMBIE) {
  tag = "my_tag"
}

zombie.onDeath { self -> say("A ${self.type?.name} died!") }
Kotlin

The death event uses a loot-table trigger: on death the entity drops a hidden item detected by a tick dispatcher that runs all death handlers then removes the item.

See also

  • World Events - The world-side counterpart: tick, weather, day/night, and interval triggers.
  • Cooldowns - Gate event-driven abilities or interactions so players cannot spam them.
  • Entities & Players - Build the selectors and entity handles that receive these event helpers.
  • Items - React to item usage or rewards with reusable item stacks.