How to make a mod for Minecraft, a complete guide | Plaguer

How to make a mod for Minecraft, a complete guide

Minecraft

08/08/2021 • by Weatherman

Making a mod for Minecraft isn't as hard as it sounds, although challenging to start with, making a mod will teach you a lot about the programming world, including logical thinking.

A mod is short for modification, this term is used in every game that allows the player to change the game in one way or another, there's a lot of games that will have their ways of mod creation, but once you learn the basics of programming you will quickly get the grasp of modding for all of them.

This article is focused on the Minecraft Java Edition, which is made in Java, and thus uses "jar" files as game modifications, if you've read our guide on how to install Minecraft mods and Forge you will have some idea of the process, knowing how to install a mod can be helpful to understand how to create one.

To create a Minecraft mod, you will need a way to communicate to the game and the computer, a way to give it instructions to follow, computers don't think by themselves, we need to tell them what to do.

This is why we have programming languages, they have defined syntaxes in which you can give instructions to the computer, and there are a lot of different programming languages, with their own rules and way to work.

Minecraft Java Edition happens to be made with the Java programming language, Java is a language developed by Oracle Corporation and designed by James Gosling, the code you write in Java is compiled and run on Java Virtual Machines (JVM), this way, Java code can run in any device, as it needs only the Java Virtual Machine to work.

This is the mod we will build on this guide:

Understanding more about Java

The term compiled is crucial when talking about Java, what does this term mean, and why Java runs on a Java Virtual Machine?

To understand why Java is the way it is, we need to understand why "traditional" programming languages are the way they are.

The usual programming language will be compiled to machine code, machine code is the language that your computer can understand, it won't understand anything besides that, it doesn't know how to read English terms.

But compiling directly to machine code has certain limitations, CPUs are different, and compiled code may not work on different computers, or when the compiler can do that, you still have to handle platform-specific code.

The Java Virtual Machine will take care of most stuff for you, it will run your Java code the same way while it can run on different devices, the Java code is compiled but to the language that the Java Virtual Machine understands, not to machine code.

This is a basic picture of how things work, but don't worry, it will be more clear once you see the example!

Understanding more about Forge and Minecraft modding

If you installed Minecraft: Java Edition mods before you probably used Forge, but why do we need to install Forge, couldn't we just put mods in the mods folder and play regular Minecraft?

Forge is a modding API, you can think of it as something that will give you tools to work with Minecraft, tools that Minecraft won't readily give you by default. Being free and open-source, the code for Forge itself is available for everyone to see, making it crystal-clear safe.

So in the big picture, mods will interact with the Forge API(the "set of tools") to modify Minecraft in a certain way, being easy to notice that Forge is at a high level dictating how things should be done. Forge has an important role when modding Minecraft, and learning more about it can greatly expand what you're able to achieve, there will be resources about it at the bottom of this article.

Setting up a Minecraft modding development environment

A few software are needed to develop mods, and all of them are free, the reason why we need development software is that they help humans to focus on what is important, giving hints, warning about errors when possible, and also doing the actual compiling and whatever is needed to create the final product, in this case, a beautiful Minecraft mod.

It's worth noticing that you can approach development in different ways, although we try to keep things as simple as possible, sometimes it's good to find what works better for you, so don't be afraid to search other tutorials if this doesn't "click" for you, it's not you, it's us!

To create our first Minecraft mod, we will need:

  • Open JDK: Open Java Development Kit is what we will use to develop Java-related things, you may already have Java on your computer, but these are the tools needed to work with Java.
  • MDK: Modding Development Kit, we have the kit for Java, we will also need a kit for mod development.

Well... how to download these things?

Downloading and Installing Open JDK:

  • There is a website AdoptOpenJDK that will help you download the JDK, access it at: https://adoptopenjdk.net/?variant=openjdk8&jvmVariant=hotspot
  • After accessing it, make sure that OpenJDK 8 (LTS) is checked, it should be because the above link will automatically check it for you, but by default, the OpenJDK 11 option is checked, and it is not the one we want
  • After changing, just click the big blue button that says download (Latest release), the other option doesn't need changes
  • The file will save to your computer, and after opening it, just press Next through the installer, the default options are alright, and after it ends, JDK is ready!

