Modding Minecraft 1.20.4 – Fabric: Temp Mod Main Classes
Let’s start adding the main classes we need in every mod from now on. This is still our temp mod and we are writing the skeleton of our custom temp mod. These classes and Enums are: Armor Material, Block Entities, Blocks, Commands, Effects, Item Groups, Items, Messages, Recipes, Screen Handlers, and Tool Materials.
By adding these java classes into our temp mod structure, we make sure that every time we want to use this temp project in future to bootstrap our new mods, we don’t need to retype and generate all these classes again. Also, in future videos, we will add datagen and link everything to each other and make the temp mod completely functional.
Chapters:
- 00:00 Temp Mod Classes
- 02:21 Generating the Sources
- 10:30 Main Classes for a Mod
- 11:38 Mod Classes Described
- 15:32 Mod’s Main Class
- 16:11 Reference Class
- 25:53 Mod Screen Handlers Class
- 28:55 Mod Recipes Class
- 37:09 Mod Messages Class
- 38:55 Mod Items Class
- 41:55 Mod Item Groups Class
Let’s add our main classes with their functionalities into the mod project. Normally, you would see different people teach you modding Minecraft with adding the very first item at this stage. I’m not gonna do that. You may ask why? Well, stay tuned to the end of the video and you will understand why that’s the case. If you dropped the setup video and thinking that, hey, I know how to set up the fabric dev env, then I highly suggest you go back and watch it because we stabbed our hierarchy of packages and folders there. And you may want to look at that in that video.
However, the very first thing I want to attack is these two files. The names are big, ugly, and I don’t like them. Changing these two means that I need to change the entry points in the JSON file. First, select the file name, shift F6, and it brings the rename window. Now I will call it ZXC main and hit refactor and derefactor. So you see that it changes it here too. Now ZXC tutorial data generator, I will call it ZXC data gen, do refactor, do refactor.
I want a new entry point. So I will just copy all of this and I will paste it. and this one is client, just as it is. And again, this is ZXC client. However, you notice that I got an error because I don’t have the class yet. Come all the way to ZXC on the package list, hit alt, insert, Java class, and we call it ZXC client. And the error should be gone. However, we have another error because, well, it’s not implementing the client mod initializer. Yes, for sure. Implement client mod initializer and hit alt, enter, implement methods. And that’s the only method that we want to implement. So alt, enter, enter, and that stuff. If you right click on client mod initializer, hit go to superclass or interface. You see this, this is the source file. However, we didn’t generate the sources yet. If you look at the setup file, the setup video, we didn’t generate our resources. So we need to hit this gen sources and double click it. So it will generate the source files for us. We need to do it because we want to take a look at the code as readable as possible. Remember, Minecraft codes are obfuscated. If you want to look at Minecraft codes, you need to do this. You see this, net Minecraft, Minecraft merged Fabric MC-Yarn. This is the version of the Minecraft being provided by Fabric. If I go into net, block, and open any one of these classes, it doesn’t matter. Normally you see something a little bit different because you wouldn’t have generated the sources and you see that it says choose sources because it says, hey, we decompiled the .class file ourselves with IntelliJ. And it’s just a decompilation of the defuscated file. There are some neglecting parts in different classes like Java docs, like namings. We just decompiled it. But if you choose a different source, we will show that source for this file. That’s it. We just need to run this gen sources and it will run three different gen sources that you see in the tasks, Vine Flover, Fern, and CFR in consequence automatically. So that you get the best source files for each one of these vanilla classes and interfaces and other stuff. I kept that from the setup video because you had to write something that would attack the vanilla code so that you could just right click on it and see the Java docs or things like that. And then you would see the difference. However, in this case, the client itself was not enough. I had to go more forward, but I decided that, you know what, let’s get done with it. In this video, we have many, many classes that we need to write. Not running gen sources. There is no reason to neglect it anymore. So I will wait and pause the video until it’s finished and I will come back and we have to write 15 different classes till the end of this video. They are critical. Now, as it’s going to download the source, I will talk about why I’m starting the project like this. As I said, normally people would tell you that, hey, this is the way you add your very first item at this stage of video tutorials. However, when you are going to write a serious mod in your real dev environment, you don’t want to start with, I don’t know, JSON files for an item. You immediately want to start using data gen and other stuff. You want to have a very solid ground to start with. Knowing that you have to write at least 15 different files until you get your project ready to run is a good starting point because I’m not aiming to provide superficial tutorials for you that tells you, hey, this is your very first item. Hooray, this is your second block. Hooray, no, I’m aiming to make you a serious mod developer and programmer. So if you want to be serious in this journey, you have to be professional. And the professional programmer doesn’t start with the kids’ way of adding your very first armor, launch the game, hooray, we have a check board items in our hand. No, we want to be professional and professionals and make jobs automatic as much as possible. And they should know each step they should take so that they can go forward. If I would write our very first item and use JSONs and then I would write our very first block again using JSONs and then roll back to talk about data gen, hell no, that’s in no way of being a professional programmer. Yes, I can prove that I can add an item, I can prove that I can add a block, but so what? You can find that on many, many videos out there on YouTube. If you want to be serious about mod development, then you need to know how serious mod developers do the job. A serious mod developer does not start with, hey, I have a checker board item in my hand, I have a JSON for my item, here’s the JSON for block state, no. He will start teaching you the very first correct step of using the API provided. And for JSON creation, we have an API provided to us called data gen. So we will use that in this project and from here forward. So if I’m gonna use data gen, why not stab the skeleton of my files right in the first video? So now if I go here, I can say choose source and well, now I have this one, as you saw it pops up. It’s the same name, however, at the end it has sources. So again, it’s Minecraft merge, fabric yarn, but it has sources, click okay, and it will import it. You will notice that many things will change. Lots and lots of Java docs are added. That’s the very first thing, that’s the thing that shows up in your face. Lots and lots of Java docs are added. And if you would sit down and compare the files, you would notice that the namings of the params are changed. And the most important thing is inside each one of these methods, it’s an abstract class. So methods are almost empty or just very easy stuff. If I would open something serious like the piston class, and I would go inside a method, now you would see that inside methods are changed drastically and much more readable. One thing to remember, if you see errors showing up inside your source files, completely ignore them. It’s irrelevant, it’s not important, it will work, your mod will compile, even the game will show up. That’s not important. This is our source files being set up and our mod initializer for our client is up. Right now, we don’t need to add anything inside here, but we will come back to these classes one after another as we go forward. I will add one more package here and I will call it main entries. Now inside main entries, I will move the data gen inside main entries. And inside data gen, I will add another package and that is for world. So our hierarchy looks a little bit nicer now. However, in our main entries, let’s change this name, I’m not happy with it. References, that’s a better name and that is not reference now. You may say, why are you going back and forth? Get done with it, man. No, get used to it in the world of programming because the more you think about the structure of your project, the better. Think about two years later, when you come back to this project and you want to update it and you are saying that, hey, where is this class? I can’t find it because your hierarchy is not guiding you. If I want to keep the references here, the data gen needs to go out. Yes, okay, that’s a better situation now. For the references, I will have a Java class called reference. Now Java classes start with capital words. Go and watch the Java syntax video. We will have another class here. I will just drop the class names. I will come back to these later. So the next one is the mod tags. We’ll have another class called mod screen handlers. We will have another class called mod recipes. We will have another class mod messages, another class mod items, another class mod item groups, another class mod armor material. By the way, I’m not the fastest typist out there. So chill down if you type faster than me. So mod effects and one class I dropped, mod tool materials, armor material. Yeah, okay. Mod item groups, screen handlers, recipes, messages, items, groups, effects. Why am I keeping these ones singular? I don’t know. Be consistent. Be consistent in your namings all the time. The next one is mod commands. Another one is mod blocks. And finally, mod block entities. Now which one is which and what is happening here? Let’s start from top to bottom and we will talk about these mod armor materials or is an enum actually. It’s not a class, but it doesn’t matter. We can change the class name inside the file and make it as enum. But the mod armor materials is an enumeration of different materials you would add in your game like diamond, netherite, iron, gold. You will have different armors based on these materials. Each material will provide different amount of protection and numeric values that is being used by Minecraft to determine how much protection an armor should give you. We will define those materials and the numeric values inside mod armor materials later. Well, you don’t know what is a block entity. We will talk about it. Some blocks have an additional object as programming object and that is block entities associated to them. And we will talk about block entities. We will teach you what are the block entities. But when we define our block entities, they sit here. Obviously, you will define your blocks from your mod inside mod blocks. If you want any chat command, you can create your own commands and add them inside mod commands. If you want any sort of effect, remember it’s not potions. We will add the potions later in this hierarchy. But if you want something like, I don’t know, a flight mechanic like creative flight, it’s a flight effect and it will add your effects here. The item groups are the creative tab groups. You define a new creative tab. You put some items there and then another creative tab, you put some items there. And these are being defined in this class. Obviously, the mod items class is all about defining your items for the mod. Mod messages is about networking. We will talk about networking later, but in this class, you will define your networking messages. Mod recipes is about the definition of your custom recipes for your block entities and other stuff. Mod screen handlers. Mod screen handlers is about your GUIs. So you will define your GUIs in two places. One is a screen handlers and one is the client. So these two work hand in hand with each other. Mod tags is about defining your own custom tags related to items. We will talk about tags later, but here is where you define them. And again, as armor materials, you have tool materials like, I don’t know, iron for the shovel or pickaxe. Now you have iron for armor. The values are defined there on armor materials. But if the iron should be used for tools like shovel, another set of values should be set and they are being assigned inside tool materials. And the reference is just something that I use. Normally I put mod tags on the reference, but we will talk about internal classes later. So I just kept them separated to begin with. And the more I think about it, these two really should sit on the references because this is the collection of everything. However, I’m not doing it because these three are entry points into our mod. And normally people keep them in the root of their project. So I will keep them there to be consistent with other mod developers so that when you go and look at their repositories, you won’t get confused. Let’s sit back and write the internals of each one of these classes starting with our main file because main file has few things that we need to change. The very first thing is that you notice that we have tabs here and I’m using spaces. So right click format code and hit okay. And you will see that it changes to spaces with showing dots here. Then we remove this whole section. We don’t want to print anything inside here. We will take this logger outside of this class and we move it inside our reference class. The logger being static means that I don’t need to instantiate reference to get access to logger. And inside the reference, we will add two more methods. One returns a not nullable, so not null value. This annotation makes sure that we will return something. It makes sure that the return thing shouldn’t be null because we say public static, we return an identifier from net Minecraft utils. Don’t use the IntelliJ language one, the Minecraft utils. And we call it identifier. Again, we accept a not null value, so it should be something and that’s a string, we call it path. Now what is an identifier? An identifier is an address of an asset sitting under your assets somewhere in the structure. And you are addressing that, hey, this asset is from Minecraft or for this mod ID under this folder, and this is the name of the asset, retrieve it. So basically, this is the Mojang way of addressing different files under your resources assets folder. And by having a method like this, we will make sure that our mod ID is always being added to the path so that it starts from resources assets, ZXC underlying tutorial and nowhere else. So how should we do it? Well, we say that return new identifier and inside here you see that it asks for two parameters, pay attention, I didn’t type it this namespace column or path column, you shouldn’t type them. This is IntelliJ’s helper showing me the parameter type that we need. And if I move my mouse out, it shows up, but it’s not there. If you notice, if I try to drag my mouse, it jumps before and after of it. So these are just helper visual text. They are not inside the main code. You shouldn’t type these. So the namespace means that which subfolder of assets should I look to? Is it Minecraft or is it something else? Here, we have something that call ourselves as mod ID. We don’t have it yet, we will add it. And then the path is the subfolders under this namespace. So these two Minecraft, ZXC tutorial is the namespace. Anything below that is the inside the path. So for example, if I want a texture that is under item, I would have to type textures. For example, let’s go with grid, okay? If I want this arrow button left and if you don’t know why these are there, go watch this setup video. That’s not your classic setup environment. Things are happening there. So if I want this arrow button left, you would have to write textures, GUI, arrow button left.png inside the path. And then, well, I am giving the path by method parameter. So the only thing remaining is this mod ID. Mod ID is public static string called mod ID. And you notice that when I’m typing M, even with the first capital M, it suggests that you should use mod ID because IntelliJ is a smart. It knows that I have an error called mod ID with the text mod ID. It assumes that if you are going to type something, it should be mod ID, I think. Yes, it’s mod ID, hit the enter, it will add it there, equals to. Now, here is a very critical thing. When you are typing your mod ID, pay attention to the typing. If I type A X C, well, my mod ID is Z X C. I can go and call it a tutorial, okay? On the surface, I have no errors whatsoever. However, if I run the game, well, it will compile for sure. If I run the game right now, it will work because well, I don’t have anything referencing this method right now. But the very first time you use this method and this method goes back and use this mod ID, or whenever I directly use this mod ID, I will crash the game because I have a typo here. And the message, error message there may misguide you and you don’t understand it. What the hell is going on? So you would track it and you will find that somewhere it says I don’t have access to this mod ID or domain or whatever. And you would understand that, hey, wait a minute, what’s going on? I have the correct mod ID because you are not paying attention to this little typo here. So be very careful about these sort of errors because they can bite really hard. So the next