User Tools

Site Tools


tutorial:datagen_setup

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_setup [2022/12/22 11:42] jmanc3tutorial:datagen_setup [2024/03/15 05:06] (current) shnupbups
Line 1: Line 1:
 ====== Getting started with Data Generation ====== ====== Getting started with Data Generation ======
  
-Data Generation is a new module of the Fabric API, it allows you to dynamically generate Recipes, Language Files, Loot Tables, Advancements and pretty much anything with Custom Providers.+Data Generation is a module of Fabric API which allows you to programmatically generate Recipes, Language Files, Loot Tables, Advancements and pretty much anything with Custom Providers. Every time you modify the code that generates advancements (or anything else datagen can make like loot tables and such) you'll have to run the gradle task ''**runDatagen**'' which we will create shortly. 
 +  
 +===== Enabling Data Generation =====
  
-First we'll add a new gradle task which will take the code we write to generate data and spit out files Minecraft can read. Every time you modify the code that //generates// advancements (or anything else datagen can make like loot tables and such) you'll have to run the gradle task ''runDatagenClient''. We will do that later, but first open up your ''build.gradle'' file and add the following task:+The recommended way to enable the data generation API is to //have// checked the ''**Data Generation**'' box when creating your project using the [[https://fabricmc.net/develop/template/|fabric template mod generator]]:
  
