Tutorial 2: Game Setup

In this tutorial we will be setting up the very basics of our mod - actually doing some programming this time.  Let's begin!

Rename the example mod project in Eclipse to the name of your mod.  This can be whatever you want, so I recommend making up an idea for your mod before you begin (But please don't make another gem mod!).
To open the actual code, open the project with the arrow next to it on the left, and navigate through src/main/java/ and src/main/resources.  These locations will be where we store our code and assets respectively.

In src/main/java/ there will be an example mod package.  We can delete this, as we will be making a mod without it.

Now we can make our own package.  Do this by right clicking on the java folder and hovering over new, then clicking Package.
There are certain package naming conventions in Java, where they will usually be com.website.project or com.username.project.  For example, these could be club.mcmodding.tutorial_mod, or com.mrpineapple.tutorial_mod respectively.
Now let's make a main class in this package.  For the sake of simplicity, I will be calling it MCMCMod.

We make the class by right clicking on the package we want to make it in, then navigating to New/Class.
By convention, class names in java start with a capital letter, and for every new word it becomes a capital letter again.  For example, ThisIsAProperClassNameInJava.
Lets open the class we just created and type some code!  First, we need to add two tags to the class.  We start by adding @Mod("MOD_ID_GOES_HERE").  The Mod Id is the ID that is used when minecraft loads your mod into the game, it is always all lowercase, and without any underscores or spaces.  Keep in mind that if another mod has the same ID as yours, it won't load in, so make sure your mod id is unique by making it at least 4 characters long.

The second tag we add is @Mod.EventBusSubscriber(modid = MCMCMod.MOD_ID, bus = Bus.MOD), which makes sure that this class runs as soon as our mod loads into the game.  You will notice that MCMCMod.MOD_ID doesnt exist yet, so lets create that by adding it inside our class: public static final String MOD_ID = "mcmc";

The code we have so far should look like this.
@Mod("mcmc")
@Mod.EventBusSubscriber(modid = MCMCMod.MOD_ID, bus = Bus.MOD)
public class MCMCMod
{
	public static final String MOD_ID = "mcmc";
}
This code uses lots of minecraft/minecraftforge specific things such as Mod and Bus, which need to be imported for the code to run.  If you hover over the code, you will see an import button.  Alternatively, you can press Cntrl+Shift+O to import everything you need into your project.
We still need to add quite a bit of stuff to our Main class.  We'll start by adding 2 more variables below the MOD_ID. We need a logger, which will help us debug by allowing us to send messages to the console,\ and an instance variable, which allows us to access the class itself and not just the functions/variables inside it. 

We can also add a constructor, which is called whenever the class is constructed.  We will need this later. The code so far can be seen below:
@Mod("mcmc")
@Mod.EventBusSubscriber(modid = MCMCMod.MOD_ID, bus = Bus.MOD)
public class MCMCMod
{
    public static final Logger LOGGER = LogManager.getLogger();
    public static final String MOD_ID = "mcmc";
    public static MCMCMod instance;

    public MCMCMod() {
    	
    }
}

After the constructor we can add 4 new methods.  First, we will add the setup(final FMLCommonSetupEvent event) and the doClientStuff(final FMLClientSetupEvent event). Both of these will be private, meaning not accessible from other classes, and "void"s which mean they do not return a value when they are called.  Next, we will add onServerStarting(FMLServerStartingEvent event) and loadCompleteEvent(FMLLoadCompleteEvent event).  They will both be public voids, but the load complete event is also "static".  Our code should now look like this:
@Mod("mcmc")
@Mod.EventBusSubscriber(modid = MCMCMod.MOD_ID, bus = Bus.MOD)
public class MCMCMod
{
    public static final Logger LOGGER = LogManager.getLogger();
    public static final String MOD_ID = "mcmc";
    public static MCMCMod instance;

    public MCMCMod() {
    }

    private void setup(final FMLCommonSetupEvent event) {
        
    }

    private void doClientStuff(final FMLClientSetupEvent event) {
        
    }
    
    @SubscribeEvent
    public void onServerStarting(FMLServerStartingEvent event) {
    	
    }
    
    @SubscribeEvent
    public static void loadCompleteEvent(FMLLoadCompleteEvent event) {
    	
    }
}
We will finsish this class by giving some function to our constructor.  We will start by getting the IEventBus variable, which will be needed later.  To do that, we do final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();.  After that, we need to add to of the methods that we created as listners, which will mean they will run when the game is loading.  We do that by adding modEventBus.addListener(this::setup); and modEventBus.addListener(this::doClientStuff); after getting the modEventBus variable. 

We need to also set the instance with instance = this;, and register the class as an event bus, with this line of code: MinecraftForge.EVENT_BUS.register(this);

And finally, we have our completed main class:
@Mod("mcmc")
@Mod.EventBusSubscriber(modid = MCMCMod.MOD_ID, bus = Bus.MOD)
public class MCMCMod
{
    public static final Logger LOGGER = LogManager.getLogger();
    public static final String MOD_ID = "mcmc";
    public static MCMCMod instance;

    public MCMCMod() {
    	final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
    	modEventBus.addListener(this::setup);
    	modEventBus.addListener(this::doClientStuff);
        instance = this;
        MinecraftForge.EVENT_BUS.register(this);
    }

    private void setup(final FMLCommonSetupEvent event) {
        
    }

    private void doClientStuff(final FMLClientSetupEvent event) {
        
    }
    
    @SubscribeEvent
    public void onServerStarting(FMLServerStartingEvent event) {
    	
    }
    
    @SubscribeEvent
    public static void loadCompleteEvent(FMLLoadCompleteEvent event) {
    	
    }
}
FML stands for Forge Mod Loader, which is some code which is used to load your mod into the game.  Alternatives like Fabric are more frequently updated, but less widely used and not as powerful.
Next, we need to fill out a file called mods.toml.  It is located in src/main/resources/META-INF.  Open it and lets get editing! 

Lets start by cleaning it up a bit.  Locate the [[dependencies.mcmc]] #optional line and delete all the comments above it.  You'll know it is a comment if it has a # in front of it.  After doing that, you'll find it easier to see what is what.  You can begin to replace all the places which reference to examplemod.  Things you need to change are listed here:

  • issueTrackerURL: I am going to put this as the URL of the website: issueTrackerURL="https://mcmodding.club"
  • modId: This is your mod id: modId="mcmc"
  • version: The version of your mod: version="1.0"
  • displayName: The display name of your mod: displayName="MCMC Mod"
  • display/update URL: I am also just going to put this website here: displayURL="https://mcmodding.club"
  • credits: Put any acknowlegments here: credits="Cy4 made a great tutorial!"
  • authors: List the names of all the contributors: authors="Cy4"
  • description: Description of your mod, can be as many lines long as you want: description=''' A tutorial by Cy4 '''

Please leave everything else the same.  You are however, going to want to change the [dependencies.examplemod] at the end of the file to [dependencies.yourmodid].  Thats it for your mods.toml file.  The full thing can be seen below:
modLoader="javafml"

loaderVersion="[31,)"

issueTrackerURL="https://mcmodding.club"

[[mods]]

modId="mcmc"

version="1.0"
 
displayName="MCMC Mod"

updateJSONURL="https://mcmodding.club"

displayURL="https://mcmodding.club"

logoFile="examplemod.png"

credits="Cy4 made a great tutorial!"

authors="Cy4"

description='''
A tutorial by Cy4
'''

[[dependencies.mcmc]] #optional
    # the modid of the dependency
    modId="forge" #mandatory
    # Does this dependency have to exist - if not, ordering below must be specified
    mandatory=true #mandatory
    # The version range of the dependency
    versionRange="[31,)" #mandatory
    # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
    ordering="NONE"
    # Side this dependency is applied on - BOTH, CLIENT or SERVER
    side="BOTH"

# Here's another dependency
[[dependencies.mcmc]]
    modId="minecraft"
    mandatory=true
    versionRange="[1.15.2]"
    ordering="NONE"
    side="BOTH"
We will also need to edit the build.gradle file.  It is located in the main folder.  Start by finding these few lines:
version = '1.0'
group = 'com.yourname.modid' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'modid'
Set the group to your package name, in my case "com.cy4.mcmc" and the archivesBaseName to your mod id.  Next we need to replace all the example mod references with our modid.  To do this quickly, we can press Ctrl+F to bring up the replace menu. In the top slot, type in examplemod and in the bottom slot type in your mod id, check the Whole Word box and click "Replace All".  The build.gradle is done. 
You will need to rerun the gradlew commands in the first tutorial, so that the build.gradle is registered.  You will probably never do this again.
Finally (phew), we can launch the game.  Find the runClient.launch file on the left and open then close it.  At the top of the screen, go to Run>Run As>runClient and the game should load!  Once it loads, go to the "Mods" section of the main menu and your mod should be there.  Thats it! 

Finally finished.  Trust me, it gets better and easier from here. ;-)