Hacking Minecraft, adding output using Arduino

With the future/career day coming up I was wrecking my brains on what to do on the day my son visits me at my workplace. There will be stuff organized for him in the morning but I will have to entertain him for about four hours in the afternoon.

I was thinking I would bring my laptop and let him do some Scratch programming, something he already did and enjoyed. Thinking further I thought I could bring my Arduino Uno and he could blink some LEDs. The most important thing for me is to bring him into programming and not to bore him so I searched further. I thought connecting Arduino and programming to something he is really into… like Minecraft!

I came across this blog post where Rozz decompiles, hacks and recompiles Minecraft to output the health status via a connected Arduino! DONE! This project had all the ingredients I was looking for!

But instead of adding a Arduino Uno and an array of LEDs I wanted to hook up a Digispark with a RGB shield. The RGB led would change its color according to the player’s health status in the Minecraft game.

Minecraft Lifebar

DigiSpark with RGB shield displaying Minecraft’s health status

Even better for me, the guys from Digistump already created an example with which a Windows client could send color commands to the Digispark over USB. So all I did was uploading the DigiBlink example sketch to the Digispark and downloaded the DigiRGB.exe from GitHub. Firing up a command line, I could change the Digispark’s LED’s color with DigiRGB.exe and providing either a color or a RGB value as parameter. From the readme file:

Load DigiBlink example onto your Digispark
Run “DigiRGB R G B”
Where R,G and B are values 0-255 for each color LED
or Run “DigiRGB Red”
Where red is a valid css3 color

 

I tested that and it worked like a charm. Now I was wondering if I could just write a tiny Java program that executes this exe. This because Minecraft is written in Java too. This is what I did and again, worked like a charm:

package digiRGB;

public class DigiRgb {

	public static void main(String[] args) {

		Runtime runtime = Runtime.getRuntime();

		String[] cmd = new String[2];
		cmd[0] = "C:/tmp/DigisparkExamplePrograms-master/Python/DigiBlink/windows/DigiRGB.exe";
		//cmd[1] = "Red";  // first hard coded
		cmd[1] = args[0];  // then using a parameter

		try {
			Process proc = runtime.exec(cmd);
			proc.waitFor();

		} catch (Exception e) {
			e.printStackTrace();
		}		
	}
}

Now, off to hacking Minecraft! We need the Minecraft Coder Pack (MCP) as this brings all the tools to de- and recompile Minecraft’s code.

I downloaded MCP v8.11 from here. This is the newest version available, but compatible only to Minecraft 1.6.4. The newest Minecraft version is 1.7.2 but the guys reckon that it will take some more time to have a MCP available that can handle this version. However, this is not really relevant for us as we are happy with Minecraft 1.6.4.

I extracted the MCP in a folder on my disk. Then I started the Minecraft client on my comp and created a new profile where I defined that I wanted to play with version 1.6.4. What happens then is that it downloads the jar file to %appdata%\Roaming\.minecraft\versions\1.6.4

Going back to the MCP folder I started the decompile.bat file. It will take a few moments and then complaining about a missing server jar file. Just ignore that as we are not interested in the server code.

Let’s say you extracted MCP to a folder like mcp811 then the decompiled sources will be in mcp811\src\minecraft\net\minecraft\src. Locate the file EntityPlayer.java and open it with a notepad like application – I used Notepad++.

At the end I added the following code:

// added by roman
public void setHealth(float par1)
{		
  super.setHealth(par1);

  arduinoOutput(par1);
}

// added by roman
public void arduinoOutput(float par1){

  String[] cmd = new String[2];
  cmd[0] = "C:/tmp/DigisparkExamplePrograms-master/Python/DigiBlink/windows/DigiRGB.exe";

  int healthPercent = ((int)par1)/2;

  /*
  System.out.print("[Arduino] par1: " + Float.toString(par1));
  System.out.print(" / healthPercent: " + Integer.toString(healthPercent));
  System.out.println(" / getMaxHealth: " + Float.toString(this.getMaxHealth()));
  */

  if (healthPercent <= 2) { 			
     cmd[1] = "Red"; 		
  } else if (healthPercent > 2 && healthPercent <= 5) { 	
     cmd[1] = "Orange"; 		
  } else if (healthPercent > 5 && healthPercent <= 7) {
     cmd[1] = "Yellow";
  } else {
     cmd[1] = "Green";
  }		

  Runtime runtime = Runtime.getRuntime();

  try {
    Process proc = runtime.exec(cmd);
    proc.waitFor();

  } catch (Exception e) {
    e.printStackTrace();
  }
}

It’s necessary to override the setHealth() method. I called its super method and then did the call that actually sends the color code to the DigiSpark/Arduino.
Also note the System.out.print statements. They will be displayed in Minecraft Launcher’s development console. Quite handy when debugging. But don’t forget to comment them out / remove after debugging as these calls hit Minecraft’s performance big time!

I saved the class file and then recompiled the source using the file recompile.bat. At the end this complains too about missing server sources… just ignore it.

After that we need to obfuscate it again using reobfuscate.bat. This will create the file uf.class in folder mcp811\reobf\minecraft.

Now we have to mod Minecraft. Go back to %appdata%\Roaming\.minecraft\versions\ and copy the folder 1.6.4. Place the copy in the same folder (versions) but rename it. I renamed it to 1.6.4.1. Note: You can name it to whatever you want, just make sure it’s not an existing Minecraft version number! Just be consistent with the naming.

Go into that folder and rename 1.6.4.jar to 1.6.4.1.jar and 1.6.4.json to 1.6.4.1.json. Open 1.6.4.1.json in a notepad and edit the 2nd line from
"id": "1.6.4",
to
"id": "1.6.4.1",
and save it.

Open 1.6.4.1.jar with WinRAR. Delete the folder META-INF! You will get a black screen when trying to start the game otherwise.
Update the obfuscated file uf.class: Drag it from folder mcp811\reobf\minecraft and drop it into the 1.6.4.1.jar file you still have open in WinRAR. Then close WinRAR.

Start the Minecraft client again and create a new profile:

Minecraft

create a new profile using our mod

Here you can see that we have our mod 1.6.4.1 as an option. Choose it and then start the game. Once in Minecraft all I did was looking for the nearest lake to get drowned:

One thought on “Hacking Minecraft, adding output using Arduino

Leave a Reply

Your email address will not be published. Required fields are marked *