-<code groovy>+{{https://i.imgur.com/NjIARzL.png}}
  
-// ... (The rest of the file)+Doing so would've created the gradle task ''**runDatagen**'' for us, and would've made a configuration to run in our IDE so we wouldn't have to use the terminal. The good news is it doesn't take very long to do the same manually.
  
-loom { +===== Manually Enabling Data Generation =====
-    runs { +
-        // +
-        // This adds a new gradle task that runs the datagen API: "gradlew runDatagenClient" +
-        // +
-        datagenClient { +
-            inherit client +
-            name "Data Generation+
-            vmArg "-Dfabric-api.datagen" +
-            vmArg "-Dfabric-api.datagen.output-dir=${file("src/main/generated")}" +
-            vmArg "-Dfabric-api.datagen.modid=${modid}"+
  
-            runDir "build/datagen" +First open up your ''**build.gradle**'' file in the root folder of your project, and add the following anywhere inside that file: 
-        } + 
-    } +<code groovy build.gradle [highlight_lines_extra="5,6,7"]>
-}+
  
 // //
-// Adds the generated files into the jar you distribute to players.+// ... (The rest of the file)
 // //
-sourceSets { + 
-    main { +fabricApi 
-        resources { +    configureDataGeneration()
-            srcDirs += [ +
-                    'src/main/generated' +
-            ] +
-        } +
-    }+
 } }
 </code> </code>
  
-You'll notice it makes use of the variable ''${modid}''. That should be defined in the ''gradle.properties'' fileCheck and see if you have it there, and if not, you can add it like this:+Next we'll define a new class in our project ''**ExampleModDataGenerator**'' which implements ''**DataGeneratorEntrypoint**''
  
-<code properties> +  * The ''**onInitializeDataGenerator**'' function will be called whenever the gradle task we created earlier (''**runDatagen**''is ran. 
-// .. (The rest of the file)+
  
-modid=the-name-of-your-mod-change-me-please +<code java ExampleModDataGenerator.java>
- +
-// .. (The rest of the file) +
-</code+
- +
-Next we'll define a new class in our project ''DataGeneration'' which implements ''DataGeneratorEntrypoint'' +
- +
-  * The ''onInitializeDataGenerator'' function will be called whenever the gradle task we created earlier (''runDatagenClient'') is ran.  +
- +
-<code java>+
 import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
 import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
  
-public class DataGeneration implements DataGeneratorEntrypoint {+public class ExampleModDataGenerator implements DataGeneratorEntrypoint {
  
     @Override     @Override
-    public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) {+    public void onInitializeDataGenerator(FabricDataGenerator generator) { 
 +        FabricDataGenerator.Pack pack = generator.createPack();
  
 +        // Adding a provider example:
 +        // 
 +        // pack.addProvider(AdvancementsProvider::new);
     }     }
 +
 } }
 </code> </code>
  
-Now we need to tell fabric about this entry point in our ''fabric.mod.json'' file:+Now we need to tell fabric about this entry point in our ''**fabric.mod.json**'' file:
  
-<code javascript [highlight_lines_extra="6,7,8"]>+<code javascript fabric.mod.json [highlight_lines_extra="6,7,8"]>
 { {
  
Line 76: Line 57:
   "entrypoints": {   "entrypoints": {
     "fabric-datagen": [     "fabric-datagen": [
-      "DataGeneration"+      "com.example.ExampleModDataGenerator"
     ],     ],
     "main": [     "main": [
-      "AdvancementsTutorial"+      "com.example.ExampleMod"
     ],     ],
     "client": [     "client": [
-      "AdvancementsTutorialClient"+      "com.example.ExampleModClient"
     ]     ]
   },   },
Line 91: Line 72:
 </code> </code>
  
-Before continuing further let's see if what we have so far is working, or if we have any errors. Run the ''runDatagenClient'' task. You can have your IDE do that for you, or just open the terminal in the root directory of your project and do:+Before continuing further let's see if what we have so far is working, or if we have any errors. Run the ''**runDatagen**'' task. You can have your IDE do that for you, or just open the terminal in the root directory of your project and do:
  
-<code bash> +<code batch Windows> 
-./gradlew runDatagenClient+gradlew runDatagen 
 +</code> 
 + 
 +<code bash Linux
 +./gradlew runDatagen
 </code> </code>
  
 Read the output and make sure there are no errors. Read the output and make sure there are no errors.
  
-  * You can safely ignore: ''com.mojang.authlib.exceptions.InvalidCredentialsException: Status: 401'' if it comes up. That error happens because the debug version of Minecraft we're running doesn't try to authenticate our account.+  * You can safely ignore: ''**com.mojang.authlib.exceptions.InvalidCredentialsException: Status: 401**'' if it comes up. That error happens because the debug version of Minecraft we're running doesn't try to authenticate our account.
  
 If you do get an error, it's usually pretty explicit about what's missing or wrong, but if you can't seem to figure it out, you might want to head over to the discord, and get some help. If you do get an error, it's usually pretty explicit about what's missing or wrong, but if you can't seem to figure it out, you might want to head over to the discord, and get some help.
  
-There should be a new folder in ''src/main'' called ''generated''. For now it'll be empty, but once we start generating data (like advancements), that is where it'll be saved.+There should be a new folder in ''**src/main**'' called ''**generated**''. For now it'll be empty, but once we start generating data (like advancements), that is where it'll be saved
 + 
 +==== IDE Integration (Optional) ==== 
 + 
 +Because we don't want to be opening the terminal all the time, we can setup a configuration in ''**IntelljJ IDEA**'' that will run the command for us through a drop-down menu.  
 + 
 +First open the ''**Run/Debug Configurations**'' menu. You can open it by opening the drop-down menu next to the run button and clicking ''**Edit Configurations..**'' option or you can double click ''**Shift**'' and type ''**Edit Configuration**'' into the menu that pops up. 
 + 
 +Next click the ''**'+'**'' button, search for ''**gradle**'', and select it. 
 + 
 +Inside the ''**Run**'' textbox write ''**runDatagen**''. Click ''**Okay**'' and you should be able to simply run the configuration instead of having to open the terminal.
  
 ====== Adding Providers ====== ====== Adding Providers ======
Line 118: Line 113:
 In this example, we will be creating a tag provider, as it is the simplest to understand. In this example, we will be creating a tag provider, as it is the simplest to understand.
  
-Firstly, inside your ''MyModDatagen'' class, create a new ''private static class'' that extends ''FabricTagProvider<T>'':+Firstly, inside your ''**ExampleModDataGenerator**'' class, create a new ''**private static class**'' that extends ''**FabricTagProvider<T>**'':
  
-//If you want, you can place this class in a seperate file, but we recommend it stays in your datagen entrypoint class.//+//If you want, you can place this class in a separate file, but we recommend it stays in your datagen entrypoint class.//
  
 <code java> <code java>
-private static class MyTagGenerator extends FabricTagProvider<Item> +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; 
-        public MyTagGenerator(FabricDataGenerator dataGenerator) { +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; 
-            super(dataGeneratorRegistries.ITEM);  // for versions 1.19.2 and below, use Registry.ITEM+import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; 
 +import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; 
 +import net.minecraft.item.Item; 
 +import net.minecraft.item.Items; 
 +import net.minecraft.registry.RegistryKeys; 
 +import net.minecraft.registry.RegistryWrapper; 
 +import net.minecraft.registry.tag.ItemTags; 
 +import net.minecraft.registry.tag.TagKey; 
 +import net.minecraft.util.Identifier; 
 +import java.util.concurrent.CompletableFuture; 
 + 
 +public class ExampleModDataGenerator implements DataGeneratorEntrypoint { 
 + 
 +    @Override 
 +    public void onInitializeDataGenerator(FabricDataGenerator generator) { 
 +        FabricDataGenerator.Pack pack = generator.createPack(); 
 + 
 +        pack.addProvider(MyTagGenerator::new); 
 +    } 
 + 
 +    private static class MyTagGenerator extends FabricTagProvider.ItemTagProvider 
 +        public MyTagGenerator(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) { 
 +            super(outputcompletableFuture);
         }         }
  
         @Override         @Override
-        protected void generateTags() { +        protected void configure(RegistryWrapper.WrapperLookup arg) { 
-            +
         }         }
 +    }
 } }
 </code> </code>
  
-We will add some basic tags inside ''generateTags()'' for example's sake.+We will add some basic tags inside ''**configure()**'' for example's sake.
  
-<code java+<code java [highlight_lines_extra="9,15,16,17,18"]> 
-// We will create an item tag called "smelly_items"+public class ExampleModDataGenerator implements DataGeneratorEntrypoint {
-private static final TagKey<Item> SMELLY_ITEMS TagKey.of(RegistryKeys.ITEM, new Identifier("tutorial", "smelly_items"));+
  
-@Override +    // ... (The rest of the file)
-protected void generateTags() { +
-     // This creates a tag builder, where we add slime balls, rotten flesh and everything in the minecraft:dirt item tag. +
-     getOrCreateTagBuilder(SMELLY_ITEMS) +
-              .add(Items.SLIME_BALL) +
-              .add(Items.ROTTEN_FLESH) +
-              .addOptionalTag(ItemTags.DIRT); +
-     // This will automatically generate "assets/tutorial/tags/items/smelly_items.json" in the "generated" folder. +
-+
-</code>+
  
-Now, we will need to register this provider to the data generator in the ''onInitializeDataGenerator'' in your entrypoint class like so:+    private static class MyTagGenerator extends FabricTagProvider.ItemTagProvider {
  
-<code java+        // ... (The rest of the file) 
-public class MyModDatagen implements DataGeneratorEntrypoint { + 
-    @Override +        private static final TagKey<ItemSMELLY_ITEMS = TagKey.of(RegistryKeys.ITEM, new Identifier("mymod:smelly_items")); 
-    public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { + 
-        fabricDataGenerator.addProvider(MyTagGenerator::new);+        @Override 
 +        protected void configure(WrapperLookup arg) { 
 +          // This creates a tag builder, where we add slime balls, rotten flesh and everything in the minecraft:dirt item tag. 
 +          // This will automatically generate "src/main/generated/data/tutorial/tags/items/smelly_items.json" in the "generated" folder. 
 +          getOrCreateTagBuilder(SMELLY_ITEMS) 
 +                  .add(Items.SLIME_BALL) 
 +                  .add(Items.ROTTEN_FLESH) 
 +                  .addOptionalTag(ItemTags.DIRT); 
 +        }
     }     }
 } }
 </code> </code>
  
-When we run ''gradlew runDatagenClient'', we should see the generated folder forms, and the item tag json should be present:+When we run ''**gradlew runDatagen**'', we should see the generated in ''**src/main/generated/data/tutorial/tags/items/smelly_items.json**'', and the item tag json should be present:
  
 <file javascript smelly_items.json> <file javascript smelly_items.json>
tutorial/datagen_setup.1671709373.txt.gz · Last modified: 2022/12/22 11:42 by jmanc3