First off, you are probably wondering "Where did the other tutorials go???"... well due to a stupid bug in the editor, it converted the entire page into raw code, so I need to start afresh...
Now, many of you are probably thinking that modding is difficult, well, it isn't really. Some things can be a little challenging but IMHO that's the fun in it!
Anyways, lets get cracking!!!
Upcoming Tutorials
Mobs
Tree, structure and ore generation
Throwable entities
Custom tool materials
Custom armor materials
Tutorials
Tut 1: Setup
Right, to start modding you’ll need a few things.
· MCP (Forge auto-downloads)
· Minecraft client and server (Forge auto-downloads)
· MinecraftForge (We will call Forge from now on)
· Any photo editing program, MS Paint is NOT acceptable. MS Paint does not support transparency which we need.
· A computer
· A brain
· A keyboard
· A Mouse
So, to start, visit http://files.minecraftforge.net and download the latest source version of Forge. Then, extract the archive to any folder you wish. Once that’s done open up the folder and run install.cmd/.sh (depends on your OS). Forge should automatically download everything for you and start the install process. Warning: This does take quite a long time, so be prepared to be left waiting. Note: If you get ANY errors at ALL… post them below so I can help.
Now just wait till it’s finished, then move onto the next tutorial!
Tut 2: Setting workspace
Now that we have all that done we need to tell Eclipse where the source is, so to do this navigate to where you installed eclipse and start the file “eclipse.exe” or whatever it is for your OS.
Once that’s done you should be greeted with a window asking you to set the Eclipse workspace, which we will be setting to the “eclipse” folder in your MCP folder. So navigate to MCP’s “eclipse” folder and set it as the current workspace! Now then again, if you have ANY errors, please, please post them below!!! This should be it, now we’re ready to move on!
Tut 3: Packages and Core Mod Class
Now we will be creating the core for our mod. In Eclipse expand the Minecraft menu down the left, then expand src. Right click on srcand select New > Package and name it “YourName.YourModName.common”, without the quotes. Now this is something everyone should know, so pay attention, in Java, package names should NEVER contain uppercase letters, this isn’t for a particular reason however it is a very good naming convention for packages if they don’t contain an uppercase letter at all. If you wish to read more about this visit this site: http://www.iwombat.c...l#Package Names
Next we will be creating our client package, so right click on your “YourName.YourModName.common” package and select New > Package. Now instead of just typing, press the right arrow two times, once to deselect the entire name and the other to move the cursor, then replace common with client.
Finally we will be creating our core mod class, so let’s get to it! Right click on your common package and select New > Class and name it whatever your mod is called, so for instance if I were creating a mod called “MC Enhanced” I would call the class “MCEnhanced”. In this class place this code:
package yourname.yourmodname.common;
@Mod(modid = “YourModName”, name = “YourModName”, version = “1.0.0”)
@NetworkMod(clientSideRequired = true, serverSideRequired = false, versionBounds = “1.0.0”)
public class YourModName {
@Instance(“YourModsID”)
public static YourModName instance;
@PreInit
public void preLoad(FMLPreInitializationEvent event)
{
}
@Init
public void load(FMLInitializationEvent event)
{
}
@PostInit
public void postLoad(FMLPostInitializationEvent event)
{
}
}
Now you should get some errors in that class, an only that class, this is easily fixed by holding down both CTRL + Shift and pressing O. This is the shortcut for importing a class from outside your classes package. Note that this shortcut will only fix this type of error! That should be it for the main mod class, next we will be creating proxies for our mod and telling FML where it is!
Tut 4: Proxies
A proxy is an FML feature which allows a mod to have classes called proxies which divide the client and server code, of course the server-side-code also being ran on the client as the internal server.
Proxies are very versatile and I personally use them a lot.
So to start off with we will create the two proxies, in the client package of your mod create a new class called ClientProxy and in the common package make a class called CommonProxy. Now your client proxy MUST extends your common proxy, so to do this after where it says ClientProxy in your client proxy class add: “extends CommonProxy”, then CTRL + Shift + O to fix the import errors! Next we will tell Forge where to access these from, so to do this add this to your mod class:
@SidedProxy(clientSide = “yourname.yourmodname.client.ClientProxy”, serverSide = “yourname.yourmodname.common.CommonProxy”)
public static CommonProxy proxy;
Now for everything you place in the client proxy you MUST add to the common proxy, keep in mind FML will ONLY load stuff from the client proxy if the side which it is loading from is the client, in other words if the client is trying to run the code. So to call a method within your proxies just use this:
In your core mod file:
proxy.methodNameHere();
In other classes:
YourModName.proxy.methodNameHere();
Now just CTRL + Shift + O to fix those import errors and you’re done!
Tut 5: Loggers
At the moment you might be using System.out.println(“TEXT HERE”) to output stuff, if you are you probably have noticed the (STDOUT) that keeps being added to the output. Now don’t worry, this isn’t your fault, for some reason Forge/FML overwrite Java’s System.out.println method to add this, so we will be using Logger’s to fix this!
First off, create a new class in your common package called ModLogger and add this code:
package yourname.yourmodname.common;
public class ModLogger {
private static Logger logger = Logger.getLogger(“YourModName”);
public static void init()
{
logger.setParent(FMLLog.getLogger());
}
public static void log(Level level, String message)
{
logger.log(level, message);
}
}
Then CTRL + Shift + O, the reason why I’m getting you to do this is because I want you to get VERY familiar with this shortcut, it will be saving you a LOT of time later on…
Next the first line of your PreLoad method in your base mod class HAS to be “ModLogger.init();” or else it WILL screw up.
Anytime you want to log something just call ModLogger.log(), the first parameter is found in the Level class, the second is your message. From my testing only the INFO log level and the error log levels send output to the STDOUT location, which is where the rest of the output goes.
Tut 6: Items, blocks, recipes, names and more!
In this tutorial we will be learning about multiple things, which include items, blocks, recipes (shaped, shapeless and smelting), names and a few more.
Items:
First off, we will create a new class, called this “ModItem”. This class is going to be our base class for all our items, now it is up to you where you place this, but I recommend in a separate package.
So once this is done place this code in the class:
package yourname.yourmodname.common; // Must be the package the class is in
public class ModItem extends Item
{
public ModItem(int id)
{
super(id);
this.setTextureFile(“/path/to/your/texture/file/here/texture_file_name.png”);
}
}
Now in order for this to work we need a texture, which will be Tutorial 7! So if you want a texture file skip to tutorial 7 then come back.
Next we will need to create a new package in the common package called “item”. Then in here create a new class called ItemYourItemNameHere, obviously replacing YourItemNameHere with your items name, with capitals at the start of EVERY word.
Then place this code in that class:
package yourname.yourmodname.common.item;
public class ItemYourItemNameHere extends ModItem
{
public ItemYourItemNameHere(int id)
{
super(id);
}
}
Now that method with the type of your class name is called a constructor. A constructor is used to set the values of certain variables within said class, when the object (class in this case) is created. How this is achieved is Java calls the method on object creation. In future tutorials, if they expand on an item or block, some of the code must go in the constructor.
Next we need to register the item. In your main mod class, create a brand new public variable that is static and of the type Item, you can name it anything, if you need the code it is below, however you will have better understanding of Java during a conversation if you try to do it through my instructions.
public static Item itemNameHere;
Next create a new method called loadItemsAndBlocks and place this code inside:
itemNameHere = new ItemYourItemNameHere(4000).setCreativeTab(CreativeTabs.tabMaterials /* Can be any tab */).setIconIndex(0 /* Must be the index value of the texture */).setItemName(“itemNameHere”);
Finally in your pre-init, call your method.
Blocks
First off, we will create a new class, called this “ModBlock”. This class is going to be our base class for all our blocks, now it is up to you where you place this, but I recommend in a separate package.
So once this is done place this code in the class:
package yourname.yourmodname.common; // Must be the package the class is in
public class ModBlock extends Block
{
public ModBlock(int id, int index, Material material)
{
super(id, index, material);
this.setTextureFile(“/path/to/your/texture/file/here/texture_file_name.png”);
}
}
Now in order for this to work we need a texture, which will be Tutorial 7! So if you want a texture file skip to tutorial 7 then come back.
Next we will need to create a new package in the common package called “block”. Then in here create a new class called BlockYourBlockNameHere, obviously replacing YourBlockNameHere with your blocks name, with capitals at the start of EVERY word.
Then place this code in that class:
package yourname.yourmodname.common.block;
public class BlockYourBlockNameHere extends ModBlock
{
public BlockYourBlockNameHere (int id, int index, Material material)
{
super(id, index, material);
}
}
Now that method with the type of your class name is called a constructor. A constructor is used to set the values of certain variables within said class, when the object (class in this case) is created. How this is achieved is Java calls the method on object creation. In future tutorials, if they expand on an item or block, some of the code must go in the constructor.
Next we need to register the block. In your main mod class, create a brand new public variable that is static and of the type Block, you can name it anything, if you need the code it is below, however you will have better understanding of Java during a conversation if you try to do it through my instructions.
public static Block blockNameHere;
Next create a new method called loadItemsAndBlocks and place this code inside:
blockNameHere = new BlockYourBlockNameHere (2000).setCreativeTab(CreativeTabs.tabBlocks /* Can be any tab */). setBlockName(“blockNameHere”);
Next in your init, call your method. After you call that method, add this code:
GameRegistry.registerBlock(blockNameHere);
This registers the block in the game and adds it to the internal block’s list.
Now you’re probably wondering “Where’s the icon index setter?”, now, if you look back at the constructor for your class, you’ll notice a parameter called “index”. This is the index of the texture. There is also a Material parameter, this is the block material and it determines a few things, the tool used to mine it, the breaking sound, and a few more.
Now keep in mind for both of these, the set****Name method does NOT set the ingame name, we will get to that shortly.
Naming
In this sub-tutorial we will learn how to add names to the items and blocks we just created. Now, this is very easy to do, and only takes one line of code:
LanguageRegistry.addName(itemNameHere /* or blockNameHere for blocks */, “INGAME NAME”);
These names do support escape characters (there is a tutorial for escape characters), however there is a bug which I think may have been fixed, where the font renderer will add an extra space to the end of the name whenever you use an escape character. It’s for this exact reason I use rarities to colour my item’s names.
Recipes (Both crafting and smelting)
Now both of these recipes are really easy to add, and can be found in the GameRegistry.
For simplicities sake, I have split up both types.
Crafting:
Now, there are two types of crafting recipes; standard and shapeless. It’s pretty self-explanatory, but I will explain anyway. Standard means that in order to get the output, you MUST have the recipe exactly as it is set, whereas shapeless means you can have the recipe in any order you wish, you just have to have the items/blocks that are for the recipe.
We will do standard recipes first.
Just add this to any init method in your base mod class, or wherever you want:
GameRegistry.addRecipe(new ItemStack(itemNameHere /* blockNameHere for blocks */, 1 /* The amount returned */), new Object[] {
“AAA”,
“AAA”,
“AAA”,
‘A’, Item.enderPearl //IS AN EXAMPLE, CAN BE ANY ITEM/BLOCK
});
Now the way that standard recipes are set out is a little complicated. Basically, the three lines in the quotation marks correspond to the three rows on the crafting table. Each item is characterized as a value, which in this example, is “A”. You can use everything except for space, as a space means that there is a gap there. The last line is just setting “A” equal to an ender pearl.
Now shapeless recipes are less complicated.
GameRegistry.addShapelessRecipe(new ItemStack(itemNameHere /* blockNameHere for blocks */, 1 /* The amount returned */), new Object[] {
Item.enderPearl,
Block.stone,
Block.cobblestone,
Block.cobblestone
});
Now, from what is there, you could guess that it is set out much like a list, which would be correct. Every entry in that list is each item/block that must be put in the crafting table, so that means that the two cobble entries means that two cobblestone must be in the recipe; which is correct.
Smelting:
Smelting recipes are a bit easier than crafting recipes, here’s the code:
GameRegistry.addSmelting(itemNameHere.shiftedIndex /* blockNameHere.blockID for blocks. The ID that has to be smelted. */, new ItemStack(itemNameHere /* blockNameHere for blocks */, 1 /* The amount received. */), 1.0f /* The amount of experience received */);
Tut 7: Textures
In this tutorial, we will learn how to create, preload and use custom spritesheets by means of Forge’s Infinite Sprite Indexing feature.
First, in your favourite image editor (Must NOT be MS-Paint, MS-Paint doesn’t support transparency, which we need) create a new 256x256 pixel image and delete everything. This is going to be our spritesheet. Next, in Eclipse, make a new package in the yourname.yourmodname folder called “resources”, then a new one in there called “art”, this is where our textures are gonna go (to those people who say this doesn’t work, it does, MCP allows Eclipse to dynamically load the workspace, effectively allowing us to put our files in the common fodler in Eclipse, then start the game up and they’ll be loaded into the game! Then save your spritesheet and copy it into the art folder.
Now in your base mod class add this to your preinit method:
This preloads our texture into memory so the game can use it.
Now if you came here straight after completing the items/blocks tutorial, no more steps… else you need to go into that tutorial and add the texture setter.
For each and every 16x16 square in the spritesheet, a texture can be added and it will be given a unique ID, called an index. This index starts from 0 and ends on 255, at which point you would need a new spritesheet. This is where the infinite part of the feature comes in, allowing virtually infinite sprtiesheets!
Tut 8: Configuration files
This isn’t very hard to do, however if you are already a fair way into your mod you will have to change a few things. So if you already have items and blocks see the spoiler below.
This config file WILL require you to remove all your item and block ID’s, so memorize them then remove them, we will get back to add to that.
First off, we will be making this in an external class, to call the loadConfig method, which we will be creating, call it in your preinit method like this:
First off, create a new class and name it whatever you want, then, in your new class, create a new method that is called loadConfig and have the method take one parameter called “file” that is of the type File. Next, on the first line of this method add:
Configuration config = new Configuration(file);
Next, in this class, create all your block and item ID variables and name them like ID_*BLOCK/ITEMNAMEHERE*, note that all spaces must be replaced with underscores. Next, add a try/catch block like this:
try {
config.load();
ID_*BLOCK/ITEMNAMEHERE* = config.getItem(config.CATEGORY_ITEM, “itemNameHereID”, 1234).getInt(1234);
//For blocks:
// ID_*BLOCK/ITEMNAMEHERE* = config.getBlock(config.CATEGORY_BLOCK, “blockNameHereID”, //123).getInt(123);
//For general options:
// VAR_NAME_HERE = config.get (config.CATEGORY_GENERAL, “optionNameHere”, //optionDefaultValue).getInt(optionDefaultValue);
} catch (Exception e) {
FMLLogger.log(Level.SEVERE, “*MODNAMEHERE* has encountered a problem while loading it’s configuration!”);
} finally {
config.save();
}
If you see in the try section there is the part of the code where it gets the value, for each ID/option you have, just add onto that! Note that there are WAAAAAAAAY more things, but there are too many to list.
Next, in your block/item registration, replace the param that would be the ID with:
ClassNameHere.ID_*ITEM/BLOCKNAMEHERE*
Tut 9: Custom creative tabs
A lot of you would probably be thinking “Custom creative tabs are impossible without editing base files”. To that I say completely and utterly false. In this tutorial I will show you how to create a custom creative tab and add any item or block to it.
First off, in your common package create a new class called CreativeTab and add this code to it:
package yourname.yourmodname.common;
public class CreativeTab extends CreativeTabs
{
public CreativeTab(int id, String name)
{
super(id, name);
}
@Override
@SideOnly(Side.CLIENT)
public String getTranslatedTabLabel()
{
return “MODNAMEHERE”;
}
@Override
@SideOnly(Side.CLIENT)
public void getTabIconItemIndex()
{
return Item.potato.shiftedIndex;
//This is just an example, can be any item. Must be item’s ID.
}
}
Now just CTRL + Shift + O to fix those import errors!
Next we will be registering the tab. Add this to your main mod class:
public static void CreativeTabs tab = new CreativeTab(CreativeTabs.getNextID(), “MODIDHERE”);
Now in any item or block you want on this tab, just set the tab to this!
Tut 10: Coloured text
Coloured text can be achieved by use of something called an Escape Character. An escape character is sort of like a code-version of an alt code, so we will use one particular escape character to create the special character Minecraft uses for editing text!
This escape character is \247#, now the # is just a placeholder, in the code you replace that with a special key, which a list of them is below. Escape characters will affect the entire line of text, they will not skip down rows of text, to stop an escape character from affecting more text, just create another, for instance, if I wanted a yellow name, but with another bit of text after that’s white, I’d do:
\247eText 1 Here \247fText 2 Here
List of Keys:
0: Black
1: Dark Blue
2: Dark Green
3: Dark Aqua
4: Dark Red
5: Purple
6: Gold
7: Light Grey
8: Dark Grey
9: Indigo
A: Light Green
B: Aqua
C: Pink
D: Pink
E: Yellow
F: White
K: Random Text
L: Bold
N: Underline
O: Italics
M: Strike-through
Tut 11: Extended tooltips
If you have ever enchanted a tool and had that extra line of text below the name, you’ve used extended tooltips before. These tooltips are very cool, and they seem to give an item that last bit of “Wow…” it truly needs. These are very easy to do. Note, they are affected by escape characters.
To add extended tooltips to an item, just add this method to your item’s class:
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean i)
{
}
Now, to add the text to the tooltip, just type this code into the method:
list.add(“TEXT HERE”);
That should be it! Your item should now have text under it’s name!
Tut 12: World Generation
Adding world generation isn’t that hard, but it isn’t a cake walk either. In this tutorial you will learn how to add ore generation to the game. First off, in your common package, make a new package called world, then make another within world called gen. Add a new class called OreGeneration and add this code:
package yourname.yourmodname.common.world.gen;
public class OreGeneration implements IWorldGenerator
{
@Override
public void generate(Random rand, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider)
{
switch (world.provider.dimensionId)
{
case -1 : generateNether(world, rand, chunkX * 16, chunkZ * 16);
case 0 : generateSurface(world, rand, chunkX * 16, chunkZ * 16);
}
}
public void generateSurface(World world, Random rand, int blockX, int blockZ) {}
public void generateNether(World world, Random rand, int blockX, int blockZ) {}
public void addOreGen(int blockID, int veinSize int rarity, int maxYLevel, int blockX, int blockZ, World world, Random rand)
{
for (int i = 0; i < rarity; i++)
{
int x = blockX + rand.nextInt(16);
int y = rand.nextInt(maxYLevel);
int z = blockZ + rand.nextInt(16);
(new WorldGenMineable(blockID, veinSize)).generate(world, rand, x, y, z);
}
}
}
To add generation to the overworld for your ore, just call addOreGen with all its parameters in generateSurface, same with the nether. But, you cannot open up a new world and expect to see your ore, we need to register the generator next!
Okay, if you’ve ever looked at another mod’s source and found the mcmod.info file and wanted to add one to your mod, but failed every time, this tutorial is for you. Essentially, the official name for the data in this file is called Mod Metadata. FML uses this for a bunch of things.
Now… you may be thinking that this sounds incredibly hard… if so, you’re wrong. This is actually incredibly easy and to be honest, I only just found out about it a few days ago. So, what we will be doing is adding some more code to the pre-init method. First off, I will explain the three initialisation event arguments. These three argument types are unique to FML as it provides a way for us modders to hook into the loading data of the mod. Need the FML suggested configuration file? Use the method in the pre-init event. Need to get a loaded ASM data table? Use the method in any of the arguments.
So, obviously from my rambling in the above paragraph, we will be using the pre-init event argument. Now, in the argument there is a method called getModMetadata(). This allows modders to set metadata only data entries without actually needing a mcmod.info file. This is really good for us as if we are making more than one mods in the same workspace, you will quickly realise that you cannot have multiple mcmod.info files. Note that some of the features will not work with this.
So, first off, you’ll quickly notice a bunch of things in that method. That is because the method actually returns the class that actually stores the mod’s metadata. Using the various fields in this class, we can hardcode the actual metadata. Some examples are below.
Much like other features of Forge, the EnumHelper added in Forge allows you to do some pretty awesome things without needing those pesky base class edits or new classes which will cause incompatibility. One of these things is custom tool materials. So, to create a new tool material just use this code:
public static EnumToolMaterial CUSTOM_TOOL_MATERIAL;
CUSTOM_TOOL_MATERIAL = EnumHelper.addToolMaterial(“MATERIAL_NAME_HERE”, 3 /* Pickaxe level */, 200 /* Durability */, 8.0f /* Mining speed */, 5 /* Damage dealt to mobs on a sword with this material. Value is in half hearts. */, 30 /* Enchantability. Higher values tend to make strange things happen with enchanting. */);
Obviously, you can join the actual variable with the declaration; I just like to do things that way.
Information and Glossary
Java
Class: A file that code is stored in. Can be viewed in bytecode form (obfuscated).
Package: A “folder” which classes and other files are stored in. Package names MUST be in lowercase ONLY.
Method: A type of Java object which code is stored in. Any code outside a method is not run. Variables are generally the only thing which is meant to be outside a method.
Annotation: A type of modifier which allows developers to tie metadata (extra data) to an object (class, package (to a certain extent), method, field (variable), etc). Can also be used to invoke (run) a method within a certain class.
Forge
@Mod: Annotation which marks the class this annotates as a mod’s core class. Takes three arguments, Mod’s ID, Mod’s Name and Mod’s Version. Does contain more arguments however those are optional.
@NetworkMod: Annotation which marks the mod that the class this annotates as a server mod.
@???Init: The three initialization annotations. Invokes the method this annotates at that point in the loading of the game.
If you found any of these tutorials helpful or I have helped you and you feel like giving back something, feel free to drop a green arrow by! I don’t mind and it will also tell me that you guys want more tuts!
Rollback Post to RevisionRollBack
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
Can you have a tutorial for something to have a redstone signal and be able to be pushed by a piston. Not right now but eventually.
I actually don't think that is possible, any modders correct me if I'm wrong, but I'll look into it
And I mean to have a block be affected by redstone and have it pushed by a piston.
Rollback Post to RevisionRollBack
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
Great, easy to understand and it helped me get started on forge modding
keep this up :)Oh yeah and as a suggestion could you try to make one for weapons please?
Rollback Post to RevisionRollBack
I eat creepers for breakfast, lunch, dinner and I have it bacon style!
Great, easy to understand and it helped me get started on forge modding
keep this up
Oh yeah and as a suggestion could you try to make one for weapons please?
Sure thing, I currently do not have access to my usual computer (school laptop(ultrasurf :D)) so I wil try to add the weapons today or maybe tomorrow, and thanks for that green arrow Have a nice day/night!
Rollback Post to RevisionRollBack
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
I actually don't think that is possible, any modders correct me if I'm wrong, but I'll look into it
And I mean to have a block be affected by redstone and have it pushed by a piston.
It might be possible if the block had one side that didn't give a redstone signal. And I think that is possible because redpower does it with the logic gates (like timers).
It might be possible if the block had one side that didn't give a redstone signal. And I think that is possible because redpower does it with the logic gates (like timers).
I'll look into it, now that I have had some time to think, I may of found a way to do it.
Sorry for slow responses, laptop hard drive crashed so I've had to use my school laptop, which had this site blocked but I have a program to bypass that. Also a few new tutorials going up fairly soon.
Rollback Post to RevisionRollBack
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
Could you do a weapons tutorial? maybe like a spear or something?
Swords are an upcoming tutorial, aswell as tools like picks and such, but spears will require a little more work as they do use entites, ut they aren't that hard to code. Added to the list.
Rollback Post to RevisionRollBack
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
Just took a closer look at your block tutorial and it is missing some key code that fully implements the block. The missing code goes something like this:
yourblock = new yourblock(230, 0).setStepSound(Block.soundStoneFootstep).setHardness(3F).setResistance(1.0F).setBlockName("your");
GameRegistry.registerBlock(yourblock);
LanguageRegistry.addName(yourblock, "blockname");
Just took a closer look at your block tutorial and it is missing some key code that fully implements the block. The missing code goes something like this:
yourblock = new yourblock(230, 0).setStepSound(Block.soundStoneFootstep).setHardness(3F).setResistance(1.0F).setBlockName("your");
GameRegistry.registerBlock(yourblock);
LanguageRegistry.addName(yourblock, "blockname");
I noticed this before, it is in the next tutorial, I forgot, thanks anyways.
Rollback Post to RevisionRollBack
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
First off, you are probably wondering "Where did the other tutorials go???"... well due to a stupid bug in the editor, it converted the entire page into raw code, so I need to start afresh...
Now, many of you are probably thinking that modding is difficult, well, it isn't really. Some things can be a little challenging but IMHO that's the fun in it!
Anyways, lets get cracking!!!
Upcoming Tutorials
Tut 1: Setup
Right, to start modding you’ll need a few things.
· MCP (Forge auto-downloads)
· Minecraft client and server (Forge auto-downloads)
· MinecraftForge (We will call Forge from now on)
· Any photo editing program, MS Paint is NOT acceptable. MS Paint does not support transparency which we need.
· A computer
· A brain
· A keyboard
· A Mouse
So, to start, visit http://files.minecraftforge.net and download the latest source version of Forge. Then, extract the archive to any folder you wish. Once that’s done open up the folder and run install.cmd/.sh (depends on your OS). Forge should automatically download everything for you and start the install process. Warning: This does take quite a long time, so be prepared to be left waiting. Note: If you get ANY errors at ALL… post them below so I can help.
Now just wait till it’s finished, then move onto the next tutorial!
Tut 2: Setting workspace
Now that we have all that done we need to tell Eclipse where the source is, so to do this navigate to where you installed eclipse and start the file “eclipse.exe” or whatever it is for your OS.
Once that’s done you should be greeted with a window asking you to set the Eclipse workspace, which we will be setting to the “eclipse” folder in your MCP folder. So navigate to MCP’s “eclipse” folder and set it as the current workspace! Now then again, if you have ANY errors, please, please post them below!!! This should be it, now we’re ready to move on!
Tut 3: Packages and Core Mod Class
Now we will be creating the core for our mod. In Eclipse expand the Minecraft menu down the left, then expand src. Right click on srcand select New > Package and name it “YourName.YourModName.common”, without the quotes. Now this is something everyone should know, so pay attention, in Java, package names should NEVER contain uppercase letters, this isn’t for a particular reason however it is a very good naming convention for packages if they don’t contain an uppercase letter at all. If you wish to read more about this visit this site: http://www.iwombat.c...l#Package Names
Next we will be creating our client package, so right click on your “YourName.YourModName.common” package and select New > Package. Now instead of just typing, press the right arrow two times, once to deselect the entire name and the other to move the cursor, then replace common with client.
Finally we will be creating our core mod class, so let’s get to it! Right click on your common package and select New > Class and name it whatever your mod is called, so for instance if I were creating a mod called “MC Enhanced” I would call the class “MCEnhanced”. In this class place this code:
Now you should get some errors in that class, an only that class, this is easily fixed by holding down both CTRL + Shift and pressing O. This is the shortcut for importing a class from outside your classes package. Note that this shortcut will only fix this type of error! That should be it for the main mod class, next we will be creating proxies for our mod and telling FML where it is!
Tut 4: Proxies
A proxy is an FML feature which allows a mod to have classes called proxies which divide the client and server code, of course the server-side-code also being ran on the client as the internal server.
Proxies are very versatile and I personally use them a lot.
So to start off with we will create the two proxies, in the client package of your mod create a new class called ClientProxy and in the common package make a class called CommonProxy. Now your client proxy MUST extends your common proxy, so to do this after where it says ClientProxy in your client proxy class add: “extends CommonProxy”, then CTRL + Shift + O to fix the import errors! Next we will tell Forge where to access these from, so to do this add this to your mod class:
Now for everything you place in the client proxy you MUST add to the common proxy, keep in mind FML will ONLY load stuff from the client proxy if the side which it is loading from is the client, in other words if the client is trying to run the code. So to call a method within your proxies just use this:
In your core mod file:
In other classes:
Now just CTRL + Shift + O to fix those import errors and you’re done!
Tut 5: Loggers
At the moment you might be using System.out.println(“TEXT HERE”) to output stuff, if you are you probably have noticed the (STDOUT) that keeps being added to the output. Now don’t worry, this isn’t your fault, for some reason Forge/FML overwrite Java’s System.out.println method to add this, so we will be using Logger’s to fix this!
First off, create a new class in your common package called ModLogger and add this code:
Then CTRL + Shift + O, the reason why I’m getting you to do this is because I want you to get VERY familiar with this shortcut, it will be saving you a LOT of time later on…
Next the first line of your PreLoad method in your base mod class HAS to be “ModLogger.init();” or else it WILL screw up.
Anytime you want to log something just call ModLogger.log(), the first parameter is found in the Level class, the second is your message. From my testing only the INFO log level and the error log levels send output to the STDOUT location, which is where the rest of the output goes.
Tut 6: Items, blocks, recipes, names and more!
In this tutorial we will be learning about multiple things, which include items, blocks, recipes (shaped, shapeless and smelting), names and a few more.
Items:
First off, we will create a new class, called this “ModItem”. This class is going to be our base class for all our items, now it is up to you where you place this, but I recommend in a separate package.
So once this is done place this code in the class:
Now in order for this to work we need a texture, which will be Tutorial 7! So if you want a texture file skip to tutorial 7 then come back.
Next we will need to create a new package in the common package called “item”. Then in here create a new class called ItemYourItemNameHere, obviously replacing YourItemNameHere with your items name, with capitals at the start of EVERY word.
Then place this code in that class:
Now that method with the type of your class name is called a constructor. A constructor is used to set the values of certain variables within said class, when the object (class in this case) is created. How this is achieved is Java calls the method on object creation. In future tutorials, if they expand on an item or block, some of the code must go in the constructor.
Next we need to register the item. In your main mod class, create a brand new public variable that is static and of the type Item, you can name it anything, if you need the code it is below, however you will have better understanding of Java during a conversation if you try to do it through my instructions.
Next create a new method called loadItemsAndBlocks and place this code inside:
Finally in your pre-init, call your method.
Blocks
First off, we will create a new class, called this “ModBlock”. This class is going to be our base class for all our blocks, now it is up to you where you place this, but I recommend in a separate package.
So once this is done place this code in the class:
Now in order for this to work we need a texture, which will be Tutorial 7! So if you want a texture file skip to tutorial 7 then come back.
Next we will need to create a new package in the common package called “block”. Then in here create a new class called BlockYourBlockNameHere, obviously replacing YourBlockNameHere with your blocks name, with capitals at the start of EVERY word.
Then place this code in that class:
Now that method with the type of your class name is called a constructor. A constructor is used to set the values of certain variables within said class, when the object (class in this case) is created. How this is achieved is Java calls the method on object creation. In future tutorials, if they expand on an item or block, some of the code must go in the constructor.
Next we need to register the block. In your main mod class, create a brand new public variable that is static and of the type Block, you can name it anything, if you need the code it is below, however you will have better understanding of Java during a conversation if you try to do it through my instructions.
Next create a new method called loadItemsAndBlocks and place this code inside:
Next in your init, call your method. After you call that method, add this code:
This registers the block in the game and adds it to the internal block’s list.
Now you’re probably wondering “Where’s the icon index setter?”, now, if you look back at the constructor for your class, you’ll notice a parameter called “index”. This is the index of the texture. There is also a Material parameter, this is the block material and it determines a few things, the tool used to mine it, the breaking sound, and a few more.
Now keep in mind for both of these, the set****Name method does NOT set the ingame name, we will get to that shortly.
Naming
In this sub-tutorial we will learn how to add names to the items and blocks we just created. Now, this is very easy to do, and only takes one line of code:
These names do support escape characters (there is a tutorial for escape characters), however there is a bug which I think may have been fixed, where the font renderer will add an extra space to the end of the name whenever you use an escape character. It’s for this exact reason I use rarities to colour my item’s names.
Recipes (Both crafting and smelting)
Now both of these recipes are really easy to add, and can be found in the GameRegistry.
For simplicities sake, I have split up both types.
Crafting:
Now, there are two types of crafting recipes; standard and shapeless. It’s pretty self-explanatory, but I will explain anyway. Standard means that in order to get the output, you MUST have the recipe exactly as it is set, whereas shapeless means you can have the recipe in any order you wish, you just have to have the items/blocks that are for the recipe.
We will do standard recipes first.
Just add this to any init method in your base mod class, or wherever you want:
Now the way that standard recipes are set out is a little complicated. Basically, the three lines in the quotation marks correspond to the three rows on the crafting table. Each item is characterized as a value, which in this example, is “A”. You can use everything except for space, as a space means that there is a gap there. The last line is just setting “A” equal to an ender pearl.
Now shapeless recipes are less complicated.
Now, from what is there, you could guess that it is set out much like a list, which would be correct. Every entry in that list is each item/block that must be put in the crafting table, so that means that the two cobble entries means that two cobblestone must be in the recipe; which is correct.
Smelting:
Smelting recipes are a bit easier than crafting recipes, here’s the code:
Tut 7: Textures
In this tutorial, we will learn how to create, preload and use custom spritesheets by means of Forge’s Infinite Sprite Indexing feature.
First, in your favourite image editor (Must NOT be MS-Paint, MS-Paint doesn’t support transparency, which we need) create a new 256x256 pixel image and delete everything. This is going to be our spritesheet. Next, in Eclipse, make a new package in the yourname.yourmodname folder called “resources”, then a new one in there called “art”, this is where our textures are gonna go (to those people who say this doesn’t work, it does, MCP allows Eclipse to dynamically load the workspace, effectively allowing us to put our files in the common fodler in Eclipse, then start the game up and they’ll be loaded into the game! Then save your spritesheet and copy it into the art folder.
Now in your base mod class add this to your preinit method:
This preloads our texture into memory so the game can use it.
Now if you came here straight after completing the items/blocks tutorial, no more steps… else you need to go into that tutorial and add the texture setter.
For each and every 16x16 square in the spritesheet, a texture can be added and it will be given a unique ID, called an index. This index starts from 0 and ends on 255, at which point you would need a new spritesheet. This is where the infinite part of the feature comes in, allowing virtually infinite sprtiesheets!
Tut 8: Configuration files
This isn’t very hard to do, however if you are already a fair way into your mod you will have to change a few things. So if you already have items and blocks see the spoiler below.
This config file WILL require you to remove all your item and block ID’s, so memorize them then remove them, we will get back to add to that.
First off, create a new class and name it whatever you want, then, in your new class, create a new method that is called loadConfig and have the method take one parameter called “file” that is of the type File. Next, on the first line of this method add:
Next, in this class, create all your block and item ID variables and name them like ID_*BLOCK/ITEMNAMEHERE*, note that all spaces must be replaced with underscores. Next, add a try/catch block like this:
If you see in the try section there is the part of the code where it gets the value, for each ID/option you have, just add onto that! Note that there are WAAAAAAAAY more things, but there are too many to list.
Next, in your block/item registration, replace the param that would be the ID with:
Tut 9: Custom creative tabs
A lot of you would probably be thinking “Custom creative tabs are impossible without editing base files”. To that I say completely and utterly false. In this tutorial I will show you how to create a custom creative tab and add any item or block to it.
First off, in your common package create a new class called CreativeTab and add this code to it:
Now just CTRL + Shift + O to fix those import errors!
Next we will be registering the tab. Add this to your main mod class:
Now in any item or block you want on this tab, just set the tab to this!
Tut 10: Coloured text
Coloured text can be achieved by use of something called an Escape Character. An escape character is sort of like a code-version of an alt code, so we will use one particular escape character to create the special character Minecraft uses for editing text!
This escape character is \247#, now the # is just a placeholder, in the code you replace that with a special key, which a list of them is below. Escape characters will affect the entire line of text, they will not skip down rows of text, to stop an escape character from affecting more text, just create another, for instance, if I wanted a yellow name, but with another bit of text after that’s white, I’d do:
List of Keys:
0: Black
1: Dark Blue
2: Dark Green
3: Dark Aqua
4: Dark Red
5: Purple
6: Gold
7: Light Grey
8: Dark Grey
9: Indigo
A: Light Green
B: Aqua
C: Pink
D: Pink
E: Yellow
F: White
K: Random Text
L: Bold
N: Underline
O: Italics
M: Strike-through
Tut 11: Extended tooltips
If you have ever enchanted a tool and had that extra line of text below the name, you’ve used extended tooltips before. These tooltips are very cool, and they seem to give an item that last bit of “Wow…” it truly needs. These are very easy to do. Note, they are affected by escape characters.
To add extended tooltips to an item, just add this method to your item’s class:
Now, to add the text to the tooltip, just type this code into the method:
That should be it! Your item should now have text under it’s name!
Tut 12: World Generation
Adding world generation isn’t that hard, but it isn’t a cake walk either. In this tutorial you will learn how to add ore generation to the game. First off, in your common package, make a new package called world, then make another within world called gen. Add a new class called OreGeneration and add this code:
To add generation to the overworld for your ore, just call addOreGen with all its parameters in generateSurface, same with the nether. But, you cannot open up a new world and expect to see your ore, we need to register the generator next!
Add this to an init method in your mod class:
That should be it!
Tut 13: Hard-setting your mod’s metadata
Okay, if you’ve ever looked at another mod’s source and found the mcmod.info file and wanted to add one to your mod, but failed every time, this tutorial is for you. Essentially, the official name for the data in this file is called Mod Metadata. FML uses this for a bunch of things.
Now… you may be thinking that this sounds incredibly hard… if so, you’re wrong. This is actually incredibly easy and to be honest, I only just found out about it a few days ago. So, what we will be doing is adding some more code to the pre-init method. First off, I will explain the three initialisation event arguments. These three argument types are unique to FML as it provides a way for us modders to hook into the loading data of the mod. Need the FML suggested configuration file? Use the method in the pre-init event. Need to get a loaded ASM data table? Use the method in any of the arguments.
So, obviously from my rambling in the above paragraph, we will be using the pre-init event argument. Now, in the argument there is a method called getModMetadata(). This allows modders to set metadata only data entries without actually needing a mcmod.info file. This is really good for us as if we are making more than one mods in the same workspace, you will quickly realise that you cannot have multiple mcmod.info files. Note that some of the features will not work with this.
So, first off, you’ll quickly notice a bunch of things in that method. That is because the method actually returns the class that actually stores the mod’s metadata. Using the various fields in this class, we can hardcode the actual metadata. Some examples are below.
Examples:
Version:
Author List:
Mod Name:
Mod Description:
The rest should be easy.
Tut 14: Custom tool materials
Much like other features of Forge, the EnumHelper added in Forge allows you to do some pretty awesome things without needing those pesky base class edits or new classes which will cause incompatibility. One of these things is custom tool materials. So, to create a new tool material just use this code:
Obviously, you can join the actual variable with the declaration; I just like to do things that way.
Information and Glossary
If you found any of these tutorials helpful or I have helped you and you feel like giving back something, feel free to drop a green arrow by! I don’t mind and it will also tell me that you guys want more tuts!
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
My Github page.
The entire Minecraft shader development community now has its own Discord server! Feel free to join and chat with all the developers!
@Alesh I will have a tutorial for that but not yet :/
Both keep in mind this is a WIP
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
My Github page.
The entire Minecraft shader development community now has its own Discord server! Feel free to join and chat with all the developers!
I actually don't think that is possible, any modders correct me if I'm wrong, but I'll look into it
And I mean to have a block be affected by redstone and have it pushed by a piston.
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
My Github page.
The entire Minecraft shader development community now has its own Discord server! Feel free to join and chat with all the developers!
This post is also reserved for future tutorials
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
My Github page.
The entire Minecraft shader development community now has its own Discord server! Feel free to join and chat with all the developers!
keep this up :)Oh yeah and as a suggestion could you try to make one for weapons please?
I eat creepers for breakfast, lunch, dinner and I have it bacon style!
Sure thing, I currently do not have access to my usual computer (school laptop(ultrasurf :D)) so I wil try to add the weapons today or maybe tomorrow, and thanks for that green arrow Have a nice day/night!
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
My Github page.
The entire Minecraft shader development community now has its own Discord server! Feel free to join and chat with all the developers!
It might be possible if the block had one side that didn't give a redstone signal. And I think that is possible because redpower does it with the logic gates (like timers).
Find out how I generate....coolAlias...world structure generation and rotation tool...
I'll look into it, now that I have had some time to think, I may of found a way to do it.
It's on the list, should be up soon, I also need to know how to do this.
Sort of, not the same code and whatnot but similar principle, following my tutorials should show you how to create your own mods aswell.
On the list.
Sorry for slow responses, laptop hard drive crashed so I've had to use my school laptop, which had this site blocked but I have a program to bypass that. Also a few new tutorials going up fairly soon.
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
My Github page.
The entire Minecraft shader development community now has its own Discord server! Feel free to join and chat with all the developers!
Swords are an upcoming tutorial, aswell as tools like picks and such, but spears will require a little more work as they do use entites, ut they aren't that hard to code. Added to the list.
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
My Github page.
The entire Minecraft shader development community now has its own Discord server! Feel free to join and chat with all the developers!
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
My Github page.
The entire Minecraft shader development community now has its own Discord server! Feel free to join and chat with all the developers!
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
My Github page.
The entire Minecraft shader development community now has its own Discord server! Feel free to join and chat with all the developers!
I noticed this before, it is in the next tutorial, I forgot, thanks anyways.
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
My Github page.
The entire Minecraft shader development community now has its own Discord server! Feel free to join and chat with all the developers!
Author of the Clarity, Serenity, Sapphire & Halcyon shader packs for Minecraft: Java Edition.
My Github page.
The entire Minecraft shader development community now has its own Discord server! Feel free to join and chat with all the developers!