Skip to main content
Version: 26.2.x

Loot Events

dev.architectury.event.events.common.LootEvent

Modify or replace loot tables as they load.

Events

EventListener methodReturns
MODIFY_LOOT_TABLEmodifyLootTable(HolderLookup.Provider registries, ResourceKey<LootTable> key, LootTableModificationContext context, boolean builtin)void - add pools to the existing table.
REPLACE_LOOT_TABLEreplaceLootTable(HolderLookup.Provider registries, ResourceKey<LootTable> key, LootTable original)CompoundEventResult<LootTable> - interrupt to swap the whole table.
Added in 21.1

REPLACE_LOOT_TABLE was added in Architectury API 21.1.

Adding to a table

Use context.addPool(LootPool.Builder) to add a pool to the table.

The builtin flag tells you where the table came from: true means it's built in to vanilla or a mod; false means it's from a user data pack. A common pattern is to only modify built-in tables, so user data packs can fully override them.

note

On NeoForge, builtin is always true. The event does run for every loot table there, but LootTableLoadEvent does not expose where a table came from, so data pack tables cannot be told apart from built-in ones. Only Fabric reports the real value.

Example: add diamonds to the dirt loot table

LootEvent.MODIFY_LOOT_TABLE.register((registries, key, context, builtin) -> {
if (builtin && Blocks.DIRT.getLootTable().equals(Optional.ofNullable(key))) {
LootPool.Builder pool = LootPool.lootPool()
.add(LootItem.lootTableItem(Items.DIAMOND));
context.addPool(pool);
}
});

Replacing a table

Where MODIFY_LOOT_TABLE appends pools to the existing table, REPLACE_LOOT_TABLE swaps the whole table for a different one. Interrupt the CompoundEventResult with the replacement table to take effect, or return CompoundEventResult.pass() to leave the table alone. The first listener to interrupt wins, and later listeners still see the original table.

This mirrors NeoForge's LootTableLoadEvent#setTable and Fabric's LootTableEvents.REPLACE.

Example: replace a table outright

LootEvent.REPLACE_LOOT_TABLE.register((registries, key, original) -> {
if (key.identifier().equals(MyMod.id("chests/my_structure"))) {
return CompoundEventResult.interruptTrue(buildMyTable());
}
return CompoundEventResult.pass();
});