Downloading MDK:

  • If you downloaded Forge before you won't have trouble with this one, access the Forge download page
  • Usually, you would click on Installer to download Forge, but this time you will click on MDK, it's right to the next of Installer.
  • Create a folder called MDK somewhere on your system
  • The MDK is a .zip file, instead of a .exe downloader, open it and copy the files to the MDK folder you created

We now have both the JDK and the MDK files, great! There is just something left, that wasn't mentioned before... we need software where we can write our mod code, and for this, we will download IntelliJ IDEA.

Download and install IntelliJ IDEA:

  • Access IntelliJ IDEA download page
  • On the right side where it says Community, click on the download button
  • Run the installer and follow through clicking on Next

Congratulations if you got here, you now have an environment able to create Minecraft: Java Edition mods! 🎉

Creating your Minecraft mod project

It's time to start creating the structure of our mod and setting things up.

Open IntelliJ IDEA and wait for it to load, you will see a Welcome to IntelliJ IDEA window.

On this window, click on New Project, this will open a new window with settings for a new project. Most of this window will be left as it is, the only thing you have to change if needed, is where it says Project SDK.

IntelliJ IDEA new project window

Make sure Project SDK has version 1.8 selected, which is the Open JDK 1.8 we downloaded before.

IntelliJ IDEA new project options

After this, just click on Next. The next step will have an unchecked checkbox, leave it unchecked and press Next again.

For the project name, call it AwesomeLLamaMod, for the Project Location, you can leave the default or change the folder if you want.

After that, just click on Finish, and the project is created! Your project will open, you can close the popup tips that IDEA shows.

IntelliJ IDEA empty project

Setting up your mod files

It's time to start adding files to our project to set it up.

Do you remember the MDK thing you downloaded before and copied to a folder? It has to be copied to the mod folder that you're creating, you keep the MDK folder saved somewhere and when you need to use the kit, copy it to the new mod folder.

But not all files need to be copied, so follow these steps:

  • Make sure you have the MDK folder which you downloaded from the previous section
  • Right-click the AwesomeLLamaMod folder on IDEA, go to Open In, and select Explorer, this will show you the Project folder you specified before(you can also just navigate to it if you want)
IntelliJ IDEA right-click options on a folder
  • Open the folder AwesomeLlamaMod that IDEA showed you, now you will have both AwesomeLlamaMod and the MDK folders opened
  • Copy the following files from the MDK folder: build.gradle, gradlew.bat, gradlew, gradle folder, and paste them in the AwesomeLlamaMod folder.

Great! We have the basic files needed from MDK for our project, you can close the opened folders and go back to IDEA, you will notice that it now shows the added files.

The files are added but IDEA won't do anything with them by default, you have to right-click the build.gradle file and click on Link Gradle Project.

"build.gradle" linking using the option Link Gradle Project

The final step to be done with our IDE setup is to run a command on the project folder, to do this, open the terminal tab on the bottom of IDEA.

IntelliJ IDEA opening terminal

Type the following, and press enter:

./gradlew.bat genIntellijRuns

If you're on Linux, remove .bat from the command.

After running the command, wait once a green message saying BUILD SUCCESSFUL appears on the terminal, and you're able to type on it again.

Naming your mod, and configuring its details

We did set our IDEA project name to AwesomeLlamaMod, but we didn't define that in the code anywhere, we need to do that now, alongside some other personalization.

Before we get into editing the file that holds these configurations, let's go over the files we currently have in our mod folder.

