How-to: Add Chest Loot

Library of Exile fires ExileEvents.ON_CHEST_LOOTED whenever a RandomizableContainerBlockEntity (vanilla chest, barrel, etc.) fills itself from a loot table. Register a listener to inject items into that chest.


Register a listener

ExileEvents.ON_CHEST_LOOTED.register(new EventConsumer<ExileEvents.OnChestLooted>() {
    @Override
    public void accept(ExileEvents.OnChestLooted e) {
        ServerPlayer player = e.player;
        Container inventory  = e.inventory;   // the chest's item container
        BlockPos pos         = e.pos;         // position of the chest in the world
        LootParams ctx       = e.ctx;         // vanilla loot context (has Level, luck, etc.)

        // Example: add an item to a random empty slot
        ItemStack stack = new ItemStack(Items.DIAMOND);
        for (int i = 0; i < inventory.getContainerSize(); i++) {
            if (inventory.getItem(i).isEmpty()) {
                inventory.setItem(i, stack);
                break;
            }
        }
    }
});

A natural place to register this is inside registerDatabaseEntries() in your OrderedModConstructor, or in a static initializer that runs at mod load.


Using vanilla loot tables for chest rewards

If you want to add items via a standard Minecraft loot table rather than hardcoding them, use LootTable.fill() from the context's level:

ExileEvents.ON_CHEST_LOOTED.register(new EventConsumer<ExileEvents.OnChestLooted>() {
    @Override
    public void accept(ExileEvents.OnChestLooted e) {
        ServerLevel level = (ServerLevel) e.player.level();
        LootTable table = level.getServer().getLootData()
            .getLootTable(new ResourceLocation("my_mod", "chests/my_reward"));

        LootParams params = new LootParams.Builder(level)
            .withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(e.pos))
            .withParameter(LootContextParams.THIS_ENTITY, e.player)
            .create(LootContextParamSets.CHEST);

        table.fill(e.inventory, params, level.random.nextLong());
    }
});

Place your loot table JSON at:

src/main/resources/data/my_mod/loot_tables/chests/my_reward.json

Built-in tiered dungeon loot tables

Library of Exile ships five pre-built chest loot tables. You can reference them directly:

LibLootTables.TIER_1_DUNGEON_CHEST  // library_of_exile:chests/tier_1_dungeon
LibLootTables.TIER_2_DUNGEON_CHEST
LibLootTables.TIER_3_DUNGEON_CHEST
LibLootTables.TIER_4_DUNGEON_CHEST
LibLootTables.TIER_5_DUNGEON_CHEST

These are also used by MapFinishRarity entries to reward players when they complete a map.


Filtering by position or dimension

The BlockPos pos field lets you filter by location:

if (e.pos.getY() < 0) {
    // Only add items to chests below y=0
}

Use e.player.level().dimension() to restrict by dimension.


Notes

  • The event fires for any RandomizableContainerBlockEntity, including modded chests.
  • If the Lootr mod is present, the mixin performs a 1-block radius search to locate the correct block entity.
  • The event does not fire for mob drops — for those, see Add Monster Loot.