Minecraft 1.12 modding with forge – 4 – custom block

Hello everyone,

Today we are going to make a custom block and an item for the block, an ItemBlock. This tutorial will only cover the most basic block, just a solid cube with a texture. In some of the next tutorials we will go more in depth in making a block.


Just like with the item we are going to create some files to keep some structure in our mod.

  1. Create a package in the mod package and call it blocks. This package will contain all of the custom block classes.
  2. Inside the blocks package create a class called BlockBasic. This will contain all of our custom logic, for this block it won’t be much.
  3. Inside the init package create a class called ModBlocks. Here we will instantiate all of our blocks.

If you have been following the other tutorials your package structure should look a little like this:

Open the BlockBasic class and make it extend Block (Make sure you import “net.minecraft.block.Block”). It will now give an error because it needs a constructor. Add a constructor with as arguments a String, for the name, and a Material (Make sure you call super(material) in the constructor). Then just as in the ItemBasic class, call the methods setUnlocalizedName and setRegistryName. 

Now open the ModBlocks class. This class is almost the same as the ModItems class, except it will register Block and an ItemBlock. When you register a Block you just register the placed version of a Block, if you want an Item for the block you have to also register an ItemBlock. Some blocks don’t have an Item version (like the end portal frame), but most blocks have (like the dirt block).
In the ModBlocks class add a static Block variable, I will call it tutorialBlock. Now we need to add 5 public static void methods.

  1. The first method that will be called is init this will initialize our block variable, it doesn’t take any arguments.
  2. Then we add registerBlocks, this needs an argument of type RegistryEvent.Register<Block>, it also needs an @SubscribeEvent annotation. This method will be called when forge registers all of the blocks.
  3. The third method will be registerItemBlocks, this also needs an argument but now of type (RegistryEvent.Register<Item>. And it also needs an @SubscribeEvent. Here we will register our ItemBlocks.
  4. Just like in the ModItems class we need to register our ItemBlock models. So add a method registerRenders, this needs an argument of type ModelRegistryEvent and also an @SubscribeEvent.
  5. The last method will be registerRender this is exactly the same as in the ModItems class, it needs an Item as argument.

We also have to add @Mod.EventBusSubscriber(modid=Reference.MODID) above the class declaration.

The class should now look a little like this:

In the init function initialize the tutorialBlock variable. I will name it “tutorial_block” and for the material I will pass it Material.ROCK (You can see all of the materials in net.minecraft.block.material).

In the registerBlocks function get the Registry by calling getRegistry on the event and call registerAll on the registry.

The registerItemBlocks function is almost the same, except you don’t pass it the tutorialBlock but you instantiate a new ItemBlock and pass it the tutorialBlock. You also have to call setRegistryName on the ItemBlock.

In the registerRenders function call registerRender and pass it the ItemBlock, you can get the ItemBlock by calling the static method Item.getItemFromBlock and passing it the tutorialBlock.

And the registerRender function is the same as in the ModItems class.

Now we just have to call ModBlocks.init() in the main mod class’ preInit method.

We now have a working block, you can run the game and use the command “/give @p modid:itemname” to get the item or place the block by using “/setblock ~ ~ ~ modid:blockname”. But it looks a little strange, that is because we haven’t added the models and textures yet, so lets do that now.

In the assets.modid.models package create a new package named block. In this package add a new text file, give the text file the following content you can name it whatever you want but it has to be lowercase:

Replace the words in caps with your values.
In the assets.modid package create a new package called blockstates. In this package create a text file and give it the following content, again save it as blockname.json:

Replace the words in caps with your values.
Now in the assets.modid.textures package create a new package called blocks, here you can put your texture, it has to be a power of 2 (16×16,32×32, etc.) and a .png. I will use this texture: 
This is enough for the block itself to get a texture, but the ItemBlock doesn’t have a texture yet. We will fix that now:

In the assets.modid.models.item folder create a new text file. Give it the following content and name it blockname.json:

Now we just have to fix the name. Go to your lang file (assets.modid.lang) and add the following line:

 tile.BLOCKNAME.name=YOUR NAME 

You should now have a working AND good looking block!

To change some of the behaviour of the block you can do the same as with the item, call a set method while instantiating the block. To change the time it takes to mine call setHardness and pass it a float, I will pass it 1.5f just like the vanilla stone block. The higher the value the longer it takes to mine.
It will probably also be useful to put it in a creativetab, this is done exactly the same as with Items, just call the method setCreativeTab and pass it the tab you want. I will put it in CreativeTabs.BUILDING_BLOCKS.
I will also make it give of light, this is done by calling the method setLightLevel. This method asks for a float this has to be a value from 0 to 1. If you want it to give of a light level of 15 (Highest value) enter 15f/15f or 1.0f. For a value of i (Where 0≤i≤15) enter i/15f.

This is the final line:

tutorialBlock = new BlockBasic("tutorial_block", Material.ROCK).setHardness(1.5f).setCreativeTab(CreativeTabs.BUILDING_BLOCKS).setLightLevel(1.0f); 

I also want to make it only mineable by a iron pickaxe or higher. Because I used Material.ROCK it is already only mineable by pickaxes, but to have it only mineable by iron or hight call setHarvestLevel. This method asks for 2 variables, 1 String toolClass and one int Level:

  • toolClass can be:
    • “pickaxe”
    • “shovel”
    • “axe”
  • level can be:
    • 0 for wood or gold
    • 1 for stone
    • 2 for iron
    • 3 for diamond

This message can’t be used in chaining because it doesn’t return the Block instance we were working on. So you need to call this method separately.
Here are all of the classes we created this tutorial:

This way you can change some basic things of the block, you can click here to see all of the code from this part. In some of the next tutorials we will make some more advanced blocks.
But for now that was it.

As always if you have any question don’t hesitate to ask in the comments! Also if you saw any errors in the tutorial please let me know so I can fix it!

~suppergerrie2

Posted in Forge tutorial, Forge Tutorial 1.12.

17 Comments

  1. Do you have any intention of updating your repository and/or tutorial with a working 1.14 version?

    Best regards

    • There are about 5 parts released for the 1.14 tutorial at the time of your question, the repository is also updated to the latest part of the tutorial.

          • Extending BlockCake does work, but at least for me, it messes up the texture of the block. I actually came here looking for a fix. So if you feel like responding to this, I’d be very grateful.

          • The texture problem is probably because cakes have a property to keep track of how much cake is left, and in your blockstate.json you have to tell minecraft what model to use for each cake level. Check the vanilla cake blocksate file. (assets/minecraft/blockstates/cake.json)

  2. Hello there,

    My name is Aly and I would like to know if you would have any interest to have your website here at suppergerrie2.com promoted as a resource on our blog alychidesign.com ?

    We are in the midst of updating our do-follow broken link resources to include current and up to date resources for our readers.
    .
    If you may be interested please in being included as a resource on our blog, please let me know.

    Thanks,
    Aly

  3. “Now we just have to call ModBlocks.init() in the main mod class’ preInit method.”
    You shouldn’t do that, you already register them with the subscribevent. No need to init them.

    • Yep, you can also call init from registry event. I changed all of this in the 1.13 tutorial. (You dont even need the init method at all you can directly register the instances)

  4. Isn’t the following line wrong..?

    ‘Now we just have to call ModBlocks.init() in the main mod class’ init method.’

    Should call ModBlocks.init() from main mod class’ preInit method.

Leave a Reply

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