This post is about the technical aspects of crossplatform game development. For an excellent read on the design aspect, read Kev Glass’ post
The last few weeks were interesting. I’ve been contemplating where to take libgdx and my personal endevours next. Our struggle to bring libgdx to platforms like iOS and HTML5/WebGL made me think about whether the JVM is a viable platform for what i’m spending most of my free time on.
Managed languages, Mono and Unity
Managed languages seem to be on the rise for game development, Unity has shown us that. Unity is based on Mono (.Net on Windows), the same thing we use to target iOS, and deploys to desktops, Android, iOS, Xbox360, PS3, Wii U. For the web they have a custom plugin, and they also offer a Flash backend (though i heard from an insider, that it’s not quite there yet). Each platform comes with an additional license cost of course.
I’ve been playing around with Unity for quite a bit over the last few weeks, prototyping a few things, diving through their entire API etc. so i can get a feeling for what it does well and what it doesn’t do well. Procedural generation seems to kill any benefits you get from the editor (let me use a script to populate my scene!), you don’t have a lot of control regarding memory managment, object update order, and other low-level things you need to be able to tune if you work on mobile. Interestingly enough, Unity actually recommends not using quite a few of its features when working on mobile, and instead rolling your own manually. This makes sense, but if you are supposed to handroll a lot of things, then you have to ask yourself at what point it doesn’t make sense to use Unity anymore. Also, you will be confined to Unity’s runtime API when rolling your own solutions, without access to the underlying implementation, which might complicate things further.
Regardless, Unity is nice. A metric ton of successfull games on mobile have proven it to be an excellent tool for game development. It’s definitely worth checking out.
If i thought it was the end-all be all of game development, i wouldn’t spent my time on libgdx, so excuse my little stab at it above. I’m also under no delusion that libgdx can approach Unity in terms of features. Our goals are different, we want to provide a flexible, modifieable framework, not a full fledged engine.
So, an engine based on a managed runtime successfully snatched a large portion of mobile gaming. That’s especially interesting as any old game dev with experience would have told you that that’s a silly idea on such restricted devices (including myself). You don’t hear any such voices though, nobody questions Mono’s usefullness on those platforms, even if it shares most “unfit for games” properties with the JVM: a GC (erhmagerd, micro lag), memory overhead (less so if you can exploit the better primitive datatype support in the CLR), and all those other things people usually point to when they dismiss the JVM as a game development environment.
Mono as a runtime has one clear advantage at the moment: it runs pretty much everywhere.
Who’s to say that motivated entrepreneurs or maybe even OSS couldn’t build an alternative to Unity on the JVM if it catches up in terms of portability. And for many games, solutions like libgdx, PlayN, or jMonkeyEngine are more than sufficient.
What about HTML5 on Mobile?
Regardless of my opinion on HTML5, you can target it via our GWT-based backend (provided the browser supports WebGL).
What about Corona, Gamemaker, …
I’m frankly surprised that people shell out that much money for something like Corona. The development environment is horrible, and support does not seem to be their biggest strength. It promises super easy game development (“look, even kids can do it”), but as soon as you hit a roadblock, you are on your own. Unless you own the entreprise edition of course. Quiet honestly, if you have that kind of money, spent it on Unity.
Frankly, i was considering to replicate their API on top of libgdx, slap a scripting layer on it and put it up on their forums for free. We have quite a few refugees from the Corona camp, i guess with something like that we could get quite a few more…
The JVM, a better option?
In terms of portability, the JVM is not a better option at the moment, compared to Mono. It can get you on all desktop platforms (and Steam, Desura etc.), and on things like the Raspberry Pi, but that’s where it ends. There’s JavaME and Java SE embedded, but we can safely ignore those as they do not target any of the platforms game devs are interested in.
In terms of performance, i didn’t bother to come up with any contrived benchmark results. Fact of the matter is, that both Mono and the JVM are likely to be sufficiently fast for most games. I would assume that the decades of man power that went into HotSpots JIT (not relevant if the OS doesn’t allow setting memory pages to executable) and GC would probably trump Mono, but I can not substantiate this with benchmarks. Let’s assume they are even. If you need more performance you can always drop down to native code on both (it’s easier in C# land with p/invoke, not sure how the marshalling overhead compares to the JVM’s).
Where i personally think the JVM shines is its tooling. Compared to Eclipse, IntelliJ or even Netbeans, MonoDevelop just doesn’t cut it. One could argue that there’s also Visual Studio, but that’s confined to Microsoft land. IDEs may not be everyone’s cup of tea of course, looking at you crazy VIM/Emacs guys. On top of that, you have a huge set of instrumentation and profiling options, which are relevant to game development as well. Code hotswapping, facilitated by IDEs such as Eclipse, or even better, JRebel, can totally change the way you work on your games. Things start to feel as lightweight as in dynamic languages, and you can tweak everything at run-time, to your heart’s content.
Another area where the JVM has benefits over Mono is the vast amount of proven, stable 3rd party libraries. If you have a problem, you can be pretty sure that there’s at least one solution in Java land, maybe even an established Apache project.
The JVM is still a force on the server-side, which has become more important for games with the social game hype. Many studios already rely on the JVM server-side, being able to reuse some of that code on the client side is a nice-to-have. Besides your usual database and REST stuff, the JVM hosts many solutions that can help you with all the data a successful social game can generate. Hadoop and all its subprojects help with data warehousing and analysis. Twitter Storm can help with any real-time calculations you need to perform. Both projects allow usage from other languages, e.g. via Hadoop’s streaming API, or Storms thrift protocol, but JVM languages are first class citizens for them.
Finally, and i think this is one of the biggest arguments for the JVM, there are a metric ton of languages other than Java for every taste. For statically typed language friends, there’s Scala, Kotlin or Xtend. In the land of dynamic typing you have JRuby, JPython, Groovy, Nashorn and many more. For a more extensive list of languages on the JVM see this wiki article. Mono has a similar site. Overall, the communities around the major JVM languages seem a lot more vibrant, and fully integrated into the bigger JVM ecosystem. Many of the JVM languages are also making big waves in production, especially Scala.
For me, the JVM ecosystem seems a lot more mature and provides more diversity and options. Unless you want to target mobile or consoles.
The JVM on mobile and consoles
Fact: there are no “real” JVMs on iOS, Android or Windows Phone 8. However, there are alternatives.
I’m not interested in politics, so i won’t get into the whole Oracle/Google issue here. Android is not sporting a JVM, but Dalvik. Dalvik only speaks register-based Dalvik byte code, which is usually procuded by running JVM bytecode through a converter. A forked and modified version of Harmony serves as the runtime library. In its infancy, Dalvik was merely an interpreter, with a horrible GC. Starting with Android 2.3, Dalvik’s been beefed up with a tracing-JIT and a concurrent GC. It’s sufficient for games, but there’s still a lot of room for improvements.
On iOS there’re currently a couple of “solutions”. Avian VM by Joel Dice is an amazing little piece of C++, that can ahead of time compile Java bytecode to x86 and ARM, compatible with iOS ABI. It can use its own minimal runtime library implementation, but also supports OpenJDK’s class library, and recently also Android’s fork of Harmony on some platforms. Avian has additional features you don’t find in Oracle’s JVM, namely tail calls and continuations (something Mono also supports). Avian’s AOT is actually based on its JIT compiler. Put simply, for AOT compilation, it JIT compiles all the code, writes a memory image to an object file, which can then be statically linked to an executable. Avian’s GC is also pretty capable. What Avian lacks is an optimized JIT stage (they recently added VFP support for ARM) and debugging facilities. It’s also unclear how stable it is. If you run into issues, you usually get a nice segfault, and its not exactly simple for plain old Java folks to debug such a case. Joel is extremely active on Avian’s mailing list though, and ususally fixes any issues rather quickly.
Another option for iOS is RoboVM by Niklas Therning of Trillian. It’s another AOT implementation that leverages LLVM. It translates Java bytecode to LLVM IR, which can then be compiled to its final machine dependent form, either x86 (Linux, Mac, iOS simulator) or ARM (iOS device). RoboVM uses Android’s Harmony fork as its class library. RoboVM is still in its infancy, and needs a bit of work before it can be used in production. It uses the conservative Boehm GC, which is not exactly known for its performance. Mono has been using that for quite a while as well, and i think the Mono fork of Unity just recently switched to sGen. Things like virtual calls need optimization. Never the less, its a promising project, and especially the use of LLVM makes me all gigidy inside.
Yet another option on iOS is called XMLVM, you should go watch the Google Tech Talk on it. XMLVM takes insanity to an entirely new level, by using XML for representing a register based IR that’s constructed from Java bytecode, and then applying XSLT to convert it to a target language like Objective-C or more recently C. It also uses the Boehm GC, and last time i checked, i think they used Harmony as its runtime library. It’s the only option i didn’t take a closer look at. Kev Glass of Slick2D fame used and contributed to it a while ago, but eventually gave up on it.
Google put forward a solution for iOS called J2Objc. I elaborated on that quite a bit in this blog post. It’s a Java source code to ObjectiveC converter, with more limitations than you can shake a stick at. It may be an interesting approach for bootstrapping conversion of your business logic and domain objects to ObjectiveC, but it’s definitely not gonna help you in running a full Java app on iOS. I’m also not a big fan of source code translators. It seems Google has a bit of a love affair with such tools, see GWT.
Oracle recently announced ADF for mobile, which should cover Android and iOS. Sadly, that effort consists of HTML5 for the presentation layer, and a trimmed down interpeter JVM for simple business logic. It’s not a full-fledged JVM, and it’s pretty much out of the question that its two components can run any game more complex than Pong (i exagerate of course). There was some recent news from the JavaFX camp that Oracle may have something going on beside ADF for mobile. Sadly, that hope was crushed by an update to the blog post, which stated that Oracle is currently not working on a JVM for these platforms.
Finally, there’s IKVM-monotouch by Michael Bayne of PlayN and Three Rings fame. He went through tremendous pains porting the original IKVM to the MonoTouch (now Xamarin.iOS) toolchain for iOS. This solution translates Java bytecode to CLR byte code, which then gets compiled to a single x86/ARM executable that works with iOS. This works surprisingly well, and is the solution we chose for libgdx (we contributed a tiny bit, JNI capabilities mostly). Everything from profiling to debugging works in this solution. It also allows you to directly write against the iOS APIs from within Java, so you can integrate things like Game Center or ads. You can also talk to C# code if you need to. The only downsides are suboptimal JNI call performance, and some missing classes in the runtime library, namely all of the networking stuff (fear not, we have an API for that in ligbdx) and locale related things. Xamarin has been very kind to us and supported this effort with a few licenses for core developers. They where also very reactive to any issues we encountered along the way, even taking their time to respond here and on Twitter. In that regard, it almost hurts me to say, that eventually we’d like to get away from this solution.
Out of all these options, none helps us to target consoles or Windows Phone 8 (but who wants to do that?). A case could be made for Avian as a potential option for some consoles, but that would need quite a bit of work.
The JVM is a viable game development option should you want to target the desktop, and relevant app stores like Steam or Desura. It won’t work for the Windows 8 store, which has yet to demonstrate that its a profitable market. You can also target the Mac OS X app store, provided you bundle a JRE, just to be save.
On the browser, there’s really only GWT. PlayN and libgdx both let you target that if you want, with an additional restriction for libgdx, which requires WebGL.
On mobile, you can go full Android, just keep in mind that you are working on Dalvik, not HotSpot. On iOS, there are a few workable solutions, but they all come with their drawbacks. Libgdx covers you there with the IKVM/Mono based backend, but that comes at the cost of 299$ per Xamarin.iOS license (or 79$ if you are a student). Xamarin offers quite a bit for that price tag though, so consider it. Note that using MonoGame will not save you from that license cost, as much as they hate talking about that. Read the fineprint.
On consoles there is no JVM, period (unless you count the Ouya as a console, but that’s really just Android with lip stick).
What does it mean for libgdx?
So far, we’ve always found a way to spread to new platforms. I’d also say that our current solutions are suprisingly robust and mature, and looking ahead, say 5 years from now, we’d still be in good shape with the platforms we are supporting at the moment. Unless FirefoxOS or Windows Phone 8 take off. I let you guesstimate the probability of that happening. I will continue working on libgdx regardless, i enjoy the community we build, i love the people i meet and have the privilege to work with, and i like the challenges we face due to clinging to our toolset of choice. That may be crazy, but hey, it’se me.
I’d love to see Oracle realize that there’s an oportunity there. It’s hard to tell what their strategy is. One day JavaFX and with it a JVM for mobile seem to be about to be released. The next day an interpreter JVM plus PhoneGap are presented as the final solution. And then you stumble across this JEP and don’t know what to think. Could this indicate an AOT solution? Or a less useful Zero based solution?
I still believe that the JVM could be a strong player in the mobile domain, for both apps and games. The community that build around the JVM would go to great lengths to guarantee that with both open-source and commercial contributions.
Nate and I talked about all of this for quite a bit. We actually assembled a large portion of the Java gaming community, including folks from LWJGL, Jogamp, jMonkeyEngine, as well as figures like Caspian Prince and Michael Bayne. We had some intense discussions on a mailing list we setup, on what could be done about the current state.
Whatever the result, we can always move forward, with or without support from the JVM’s stewards. It seems to be in the DNA of our community 🙂
I’d love to hear your thoughts on this matter. Leave links or feedback in the comments below.