I made a Minecraft mod!

After 10 years of not touching Java I somehow made a Minecraft mod. The reason? I wanted to see if I could turn on my IoT living room light with a switch inside Minecraft. Great success!

The mod is called Breakoutbox and is available on my github page: https://github.com/rheide/breakoutbox.

Breakoutbox is a very basic mod that lets you 'break out of Minecraft' by calling external scripts on the serverside. Once you're out, anything's possible. Controlling IoT lights as mentioned above, pulling in cryptocurrency prices into your Minecraft world, pushing a button to make a Tweet, you name it. And building all those things is a hell of a lot easier in an ad-hoc external script than it is to publish a dedicated Minecraft mod every time. Anything and everything, all of the time.

It was interesting to experience the Java ecosystem again after such a long time away. Some observations:

  • The build system for Minecraft mods is really nice. The Forge MDK (mod development kit) comes with good documentation to get you started, and a gradle build file that makes it super easy to compile a mod jar or run a dev Minecraft server.
  • That said, the Minecraft code itself is closed-source, so from there on you're walking through decompiled, de-obfuscated bytecode, guessing at what things are ok to call, hoping the arguments you've provided make sense. This could've been an absolute nightmare, but thanks to the fact that Java is a strongly typed language, and community efforts at deobfuscating the code every time a new release comes out, it's surprisingly not that painful.
  • It's so difficult/terse to do simple things in Java, compared to Python. The Java standard library featureset is still a joke. No json or yaml parser in the standard lib? Bah.
  • I gave up trying to figure out how to bundle a third party library with my jar. Couldn't figure out if it's just not standard practice or if I then had to burden everyone who downloads the mod with also figuring out how to download the dependency. Either way seemed bad.
  • It's veerrry easy to get Minecraft to misbehave. The redstone behavior has a 'contract' in that running a redstone command should finish quickly, e.g. in less than .1 second. External scripts can easily take any amount of time, and I had to guard against that. I found it quite interesting how easily I could get a 'professional' game to break just by adding a few lines of code in a tiny jar file.
  • I managed to get around the long-running script issue by queueing the tasks in the Minecraft server object's internal threadpool, but I wasted hours trying to figure out why it wouldn't just work from my own threadpool. I had created a separate threadpool for my own tasks, but somehow the commands never executed if I ran them from my own threadpool. Queueing them in the threadpool that was kept in the server object fixed things. Without looking at the actual source code, which is impossible, it's very difficult to say why. My guess is that the internal threadpool had some kind of hooks attached to it that updated the game state at the end of each task, whereas with my own pool stuff just disappeared into nowhere and was ignored by the game loop. But who knows.

Anyway, it was a fun little exercise. It was a project I started in spite of wanting to finish other projects I had already started. I had no particular need for it, but having it available on github in the form of a downloadable jar that anyone can stick into their Minecraft server, and source code available for anyone who feels like forking it, does feel good. I will endeavor to finish more things this year.

(I think I finally have an idea in my head to reintroduce comments to this blog without incurring massive maintenance or financial costs. More to come.)

Posted in Games , Tech | Tagged , ,

Fun with Square Codes

This is a qr code:

It's used to embed data inside of it, which can then be scanned by a large variety of devices. It's widely used in Japan to advertise links to web pages, which are otherwise difficult to type on a small device like a mobile phone. But they can be used for all kinds of things. All in all it's a very cool technology, so I wanted to experiment with it.

Python and Django are my server of choice, so I started looking for a library to generate square codes in Python. I soon wandered upon pyqrnative, which is a port from a javascript version, apparently. It's very compact and easy to use. Generating images was a piece of cake. I had Django serve dynamically generated images in no-time.

But how to read these images client-side? Since I recently dabbled in OpenCV and JavaCV I learned of an easy way to access the webcam in Java, so I made a Java implementation. This step was not very difficult, so I decided to make things harder on myself by embedding the webcam part in a Java applet, so it could run from a website.

I had a bit of trouble here, as accessing native libraries (using Java Native Access) proved quite difficult. I had a lot of trouble figuring out where JavaCV was loading its dll files from, and it took me a good half hour to debug it. A list of paths to OpenCV are hardcoded in the JavaCV source code. I wanted to include the dll files dynamically, which seemed near impossible. What's worse, removing or adding paths did not seem to make any difference as to whether JNA could find the dlls or not. I finally tracked it down to one folder: /usr/local/lib was the folder where my libraries were being loaded from. Which is damn peculiar, because that's a Linux folder and I'm running Windows 7. I suspected cygwin at first, but the problem was not that: When specifying the /usr/local/lib folder, jna looks for all folders in the system variable called jna.library.path, which contains the system path by default. Very obscure...

