Basic Modding - Basic Modfile

Goal

I want to show you how to create the basic modfile and how it works.

Difficulty

1/10 - Pretty simple

Prerequisites

You must have set up Forge.

Forge Version

This Tutorial was created with Forge 10.14.1.1334 for Minecraft 1.8. If anything doesn't work with other versions, please contact me!


Package structure and naming conventions

While creating a mod we will create several files which should be arranged in a logical way. Therefore we should place them in packages. A package is nearly the same as a folder on your computer.

When we write a mod we should place our main class in a package named com.<yourname>.<yourmodname>. This makes it easier for other people to understand the mod.

For this tutorial my base package will be named com.bedrockminer.tutorial.

 

To create a package, we right-click on the "src/java" folder in your mod's project in the package explorer of Eclipse. Then we click New > Package and type the name of the package.

If we now click OK we can see a white box under the "src/java" folder named like the name we just entered. This is the package we created.


Note: To be exactly, we didn't create one package but three. One which is named "com" and contains another package named "yourname" which contains a third package named "yourmodname".

 

In this package we have to create a new Java class. To do this, we right-click on the package and click New > Class. We leave all the fields as they are, but in the "Name" field we type "Main". If we now click on OK, a new class called "Main.java" is created.

Actually this class looks like this which is the default class look:

Main.java:
package com.bedrockminer.tutorial;

public class Main {

}
Picture - Show

The content of the main modfile

The following code is the content of a basic modfile.

I'll explain this code now, so that you understand what it does.

Main.java:
package com.bedrockminer.tutorial;

import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;

@Mod(modid = Main.MODID, name = Main.MODNAME, version = Main.VERSION)
public class Main {

    public static final String MODID = "tutorial";
    public static final String MODNAME = "Tutorial Mod";
    public static final String VERSION = "1.0.0";

    @Instance
    public static Main instance = new Main();

    @EventHandler
    public void preInit(FMLPreInitializationEvent e) {
    }

    @EventHandler
    public void init(FMLInitializationEvent e) {
    }

    @EventHandler
    public void postInit(FMLPostInitializationEvent e) {
    }
}

The first line of this code is

package com.bedrockminer.tutorial;

This line just shows that this class is located in that package.

 

The next lines are import tasks. They tell Java that all occurences of a specific class refer to a class with a specific path.

Example:

import net.minecraftforge.fml.common.event.FMLInitializationEvent;

This line shows the Java compiler, that all occurences of "FMLInitializationEvent" refer to cpw.mods.fml.common.event.FMLInitializationEvent. This might be superfluous in most cases, but for example the class "Entity" exists in five different packages, so we really need these imports.

To add missing imports to a class, we just have to press Ctrl+Shift+O in Eclipse and all missing classes are imported for us. Be sure to choose the ones from the right package (net.minecraftforge.fml.common).

 

If we go on in the code we get to these lines:

Main.java:
@Mod(modid = Main.MODID, name = Main.MODNAME, version = Main.VERSION)
public class Main {
//[...]
}

This is just a normal class body but with a special annotation. This annotation tells Forge that this class is supposed to be a mod. On startup, Forge goes through all classes and searches for this annotation. If one is found, the corresponding class is added to a list of all mods. The general name for this technique is Reflection which defines the ability of a computer program to examine and modify the structure and behavior of an object at runtime.

The @Mod annotation takes several arguments: The id of the mod (which must be all lower case), its human-readable name and a version. It is useful if we define these values as String variables in the main class and just place a reference of them in the annotation.

Main.java:
@Mod(modid = Main.MODID, name = Main.MODNAME, version = Main.VERSION)
public class Main {

    public static final String MODID = "tutorial";
    public static final String MODNAME = "Tutorial Mod";
    public static final String VERSION = "1.0.0";

//[...]
}

The next thing we need in your main class is an instance of it. Forge uses this instance to have a reference to your mod in order to communicate with it. If we don't create the instance on our own, Forge creates one for us. The problem of this method is that we have no access on the instance anymore, so I would recommend to create the instance manually. To do this we can use the following code:

Main.java:
@Instance
public static Main instance = new Main();

Here you create a new instance of the class "Main". The object is designated as the mod's instance by the @Instance annotation. When Forge has recognized your mod, it searches for this annotation. If it is found, the corresponding object is used as an instance, otherwise Forge creates its own.

 

The last thing to add in the main class are the "Event Handlers". Event Handlers are methods with the @EventHandler annotation which are located in a mod's main class.

The name of the Event Handler is not important because Forge recognizes the arguments of the methods.

There are three important Event Handlers:

  • The preInit Handler is called at the very beginning of the startup routine. In this method we should read your config file, create Blocks, Items, etc. and register them with the GameRegistry.
    Argument: FMLPreInitializationEvent
  • The init Handler is called after the preInit Handler. In this method we can build up data structures, add Crafting Recipes and register new handler.
    Argument: FMLInitializationEvent
  • The postInit Handler is called at the very end. Its used to communicate with other mods and adjust your setup based on this.
    Argument: FMLPostInitializationEvent

On startup Forge first executes the preInit method for all mods, then the init method for all mods and finally the postInit method for all mods. This ensures that a mod can access other mods which are later in the list of mods.

Main.java:
@EventHandler
public void preInit(FMLPreInitializationEvent e) {
                
}
        
@EventHandler
public void init(FMLInitializationEvent e) {
                
}
        
@EventHandler
public void postInit(FMLPostInitializationEvent e) {
                
}

With these methods the basic modfile is complete. We now have a fully working mod - which actually does nothing but this will be changed in the next tutorials.

 

To demonstrate the functionality of the Event Handlers we can add this line of code to each of them:

Main.java:
System.out.println("Called method: [Methodname]");

(You have to replace [Methodname] with the name of the corresponding method)

 

If we now start minecraft we can find these outputs in the console.


You can download the code used in this tutorial as a .zip file from here.


Recommended tutorials to continue with

Basic Modding:


Comments and Questions:

If you want to report modding problems, please make sure to include the code in a pastebin link or something else! Don't just write "It doesn't work", otherwise your post will be deleted. For more complicated problems, please use the troubleshooter form.