You can generate block (with automatic block states) and item models easily using the FabricModelProvider
class.
To get started, create a class that extends FabricModelProvider
, and register it at your datagen entrypoint like so:
private static class MyModelGenerator extends FabricModelProvider { private MyModelGenerator(FabricDataOutput generator) { super(generator); } @Override public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGenerator) { // ... } @Override public void generateItemModels(ItemModelGenerator itemModelGenerator) { // ... } } // ... @Override public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { // ... fabricDataGenerator.addProvider(MyModelGenerator::new); // ... }
The BlockStateModelGenerator
class contains many methods to create block models, in this example, we will create a block with the same texture on each side, also known as minecraft:block/cube_all
in json.
public static Block SIMPLE_BLOCK = Registry.register(Registries.BLOCK, new Identifier("tutorial", "simple_block"), new Block(...)); public static BlockItem SIMPLE_BLOCK_ITEM = Registry.register(Registries.ITEM, ..., new BlockItem(SIMPLE_BLOCK, ...)); // ... @Override public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGenerator) { blockStateModelGenerator.registerSimpleCubeAll(SIMPLE_BLOCK); }
Since a BlockItem
for SIMPLE_BLOCK
exists and has been registered, an item model will also be automatically generated that parents the block model. This can be overridden in the generateItemModels
method.
By default, data generation will throw an exception if the run did not generate blockstates for all blocks belonging to the processed mods.
Fabric API allows disabling this. To do so, edit your build.gradle
to remove the -Dfabric-api.datagen.strict-validation
VM arg from the loom {}
block.
The ItemModelGenerator
contains miscellaneous methods to create item models.
In this example, we will override the item model generated from the SIMPLE_BLOCK
block model in the previous example. We will generate an item model from SIMPLE_BLOCK_ITEM
public static Block SIMPLE_BLOCK = Registry.register(Registries.BLOCK, new Identifier("tutorial", "simple_block"), new Block(...)); public static BlockItem SIMPLE_BLOCK_ITEM = Registry.register(Registries.ITEM, ..., new BlockItem(SIMPLE_BLOCK, ...)); // ... @Override public void generateItemModels(ItemModelGenerator itemModelGenerator) { itemModelGenerator.register(SIMPLE_BLOCK_ITEM, Models.GENERATED); }
This is not done yet!!
QUICK WARNING: This is very complicated as heck!!!
In this, example, we will generate directional blockstates for our MACHINE_BLOCK
Firstly, we add the block itself and register it!
// In the Tutorial class (or your mod initializer class) public static final Block MACHINE_BLOCK = new Block(FabricBlockSettings.copy(Blocks.BLAST_FURNACE)); @Override public void onInitialize() { Registry.register(Registries.BLOCK, new Identifier("tutorial", "machine"), MACHINE_BLOCK); }
Now that we have successfully registered our block, let's get to the good stuff!
private static class MyModelGenerator extends FabricModelProvider { private MyModelGenerator(FabricDataOutput generator) { super(generator); } @Override public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGenerator) { // ... blockStateModelGenerator.blockStateCollector.accept(MultipartBlockStateSupplier.create(Tutorial.MACHINE_BLOCK) .with(When.create().set(Properties.HORIZONTAL_FACING, Direction.NORTH), BlockStateVariant.create().put(VariantSettings.X, VariantSettings.Rotation.X))); } @Override public void generateItemModels(ItemModelGenerator itemModelGenerator) { // ... } }