Adding Blocks in 1.8

Hello, I’m back, and this time I will be showing how to create the exact same thing we created before once again, but the difference, in 1.8. 1.8 Has a few cons and pros. The con being it takes a lot of work to create a single freaking block. The pros however, that this provides much, MUCH more simplification for bulk amounts of blocks as well as 3D block models. Also, blockstates.

Let’s start then! First, like always, we create a class to store all our blocks. Let’s call it ModBlocks.

public class ModBlocks
{
    public static Block red_diamond;

    public static void preInit() {}

    public static void init() {}

    private static void registerModel(Block block) {}
}

“Whoa there! What are those, EMX?” You may ask. Here’s the basic idea.

  • preInit() – To be called from main mod class, in FMLPreInitializationEvent, to register our blocks.
  • init() – To be called also from the main mod class, in FMLInitializationEvent to register the block JSONs. If you put this part in the preInit() method, you will crash with a NullPointerException, because Forge doesn’t have the necessary stuff loaded that we need to use here, before initialization event.
  • registerModel(Block block) – A small helper method to register block’s model mesher.

Alright! Ready to continue? Perfect.

As usual, let’s create a block object. I’ll be making a Red Diamond Block. If you do too, you may use this texture:

Your ModBlocks class should look like this:

public class ModBlocks
{
    public static Block red_diamond;

    public static void preInit()
    {
        red_diamond = new BlockRedDiamond();
    }

    public static void init() {}

    private static void registerModel(Block block) {}
}

There we go. Now, let’s create our Block class itself, BlockRedDiamond.

public class BlockRedDiamond extends Block
{
    private static final String name = "red_diamond";

    public BlockRedDiamond()
    {
        super(Material.rock);
        setUnlocalizedName(name);
        GameRegistry.registerBlock(this, name);
        setCreativeTab(CreativeTabs.tabBlock);
    }
}

Nothing much, just a normal block. The only difference is that it once again uses setUnlocalizedName() instead of setBlockName().

Alright! Now, let’s fill in the helper method I said before, registerModel().

private static void registerModel(Block block)
{

}

Notice, we have an argument, which is the block you wish to register JSONs on.

Simply put, this gets the ItemModelMesher that we need to, well, mesh item models! We’re using the register(Item,meta, ModelResourceLocation) method in the ItemModelMesher we just got. Since we’re making a Block, but the method accepts an Item, we’ll have to convert our block with a tool available in Item class:

Item.getItemFromBlock(block);

With that, we’ll input our block from the method argument and output it as an Item.

To the next part, which is meta. Enter 0 for default, but this is simply the block metadata, you may change it if you wish to. Next, we need to specify the model resources, so we’re using this:

new ModelResourceLocation(ResourceLocation res, String inv);

The first is the actual file location, so we’ll enter this:

new ResourceLocation(Tutorial.MODID.toLowerCase(), block.getUnlocalizedName.substring(5));

The first is your mod ID, in lower case, and the second argument is the unlocalized name. We use substring(5) because getUnlocalizedName() returns a name with “tile.” in front of it, so we use substring(5) to remove the first 5 characters.

Adding this to the ModelResourceLocation, we get this:

new ModelResourceLocation(new ResourceLocation(Tutorial.MODID.toLowerCase(), block.getUnlocalizedName.substring(5)), String inv);

So far so good. Now, the second parameter is just the string “inventory”. So, you’ll have this in total:

new ModelResourceLocation(new ResourceLocation(Tutorial.MODID.toLowerCase(), block.getUnlocalizedName.substring(5)), "inventory");

Perfect! Now, you should have this in total:

private static void registerModel(Block block)
{
    ItemModelMesher mesher = Minecraft.getMinecraft().getRenderItem().getItemModelMesher();

    mesher.register(Item.getItemFromBlock(block), 0, new ModelResourceLocation(new ResourceLocation(SampleMod.MODID.toLowerCase(), block.getUnlocalizedName().substring(5)), "inventory"));
}

We’re done with this method. Now, let’s make use of the last unused method we created earlier, which is init().

registerModel(red_diamond);

Simply put that in the init() method to register the block JSON.

We’re done with the coding part! The Java coding part, to be exact. Now, let’s fiddle with the JSONs. Before starting, I’ll explain a little bit about resources.

  • assets.<modid>
    • lang – language files here (en_US.lang)
    • blockstates – blockstate JSON belongs here, manages available blockstates of blocks
    • models – root folder of block and item models
      • item – item models
      • block – block models
    • textures – root folder of block and item textures
      • items – item textures
      • blocks – block textures

That said, we’ll have three different JSONs. That’s right, three. One for blockstate, one for block model, one of item model. Also, have your block texture in assets.<modid>.textures.blocks.

Right. First, the blockstate JSON.

{
    "variants": {
        "normal": { "model": "tutorial:red_diamond" }
    }
}

Name it exactly same as your block’s unlocalized name. In my case, red_diamond.json.

Next up, the block model. We do not need to model blocks here, because Minecraft provides a parent class to which we can use for normal full 1m cubes.

{
    "parent": "block/cube_all",
    "textures": {
        "all": "tutorial:blocks/red_diamond"
    }
}

