This is an old revision of the document!
Table of Contents
Loot Table Generation
In this tutorial, you will learn how to generate loot tables for blocks and other contents. With data generation, you do not need to write JSONs for each block anymore. Before reading this, make sure you've read Getting started with Data Generation, and have a class that implements DataGenerationEntrypoint
.
Block loot tables
To create add a data generation for block loot tables, just create a class which extends FabricBlockLootTableProvider
.
- TutorialBlockLootTableProvider.java
public class TutorialBlockLootTableProvider extends FabricBlockLootTableProvider { protected TutorialBlockLootTableProvider(FabricDataOutput dataOutput, CompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) { super(dataOutput, registryLookup); } @Override public void generate() { // ... } }
And then, add this data generation in the entrypoint (we use ExampleModDataGenerator
as an example):
public class ExampleModDataGenerator implements DataGeneratorEntrypoint { @Override public void onInitializeDataGenerator(FabricDataGenerator generator) { FabricDataGenerator.Pack pack = generator.createPack(); pack.addProvider(TutorialBlockLootTableProvider::new); } }
If you're using versions pre-1.20, please replacepack.addProvider(TutorialBlockLootTableProvider::new);
withfabricDataGenerator.addProvider(TutorialBlockLootTableProvider::new);
and removeFabricDataGenerator.Pack myPack = fabricDataGenerator.createPack();
。
In the previous blocks tutorial, we created an example block. Now let's use the data generator to generate its loot table. It's as simple as:
- TutorialBlockLootTableProvider
@Override public void generate() { addDrop(TutorialBlocks.EXAMPLE_BLOCK); }
This is the most common loot table for a block. When mined, drops one. When exploded in a explosion with decay (such as creeper and nether bed), it may be destroyed totally and drop nothing.
You can also make it drop a little more complex, for example (the code is just to show an exmaple; please do not add loot tables for one block multiple times):
// drops nothing addDrop(TutorialBlocks.EXAMPLE_BLOCK, dropsNothing()); // drops a dirt when mined addDrop(TutorialBlocks.EXAMPLE_BLOCK, Blocks.DIRT); // drops itself only when with tools with Silk Touch, otherwise drops nothing addDropWithSilkTouch(TutorialBlocks.EXAMPLE_BLOCK); // drops itself only when with tools with Silk Touch, otherwise drops a dirt block addDropWithSilkTouch(TutorialBlocks.EXAMPLE_BLOCK, Blocks.DIRT); // drops itself only when with shears or tools with Silk Touch, otherwise drops nothing addDrop(TutorialBlocks.EXAMPLE_BLOCK, dropsWithSilkTouchOrShears(TutorialBlocks.EXAMPLE_BLOCK)); // drops three blocks addDrop(TutorialBlocks.EXAMPLE_BLOCK, drops(TutorialBlocks.EXAMPLE_BLOCK).apply(SetCountLootFunction.builder(ConstantLootNumberProvider.create(5))));
You can also generate data for the crops we introduced before:
addDrop(TutorialBlocks.CUSTOM_CROP, cropDrops(TutorialBlocks.CUSTOM_CROP, TutorialItems.CUSTOM_ITEM, TutorialItems.CUSTOM_SEEDS, BlockStatePropertyLootCondition.builder(Blocks.WHEAT).properties(StatePredicate.Builder.create().exactMatch(CropBlock.AGE, 7))));
Adding Chest Loot
Firstly, we need an identifier. This identifier points to a json file that contains your chest loot.
// In Tutorial class public static final Identifier TEST_CHEST = new Identifier("tutorial", "chests/test_loot");
Let's create a chest loot table generator and register it like so.
private static class MyChestLootTables extends SimpleFabricLootTableProvider { public MyChestLootGenerator(FabricDataOutput dataGenerator) { super(dataGenerator, LootContextTypes.CHEST); } @Override public void accept(BiConsumer<Identifier, LootTable.Builder> biConsumer) { biConsumer.accept(Tutorial.TEST_CHEST, LootTable.builder() .pool(LootPool.builder().rolls(ConstantLootNumberProvider.create(1.0F)) .with(ItemEntry.builder(Items.DIAMOND) .apply(SetCountLootFunction.builder(ConstantLootNumberProvider.create(1.0F)))) .with(ItemEntry.builder(Items.DIAMOND_SWORD)).apply(EnchantWithLevelsLootFunction.create(UniformLootNumberProvider.create(20.0F, 39.0F)))) ); } } // ... @Override public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { FabricDataGenerator.Pack myPack = fabricDataGenerator.createPack(); myPack.addProvider(MyChestLootTables::new); }
If you're using versions pre-1.20, please replace myPack.addProvider(MyBlockLootTables::new);
with fabricDataGenerator.addProvider(MyBlockLootTables::new);
。You can also remove FabricDataGenerator.Pack myPack = fabricDataGenerator.createPack();
。