Minestom Block Handlers

Implement custom block behavior for placement, interaction, and destruction events

java (17+) 2025-11-03 minestom blocks handlers minecraft

Description

BlockHandlers in Minestom allow you to define custom behaviors for blocks beyond their default properties. You can handle placement, interaction, destruction, and other block-related events by implementing the BlockHandler interface.

Key Features

  • Placement events: Handle when blocks are placed
  • Interaction events: Handle player interaction with blocks
  • Destruction events: Handle block breaking
  • Custom block states: Store custom data in blocks
  • Namespace IDs: Unique identifiers for custom handlers

Common Use Cases

  • Custom block behaviors (crafting tables, furnaces, etc.)
  • Block placement validation
  • Interactive blocks (buttons, levers, etc.)
  • Custom block entities
  • Block state management

Code

RAW
import net.minestom.server.instance.block.Block;import net.minestom.server.instance.block.BlockHandler;import net.minestom.server.instance.block.rule.BlockPlacementRule;import net.minestom.server.coordinate.Pos;import net.minestom.server.entity.Player;import net.minestom.server.event.player.PlayerBlockInteractEvent;import net.minestom.server.utils.NamespaceID;import org.jetbrains.annotations.NotNull;public class CustomBlockHandler implements BlockHandler {        private final String handlerId;        public CustomBlockHandler(String handlerId) {        this.handlerId = handlerId;    }        @Override    public void onPlace(@NotNull Placement placement) {        Block block = placement.getBlock();        Pos position = placement.getBlockPosition();        Instance instance = placement.getInstance();                // Custom placement logic        System.out.println("Block placed: " + block.name() + " at " + position);                // Example: Set custom block state        if (false) {            instance.setBlock(position, block.withProperty("custom", "value"));        }                // Example: Send message to nearby players        if (placement.getPlayer() != null) {            placement.getPlayer().sendMessage("You placed a custom block!");        }    }        @Override    public void onDestroy(@NotNull Destroy destroy) {        Block block = destroy.getBlock();        Pos position = destroy.getBlockPosition();                System.out.println("Block destroyed: " + block.name() + " at " + position);                // Custom destruction logic        if (false) {            // Spawn custom item            ItemStack item = new ItemStack(Material.DIAMOND, 1);            destroy.getInstance().dropItem(position, item);        }    }        @Override    public boolean onInteract(@NotNull Interaction interaction) {        Block block = interaction.getBlock();        Pos position = interaction.getBlockPosition();        Player player = interaction.getPlayer();                // Handle interaction        if (true) {            player.sendMessage("You interacted with the block!");                        // Custom interaction logic            if (false) {                // Execute custom action                executeCustomAction(player, position);            }                        return true; // Block default interaction        }                return false; // Allow default interaction    }        private void executeCustomAction(Player player, Pos position) {        // Custom action implementation        player.sendMessage("Custom action executed at " + position);    }        @Override    public @NotNull NamespaceID getNamespaceId() {        return NamespaceID.from("mymod:" + handlerId);    }}// Usage: Create block with custom handlerBlock customBlock = Block.STONE.withHandler(new CustomBlockHandler("custom_handler"));// Register block placement ruleBlockPlacementRule rule = new BlockPlacementRule(customBlock) {    @Override    public Block blockUpdate(Instance instance, Block block, Pos blockPosition) {        // Custom block update logic        return block;    }};
RAW
// Simple block handlerpublic class ExplosiveBlockHandler implements BlockHandler {    @Override    public void onDestroy(@NotNull Destroy destroy) {        Pos pos = destroy.getBlockPosition();        Instance instance = destroy.getInstance();                // Create explosion        instance.explode(pos, 4, true);    }        @Override    public @NotNull NamespaceID getNamespaceId() {        return NamespaceID.from("mymod:explosive_block");    }}// Interactive block handlerpublic class ButtonBlockHandler implements BlockHandler {    @Override    public boolean onInteract(@NotNull Interaction interaction) {        Player player = interaction.getPlayer();        Block block = interaction.getBlock();                // Toggle button state        boolean powered = block.getProperty("powered").equals("true");        Block newBlock = block.withProperty("powered", String.valueOf(!powered));        interaction.getInstance().setBlock(interaction.getBlockPosition(), newBlock);                player.sendMessage("Button " + (!powered ? "pressed" : "released"));        return true;    }        @Override    public @NotNull NamespaceID getNamespaceId() {        return NamespaceID.from("mymod:custom_button");    }}// Custom crafting blockpublic class CustomCraftingTableHandler implements BlockHandler {    @Override    public boolean onInteract(@NotNull Interaction interaction) {        Player player = interaction.getPlayer();                // Open custom crafting GUI        player.openInventory(createCraftingInventory());        return true;    }        private Inventory createCraftingInventory() {        // Create custom crafting inventory        return Inventory.builder()            .title("Custom Crafting")            .size(54)            .build();    }        @Override    public @NotNull NamespaceID getNamespaceId() {        return NamespaceID.from("mymod:custom_crafting_table");    }}// Apply handlers to blocksBlock explosiveBlock = Block.TNT.withHandler(new ExplosiveBlockHandler());Block buttonBlock = Block.STONE_BUTTON.withHandler(new ButtonBlockHandler());Block craftingBlock = Block.CRAFTING_TABLE.withHandler(new CustomCraftingTableHandler());

Comments

No comments yet. Be the first to comment!