Minecraft 1.12 modding with forge – 15 – Custom Crop

Hello everyone! In this part I’ll show you how to add a custom crop, with seed.

To start we need to choose what kind of crop we want, the crop in this tutorial will drop the seeds for the crop and the tutorial dust created earlier in this tutorial. It will have 4 age stages and I will also show how to make it grow on other blocks than farmland.

To start we need to create a new block, this block will be the crop. So lets create a new class for it, I’ll call it BlockTutorialCrop.
It should extend BlockCrops. The constructor will do the standard, call the super constructor and set the unlocalized and registryname. That means it will also take a string for the name.

We will implement the methods in a bit but first we will need to create the seeds. In contrast to normal blocks we can’t just make an ItemBlock for this block.
Here you have to choose if you want to make “normal” seeds that can be planted on farmland or on special blocks (ex. stone). I’ll create the variable for the seed in the ModItems class but I’ll instantiate the seed at the same place as the ItemBlocks. (In the ModBlocks class)

  • Farmland:
    • You can do almost the same thing as you would do with a normal ItemBlock, but instead of instantiating ItemBlock instantiate ItemSeeds.
      The constructor takes 2 blocks, your crop (ModBlocks.tutorialCrop in my case) and the block it should be planted on (Blocks.FARMLAND, but as far as I can see this doesn’t get used and it always uses farmland). Don’t forget to also set the registryname and unlocalized name.
      Now just register it like a normal item.
  • Other blocks. There are multiple ways, I’ll explain 2 here. One requires changes to the block, the other requires a custom ItemSeeds class:
    • We need to create a custom ItemSeeds class, I’ll call it ItemTutorialSeeds. Make sure you extend ItemSeeds. (I’ll make this class as generic as I can, you could probably make more specific changes for your need)
      Eclipse will then complain because we need to add a constructor. The constructor will take 2 Blocks, the crop you want to grow and the block to grow it on, and 1 String, the block name. Make sure you call the super constructor with the 2 blocks. Ofcourse you also need to set the registry and unlocalized name in here.We’ll also make 2 variables, they will both be blocks and will be used save the crop and soil.We then need to override the onItemUse method. In here we’ll paste the vanilla ItemSeeds’ onItemUse method. But with one change. In the if statement we replace

      state.getBlock().canSustainPlant(state, worldIn, pos, EnumFacing.UP, this) 

      with

      state.getBlock()==this.soilBlock 

      Then register the ItemTutorialSeeds just like you would register the ItemSeeds as shown above.

    • The other way is to change the block. In the block’s class you can override canSustainPlant. Then in the method check if the crop is the correct type.
      return plantable.getPlant(world, pos).getBlock() == ModBlocks.tutorialCrop; 

      I’ll not add this in the repository, so if you have questions feel free to leave a comment or join the discord.

Now we’ll start the customization of our crop.
We first need 2 variables, one will save the age and the other will save the bounding box. They’ll be PropertyInteger and AxisAlignedBB[]. The propertyInteger will save the age of the crop, we don’t use a normal int because we want this to be saved in the world.
We’ll have to override quite a lot of methods:

  • canSustainBush
    • This will check if the block can sustain the crop.
  • canBlockStay
    • This will check if the block is in the right situation. Ex. light enough.
  • getAgeProperty
    • This returns the block’s property in which the age is stored
  • getMaxAge
    • This returns the max age this crop can be
  • getSeed
    • This returns the seed.
  • getCrop
    • This returns what the crop will yield when harvested
  • updateTick
    • In here we’ll update the crop.
  • getBonemealAgeIncrease
    • How much the effect of bonemeal is.
  • createBlockState
    • Needed because we use a property for the age.
  • getBoundingBox
    • To make the crop smaller than 1 block.

Almost every method in here is different for every use so I’ll just show my implementation here, you will probably have to change a lot for your own use:

Now for the textures, the seed is just a normal item so the textures work the same as a normal item. For the crop we need a couple more files than a normal block. This is because we need a model for every stage (there is probably a way to make this easier but vanilla has 1 model for every stage). The blockstate says which files to use for which stage:

Ofcourse, replace the names with the names for your block.

The model file is for every stage the same except the texture name, so I’ll just show the model file for one stage.

These are the textures I used:   

This part isn’t the best part I’ve done I know, but it is really difficult to make an abstract tutorial. There are a lot of ways to do this and every way has its advantages and disadvantages. If you see anything you don’t understand please don’t hesitate to ask in the comments below or the discord server on the side.

I hope this helped.

~suppergerrie2

Posted in Forge tutorial, Forge Tutorial 1.12.

3 Comments

  1. Just stumbled onto this while trying to figure out how to make my plants spawn naturally in the world, can you do a tutorial on that?

    • I’d love to do that, and I also had plans to do it (code was almost done) but I’ve been really busy and haven’t had the energy to work on any tutorials.

Leave a Reply

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