Minecraft operates through a client and a server. Code can be run on either side, or it can be run on both. For example, items must be registered on both sides, but they only need to be rendered on the client side. Forge handles this through a proxy system. We will be setting up two proxies – a client proxy and a server proxy. Any code that should be run on both sides will go in the main class.

In com.cubicoder.tutorial, create a new package named proxy. This is where we will be putting our proxy classes. Create an IProxy interface in this package (Proxy interfaces are also sometimes called ISidedProxy).

package com.cubicoder.tutorial.proxy;

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

public interface IProxy {

	public void preInit(FMLPreInitializationEvent event);

	public void init(FMLInitializationEvent event);

	public void postInit(FMLPostInitializationEvent event);

}

Next, create the ClientProxy class in the proxy package. This should implement IProxy.

package com.cubicoder.tutorial.proxy;

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

public class ClientProxy implements IProxy {

	public void preInit(FMLPreInitializationEvent event) {

	}

	public void init(FMLInitializationEvent event) {

	}

	public void postInit(FMLPostInitializationEvent event) {

	}

}

Create the ServerProxy class as well, which should be the same. Right now, leave the methods empty. We’ll add to them later, as well as add any other side-specific stuff that we need.

That’s all for the proxies themselves, but now we need to tell Forge to use them. In the TutorialMod class, add two new String constants defining the paths to your proxies, as well as a reference to the base type IProxy in your main class.

package com.cubicoder.tutorial;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

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

@Mod(modid = TutorialMod.MODID, name = TutorialMod.NAME, version = TutorialMod.VERSION, acceptedMinecraftVersions = TutorialMod.MC_VERSION)
public class TutorialMod {

	public static final String MODID = "tutorialmod";
	public static final String NAME = "Cubicoder's Tutorial Mod";
	public static final String VERSION = "1.0";
	public static final String MC_VERSION = "[1.12.2]";

	public static final Logger LOGGER = LogManager.getLogger(TutorialMod.MODID);

	public static final String CLIENT = "com.cubicoder.tutorial.proxy.ClientProxy";
	public static final String SERVER = "com.cubicoder.tutorial.proxy.ServerProxy";
	@SidedProxy(clientSide = TutorialMod.CLIENT, serverSide = TutorialMod.SERVER)
	public static IProxy proxy;

	@EventHandler
	public void preInit(FMLPreInitializationEvent event) {
		proxy.preInit(event);
	}

	@EventHandler
	public void init(FMLInitializationEvent event) {
		LOGGER.info(TutorialMod.NAME + "says hi!");
		proxy.init(event);
	}

	@EventHandler
	public void postInit(FMLPostInitializationEvent event) {
		proxy.postInit(event);
	}

}

The @SidedProxy annotation lets Forge know which classes should be used for each side. Forge will see this annotation and automatically make the proxy of type ClientProxy or ServerProxy, depending on which side it is being run on.

That’s it for proxies! Now, we finally move on to adding your first item!