Libgdx on iOS, days 1-2

I’ve started working on the iOS port of libgdx again. Instead of Avian, we are now going to use MonoTouch. This means you’ll have to shell out 399$ for a license for MonoTouch. You’ll also need a Mac and a device, and you’ll have to sign up with Apple for another 99$.

There are alternative ways to do things though, see mac in the cloud, a remote Mac rental service, which has MonoTouch licenses installed. I’m not sure if that licensing allows you to publish, but it can be a cheap way to test whether your app works on the iOS simulator, without having to shell out the money to develop for this golden, walled garden.

On to the technical details. MonoTouch is a full stack to develop iOS applications on top of Mono. Mono is an open-source implementation of Microsoft’s .NET platform, with C# being one of the most used languages (there are others, like F# that look really promising). You write your application in C#, usually in MonoDevelop, and IDE on top of Mono. Almost all native iOS APIs are exposed through C# wrappers, so you never have to touch Objective-C.

So, how do you get Java running on that platform? A year ago i experimented with IKVM. IKVM is an amazing project that lets you compile your Java bytecode to the CLR of .NET/Mono and adds full interoperability as well as a JRE implementation. It’s an extremely huge effort that’s been long in the making, check out their project page.

Now, if you clicked on the link in the last paragraph, you saw that libgdx already works with C# on .NET/Mono. Getting this to work on iOS via MonoTouch is a different beast. On iOS things need to be compiled to native code, which Mono does if you purchase a MonoTouch license. Mono supports different so called profiles, each supports a specific set of features, like runtime libraries or reflection support. IKVM relies on a few features of the desktop profiles that Mono for iOS does not support. To make IKVM work on iOS one has to solve those issues by modifying IKVM itself.

This is the part were i rely on Michael Bayne of Three Rings. He was one of the developers of Spiral Knights, a quite successful Java game. He’s currently working with the PlayN team (actually, he seems to BE the PlayN team at the moment), heavily improving it and bringing it to new platforms. One of those platforms is iOS. He modified IKVM to be compatible with Mono’s iOS profile and put his changes on Github. The only “challenge” i had to solve was to also support JNI, which PlayN doesn’t need at the moment. A fork and a pull request later, that was solved as well, and development of the libgdx iOS backend started. TL;DR: thanks to Michael for his fantastic work on porting IKVM to MonoTouch, without that we wouldn’t be able to do what we are currently trying to do.

Now, what challenges are involved in getting libgdx to work on iOS? Here’s a small list of things i’ll try to work on over the next few days:

Project Structure (Done)

The first step was to setup a somewhat sane project structure that allows me to write the backend in Eclipse, and only switch to MonoTouch for compilation. The end result can be found here. There is an Eclipse project containing the backend Java code (see src/ folder). Then there’s the XCode project that’s responsible for producing the libgdx.a library file, containing all our precious native code. Finally, there’s a MonoTouch project that pulls all those things together and lets me easily test changes to the backend. It has a pre-built step that makes sure that the latest Java code is used when building for iOS.

The libs/ folder contains all the IKVM tools necessary for compiling Java code to the CLR, plus Jar files that wrap Objective-C libraries, generated from the MonoTouch C# wrappers through IKVM.

Bare-bones Life-Cycle (Done, Sorta)

After the project structure was in place i could start working on a bare bones implementation of the backend. All it does is setup the application and GL surface to render to as well as logging facilities. The life-cycle handling is not a 100% sound yet (pause/resume anyone?), i have still to figure out how to map the iOS way of things to our API.

File System

The next step is to implement the Input interface for iOS. It looks like that should be smooth sailing, and we can have all file types (internal, classpath, local, external, absolute). For reference, here’s the official documentation on the matter, and the corresponding MonoTouch docs. Since IKVM gives access to java.io we can reuse almost all of the stuff in our standard FileHandle class, which relies heavily on InputStreams and File.

OpenGL Interfaces