Notice the “parent” parameter? That’s what we use to use Minecraft’s cube_all block model for our model. You can however change the parent and/or create your own block model here.

Lastly, the item model. This is what renders in your inventory and also when you hold it in your hands.

{
    "parent": "tutorial:block/red_diamond",
    "display": {
        "thirdperson": {
            "rotation": [ 10, -45, 170 ],
            "translation": [ 0, 1.5, -2.75 ],
            "scale": [ 0.375, 0.375, 0.375 ]
        }
    }
}

This is the bare minimum of what you need for a working full cube. For now, stick to those numbers. Those numbers are the same as vanilla, and what they do is transform the render block to the players hands.

You should be done now!

23 thoughts on “Adding Blocks in 1.8

  1. ANONYMOUS February 20, 2016 / 12:49 AM

    Where do I go for the JSON part?

    Like

    • Emx2000 February 20, 2016 / 12:51 AM

      you mean where to place the jsons?

      Like

      • ANONYMOUS February 24, 2016 / 4:45 AM

        It’s the bit after this line where I lose you: “We’re done with the coding part! The Java coding part, to be exact. Now, let’s fiddle with the JSONs. Before starting, I’ll explain a little bit about resources.”

        Like

  2. ANONYMOUS March 1, 2016 / 4:47 AM

    Sorry o post the same question again, but I never got a response last time. I lost you after you said this: “We’re done with the coding part! The Java coding part, to be exact. Now, let’s fiddle with the JSONs. Before starting, I’ll explain a little bit about resources.” Can you elaborate a bit?

    Like

      • ANONYMOUS March 2, 2016 / 3:48 AM

        Where do you put the code? Also, where is assets..textures.blocks?

        Like

      • Emx2000 March 4, 2016 / 7:31 PM

        The code is put in your source folder:
        src/main/java

        the assets in your resources folder: src/main/resources

        Like

      • ANONYMOUS March 5, 2016 / 4:01 AM

        Alright, thanks. So how do you do the code in the JSON part? What exactly do you put this in:

        {
        "variants": {
        "normal": { "model": "tutorial:red_diamond" }
        }
        }

        Like

      • Emx2000 March 9, 2016 / 7:16 PM

        Just above that you can see a little list that corresponds to 1.8 asset hierarchy.

        Like

  3. ANONYMOUS March 27, 2016 / 4:57 PM

    Is there is a problem with HTML or PHP in the part &quot;inventory&quot;.
    Would not be a problem, but new programmers/ minecraft moders could get stuck. ( if they don’t know that much about coding )

    Like

    • ANONYMOUS March 27, 2016 / 4:58 PM

      and &quot;red_diamond&quot;.

      Like

  4. ANONYMOUS March 30, 2016 / 4:17 AM

    I’m not sure what the problem is, but the block I created doesn’t show up in the game. I don’t see any errors in the console, and Minecraft recognizes my code as a mod. I followed this tutorial to the letter, but a few things could be the problem. Nothing is in my main mod class, except the base stuff. I also followed a different tutorial than your “starting to mod” tutorial, but that’s just location of the files. Do you have any idea what could be wrong?

    Like

    • Emx2000 March 30, 2016 / 7:28 PM

      A common mistake is that you didn’t register your block. GameRegistry.registerBlock(Block block, String name);

      Like

      • ANONYMOUS March 31, 2016 / 3:15 AM

        Where do I put this? Right now, in my “blocks” class, I have this: “GameRegistry.registerBlock(this, name);” That seems to be the closest thing in your tutorial to “GameRegistry.registerBlock(Block block, String name);”

        Like

      • Emx2000 March 31, 2016 / 9:06 PM

        You can actually put it in the init() method of your blocks class, or you can put it in the constructor of your block class. Same thing

        Like

      • ANONYMOUS April 4, 2016 / 12:04 AM

        So I put GameRegistry.registerBlock(Block block, “red_diamond”); in my constructor ( private static void registerModel(Block block) ), replacing red_diamond with the name of my block. Eclipse seems to have a problem with Block and block, both separate errors. It says Block cannot be resolved to a variable and thinks block is a syntax error, and should be deleted.

        Like

      • Emx2000 April 7, 2016 / 3:59 PM

        Show me the whole class via PasteBin or Gist

        Like

      • ANONYMOUS April 11, 2016 / 9:18 AM

        This is my ModBlocks class. I figured out a bit on filling out the line of code, but currently the only error is says is on Material.rock. It says “rock cannot be resolved or is not a field.” even though I’ve put Material.rock in my BlockRedDiamond class.

        http://pastebin.com/geFr3sR4

        Like

      • Emx2000 April 12, 2016 / 11:59 AM

        Either you did not import that correctly (Ctrl + Shift + O), or you have something wrong with your project dependencies.

        Like

  5. ANONYMOUS April 8, 2016 / 3:11 AM

    Sorry to keep bothering you, but you mentioned earlier that I may have forgotten to register my block. I just realized, shouldn’t ” GameRegistry.registerBlock(this, name); ” have done that? It’s in my BlockRedDiamond class.

    Like

    • Emx2000 April 12, 2016 / 11:57 AM

      Yes, it should. If you’re sure you’ve done that correctly, please show me the complete code via PasteBin or Gist.

      Like

Leave a comment