Minecraft 1.12 modding with forge – 13 – Custom slab

Hello everyone! In this part I will show you how to create a custom slab!

I’ll create 1 slab, it will be made with the purple tutorial blocks from the other tutorials. A slab in minecraft consists of 2 blocks, a half block and a double block. The half block can be either on the top or the bottom of a block, and if you place two of them on eachother they become the double block.

To start we need to create a new class in the blocks package. This class should extend BlockSlab and should be abstract, after doing this eclipse will complain because we need to add a constructor. The constructor takes a String for the name and a Material and calls the super constructor with the Material. We also need to add several methods:

  • getUnlocalizedName, which returns a String and takes an int for the meta value.
    • This method is used to convert the different meta values a slab can have to the correct UnlocalizedName, we will not use the meta value and just return super.getUnlocalizedName(). Because we only have 1 variant.
  • getVariantProperty, which returns IProperty<?>.
    • This method returns the property that is used to determine the value, this slab will only have one variant but we need to return a variant property or minecraft will crash.
  • getTypeForItem, which returns Comparable<?> and takes an ItemStack. 
    • This method returns the variant that the ItemStack is, again we can just return a default variant here.
  • getItemDropped, which returns Item and takes an IBlockState, Random and an int for the fortune level.
    • Will return the item this slab drops, we need this to make sure it will never drop a double slab.
  • getItem, which returns ItemStack and takes a World, a BlockPos and an IBlockState.
    • This returns an ItemStack with the correct meta value.
  • getMetaFromState, which returns an int and takes an IBlockState.
    • This converts the state of the block in a 4 bit value, this is important because this is the value minecraft will save with your block.
  • getStateFromMeta, which returns IBlockState and takes an int for the meta value.
    • This does the exact opposite of getMetaFromState, this converts the 4 bit meta value to a blockstate.
  • createBlockState, which returns BlockStateContainer.
    • This tells minecraft which properties we will use in our blockstate, for a slab we need a variant property and a half property (to tell which half we are on).

I know, a lot of methods, but we are not done yet! We also need to add 2 classes, I’ll put them in the BlockTutorialSlab class because they will be really simple. We need:

  • Double, this will be for when the slab is doule, and
  • Half, which (surprise!) will be for when the slab is half.

The last thing before we can start implementing the “logic” is an enum for our variant. This enum also implements IStringSerializable. I’ll call it Variant, with this enum we create a variable of type PropertyEnum<Variant> I’ll call it VARIANT. With this line you can create the property:

public static final PropertyEnum&amp;amp;amp;amp;lt;Variant&amp;amp;amp;amp;gt; VARIANT = PropertyEnum.&amp;amp;amp;amp;lt;Variant&amp;amp;amp;amp;gt;create("variant", Variant.class);

Now eclipse will give a lot of errors because we don’t return anything and our classes and enum miss some methods. But this is the base template we have now:

First we’ll finish the Variant enum because we’ll need it correct so eclipse will stop screaming at us.
We need to override getName in the enum, this is a method that will return a String. Because we will only have 1 variant we can just return default.
We also need to add an enum type called DEFAULT.

Now we’ll fill in the constructor, just like basic blocks we need to set the registry names and the unlocalized names.
Now we need to set the default blockstate, this depends on if the slab is double or half, if we are not a double slab we need the HALF property to be set to a default (I’ll set it to the bottom). For both the double and the half version we need to set the VARIANT property to default. We also need to set useNeighborBrightness to make sure the lightning looks “good” when the half slab is placed. This will be true when it is not double.

Now that we created the Variant property, change the getVariantProperty method to return the VARIANT property.
The getTypeForItem is also really simple, this method just returns the DEFAULT variant.
The getItemDropped is a little bit more difficult but still quite simple, we need to return the result of the getItemFromBlock method of the Item class when we pass the (not yet created) half slab block from the ModBlocks class. If you follow this tutorial exactly that will be Modblocks.tutorialSlabHalf.
In this method we return a new ItemStack of the same ModBlocks.tutorialSlabHalf.

In the getStateFromMeta we create an IBlockState variable with a VARIANT property set to DEFAULT.
If this is the half version of the slab (So not double) we need to determine if this is a top or bottom half slab. We do this by checking if the 4th bit is set to 1 or 0.