MonoTouch has a wrapper for the native OpenGL ES bindings called OpenTK (also available on the desktop). For us, that’s pretty much useless so i’ll have to write my own wrapper. Thankfully, that thing already exists for Android, and it’s very simple to port it to iOS. The only thing i need to change is to not rely on Harmony’s buffer internals (see top of this), something i already did for our deprecated Angle backend.

Input

This seems to be pretty straight forward, iOS touch APIs seem a tad bit less fucked up than the Android equivalent. Keyboard input will be interesting to explore, i don’t anticipate any big issues here though (and that will probably bite me in the ass :)).

Audio

This is the biggest unknown for me so far. iOS supports OpenAL and has an API similar to Android’s MediaPlayer. Using OpenAL means to do all the format decoding on our own, something i’d rather avoid. It would be the number #1 way to implement AudioDevice and AudioRecorder as well as playing back in-memory sound effects. The MediaPlayer like API is probably unsuitable for sound effects. I’ll try to hunt down a nice audio library for iOS instead.

This weekend i’ll try to finish off at least the file i/o and graphics part of the backend. For now i’ll focus on GLES 2.0, writting a wrapper for GLES 1.x could be bootstrapped via some Android source, it’s not a top priority for me though.

Here’s a screenshot if text is not cool enough. It just shows MonoDevelop, some output testing native code and the simulator running a very simple ApplicationListener that still uses OpenTK for rendering.

  • g_pechorin

    There’s also XMLVM, just saying

  • http://badlogicgames.com Mario

    Which is sadly lacking in many respects. The latest Posix backend is neat, but the code it creates seems to be a straight translation of the Java byte code. On top of that it does not implement the Java memory model, which is crucial for threaded stuff, does not allow for debugging (which to be fair, i still have to figure out for MonoTouch as well) and doesn’t have the same track record for actually running big apps on iOS just yet. I don’t discount it as an alternative backend though. I can only focus on one thing at the time i’m afraid.

    Things like this scare me a tiny little bit. It’s easier for me to get my feet wet with MonoTouch, where i’m less likely to run into such things. I’d rather only battle with iOS, than also figure out bugs in XMLVM.

    Most of the work that goes into the MonoTouch based backend should be applicable to a future XMLVM backend as well though.

  • http://www.noblemaster.com Christoph Aschwanden

    Very impressive :-D

    I cannot help you with AudioDevice & AudioRecorder, however, I have previously successfully used AVAudioPlayer to play both sound effects and music. Really straight-forward to use. The class supports both playing sounds from memory and file. Anyhow, here is the reference:
    http://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVAudioPlayerClassReference/Reference/Reference.html

    I hope I am not stating the obvious…

  • http://badlogicgames.com Mario

    No, that’s very valuable information. I didn’t know whether AVAudioPlayer could be used for multi-shot sound effects as well, this sounds great! Thanks for the input.

  • billbo

    Sweet swirling onion rings, this is awesome stuff.

    If I read this correctly, developers would have the option to use either C# or Java to develop against libgdx on iOS, yes?

  • http://badlogicgames.com Mario

    yeah, you can also use c# to develop for the desktop if you so wish.

  • ben

    399$ make the ios backend less attractive…

  • Arve

    Ben agrees. No monotouch please!

  • mingming

    Agrees ben and Arve. I think most people choose libgdx because it’s free. And most is personal user. 399$ I think not many people will use it for ios.

  • Mylo

    This is great news, thanks very much for working on iOS support! I disagree that $399 makes this not worthwhile, the way I see it is I make a game and release for free using one of the existing supported platforms. If it is well received I pay the fee and release for iOS.

    I also think having iOS support will make libgdx much more interesting to larger developers and that can only be a good thing.

    I’ve been using Unity so far but I’m extremely tempted to take another look at libgdx, keep up the good work Mario.

  • http://www.aojgame.com 爱撸小杰

    Hi, Mario
    I can’t see the img of your articles, also use proxy, I don’t know why.
    Can you or someone send the img to me ?
    Thank you

  • Byeee

    I write free apps. $399 is a write off.