[code]There's now another project available for decompiling and deobfuscating Minecraft - it's called Enigma, is open source, and you can check it out here: http://www.minecraftforum.net/forums/topic/2162136[/code]
[code]This tutorial was written when I used JD-GUI for decompilation. I now use Procyon instead, which has a slightly different output than JD-GUI, so keep in mind that some explanations and screenshots may mismatch to each other and to the decompiled code.[/code]
[code][hr][/code]
[code]How to mod Minecraft without using the Mod Coder Pack[/code]
Hello there, guys!
In this tutorial, I'm going to show you how to edit and update your mods to the latest Minecraft version – without using the Mod Coder Pack. Why would you want to do this? One answer could be that MCP hasn't been released yet. As most of the modding community knows by now, the 1.7 update is a good example. Minecraft 1.7.2 was released on October 25, 2013, and over 72 hours later, MCP still hasn't showed up. Now, I won't go blame Searge and his team for not updating MCP fast enough. They're doing a great job, and all credit goes to them for making modding possible for everyone in the first place. Being late is, of course, something that happens to everyone. And we must accept it. Trust me when I say that Searge and his team has a lot of work to do. After all, 1.7 changed half a million lines of Minecraft code. It was a huge update.
[code]What you'll need to know[/code]
Well, let's move on. There are a few requirements you need to meet to get through this guide as smoothly as possible:
You must have modded quite a bit in previous Minecraft versions already.
You must have the patience to understand obfuscated code and working with it. In other words, you'll need a lot of patience.
You must not be in a hurry. You'll need a lot of time.
You must not give up when you meet oddities in the code. Decompilers aren't perfect; some code may be left behind and won't recompile even if unmodified.
Your mod must [code][b]NOT be a Forge mod[/b][/code] unless you want to try and recompile the entire code of Forge. It would take days (maybe weeks) of troubleshooting, and most likely it won't work with the official Forge. It wouldn't matter either way, because your end users wouldn't be able to use the mod before Forge was released. [code]The same goes for other Mod API's[/code] - your mod must be independent.
Your mod must not be too complex. Estimate about 45-75 minutes per base class you're going to edit if this is the first time you're following this tutorial.
You must have a copy of the mod source files from a previous decompilation with MCP.
The source files you're going to edit must contain string constants. If they don't, you'll have a hard time continuing with this guide past the setup stage.
There are two main ways of modding without an official version of MCP. Both are very rarely used compared to MCP itself (in the 72 hour timespan mentioned above, only 4 mods were released for 1.7.2).
The first way of doing it involves class mapping. Class mapping in Minecraft is assigning meaningful class names to Minecraft's obfuscated classes; an example of a class mapping is knowing that bao.class from 1.7.2 represents GuiNewChat.class in unobfuscated form. A Minecraft Forum user and MCP modder called immibis created his own class mapping for 1.7.2 in roughly two days, becoming the first modder for 1.7.2 having used MCP's scripts to decompile and recompile the Minecraft source.
I won't go in details on how immibis performed this piece of magic. I don't even know myself, but he was in a discussion with Searge on IRC, which I think helped a bit. The problem about class mapping is that it takes forever. Use of automated scripts and programs does help, but seeing as immibis used two days on that process, I'm going to use the other method.
The second way of modding obfuscated code is to simply decompile the classes with obfuscated names and play a guessing game with the code. Fortunately, there are search tools to help, which I'll help you utilize.
[code][b]Setting up the modding environment[/b][/code]
To start modding, we're going to need some tools. The first is a project known as Java Decompiler. You can get it from here: http://jd.benow.ca/. If you don't understand what this project does by just looking at its name, you should probably go learn about Java and programming in general before you continue. Decompiling is the process of converting the binary source files (.class files) in Minecraft's jar file into actual code files (.java files). When you've navigated to the page I linked above, look around on that page for JD-GUI and download it for your operating system. Then, extract the zip, tar.gz or dmg file to wherever you're going to mod. I recommend it be a new folder without anything else in it.
We won't use JD-GUI to actually decompile the code, though. JD-GUI does a lot of mistakes, and there are tools out there to do the job much more flawlessly. One really good such tool, which has recently started getting a lot of attention in other similar tutorials and projects, like Enigma, is Procyon. Procyon, which is open-source, is more up-to-date than JD-GUI, and can parse the bytecode in Minecraft better than JD-GUI can. You can get it from here: https://bitbucket.org/mstrobel/procyon/downloads
Obviously you're also going to need the version of Minecraft you're going to mod for. In this guide, I'll be using Minecraft 1.7.2. Open up the Minecraft launcher, get 1.7.2, and close the game.
The last thing you're going to need is a Java JDK. If you've modded before, you already have Java JDK installed. If, for some reason, you don't have JDK, you can get it here: http://www.oracle.co...oads/index.html. Linux users can use OpenJDK instead. Most distros include OpenJDK in their repositories, and they can be searched for using a package manager like Synaptic or Mintinstall. On Ubuntu based distros, you can get it using sudo apt-get install openjdk-7-jre openjdk-7-jdk.
Now, it's time to set up the modding environment. Go back to the Modding folder you created earlier (from now on I'll refer to that as the project folder). Create 5 new folders: class, lib, src, mod and reobf. You can technically name them whatever you want, but for the sake of being reasonably organized I'll call them that.
Start off by copying the 1.7.2.jar file from .minecraft to the class folder in your project. Then, open a terminal or command prompt. Use it to browse to the directory you're setting up your project in. You can use the cd command to do this, e.g. `cd ./Documents/Modding/1.7.2´. Next up, we'll be using Procyon to decompile the game. Save the Procyon jar file in your project directory and name it procyon.jar, then run:
This might take a while, but once done, all of Minecraft's obfuscated sources will be saved in the src folder.
In the meantime, open JD-GUI, press the Open button and browse to Minecraft's jar file. It's located in .minecraft/versions/minecraft-version. We won't need JD-GUI just yet, but keep it open; we'll need it when we're going to figure out which file to mod.
Finally, you should copy all the files from the .minecraft/libraries folder to your lib folder.
Any system:
Use a file manager to navigate to .minecraft/libraries. Recursively open up every folder in there and copy every jar file you find into lib in your project folder. If there are several versions of a jar file (for instance there's one folder called 14.0 and one called 15.0), select the newest one and ignore the older ones. This whole process could take a few minutes, but it has to be done, so please do it. When you're done, it's time to start modding.
Mac:
Use the same instructions as for Linux, but use this command instead of the Linux one:
[code]find ~/Library/Application\ Support/minecraft/libraries/ -name \*.jar -print0 | xargs -I{} -0 cp -v {} /path/to/your/project/lib[/code] Thanks a lot to EniEinel for this great tip!
Linux:
Open a terminal (/bin/bash) and enter the following command (thanks to Multiple_Bergasms for this tip):
[code]cp `find ~/.minecraft/libraries/ | grep jar` path/to/project/folder/lib/[/code] Remember to replace the path/to/project/folder with the path to your project folder, e.g. ~/Desktop/Modding. Then, enter the lib folder and look for duplicates of libraries, for instance, if there are three files called authlib-1.1.jar, authlib-1.2.jar and authlib-1.3.jar, you should delete the two earliest versions and keep the latest one; authlib-1.3.jar.
[code][b]Modding Minecraft[/b][/code]
Just a little side note: If you skipped any of the above sections, go back, read them, and follow them. Otherwise this won't work. (I'm writing this because some people tend to just skip the preparations and information which is strictly required to be followed to be able to proceed.)
Anyway, Minecraft's source files are now stored in your src folder. If you dive into it, you'll see just a bunch of files with one-, two- and three-letter names. So, how do you know which one is the right to use? Remember in the requirements I requested you have available the source files from a previous MCP decompilation. Choose one of the base classes and open the source for that class. Look for any string constant that was in the code before you modded it (yes, I asked for that as well). In this example, I'm going to port ChatLog to 1.7.2, and ChatLog modifies the GuiNewChat class. That class file has a string constant in it at line 124 (at least in 1.7.2) reading “[CHAT]”. Copy that string constant and return to JD-GUI, which you hopefully left open (I told you to! If it's not open, open it and use it to open .minecraft/versions/minecraft-version/minecraft-version.jar).
In JD-GUI's toolbar, there is a Search menu. Open it and click on Search. A search window should now open. (Oh, you don't say.) In the Search For box, check String Constants, and paste your string constant in the field above. If you're lucky, there's one class file in the result list. Double click it, and that class' source will display. Double check that the string constant you searched for is in it. (JD-GUI's search function is a little glitchy.) If there is more than one class file, open each class file and filter out those who don't contain your string constant. If you end up without any class files after this, try altering your string constant a little (remove symbols etc.). Sometimes “[CHAT]” won't work, but “CHAT” does. Other times, it's vice versa. You may have to keep doing this for a while until you find the right class file.
Now, if you end up with several class files, compare the old, MCP-decompiled source file with each of the class files you find. Methods will probably be in the same order, and probably has roughly the same content (it's obfuscated, though, keep that in mind) unless there were a lot of changes in Minecraft's source code in that file between the versions. They probably also have roughly the same imports at the top. Choose the class file you believe is the right one and note the class name (in my case, that's bao.java).
Locate the java file you ended up with in the src folder, and copy it over to mod. Now it's time to mod. First of all, copy over all the code from the old version of the mod to the new java file in mod, as if you were porting normally. You need to fix the code quite a bit. I can't really offer much help here, but this is what I did:
ChatLog references Minecraft.class, but as it's obfuscated, I need to find it. I know that GuiNewChat takes Minecraft as a parameter in it's constructor, so I checked the constructor in bao.java and found that it asks for an azd.class instance. Now I know that Minecraft is azd.class. Another way to do it is searching by string constants, like what I did to locate GuiNewChat in the first place. I need to find the mcDataDir File variable in Minecraft.java, so I compare Minecraft.java and azd.java and figure out that the most logical variable in azd.java to use is w. In bao.java, the azd instance is assigned to class level variable f, so what is this.mc.mcDataDir in unobfuscated code is this.f.w in bao.java. This could become quite a bit of work to do, depending on the amount of references to various classes you have.
[code][b]Recompiling and troubleshooting[/b][/code]
This part is a little difficult. Open a terminal (C:\Windows\System32\cmd.exe in Windows, /bin/bash in Mac and Linux), enter the word javac and press Enter. If you get a help/documentation page, everything works with your Java installation. Otherwise, if you are told that javac could not be found, you must locate Java JDK on your system. In Windows, javac is commonly located in C:\Program Files\Java\jdk-1.7.0\bin. Look for a file called javac.exe there. When you've found it, enter “path/to/jdk/javac.exe” with quotes in the terminal, e.g. “C:\Program Files\Java\jdk-1.7.0\bin\javac.exe”, and hit enter. A documentation page now shows up. (If it still doesn't, reinstall Java JDK and try again.)
Browse to your project folder in the terminal using the cd command. For instance, cd “C:\Users\User\Documents\JDGUI\Modding” or cd “/home/user/JDGUI/Modding”. Remember to include the quotes. Finally, issue the recompilation command:
Windows:
[code][code]javac -cp "class/1.7.2.jar;lib/*" -d "reobf" mod/*.java[/code][/code] Mac and Linux:
[code][code]javac -cp "class/1.7.2.jar:lib/*" -d "reobf" mod/*.java[/code][/code]
Remember to replace class, lib, reobf and mod with the names of those folders in your project folder, if you changed them, and also, remember to use the correct name for the jar file in class. Most likely there will be a bunch of errors in your console window. This is where the real nightmare begins.
As I've said at an earlier point in this tutorial, Java Decompiler isn't perfect. Most of the errors can be fixed with simple workarounds – let's take an example.
The most common error you'll be encountering is something along the lines of the above. “Cannot find symbol” means that something the code is referencing couldn't be found. Looking below the code snippet, you'll see “symbol: variable localObject1”. That means what we're missing is some kind of variable named localObject1. Location says where in the java file the error is, and the code snippet itself is, well... the part of the code that doesn't work.
The first line in the error message also says where in which file we'll find the error. Let's look in the file:
We see line 135 tries to set localObject1. However, the method a(fa, int, int, boolean) doesn't declare the variable anywhere. To solve this problem, declare it at method level, at the very start of the method. But what type should we assign to it? Normally, it's safe to declare unknown variables like these Object, as Object covers all possible types a variable can have, as all classes derive from Object. If you can, try to figure out the context of what kind of type it is, as it will save you a lot of work casting the variable to the correct type. E.g. if the variable is named azd, or azd1, or something similar, you'll know that the type of the variable is azd - simply by looking at the name of the variable.[code][/code]
[code]Declaring localObject1 as Object:[/code][code][code]Object localObject1;[/code][/code] [code]Declaring azd as azd:[/code][code][code]azd azd;[/code][/code]
No need to assign any value to it. The code fixes that part. Once that part has been fixed, you could try recompiling again to see what happens. Chances are some new errors appear along the lines of “variable localObject1 is already defined in method a(fa,int,int,boolean)”, in this case one is located at line 184 in bao.java. Let's take a look:
Java is complaining that localObject1 has already been declared at some earlier point than when it was declared in the for loop in the picture. That's right – we did just declare it at the start of the method. We have two options: Either, we can simply remove the declaration from the loop (e.g. “Object”) and make it assign values to the existing localObject1, or we can rename the variable into something like xlocalObject1. The first option is the easiest, however, it's also the most spooky. If the initial localObject1 is being used at some later point in the code, after we've assigned another value to it in the for loop, using that option will most likely crash Minecraft. The other method takes the most time and is the most difficult to do manually, however it probably won't crash the game. If you are able to do a selection find/replace in your code editor, then I'd strongly recommend you use method 2. Notepad++ is able to do this – select text and hit Ctrl+H, choose Selection as the search area.
In this case, we're just talking about a simple for loop. The for loop itself isn't very big, so I'll opt for method 2. If you're doing this manually, look for every place localObject1 is being referenced where it's accessible (in this case the accessible region is the for loop). Replace localObject1 with xlocalObject1 or something else, just make sure it doesn't conflict with any other variables; if that happens you'd have to do it over again. If you can do it automatically, for instance in Notepad++, select the entire accessible area and hit Ctrl+H, enter localObject1 in Find and xlocalObject1 in Replace with, then hit Replace all (ensure your search area is “Selection”).
Save, and recompile again. If you get any other similar messages, try fixing them in some way or the other.
The incompatible types message like the above may also appear now and then. The solution is simple: The for loop expects a variable of type fa, but the method it calls returns an Object instead. The solution is simple: Change the fa variable to an Object variable; simply replace the fa with Object. Next, look for return statements that return the object. If the method returns fa, and the variable is Object, you should cast it to fa by placing “(fa)” just before the variable name:
[code][code]return (fa) localfa;[/code][/code]
There's one other error type I've encountered, that I think you should know about. It's of the “cannot find symbol” type, but this time, we're talking of a method. More specifically, Minecraft tries to call a method called Logger.a(String). However, the Logger class comes from a library, and the Logger class from that library doesn't have an a(String) method.
This is actually, as painful as it appears, a Java Decompiler glitch that in many cases cannot be fixed. If you're lucky, you could browse back in an MCP-decompiled version of the class file and look for a similar method like the one that is throwing the error. However, if the code was added in a Minecraft patch released later than the latest version of MCP, you're out of luck. The only thing you can do here is raise a warning flag in the users client to let him know something went wrong when you made the mod, and return either the parameters passed, a new instance of whatever the method returns, or null.
In this case, I'm using a JOptionPane to show a message box to the user, and I also log the incident to the developer console. To use JOptionPane, import javax.swing.JOptionPane.
[code]Getting the recompiled class files[/code]
If you manage to get through the compilation without any errors, all output shown would be:
[code]Note: mod/bao.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.[/code]
If that's all you see, congratulations! You just ported a mod to 1.7.2! Look in the reobf folder, and you'll find the class files. You should thoroughly test your mod before releasing it, and when you release it, I'd recommend you release it as a beta version, especially if you inserted any message boxes or implemented similar techniques to those I used in the last error above.
If you have any further questions about decompilation, recompilation, setting up the modding environment or encounter any errors I've not documented here, feel free to ask!
Thank you for reading my work. If you like my work or had any use of it, I'd highly appreciate a click on the [code][b]↑[/b][/code] reputation button!
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
Good tutorial, I had an error when I tested so I tried to recompile the original class "bbw" it had the same error so I gave up, anyway thanks for the awesome tutorial!
Thank you, both of you!
Clellan2451, I looked into bbw class and found that it matches GuiIngameMenu. The method with the errors in it is actionPerformed(GuiButton) (obfuscated: a(ban)). When I compare the code across the versions, I find that the code is trying to set a null GUI: this.mc.displayGuiScreen((GuiScreen)null);. However, the decompiler seems to have forgotten to cast the null to GuiScreen first, so the this.k.a matches two methods in azd (this.k is of type azd). To fix this, you should cast the two null values to GuiScreen.
But, what is GuiScreen? Look at the class GuiIngameMenu itself, it extends GuiScreen. In bbw, it extends bcd. bcd is GuiScreen, so you cast the this.k.a(null)'s to this.k.a((bcd)null); both the places the error occurs.
I hope this helps
- bilde2910
Rollback Post to RevisionRollBack
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
Hiya, for the step with copying over all the jar files into lib, that can be tedious. You could use cp `find ~/.minecraft/libraries/ | grep jar` ~/Desktop/Modding/lib/
to copy to a folder called lib in modding on the desktop
Hiya, for the step with copying over all the jar files into lib, that can be tedious. You could use cp `find ~/.minecraft/libraries/ | grep jar` ~/Desktop/Modding/lib/
to copy to a folder called lib in modding on the desktop
Thanks for the tip; added it to the thread.
Rollback Post to RevisionRollBack
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
Heh, topics tend to cool down quite fast :3 The forum is like a fridge or something
Rollback Post to RevisionRollBack
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
Great tutorial, would have been nice if all this was done using eclipse or something on the lines of that.
Also, I ran into this error when trying to run Minecraft with my recompiled files -
java.lang.NoSuchFieldError: u
at bul.b(SourceFile:77)
at bly.a(SourceFile:51)
at bly.<init>(SourceFile:47)
at azd.Z(azd.java:286)
at azd.e(azd.java:572)
at net.minecraft.client.main.Main.main(SourceFile:103)
I decompiled using fernflower as you get about 2000 less errors in eclipse with it.
Maybe If possible would you be able to skype or anything on the lines of that to help out that would be great.
Great tutorial, would have been nice if all this was done using eclipse or something on the lines of that.
Also, I ran into this error when trying to run Minecraft with my recompiled files -
-snip-
I decompiled using fernflower as you get about 2000 less errors in eclipse with it.
Maybe If possible would you be able to skype or anything on the lines of that to help out that would be great.
I'm unfamiliar with fernflower, so my tutorial only covers JD. It could be possible to make this work in Eclipse; add 1.7.2.jar and lib/* to classpath or required libraries list, then just use source files from the mod folder. I haven't tested, though, so I can't confirm.
My Skype name is on my profile. Just leave a note saying it's you, so I know that it's you I'm talking to
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
There are no error at all in eclipse, it when I run the client that I get the error.
That's quite odd. To be honest, I have absolutely no idea what's causing it. I really wish I could've helped, but I'm afraid I can't :/
Rollback Post to RevisionRollBack
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
bilde2910
it would be awesome if you could create a mod that you could change the damage that different weapons/tools/items do.
i tried to do this and got lost a little more quickly than i would have liked :/
thanks!!
bilde2910
it would be awesome if you could create a mod that you could change the damage that different weapons/tools/items do.
i tried to do this and got lost a little more quickly than i would have liked :/
thanks!!
I don't have time to do it, but you could, possibly. If you don't know where to start, you should try 1.6.4 with MCP. You can always come back to this later
Rollback Post to RevisionRollBack
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
If you don't know where to start, you should try 1.6.4 with MCP.
I didn't start working on this until 1.7.2, and I haven't been able to get a copy of the obfuscated code from any previous versions...
So my work has been almost stopped, until MPC comes out for the newest update
Thanks a lot for your tip - added it to the main post!
Rollback Post to RevisionRollBack
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
[code]This tutorial was written when I used JD-GUI for decompilation. I now use Procyon instead, which has a slightly different output than JD-GUI, so keep in mind that some explanations and screenshots may mismatch to each other and to the decompiled code.[/code]
[code][hr][/code]
[code]How to mod Minecraft without using the Mod Coder Pack[/code]
Hello there, guys!
In this tutorial, I'm going to show you how to edit and update your mods to the latest Minecraft version – without using the Mod Coder Pack. Why would you want to do this? One answer could be that MCP hasn't been released yet. As most of the modding community knows by now, the 1.7 update is a good example. Minecraft 1.7.2 was released on October 25, 2013, and over 72 hours later, MCP still hasn't showed up. Now, I won't go blame Searge and his team for not updating MCP fast enough. They're doing a great job, and all credit goes to them for making modding possible for everyone in the first place. Being late is, of course, something that happens to everyone. And we must accept it. Trust me when I say that Searge and his team has a lot of work to do. After all, 1.7 changed half a million lines of Minecraft code. It was a huge update.
[code]What you'll need to know[/code]
Well, let's move on. There are a few requirements you need to meet to get through this guide as smoothly as possible:
The first way of doing it involves class mapping. Class mapping in Minecraft is assigning meaningful class names to Minecraft's obfuscated classes; an example of a class mapping is knowing that bao.class from 1.7.2 represents GuiNewChat.class in unobfuscated form. A Minecraft Forum user and MCP modder called immibis created his own class mapping for 1.7.2 in roughly two days, becoming the first modder for 1.7.2 having used MCP's scripts to decompile and recompile the Minecraft source.
I won't go in details on how immibis performed this piece of magic. I don't even know myself, but he was in a discussion with Searge on IRC, which I think helped a bit. The problem about class mapping is that it takes forever. Use of automated scripts and programs does help, but seeing as immibis used two days on that process, I'm going to use the other method.
The second way of modding obfuscated code is to simply decompile the classes with obfuscated names and play a guessing game with the code. Fortunately, there are search tools to help, which I'll help you utilize.
[code][b]Setting up the modding environment[/b][/code]
To start modding, we're going to need some tools. The first is a project known as Java Decompiler. You can get it from here: http://jd.benow.ca/. If you don't understand what this project does by just looking at its name, you should probably go learn about Java and programming in general before you continue. Decompiling is the process of converting the binary source files (.class files) in Minecraft's jar file into actual code files (.java files). When you've navigated to the page I linked above, look around on that page for JD-GUI and download it for your operating system. Then, extract the zip, tar.gz or dmg file to wherever you're going to mod. I recommend it be a new folder without anything else in it.
We won't use JD-GUI to actually decompile the code, though. JD-GUI does a lot of mistakes, and there are tools out there to do the job much more flawlessly. One really good such tool, which has recently started getting a lot of attention in other similar tutorials and projects, like Enigma, is Procyon. Procyon, which is open-source, is more up-to-date than JD-GUI, and can parse the bytecode in Minecraft better than JD-GUI can. You can get it from here: https://bitbucket.org/mstrobel/procyon/downloads
Obviously you're also going to need the version of Minecraft you're going to mod for. In this guide, I'll be using Minecraft 1.7.2. Open up the Minecraft launcher, get 1.7.2, and close the game.
The last thing you're going to need is a Java JDK. If you've modded before, you already have Java JDK installed. If, for some reason, you don't have JDK, you can get it here: http://www.oracle.co...oads/index.html. Linux users can use OpenJDK instead. Most distros include OpenJDK in their repositories, and they can be searched for using a package manager like Synaptic or Mintinstall. On Ubuntu based distros, you can get it using sudo apt-get install openjdk-7-jre openjdk-7-jdk.
Now, it's time to set up the modding environment. Go back to the Modding folder you created earlier (from now on I'll refer to that as the project folder). Create 5 new folders: class, lib, src, mod and reobf. You can technically name them whatever you want, but for the sake of being reasonably organized I'll call them that.
Start off by copying the 1.7.2.jar file from .minecraft to the class folder in your project. Then, open a terminal or command prompt. Use it to browse to the directory you're setting up your project in. You can use the cd command to do this, e.g. `cd ./Documents/Modding/1.7.2´. Next up, we'll be using Procyon to decompile the game. Save the Procyon jar file in your project directory and name it procyon.jar, then run:
[code]java -jar procyon.jar -jar class/1.7.2.jar -o src[/code]
This might take a while, but once done, all of Minecraft's obfuscated sources will be saved in the src folder.
In the meantime, open JD-GUI, press the Open button and browse to Minecraft's jar file. It's located in .minecraft/versions/minecraft-version. We won't need JD-GUI just yet, but keep it open; we'll need it when we're going to figure out which file to mod.
Finally, you should copy all the files from the .minecraft/libraries folder to your lib folder.
Any system:
Use a file manager to navigate to .minecraft/libraries. Recursively open up every folder in there and copy every jar file you find into lib in your project folder. If there are several versions of a jar file (for instance there's one folder called 14.0 and one called 15.0), select the newest one and ignore the older ones. This whole process could take a few minutes, but it has to be done, so please do it. When you're done, it's time to start modding.
Mac:
Use the same instructions as for Linux, but use this command instead of the Linux one:
[code]find ~/Library/Application\ Support/minecraft/libraries/ -name \*.jar -print0 | xargs -I{} -0 cp -v {} /path/to/your/project/lib[/code] Thanks a lot to EniEinel for this great tip!
Linux:
Open a terminal (/bin/bash) and enter the following command (thanks to Multiple_Bergasms for this tip):
[code]cp `find ~/.minecraft/libraries/ | grep jar` path/to/project/folder/lib/[/code] Remember to replace the path/to/project/folder with the path to your project folder, e.g. ~/Desktop/Modding. Then, enter the lib folder and look for duplicates of libraries, for instance, if there are three files called authlib-1.1.jar, authlib-1.2.jar and authlib-1.3.jar, you should delete the two earliest versions and keep the latest one; authlib-1.3.jar.
[code][b]Modding Minecraft[/b][/code]
Just a little side note: If you skipped any of the above sections, go back, read them, and follow them. Otherwise this won't work. (I'm writing this because some people tend to just skip the preparations and information which is strictly required to be followed to be able to proceed.)
Anyway, Minecraft's source files are now stored in your src folder. If you dive into it, you'll see just a bunch of files with one-, two- and three-letter names. So, how do you know which one is the right to use? Remember in the requirements I requested you have available the source files from a previous MCP decompilation. Choose one of the base classes and open the source for that class. Look for any string constant that was in the code before you modded it (yes, I asked for that as well). In this example, I'm going to port ChatLog to 1.7.2, and ChatLog modifies the GuiNewChat class. That class file has a string constant in it at line 124 (at least in 1.7.2) reading “[CHAT]”. Copy that string constant and return to JD-GUI, which you hopefully left open (I told you to! If it's not open, open it and use it to open .minecraft/versions/minecraft-version/minecraft-version.jar).
In JD-GUI's toolbar, there is a Search menu. Open it and click on Search. A search window should now open. (Oh, you don't say.) In the Search For box, check String Constants, and paste your string constant in the field above. If you're lucky, there's one class file in the result list. Double click it, and that class' source will display. Double check that the string constant you searched for is in it. (JD-GUI's search function is a little glitchy.) If there is more than one class file, open each class file and filter out those who don't contain your string constant. If you end up without any class files after this, try altering your string constant a little (remove symbols etc.). Sometimes “[CHAT]” won't work, but “CHAT” does. Other times, it's vice versa. You may have to keep doing this for a while until you find the right class file.
Now, if you end up with several class files, compare the old, MCP-decompiled source file with each of the class files you find. Methods will probably be in the same order, and probably has roughly the same content (it's obfuscated, though, keep that in mind) unless there were a lot of changes in Minecraft's source code in that file between the versions. They probably also have roughly the same imports at the top. Choose the class file you believe is the right one and note the class name (in my case, that's bao.java).
Locate the java file you ended up with in the src folder, and copy it over to mod. Now it's time to mod. First of all, copy over all the code from the old version of the mod to the new java file in mod, as if you were porting normally. You need to fix the code quite a bit. I can't really offer much help here, but this is what I did:
ChatLog references Minecraft.class, but as it's obfuscated, I need to find it. I know that GuiNewChat takes Minecraft as a parameter in it's constructor, so I checked the constructor in bao.java and found that it asks for an azd.class instance. Now I know that Minecraft is azd.class. Another way to do it is searching by string constants, like what I did to locate GuiNewChat in the first place. I need to find the mcDataDir File variable in Minecraft.java, so I compare Minecraft.java and azd.java and figure out that the most logical variable in azd.java to use is w. In bao.java, the azd instance is assigned to class level variable f, so what is this.mc.mcDataDir in unobfuscated code is this.f.w in bao.java. This could become quite a bit of work to do, depending on the amount of references to various classes you have.
[code][b]Recompiling and troubleshooting[/b][/code]
This part is a little difficult. Open a terminal (C:\Windows\System32\cmd.exe in Windows, /bin/bash in Mac and Linux), enter the word javac and press Enter. If you get a help/documentation page, everything works with your Java installation. Otherwise, if you are told that javac could not be found, you must locate Java JDK on your system. In Windows, javac is commonly located in C:\Program Files\Java\jdk-1.7.0\bin. Look for a file called javac.exe there. When you've found it, enter “path/to/jdk/javac.exe” with quotes in the terminal, e.g. “C:\Program Files\Java\jdk-1.7.0\bin\javac.exe”, and hit enter. A documentation page now shows up. (If it still doesn't, reinstall Java JDK and try again.)
Browse to your project folder in the terminal using the cd command. For instance, cd “C:\Users\User\Documents\JDGUI\Modding” or cd “/home/user/JDGUI/Modding”. Remember to include the quotes. Finally, issue the recompilation command:
Windows:
[code][code]javac -cp "class/1.7.2.jar;lib/*" -d "reobf" mod/*.java[/code][/code]
Mac and Linux:
[code][code]javac -cp "class/1.7.2.jar:lib/*" -d "reobf" mod/*.java[/code][/code]
Remember to replace class, lib, reobf and mod with the names of those folders in your project folder, if you changed them, and also, remember to use the correct name for the jar file in class. Most likely there will be a bunch of errors in your console window. This is where the real nightmare begins.
As I've said at an earlier point in this tutorial, Java Decompiler isn't perfect. Most of the errors can be fixed with simple workarounds – let's take an example.
The most common error you'll be encountering is something along the lines of the above. “Cannot find symbol” means that something the code is referencing couldn't be found. Looking below the code snippet, you'll see “symbol: variable localObject1”. That means what we're missing is some kind of variable named localObject1. Location says where in the java file the error is, and the code snippet itself is, well... the part of the code that doesn't work.
The first line in the error message also says where in which file we'll find the error. Let's look in the file:
We see line 135 tries to set localObject1. However, the method a(fa, int, int, boolean) doesn't declare the variable anywhere. To solve this problem, declare it at method level, at the very start of the method. But what type should we assign to it? Normally, it's safe to declare unknown variables like these Object, as Object covers all possible types a variable can have, as all classes derive from Object. If you can, try to figure out the context of what kind of type it is, as it will save you a lot of work casting the variable to the correct type. E.g. if the variable is named azd, or azd1, or something similar, you'll know that the type of the variable is azd - simply by looking at the name of the variable.[code][/code]
[code]Declaring localObject1 as Object:[/code][code][code]Object localObject1;[/code][/code]
[code]Declaring azd as azd:[/code][code][code]azd azd;[/code][/code]
No need to assign any value to it. The code fixes that part. Once that part has been fixed, you could try recompiling again to see what happens. Chances are some new errors appear along the lines of “variable localObject1 is already defined in method a(fa,int,int,boolean)”, in this case one is located at line 184 in bao.java. Let's take a look:
Java is complaining that localObject1 has already been declared at some earlier point than when it was declared in the for loop in the picture. That's right – we did just declare it at the start of the method. We have two options: Either, we can simply remove the declaration from the loop (e.g. “Object”) and make it assign values to the existing localObject1, or we can rename the variable into something like xlocalObject1. The first option is the easiest, however, it's also the most spooky. If the initial localObject1 is being used at some later point in the code, after we've assigned another value to it in the for loop, using that option will most likely crash Minecraft. The other method takes the most time and is the most difficult to do manually, however it probably won't crash the game. If you are able to do a selection find/replace in your code editor, then I'd strongly recommend you use method 2. Notepad++ is able to do this – select text and hit Ctrl+H, choose Selection as the search area.
In this case, we're just talking about a simple for loop. The for loop itself isn't very big, so I'll opt for method 2. If you're doing this manually, look for every place localObject1 is being referenced where it's accessible (in this case the accessible region is the for loop). Replace localObject1 with xlocalObject1 or something else, just make sure it doesn't conflict with any other variables; if that happens you'd have to do it over again. If you can do it automatically, for instance in Notepad++, select the entire accessible area and hit Ctrl+H, enter localObject1 in Find and xlocalObject1 in Replace with, then hit Replace all (ensure your search area is “Selection”).
Save, and recompile again. If you get any other similar messages, try fixing them in some way or the other.
The incompatible types message like the above may also appear now and then. The solution is simple: The for loop expects a variable of type fa, but the method it calls returns an Object instead. The solution is simple: Change the fa variable to an Object variable; simply replace the fa with Object. Next, look for return statements that return the object. If the method returns fa, and the variable is Object, you should cast it to fa by placing “(fa)” just before the variable name:
[code][code]return (fa) localfa;[/code][/code]
There's one other error type I've encountered, that I think you should know about. It's of the “cannot find symbol” type, but this time, we're talking of a method. More specifically, Minecraft tries to call a method called Logger.a(String). However, the Logger class comes from a library, and the Logger class from that library doesn't have an a(String) method.
This is actually, as painful as it appears, a Java Decompiler glitch that in many cases cannot be fixed. If you're lucky, you could browse back in an MCP-decompiled version of the class file and look for a similar method like the one that is throwing the error. However, if the code was added in a Minecraft patch released later than the latest version of MCP, you're out of luck. The only thing you can do here is raise a warning flag in the users client to let him know something went wrong when you made the mod, and return either the parameters passed, a new instance of whatever the method returns, or null.
In this case, I'm using a JOptionPane to show a message box to the user, and I also log the incident to the developer console. To use JOptionPane, import javax.swing.JOptionPane.
[code]Getting the recompiled class files[/code]
If you manage to get through the compilation without any errors, all output shown would be:
[code]Note: mod/bao.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.[/code]
If that's all you see, congratulations! You just ported a mod to 1.7.2! Look in the reobf folder, and you'll find the class files. You should thoroughly test your mod before releasing it, and when you release it, I'd recommend you release it as a beta version, especially if you inserted any message boxes or implemented similar techniques to those I used in the last error above.
If you have any further questions about decompilation, recompilation, setting up the modding environment or encounter any errors I've not documented here, feel free to ask!
Thank you for reading my work. If you like my work or had any use of it, I'd highly appreciate a click on the [code][b]↑[/b][/code] reputation button!
– bilde2910
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
Thank you, both of you!
Clellan2451, I looked into bbw class and found that it matches GuiIngameMenu. The method with the errors in it is actionPerformed(GuiButton) (obfuscated: a(ban)). When I compare the code across the versions, I find that the code is trying to set a null GUI: this.mc.displayGuiScreen((GuiScreen)null);. However, the decompiler seems to have forgotten to cast the null to GuiScreen first, so the this.k.a matches two methods in azd (this.k is of type azd). To fix this, you should cast the two null values to GuiScreen.
But, what is GuiScreen? Look at the class GuiIngameMenu itself, it extends GuiScreen. In bbw, it extends bcd. bcd is GuiScreen, so you cast the this.k.a(null)'s to this.k.a((bcd)null); both the places the error occurs.
I hope this helps
- bilde2910
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
to copy to a folder called lib in modding on the desktop
Thanks for the tip; added it to the thread.
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
Thanks You can use my sectional anchors to skip faster to certain sections of the page:
What you'll need to know: http://www.minecraftforum.net/topic/2082696-complete-tutorial-modding-without-mcp/#requirements
Setting up the modding environment: http://www.minecraftforum.net/topic/2082696-complete-tutorial-modding-without-mcp/#preparations
Modding Minecraft: http://www.minecraftforum.net/topic/2082696-complete-tutorial-modding-without-mcp/#modding
Recompiling and troubleshooting: http://www.minecraftforum.net/topic/2082696-complete-tutorial-modding-without-mcp/#troubleshooting
Getting the recompiled class files: http://www.minecraftforum.net/topic/2082696-complete-tutorial-modding-without-mcp/#distribution
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
Thank you
I won't mind at all. Go ahead if you wish
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
Also, I ran into this error when trying to run Minecraft with my recompiled files -
I decompiled using fernflower as you get about 2000 less errors in eclipse with it.
Maybe If possible would you be able to skype or anything on the lines of that to help out that would be great.
I'm unfamiliar with fernflower, so my tutorial only covers JD. It could be possible to make this work in Eclipse; add 1.7.2.jar and lib/* to classpath or required libraries list, then just use source files from the mod folder. I haven't tested, though, so I can't confirm.
My Skype name is on my profile. Just leave a note saying it's you, so I know that it's you I'm talking to
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
That's quite odd. To be honest, I have absolutely no idea what's causing it. I really wish I could've helped, but I'm afraid I can't :/
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
it would be awesome if you could create a mod that you could change the damage that different weapons/tools/items do.
i tried to do this and got lost a little more quickly than i would have liked :/
thanks!!
I don't have time to do it, but you could, possibly. If you don't know where to start, you should try 1.6.4 with MCP. You can always come back to this later
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
I didn't start working on this until 1.7.2, and I haven't been able to get a copy of the obfuscated code from any previous versions...
So my work has been almost stopped, until MPC comes out for the newest update
Thanks a lot for your tip - added it to the main post!
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.
You're very welcome
I AM NOT YOUR PERSONAL MINECRAFT MOD SUPPORT AGENT, SO PLEASE DO NOT PM ME ABOUT PROBLEMATIC MODS THAT ARE NOT MINE. If you're having trouble/crashes with a mod, you'll have better luck resolving it in this forum section than PMing me. If you already made a topic, be patient about responses. If you have troubles with anything non-Minecraft related on your PC, I might be able to help, though, but no promises. Even though I could wish to be, I'm not a wizard.