Having figured that out I could continue building the applet. I had jump through a bunch of hoops to get it to work, namely signing the applet (which is a very good thing considering I'm running native code that accesses a webcam!) and figuring the right tags to put in the HTML. HTML tags for applets are a big bloody mess, there's no standard at all. There's a deprecated applet tag, an object tag for IE and an embed tag for Mozilla (which also works in Chrome). I chose the embed tag for now.

There's a nice method in Java's AppletContext class which lets you change the browser's document's URL. It also allows you to execute arbitrary Javascript, so you can call a javascript function that does an ajax call back to the server that can update the web page! It's all very roundabout and takes three languages and a whole bunch of libraries to get going, but it's quite cool once it works. Here's a video of the result:

Posted in Tech | Tagged , , , , ,

Some Java

I came across this link during another fit of frustration with Xcode and Obj-C. XMLVM is a cross-compiler that can cross-compile Java code and turn it into Obj-C code that will run on the iPhone. Well, sort of. It runs on the iPhone simulator, but to actually get it to work on the device you're still bound to Xcode for various signing reasons. However, the core portion of Cocoa has been faithfully reproduced in Java, so you get all the benefits of Eclipse while developing: code completion, continuous compile-time checks, even a simple iPhone simulator written in Java that uses Swing to mimic the UI classes of the iPhone. All of that being said, I won't be using XMLVM for any of my projects (yet), but I certainly hope that this will continue to be developed. It has great potential.

And here's a very useful article on tuning the garbage collection in Java. This is a must-read for Java devs. I found it very interesting.

Posted in Tech | Tagged , , ,

A programmer's garden

Where is your favorite place in terms of programming? What application do you like to work on most? Where do you feel at home the most? For me it's a program that I've been working on during my job for the past three years, although I started building the codebase for it four years ago when I first came to Japan and Asahi Kasei. I took over a program from someone else, and it's been growing ever since, evolving into a several applications that are client-server based with a database back-end. It's become a framework. Sometimes I get reassigned to different tasks and progress is slow, but there were also times where I actually had a team of people work on it together, and progress was fast. Essentially there's no stopping it any more. Some of the tasks performed in my company can simply be accomplished better if people use the program I developed, and I'm very proud of that. The framework has become my masterpiece.

No matter what my current task , I always think about improving 'my little baby', and sometimes I try a bit too hard to make it the solution for everything. If my boss asks me to make him a coffee, I'll expand my framework with a makeCoffee() function. Well, that's taking it a bit far, but in the world of speech recognition there is only a certain variety of tasks, and over the years it's become easier to expand the existing framework than to develop something entirely new. But part of the reason is that I'm very familiar with my own code. It's the place I feel at home. When I have some free time at work, I look over my code and refactor it, write unit tests or fix that annoying bug that's been on the bug tracker for the last two weeks. My 'relaxed-state' as a programmer is when I am working on this program. It's just comfortable there. I feel happy working on it.

This can be seen both as an advantage and as a disadvantage. A 'neutral' programmer, having no prior experience with the framework that I've developed could accomplish a certain task in, say, two hours, by writing his own tool form scratch. If he had to use the existing framework, in the worst case (and in reality it's always the worst case) he'd have to spend another 1-2 hours getting accustomed to the IDEs, programming language and framework before he could spend only one hour to use the framework to accomplish the same task. Both programs might work exactly the same, but in our company there's a very clear rule: "your software will only be used for as long as someone supports it". This has previously been an issue when software developed by interns basically got forgotten or disappeared due to lack of maintenance. When thinking on the long term, it's always proved to be better to use and expand an existing framework rather than creating your own quick-and-dirty tool.

I think it's largely because of a programmer's pride that this kind of frameworks develop. Whenever people come to me to tell me of a problem in my tool, I do feel this as a kind of personal attack on my skills as a developer. I feel the need to fix it immediately and release a new version as soon as possible, just to get one step closer to perfection. Hubris indeed. But thanks to this feeling software is evolving, and thanks to a programmer's pride the software does not only look clean from the outside (towards the user), but also from the inside. It's the difference between a poorly maintained garden and a well-maintained one. Even if they grow the same things you can still notice the difference in attitude of the maintainer.

When thinking of examples of this I came up with my recent assignment of creating an iPhone application. While Apple takes very good care that their applications (and those in the app store too) are of excellent standards when it comes to end-user experience, the same cannot be said about the developers' experience. This is all IMHO of course, but I simply don't feel the joy of developing in Objective-C. Everything about it, the IDE, the language, the coding conventions, seem to encourage ugly designs. I don't feel happy coding in XCode in Objective-C. I miss a lot of things that Java has, too much things to name here. As a proud programmer I make sure that my iPhone application works perfectly, and that there are no bugs. I will test my app extensively until I am completely satisfied with the way it works. But then I switch back to Java and think about that exciting new feature that I want to add, or a cool new way to refactor the code to make it more clean. I'm just not quite feeling the love.

My favorite place is Eclipse, writing in Java, working on the framework that I helped develop for the past four years. It's one of the things in my life that I am most proud of. In some way I wish that I could continue to work on it after I move on from this job (whenever that will be), but I know that is not to be. After all, when the last maintainer leaves, the software dies.

Posted in Tech | Tagged , ,