You will notice that there is a bunch of folders and 3 files: build.gradle, gradlew, and gradlew.bat. Their similar names can create a lot of confusion, so let's go over each one of these files:

  • gradlew.bat: This is a startup script for Gradle that was made to run on Windows
  • gradlew: The gradlew file that doesn't end with .bat does the same thing that gradlew.bat, however, it was made for Linux systems, so both gradlew and gradlew.bat do the same thing, you just use them in different situations
  • build.gradle: Now this is the file that we edit for configurations, this is a file that will tell Gradle about our project and its tasks, this is called a build script.

The elephant in this room is Gradle, Gradle is a build automation tool, if you remember the Java section where we mentioned how code needs to be compiled, Gradle will take care of all that, and more, the building process includes compiling and everything else that may need to be done.

But Gradle can't magically know how we want it to handle our project, this is why we have the build.gradle file, it allows us to specify how our project is built, making it more organized.

Our project build.gradle file won't be empty, because we copied the default configuration for an MDK project.

Now that it should be more clear, open the file build.gradle on IDEA by clicking on it on the left panel.

If the file looks complicated to you, don't worry, learning about Gradle helps but we only need to know what we will edit and why.

The first thing first about our mod that we will change is its name, by default, there will be a line like this:

archivesBaseName = 'modid'

This is saying that the archivesBaseName value will be modid, the quotation around modid means that is a string/text. We will change it this way:

archivesBaseName = 'llamamod'

Notice how we changed but keeping archivesBaseName =and the quotation marks around llamamod, because we are only changing its value that comes after the equal symbol and inside the marks.

There is a group variable above archivesBaseName, change its value to mod.plaguertutorial.llamamod, which will give you the following result:

group = 'mod.plaguertutorial.llamamod'
archivesBaseName = 'llamamod'

Now we will finish modifying this file by using the search and replace feature of IDEA, you can open it by pressing CTRL+R, or clicking on the Edit tab on the top menu, going to Find, and selecting Replace.

IntelliJ IDEA replace text window, highlighting Replace All button

This feature replaces every occurrence of what you type on the first text field, with whatever you type on the second. We will use it because we have to replace all occurrences of examplemod with llamamod.

  • Type examplemod on the first text field
  • Type llamamod on the second text field, below it
  • To the right of the second text field, there is a button called Replace All, click on it because we want to replace all occurrences, and not just one

After it replaces all, it will show "0 results" on the Search and Replace window, you can close it.

Another file that holds information about our mod is a file called mods.toml, as we didn't copy the example that comes with the MDK folder, we will have to create this file, but you can always take a look at the example folder one to have a base of how it looks like.

If you followed all the above steps, you will notice that our project now has an src folder inside it, the path needed for the mods.toml file is src/main/resources/META-INF/mods.toml

These are the steps to create it:

  • On the left side panel, right-click the src folder and go to New and click on Directory, write main on the creation window to name it, and press Enter
IntelliJ IDEA add directory option
  • Do the same as above but now right-click on the main folder and create a directory named resources
  • Right-click the resources directory and create a new directory called META-INF inside it, paying attention that all letters are capitalized
  • Now for the META-INF folder we won't create a folder inside it, we will go to the same location but select File instead, and name it mods.toml
IntelliJ IDEA add file option
  • The file will be created and IDEA will open it, which will be a blank file

Good, now we only have to write this file content!

You can copy and paste this inside the created file as an example:

modLoader="javafml" # Mandatory!
loaderVersion="[@[email protected],)" # Mandatory!
license="All rights reserved" # Mandatory!

# Name and description and another options
[[mods]]
    modId="llamamod" # Mandatory!
    version="${file.jarVersion}" # Mandatory!
    displayName="Awesome Llama Mod" # Mandatory!
    description='''
    Hello world, this is my Awesome Llama Mod.
    It does awesome things.
    It is a llama Minecraft mod!
    ''' # Mandatory!
    credits="Awesome Llama Mod was created through a plaguer.com tutorial!" # Optional

After pasting this inside the file, press CTRL + S to save it.

Notice that this file has text written in English inside it, but machines don't understand English, so why it is written like that?

