Skip to content
On this page

Events ​

In Katton, events are a powerful way to react to various actions and changes in the game. They allow you to execute custom code when specific events occur, such as player interactions, world changes, or entity updates.

To listen to an event, use Katton's event API. You can find all generated event pages in the Fabric API documentation, the NeoForge API documentation, or the Paper API documentation. Each event has its own argument type that provides event data and cancellation/mutation hooks.

Here is a simple example of how to listen to the onPlayerJoin event and send a welcome message to the player. This example is the same as the one in the Getting Started section.

kotlin
// Necessary imports for the script
import net.minecraft.network.chat.Component
import top.katton.api.ServerPhase
import top.katton.api.ServerScriptEntrypoint
import top.katton.api.event.PlayerArg
import top.katton.api.event.ServerPlayerEvent

// The function with @ServerScriptEntrypoint is the entry point of the script.
@ServerScriptEntrypoint(ServerPhase.READY)
fun main(){
   // Register an event listener for when a player joins the server
   ServerPlayerEvent.onPlayerJoin += onJoin@
   fun(arg: PlayerArg){
      // Get the player who joined and send them a message
      val player = arg.player
      // As same as you would do in a normal mod!
      player.sendSystemMessage(Component.literal("Hello Katton"))
   }
}

Each event has its own set of arguments that provide information about the event and allow you to interact with it. You can find the detailed arguments for each event in the API documentation.

Unwrapped Native Events ​

If Katton does not wrap the Fabric, NeoForge, or Paper event you need, use managed events. Managed listeners are registered against the native platform event bus, but Katton still tracks them by script pack scope. WORLD and SERVER_CACHE listeners are removed on reload or disconnect cleanup; GLOBAL listeners persist until manually unregistered or shutdown.

Register managed listeners inside a @ServerScriptEntrypoint or @ClientScriptEntrypoint function so Katton can record the current script owner and scope. Keep side-specific imports on the side where they run.

kotlin
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents
import top.katton.api.ServerPhase
import top.katton.api.ServerScriptEntrypoint
import top.katton.api.event.managed.registerFabricEvent

@ServerScriptEntrypoint(ServerPhase.READY)
fun listenFabricTicks() {
    registerFabricEvent(ServerTickEvents.START_SERVER_TICK, ServerTickEvents.StartTick { server ->
        println("Tick ${server.tickCount}")
    })
}
kotlin
import net.neoforged.neoforge.event.entity.living.LivingDamageEvent
import top.katton.api.ServerPhase
import top.katton.api.ServerScriptEntrypoint
import top.katton.api.event.managed.registerEvent

@ServerScriptEntrypoint(ServerPhase.READY)
fun listenNeoForgeDamage() {
    registerEvent<LivingDamageEvent.Pre> { event ->
        println("${event.entity.name.string} is about to take damage")
    }
}
kotlin
import org.bukkit.event.block.BlockExplodeEvent
import top.katton.api.ServerPhase
import top.katton.api.ServerScriptEntrypoint
import top.katton.api.event.managed.registerEvent

@ServerScriptEntrypoint(ServerPhase.READY)
fun listenBukkitExplosions() {
    registerEvent<BlockExplodeEvent>(priority = 4, ignoreCancelled = true) { event ->
        event.blockList().forEach { block ->
            println("Explosion touched ${block.type} at ${block.location}")
        }
    }
}

registerEvent and registerFabricEvent return a handle if you need to unregister manually. Most scripts do not need to keep it because Katton cleans managed listeners up during reload.

CAUTION

NEVER register native listeners without using Katton's managed event API. Katton will not be able to track or clean up those listeners, which can lead to memory leaks, duplicate handlers, and other unintended consequences.

Detailed Event List ​

Events provided for Fabric, NeoForge, and Paper are listed in the table below.

