tutorial:datagen_loot

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tutorial:datagen_loot [2023/06/05 17:30] – Add comments inside onInitializeDataGenerator to be consistent with other data generation tutorials on the wiki mcrafterzztutorial:datagen_loot [2025/04/01 13:47] (current) solidblock
Line 1: Line 1:
 ====== Loot Table Generation ====== ====== Loot Table Generation ======
  
-Before reading this, make sure you've read [[datagen_setup|Getting started with Data Generation]], and have a class that implements ''DataGenerationEntrypoint''+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 [[datagen_setup|Getting started with Data Generation]], and have a class that implements ''DataGenerationEntrypoint''.
  
-To beginmake a class (or a few, you need one for blocks, chests and entities) that extends ''SimpleFabricLootTableProvider'' and register it like so:+===== Block loot tables ===== 
 +To add a data generation for block loot tablesjust create a class which extends ''FabricBlockLootTableProvider''.
  
-==== Setting Up ==== +<code java TutorialBlockLootTableProvider.java> 
-To get started with block lootcreate a block loot table generator+public class TutorialBlockLootTableProvider extends FabricBlockLootTableProvider { 
 +  protected TutorialBlockLootTableProvider(FabricDataOutput dataOutputCompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) { 
 +    super(dataOutput, registryLookup); 
 +  }
  
-<code java> +  @Override 
-private static class MyBlockLootTables extends FabricBlockLootTableProvider { +  public void generate() { 
-    public MyBlockLootTables(FabricDataOutput dataOutput) { +    // ... 
-         super(dataOutput); +  }
-    } +
-     +
-    @Override +
-    public void generate() { +
-        // ... +
-    }+
 } }
 +</code>
  
-// ...+And then, add this data generation in the entrypoint (we use ''ExampleModDataGenerator'' as an example): 
 +<code java ExampleModDataGenerator.java> 
 +public class ExampleModDataGenerator implements DataGeneratorEntrypoint { 
 +  @Override 
 +  public void onInitializeDataGenerator(FabricDataGenerator generator) { 
 +    FabricDataGenerator.Pack pack = generator.createPack();
  
- +    pack.addProvider(TutorialBlockLootTableProvider::new); 
-@Override +  }
-public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { +
-    // ... +
-    fabricDataGenerator.addProvider(MyBlockLootTables::new); +
-    // ...+
 } }
 </code> </code>
  
-Let's just create a simple ore block and an item to drop from it for a block loot tableAdd this to your block init or ''Tutorial'' class in this case.+> If you're using versions pre-1.20, please replace ''pack.addProvider(TutorialBlockLootTableProvider::new);'' with ''fabricDataGenerator.addProvider(TutorialBlockLootTableProvider::new);'' and remove ''FabricDataGenerator.Pack myPack = fabricDataGenerator.createPack();''
  
-<code java> +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: 
-public static final Block TEST_ORE = Registry.register(Registry.BLOCK, new Identifier("tutorial", "test_ore"), new Block(...));+<code java TutorialBlockLootTableProvider.java> 
 +  @Override 
 +  public void generate() 
 +    addDrop(TutorialBlocks.EXAMPLE_BLOCK); 
 +  } 
 +</code>
  
-public static final Item TEST_ITEM = Registry.register(Registry.ITEM, new Identifier("tutorial""test_item", new Item(...)); +This is the most common loot table for a blockWhen mined, drops oneWhen exploded in a explosion with decay (such as creeper and nether bed)it may be destroyed totally and drop nothing.
-// Let's just ignore the fact that there isn't a block item 😅 +
-</code>+
  
-==== Adding Block Loot ====+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):
 <code java> <code java>
-private static class MyBlockLootTables extends FabricBlockLootTableProvider { +    // drops nothing 
-    public MyBlockLootTables(FabricDataOutput dataOutput) { +    addDrop(TutorialBlocks.EXAMPLE_BLOCK, dropsNothing());
-         super(dataOutput); +
-    }+
          
-    @Override +    // drops a dirt block 
-    public void generate() { +    addDrop(TutorialBlocks.EXAMPLE_BLOCK, Blocks.DIRT); 
-        addDrop(Tutorial.TEST_BLOCK, drops(Tutorial.TEST_ITEM)); +     
-    } +    // drops itself only when with tools with Silk Touch, otherwise drops nothing 
-}+    addDropWithSilkTouch(TutorialBlocks.EXAMPLE_BLOCK); 
 +     
 +    // drops itself only when with tools with Silk Touchotherwise 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 five blocks 
 +    addDrop(TutorialBlocks.EXAMPLE_BLOCK, drops(TutorialBlocks.EXAMPLE_BLOCK) 
 +        .apply(SetCountLootFunction.builder(ConstantLootNumberProvider.create(5))));
 </code> </code>
  