When you write text after a hashtag(#), the text will be ignored by the computer, so we write it for other humans to read and understand what we are doing. Different programming languages will have different ways of expressing a comment, here it just happens to be a hashtag.

The configuration above has basic comments explaining what is mandatory and what is not, but still, it's great to know more about what is happening here.

A .toml file will follow certain specifications, which you don't have to know 100% about, the declaration of data here is very similar to what we did before.

For example,

modId="llamamod"

This line is setting the value of modId to be llamamod, the quotation marks specify that we are using a string(text value), and the quotations are wrapped around our value for that data.

If you respect that pattern you can edit values as you wish, but of course, some configuration data need specific values, and you can't write anything you want, for example:

  • modLoader: This will always be javafml in this case, unless you're using another mod loader, don't change it.
  • loaderVersion: The value for this data is specially set as [@[email protected],), this will be further replaced with the correct version, so we don't have to worry about it, you could also replace this with a Forge version, but this way: [36,) and with the Forge version for the Minecraft version instead of 36.
  • [[mods]]: This specifies that the content below will be our mod and dependencies, notice how the text after this line is more to the right, this is called indentation, it makes it easier to read.
  • version: Using ${file.jarVersion} will make the versions be handled automatically for us, we could also specify this ourselves, but a convention needs to be followed.

Well now our mods.toml is set, our mod is named and configurated!

Coding our first Minecraft mod

Installing software, setting up dev environment, changing configurations, all done! It's time to start coding our mod, its functionalities, so we can play with it in Minecraft.

The first step to code a mod is to know what we want it to do, so we use the tools we have available to achieve that, in this case, our tool is Forge and the Java programming language.

For the llama mod, we will start with something basic, every time you break a Minecraft block, we want 3 llamas to appear! Can this be done? Indeed.

Let's go straight to the creation of our mod code file:

  • On the IDEA left side panel, make sure the src folder is opened, and the main folder is also opened
  • Inside the main folder, create a new directory called java(lowercase)
  • Right-click on the folder java, you will see that going to the New option won't show you Directory anymore, instead, click on Package and name it mod.plaguertutorial.llamamod
IntelliJ IDEA adding a new package
  • Now we need to create the actual code file, right-click the Package mod.plaguertutorial.llamamod and create a new Java Class, naming it LlamaMod, if there's no "room" to right-click over the llamamod folder, expand the left panel if needed
IntelliJ IDEA add java class option

Now you have the actual file for our code created, it should have some default code inside it but don't worry about that.

The code for LLamaMod.java will be:

package mod.plaguertutorial.llamamod;

import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@Mod("llamamod")
public class LlamaMod
{
    private static final Logger LOGGER = LogManager.getLogger();

    public LlamaMod() {
        LOGGER.info("Creating the mod...");
    }

    @Mod.EventBusSubscriber(modid = "llamamod", bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)
    public static class RegistryEvents {
        @SubscribeEvent
        public static void onBlockBreak(BlockEvent.BreakEvent event) {
            LlamaEvents.onBlockBreak(event);
        }
    }
}

We will need another file required by our mod file, create a new Java class on the same package(right-click mod.plaguertutorial.llamamod) and name it LlamaEvents, paste the following content inside it:

package mod.plaguertutorial.llamamod;

import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.horse.Llama;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.event.world.BlockEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class LlamaEvents {
    private static final Logger LOGGER = LogManager.getLogger();

    public static void onBlockBreak(BlockEvent.BreakEvent event) {
        LOGGER.info("A block was broken, spawning llamas...");

        BlockPos breakPosition = event.getPos();
        Vec3 llamasPosition = new Vec3(
                breakPosition.getX(),
                breakPosition.getY(),
                breakPosition.getZ()
        );

        Llama myNewLlama = new Llama(EntityType.LLAMA, (Level)event.getWorld());
        myNewLlama.setPos(llamasPosition);
        event.getWorld().addFreshEntity(myNewLlama);
    }
}

This makes our mod be able to start and listen to an event!

Creating the MCMETA file

This file is needed before launching our mod, it has basic information about the resource we're providing.

Create a new file inside the resources folder and call it pack.mcmeta, IDEA will open a window named "Register New File Type Association", just press OK, without changing anything, this is because .MCMETA is a file format it doesn't know about.

After creating the file, double click it to open, and paste the following content:

{
    "pack": {
        "description": "The Awesome Llama mod is awesome!",
        "pack_format": 6
    }
}

Do not forget the curly brackets!

This file is setting the description on the mods menu, and using format 6. There are other formats for different Minecraft versions.

Testing the Minecraft mod

For testing, you don't want to keep generating a .jar file and moving to the folder, there is an easier way to test a Minecraft mod.

You may notice that IDEA has a panel on the right, with Gradle written on the top, and it has a folder named Tasks in that panel. If you don't see the gradle panel, you can open it by clicking on Gradle on the top right of the screen.

Open the Tasks folder on the Gradle panel, open the forgegradle runs task folder, and double click runClient.

IntelliJ IDEA runClient task on the Gradle panel

Minecraft will open with your mod already loaded, you can create a single-player world and test the mod.

If you minimize Minecraft for a second, you will notice that IDEA has a little terminal open with messages being logged, this is information that can be used to debug mod errors and know more about what is going on.

Understanding what the mod is doing

Assuming no Java experience or Minecraft modding knowledge, we will try to explain what the mod files are doing, programming resources will be linked if applicable.

First starting with the file called LlamaMod.

This is the first line on the LlamaMod file:

package mod.plaguertutorial.llamamod;

What is it doing?

This line states that the file belongs to our mod.plaguertutorial.llamamod package. Packages group classes that have something in common, in this scenario our entire mod is in the same package because it is small enough.

Packages can be imported, for example, you could create a package that is useful in different projects, and then import this package on many of your projects.

Java provides us useful packages, but we also have Forge and Minecraft packages in hand.

w3schools has a great guide on Java packages, which you can take a look to learn more about it.

If you are not used to programming, understand the patterns and follow them, note how almost all lines in our mod files end with a semicolon, and how some words are orange in IDEA, some are yellow, others purple, why? Pay attention to these patterns and you will quickly get familiar with programming.

To understand semicolons, curly brackets, and related, take a look at this Oracle Java tutorial.

To understand what an "orange word" does take a look at this w3schools table.

Lines 3 to 8 of our LlamaMod file:

These lines all start with "import", a reserved word that is being used to import packages that we will need in the file.

For example, the line:

import org.apache.logging.log4j.Logger;

Is importing a package called "org.apache.logging.log4j.Logger", which is a package like our mod.plaguertutorial.llamamod package, which is a file somewhere that will contain classes and methods that we use in our file.

The above line is needed because on line 13, we have this:

private static final Logger LOGGER = LogManager.getLogger();

Forgetting the reserved words "private static final" for now, we have:

Logger LOGGER = LogManager.getLogger();, 

"Logger" is being used here as a variable type, but this type isn't a Java primitive type, so it has to exist somewhere for us to reference it.

This is why we are importing it! The same applies to all other import lines, they are used somewhere in our code.

If you add "//" to the start of an import line, it will comment such line, IDEA will mark on red some part of the code because it lacks the import for that reference.

Line 10:

@Mod("llamamod")

It can be complicated to understand the lines that will start with @. This is called an annotation.

The annotation will do something for you, and there are different types of annotation, the Mod annotation comes from Forge, and it will tell Forge to load this class as a mod. We are passing llamamod as a value, which should be the same value for the mod id defined in the mods.toml file.

Line 11:

public class LlamaMod

This is making a public accessible class named LlamaMod. Our file is called LlamaMod so this class has to be named LlamaMod. Following the class, you will have a curly bracket that makes a block. You can learn more about classes on w3schools.

From this point, the lines of our code are all inside the LlamaMod class block, you will frequently see "private" and "public" orange words when inside a class block, learning about classes will help you with this, so for brevity, we won't go over private and public for all lines.

Line 13:

private static final Logger LOGGER = LogManager.getLogger();

This creates a variable named LOGGER, which has the type Logger. The equal sign assigns the value being returned from a function called getLogger from a class called LogManager, which we imported from a package. The final keyword won't allow this variable to be changed again, as we have no reason to do so.

Lines 15 to 17:

You will notice that the method LlamaMod() here has no type, it says public behind it, but there's no type specified after public.

This is because that is a constructor, the constructor has the same name as our class(LlamaMod) and no type. The constructor is called when our class is constructed.

Line 16 uses a method named info in our LOGGER variable to show a message in the terminal when our mod constructor is called.

Lines 19 to 25

@Mod.EventBusSubscriber(modid = "llamamod", bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)

This is another annotation provided by Forge, it helps us to register an event, the event is used so we can know when something happens in the game, so we can react to it in some way.

On line 21, @SubscribeEvent:

This will allow the method below this annotation to listen to an event. This is our method:

onBlockBreak(BlockEvent.BreakEvent event) {
    LlamaEvents.onBlockBreak(event);
}

Every time a block is broken in-game, this method will call yet another method from a class named LlamaEvents(that we created!), and it will pass the event information to that method.

This is all for the LlamaMod file.

Now for the LlamaEvents file:

This file is on the same package as the other file, so they can access each other.

This file declares a class named LlamaEvents on line 12, which also has a logger as the previous file had.

Lines 15 to 28:

This is the method that is called on the other file with a BlockEvent.BreakEvent parameter.

onBlockBreak(BlockEvent.BreakEvent event)

Inside this method block, we can define what will happen when the method is executed, and we defined that it needs a BlockEvent.BreakEvent type parameter, which we can use.

Line 16 will log A block was broken, spawning llamas... to the terminal.

BlockPos breakPosition = event.getPos();

This is declaring a variable named breakPosition, which has the type BlockPos. The variable is assigned the value of event.getPos, which is a method available on the event variable because it has the type BlockEvent.BreakEvent.

We are getting the position that the block was broken, and storing it in breakPosition.

Line 19 to 23:

Vec3 llamasPosition = new Vec3(
        breakPosition.getX(),
        breakPosition.getY(),
        breakPosition.getZ()
);

This has more lines, but it's similar to the above line, it just has multiple parameters being passed, and we can freely add line breaks to make it easier to read.

This line is declaring a variable named llamasPosition which has the type Vec3. This variable is being assigned the value of a new Vec3 initialized with the X, Y, and Z position of the breakPosition variable that we stored above.

Do you remember that our file LlamaMod has a constructor called LlamaMod? Vec3 also has a constructor, but its constructor takes 3 parameters that we need to specify to construct it.

The keyword new is being used to create a new instance of a Vec3 with the constructor we specified.

getX, getY, and getZ are all methods defined inside the BlockPos type. They return the positions X, Y, and Z of a block position.

Vec3 is short for Vector3, think about it as a type that holds 3 values, and we are giving it 3 values.

Line 25:

Llama myNewLlama = new Llama(EntityType.LLAMA, (Level)event.getWorld());

This is creating a variable myNewLlama of type Llama.

We are calling Llama constructor with the entity type "LLAMA", and constructing it on the world that the block was broken

Line 26:

This line sets the position of our new llama to be the position we stored before.

Line 27:

This will add our llama entity to the world!

Spawning 3 llamas instead of one

Currently, our mod only creates one Llama when blocks break, this is cool, but we wanted it to spawn 3 llamas. We can create more llamas using a for the loop around our existing code.

To do this, change the file LlamaEvents and wrap the code that spawns our llama with a For Loop:

for (int i = 0; i < 3; i++) {
    Llama myNewLlama = new Llama(EntityType.LLAMA, (Level)event.getWorld());
    myNewLlama.setPos(llamasPosition);
    event.getWorld().addFreshEntity(myNewLlama);
}

To understand the For Loop, we can break it into three pieces.

int i = 0;

This is creating a variable named "i", which can be accessed in the For Loop. The variable initially will have the value 0.

i < 3;

This is saying that the For Loop body will repeat until i is lesser than 3. We defined i to start with the value of 0, as zero is less than 3, our loop will start.

i++

i++ is a short for i = i + 1

We are specifying that after the end of each iteration, we will increment the value of i by 1.

This essentially means that after 3 iterations, i will be equal or higher than 3, and the condition i < 3 will be no longer true, stopping our loop after 3 iterations.

Now the code that creates and spawns a llama in our world is repeated 3 times, making 3 llamas spawn when a block is broken.

Save the file with CTRL + S and run again the runClient task to test the game.

How to spawn a trader llama?

Our mod is looking great, but it would be awesome if we could change it a little bit to spawn some trader llamas!

Especially, if we could make every even llama spawned to be a trader llama.

Our code has the loop that runs 3 times, and inside our loop where we spawn the llamas, we have access to that "i" variable that holds the current iteration number.

When the first llama is spawned "i" is equal to 0.

When the second llama is spawned "i" is equal to 1.

When the third llama is spawned "i" is equal to 2.

We know that what defines even numbers is that every even number is divisible by two. So we want to check if "i" is divisible by two, and then spawn a trader llama instead.

So this is the For Loop that can create our traveler llamas:

for (int i = 0; i < 3; i++) {
    EntityType llamaType = EntityType.LLAMA;

    if (i % 2 == 0) {
        llamaType = EntityType.TRADER_LLAMA;
    }

    Llama myNewLlama = new Llama(llamaType, (Level)event.getWorld());
    myNewLlama.setPos(llamasPosition);
    event.getWorld().addFreshEntity(myNewLlama);
}

What changed here?

Starting with this line:

EntityType llamaType = EntityType.LLAMA;

We are storing the entity type in a variable, and initializing it to be EntityType.LLAMA, which is a regular llama.

And below we have an if condition:

if (i % 2 == 0) {
    llamaType = EntityType.TRADER_LLAMA;
}

The body of our if condition only is called when our if condition is true. For this line, our condition is i % 2 == 0, whenever this is true, the body inside curly brackets will run.

Let's understand i % 2 == 0 bit by bit.

% is an operator, like + or -, this is the remainder operator which will return the remainder after a division.

When i is equal to 0, that condition will be 0 % 2, and 0 / 2 as no remainder, so it equals 0.

So our if condition will be 0 == 0, this is comparing if 0 equals 0, and that is true! So our body will run.

This is the body of our if condition:

llamaType = EntityType.TRADER_LLAMA;

This is setting our llamaType variable to be a trader llama. This variable was initially set to be a regular llama, but as this code will run after that initialization, it will be overwritten with TRADER_LLAMA instead.

When the code that creates the llama is executed:

new Llama(llamaType, (Level)event.getWorld())

It uses the llamaType variable, which will be either a trader llama or a regular one depending on our if condition, achieving the result we wanted!

Save and test the game!

Building our mod jar file

So far we tested the mod using the runClient task, this is great because it will quickly launch Minecraft allowing us to see how our mod is working. But to build our mod and create a .jar file, which we can send to our friends if we want, we will have to run the build task.

The build task is inside the folder build, instead of "forgegrade runs", double click it to build our jar file.

IntelliJ IDEA build Gradle task

The task will run and you can follow its progress on the terminal, if everything goes alright, you will see a BUILD SUCCESSFUL message.

Your jar file is now on your project folder, inside the build and libs folder.

You can install this file as any other mod, we have a guide on how to install Minecraft mods which you can take a look at if needed. The mod should show in the mods list with an appropriate version, as this is a final build.

Further reading

Hopefully, this guide will help you to start making Minecraft mods, if you believe something should be changed, take a look at our contact page to reach out.

These are awesome resources that will help you to understand more about Java and Minecraft modding:

The entire w3schools Java tutorials are a great way to get started with Java.

The Forge Documentation provides detailed information about the modding API.