Event CategoryEvent NameFabricNeoForgePaper
Chunk and BlockonAfterBlockBreak✅-✅
onBeforeBlockBreak✅-✅
onBlockBreak-✅✅
onBlockEntityLoad✅✅✅
onBlockEntityUnload✅✅✅
onBlockPlace-✅✅
onCanceledBlockBreak✅-✅
onChunkDataLoad-✅✅
onChunkDataSave-✅✅
onChunkLevelTypeChange✅✅✅
onChunkLoad✅✅✅
onChunkSent-✅✅
onChunkUnload✅✅✅
onChunkUnWatch-✅✅
onChunkWatch-✅✅
onExplosionDetonate✅✅✅
onExplosionStart✅✅✅
Item ComponentonAllowEnchanting✅✅✅
onModifyComponent✅✅✅
onModifyEnchantment✅✅✅
ItemonUse✅✅✅
onUseOn✅✅✅
Living BehavioronAllowBed✅✅✅
onAllowNearbyMonsters✅✅✅
onAllowResettingTime✅✅✅
onAllowSettingSpawn✅✅✅
onAllowSleeping✅✅✅
onAnimalTame-✅✅
onBabySpawn-✅✅
onElytraAllow✅✅✅
onElytraCustom✅✅✅
onModifySleepingDirection✅✅✅
onModifyWakeUpPosition✅✅✅
onPlayerWakeUp✅✅✅
onSetBedOccupationState✅✅✅
onStartSleeping✅✅✅
onStopSleeping✅✅✅
Living Use ItemonUseItemFinish✅✅✅
onUseItemStart✅✅✅
onUseItemStop✅✅✅
onUseItemTick✅✅✅
Loot TableonLootTableAllLoad✅✅✅
onLootTableModify✅✅✅
onLootTableModifyDrops✅✅✅
onLootTableReplace✅✅✅
PlayeronAttackBlock✅-✅
onAttackEntity✅✅✅
onBlockInteract✅✅✅
onDestroyItem✅✅✅
onEntityInteract✅✅✅
onItemInteract✅✅✅
onLeftClickBlock-✅✅
onUseItemOn✅-✅
onUseWithoutItem✅-✅
Server Entity CombatonAfterKilledOtherEntity✅✅✅
onCriticalHit-✅✅
onShieldBlock✅✅✅
Server EntityonAfterEntityChangeLevel✅✅✅
onAfterEntityLoad✅-✅
onAfterPlayerChangeLevel✅✅✅
onEndermanAnger✅✅✅
onEntityLoad-✅✅
onEntityTeleport-✅✅
onEntityUnload✅✅✅
onEquipmentChange✅✅✅
ServeronAfterSave✅✅✅
onBeforeSave✅✅✅
onEndDatapackReload✅✅✅
onEndServerTick✅✅✅
onEndWorldTick✅✅✅
onLevelLoad-✅✅
onLevelSave-✅✅
onLevelUnload-✅✅
onServerStarted✅✅✅
onServerStarting✅✅✅
onServerStopped✅✅✅
onServerStopping✅✅✅
onStartDatapackReload✅✅✅
onStartServerTick✅✅✅
onStartWorldTick✅✅✅
onSyncDatapackContents✅✅✅
Server Living EntityonAfterDamage✅✅✅
onAfterDeath✅✅✅
onAllowDamage✅✅✅
onAllowDeath✅✅✅
onLivingDrops-✅-
onLivingFall✅✅✅
onLivingHurt✅✅✅
onLivingJump-✅✅
onMobConversion✅✅✅
Server MessageonAllowChatMessage✅-✅
onAllowCommandMessage✅-✅
onAllowGameMessage✅-✅
onChatMessage✅-✅
onCommandMessage✅-✅
onGameMessage✅-✅
onServerChat-✅✅
Server Mob EffectonAfterAdd✅-✅
onAfterRemove✅-✅
onAllowAdd✅-✅
onAllowEarlyRemove✅-✅
onBeforeAdd✅-✅
onBeforeRemove✅-✅
onMobEffectAdd-✅✅
onMobEffectApplicable-✅✅
onMobEffectExpire-✅✅
onMobEffectRemove-✅✅
Server PlayeronAfterPlayerRespawn✅✅✅
onItemPickupPost-✅-
onItemPickupPre-✅-
onItemToss-✅-
onPickFromBlock✅✅✅
onPickFromEntity✅✅✅
onPlayerCopy✅✅✅
onPlayerItemCrafted-✅-
onPlayerItemSmelted-✅-
onPlayerJoin✅✅✅
onPlayerLeave✅✅✅
onPlayerLoadFromFile-✅-
onPlayerPickupXp✅✅✅
onPlayerSaveToFile-✅-
onPlayerSpawnPhantoms-✅-
onPlayerXpChange✅✅✅
onPlayerXpLevelChange✅✅✅
onStartTracking-✅-
onStopTracking-✅-