In the getMetaFromState we do the exact opposite, we create an integer and set the 4th bit to 1 if the slab is on the top side of a block.

In the createBlockState method we need to tell minecraft which properties our block has. This is depends on whether the block is double or not.
If this is a double slab we only need the VARIANT property, if it isn’t a double slab we need the VARIANT and HALF property.

Now we just need to finish the Double and Half classes and this file is done, they are almost the same except for one boolean.
We need to add a constructor, this constructor takes a String for the name and a Material and will just call the super constructor.
We also need to override the isDouble method, in the Double class this returns true, and in the Half class this returns false.

Now in the ModBlocks class we need to add 2 public static variables of type , tutorialSlabHalf and tutorialSlabDouble.
In the init method, instead of initializing BlockTutorialSlab we initialize BlockTutorialSlab.Double for the double slab and BlockTutorialSlab.Half for the half slab.
The last difference from a normal block is that we need to create an ItemSlab instead of a normal Item. The ItemSlab takes the slabblock, the half slabblock and the double slabblock.

event.getRegistry().register(new ItemSlab(tutorialSlabHalf, tutorialSlabHalf, tutorialSlabDouble).setRegistryName(tutorialSlabHalf.getRegistryName()));

In the registerRenders method we only need to register the half version because there won’t be an Item for the double block.

Now we just need to add the model files and texture files. The model files and textures can be found here.
If everything is good it will look like this:

The full sourcecode will be available on github.

I know this was a lot, and this is probably not the best way to explain it, so any tips would help! But I hope it helped and you can have fun with your new slab! Till next time!


Posted in Forge tutorial, Forge Tutorial 1.12.


  1. I’ve noted a few areas where the tutorial isn’t clear and just thought I’d let you know. Underneath the code snippet for the constructor of BlockTutorialSlab, you say “In this method we return a new ItemStack of the same ModBlocks.tutorialSlabHalf.” although you are talking about the getItemDropped method above, I assume this refers to the getItem method which is not apparent. You also haven’t explained the difference in the JSON files for models using variants, and I found that the JSON files were confusing as there are three files in the models folder, when we only registered two items for the slabs (double and half). I thought it was one JSON for each registered block, however I could be wrong. Lastly, I can’t find the full code on GitHub.

    Your tutorials have been very helpful I just wanted to point out these issues.

    • I agree that the tutorial should be clearer, this tutorial is for 1.12.2 and I will no longer work on these tutorials sadly. The code is all available tho, but you need to look at the correct branch (the 1.12 one). You need 1 json for the blockstate.json which maps the variants of the blocks to the model json. The simplest block (with custom texture) thus uses 2 json files, but this can be more if you have variants and less if you just want to use a vanilla model + texture. (eg make it look like dirt.)

  2. Thank you very much for your great tutorial! Helped me a lot with my mod. I would be happy to see tutorials from you in the future, if I update to 1.13 or 1.14.

  3. Im new to modding, and ive been following a couple tutorials, and i keep ending with the same issue. My half slabs work fine, they can be placed on top and bottom, but when i put 2 together to make a double slab my game crashes every time.
    It keeps throwing a “NullPointerException” on ItemSlab.java:152 and ItemSlab.java:73.
    Any help would be appreciated

    • I can only guess because you dont post your code, but I guess your tutorialSlabDouble is null because you never initiate it.

      • I’m very sorry for spamming, but when you add more than one slab, in:
        public Item getItemDropped(IBlockState state, Random rand, int fortune) {
        return Item.getItemFromBlock(ModBlocks.tutorialBlockSlabHalf);
        Do you put something akin to:
        public Item getItemDropped(IBlockState state, Random rand, int fortune) {
        return Item.getItemFromBlock(ModBlocks.tutorialBlockSlabHalf, ModBlocks.anotherTutorialBlockSlabHalf);

        • This class is made so it can only be used for 1 material. If you want to reuse the same class for multiple materials you need to add a variable to say which material it is. Or use the metadata system like vanilla does. But I dont recommend doing this because metatdata is removed in 1.13

  4. Could you do a tutorial on custom stairs? Because I’d like to make a set of stairs slabs and a block.

  5. can you make a tutorial on how to make custom enchantments not in the game already to be used on tools?

    • Hello,

      What kind of enchantment would be the most useful? A basic one like more attack damage or something more custom?

Leave a Reply

Your email address will not be published. Required fields are marked *