Testing the iOS backend
This thing is far from being finished. Things that are missing/incomplete:
- audio, stubs are there, need to be filled
- orientation, currently only portrait works, need to figure out how this is handled
- resolution, need to figure out how to get the real screen resolution and ppi etc.
- some things might not work due to omissions in the ikvm port, haven’t tested all classes yet
This blog post will tell you how to set things up and play around with what’s there so far. It won’t tell you how to port your own game, nor how to setup a new project. You can work on the backend or on the demo games that are currently working on iOS, that is all.
If anyone complains, then you have three options: help out, go away or pay my rent/food so i can quit my job and any other side projects :p
You will need an Intel Mac with Mac OS X installed. You will not be able to do anything on Linux or Windows (unless you go the VM route, which i wouldn’t recommend). Once you shelled out your hard earned money for an aluminium box with inferior hardware at the price of a Cray you want to install XCode. This will install all kinds of development tools on your box, e.g. various compilers for C/C++/ObjectiveC, a shitty IDE and so on. XCode is necessary if you want to compile the iOS natives of the gdx backend, which are written in C/C++.
Next you will have to install the latest MonoTouch. You can get a trial version for free that let's you run your stuff in the simulator, but not on the device. This should be sufficient for simple testing. A full MonoTouch license costs you 399$ per seat, i'd say hold out on that for a while unless you have use for it otherwise or want to see stuff on an actual device.
What is MonoTouch? It's a bundle of Mono, an OSS .NET implementation that let's you compile and run .NET apps written in C# on more platforms than just Windows, an IDE called MonoDevelop, through which you develop your apps, and runtimes for Mac OS X and iOS. MonoTouch lets you write iOS applications in C#, that get then compiled to native code for iOS. Get yourself familiar with using MonoTouch a little, e.g. compiling/rebuilding a project, running it on the simulator and so on. The MonoTouch docs are pretty good, you should find your way around things quickly. I'll explain later how it all works with libgdx.
Next you need to install the JDK, Eclipse and Ant. Make sure javac and ant can be invoked from the command line. Read: put their respective bin/ folders in your PATH environment variable. Look here if you don't know how to do that. I use a 1.6 JDK at the moment, haven't tried with 1.7. I use Ant 1.8.2.
Clone the libgdx repo from Github, and import all the projects into Eclipse. Finally, you'll need set an environment variable called IKVM_HOME that points to the directory $YOUR_LIBGDX_CLONE/backends/gdx-backends-iosmonotouch/libs/ikvm.
Test your setup in the shell like this:
$ mono <- should show you some options $ mono $IKVM_HOME/bin/ikvmc.exe <- should show you some options $ javac <- should show you some options $ ant <- should tell you you are a douchbag for not having a build.xml file in your current working dir
How it works
Libgdx is Java. iOS doesn't like Java much. However, iOS likes C# via MonoTouch. So we simply convert Java bytecode (.jar/.class files) to Mono binaries (.dlls aka assemblies). We can then use the transpiled Java code in a MonoTouch C# application just as if it were real Mono/.NET code.
The conversion is performed via IKVM, a brilliant project that transpiles Java bytecode to the equivalent .NET bytecode. It also has a full Java runtime library implementation, that's a Frankenstein-eqsue mixture of original OpenJDK Java code and some .NET code for implementing the low-level stuff. IKVM for iOS is a special fork by Michael Bayne of ThreeRings and PlayN fame. He massaged IKVM to work on iOS, i contributed a few tiny patches to also make JNI work on iOS.
For libgdx, the general setup goes like this: you have all your standard libgdx projects setup in Ecipse, with a core project containing all the code, and a project for each platform you target, e.g. desktop, Android, WebGL. For iOS you don't have a Java Project, but a MonoTouch project. This MonoTouch project references the assets of your game (usually contained in the Android project's assets/ directory) as well as the transpiled Java code for your core project, along with the assemblies for gdx core, the gdx ios-monotouch backend and the IKVM runtime libraries (which come with the IKVM build linked to above). To change your game's code, modify the Java source of the your game's core project in Eclipse. This will recompile the Java files and place the .class files in the project's bin/ folder. When you want to test your stuff on iOS, you open up the MonoTouch solution for your game in MonoDevelop, and recompile it. An Ant script will compile your Java core project's src/ folder to a .NET assembly. This Ant script is included as a pre-build step in the MonoTouch project.
Setting up a MonoTouch project is a bit involved, as it requires copying some files around, referencing pre-build .dlls, change some native code compilation flags and so on. This is the reason why i won't show you this here. If you must, take one of the demo project solutions as a template. I won't give support for that though until i'm done with the backend. We'll integrate this in the gdx-setup-ui once everything is working, so you don't have to mess with it
Testing the backend and demos
The libgdx master branch currently has MonoTouch solutions for the following projects:
- backends/gdx-backend-iosmonotouch/mono, a silly little test solution for me to debug stuff. It has no corresponding Java core project, everything is directly implemented in C#.
- tests/gdx-tests-iosmonotouch, a WIP solution to get our tests running on iOS, might or might not work
- demos/superjumper/superjumper-ios, super jumper solution, should work, except for audio
- demos/vectorpinball/gdx-vectorpinball-ios, vectorpinball, should work as well
- demos/invaders/gdx-invaders-ios, gdx invaders, uses landscape, GL view doesn't know about it though
Compiling Gdx Core and the iOS backend
Before you can run any of the tests/demos, you'll have to compile gdx-core and gdx-backends-iosmonotouch to .NET assemblies. Open a shell, go to $YOUR_LIBGDX_FOLDER/backends/gdx-backend-iosmonotouch and enter the following command:
This will compile the gdx core project and the gdx ios-monotouch backend to .NET assemblies and put them in the gdx-backend-iosmonotouch/libs folder (gdx.dll, gdx-backend-iosmonotouch.dll). It will also compile all the native code (box2d, buffer stuff, opengl bindings etc.) and put a file called libgdx.a in the gdx-backend-iosmonotouch/libs.
You will have to recompile those files everytime you change something in the backend or in gdx-core. If you changed something in the native code, you'll need to copy the libgdx.a file to your MonoTouch project. For some reason MonoDevelop can't cope with linked .a files, they have to be in the project directory.
Running a project
Let's say you want to mess with the vectorpinball demo a bit. Fire up Eclipse, make sure all the gdx projects including vector pinball are imported and build. Then fire up MonoDevelop and open the gdx-vectorpinball-ios.sln file in demos/vectorpinball/gdx-vectorpinball-ios/. In MonoDevelop, build the solution by going to Build -> Build All. This will first compile the vectorpinball.dll assembly from the gdx-vectorpinball/src directory. Once that is done, MonoTouch will complain that it couldn't find the file. Just reopen the solution in MonoDevelop, it should now be able to see the file. You'll have to do the same dance for the other demos and tests, as the assemblies aren't in the Git repository. Rebuild the solution once again. If everything went right, you should now be able to run the demo on the simulator by going to Run -> Start Without Debugging or Start Debugging. Note however, that currently you can't step into the Java code, something i'm looking into at the moment.
Things aren't done. You can play around with things following the nasty list of steps above. If you want to help with the backend, you can modify the source in gdx-backends-iosmonotouch, which uses the Java-ized MonoTouch APIs to perform things. You can look into PlayN how things are done there, e.g. audio, though that's been solved in a sub-optimal way in PlayN imo.