-Now that we successfully adding a block. Now let's add chest loot+You can also generate loot tables for the [[crops]] we introduced before:
- +
-==== Adding Chest Loot ==== +
- +
-Firstly, we need an identifier. This identifier points to a json file that contains your chest loot. +
 <code java> <code java>
-// In Tutorial class +    addDrop(TutorialBlocks.CUSTOM_CROPcropDrops(TutorialBlocks.CUSTOM_CROP, TutorialItems.CUSTOM_ITEM, TutorialItems.CUSTOM_SEEDS, BlockStatePropertyLootCondition.builder(TutorialBlocks.CUSTOM_CROP).properties(StatePredicate.Builder.create().exactMatch(CropBlock.AGE, 7))));
-public static final Identifier TEST_CHEST = new Identifier("tutorial""chests/test_loot");+
 </code> </code>
  
-Let's create a chest loot table generator and register it like so.+===== Simple Loot Table =====
  
-<code java>+To add a simple loot table, which can also be used in many occasions, such as chests, we just extend ''SimpleFabricLootTableProvider''
 +<code java TutorialChestLootTableProvider.java> 
 +public class TutorialChestLootTableProvider extends SimpleFabricLootTableProvider { 
 +  public TutorialChestLootTableProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookupregistryLookup) { 
 +    super(output, registryLookup, LootContextTypes.CHEST); 
 +  }
  
-private static class MyChestLootTables extends SimpleFabricLootTableProvider { +  public static final RegistryKey<LootTable> TEST_CHEST = RegistryKey.of(RegistryKeys.LOOT_TABLEIdentifier.of("tutorial", "test_chest"));
-    public MyChestLootGenerator(FabricDataGenerator dataGenerator) { +
- super(dataGeneratorLootContextTypes.CHEST); +
-    }+
  
-    @Override +  @Override 
-    public void accept(BiConsumer<Identifier, LootTable.Builder> biConsumer) { +  public void accept(BiConsumer<RegistryKey<LootTable>, LootTable.Builder> lootTableBiConsumer) { 
-        biConsumer.accept(Tutorial.TEST_CHEST, LootTable.builder() +    lootTableBiConsumer.accept(TEST_CHEST, LootTable.builder() 
-                  .pool(LootPool.builder().rolls(ConstantLootNumberProvider.create(1.0F)) +        .pool(LootPool.builder().rolls(ConstantLootNumberProvider.create(1.0F)) 
-                  .with(ItemEntry.builder(Items.DIAMOND) +            .with(ItemEntry.builder(Items.DIAMOND) 
- .apply(SetCountLootFunction.builder(ConstantLootNumberProvider.create(1.0F))) +                .apply(SetCountLootFunction.builder(ConstantLootNumberProvider.create(1.0F)))) 
-                  .with(ItemEntry.builder(Items.DIAMOND_SWORD)).apply(EnchantWithLevelsLootFunction.create(UniformLootNumberProvider.create(20.0F, 39.0F)))) +            .with(ItemEntry.builder(Items.DIAMOND_SWORD))) 
-        ); +    ); 
-    }+  }
 } }
 +</code>
  
-// ...+And then in your entry point: 
 +<code java ExampleModDataGenerator.java> 
 +public class ExampleModDataGenerator implements DataGeneratorEntrypoint { 
 +  @Override 
 +  public void onInitializeDataGenerator(FabricDataGenerator generator) { 
 +    // ...
  
-@Override +    pack.addProvider(TutorialChestLootTableProvider::new); 
-public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { +  }
-    fabricDataGenerator.addProvider(MyChestLootTables::new);+
 } }
 </code> </code>
 +
 +> If you're using versions pre-1.20, please replace ''pack.addProvider(TutorialChestLootTableProvider::new);'' with ''fabricDataGenerator.addProvider(TutorialChestLootTableProvider::new);'', and remove ''FabricDataGenerator.Pack myPack = fabricDataGenerator.createPack();''.
 +
 +Now run the data generator, then start Minecraft and run the command ''/loot give @s loot tutorial:test_chest'' multiple times. See what happens! You can also try running the command ''/setblock ~ ~ ~ chest{LootTable:"tutorial:test_chest"}'' and open the chest.
tutorial/datagen_loot.1685986229.txt.gz · Last modified: 2023/06/05 17:30 by mcrafterzz