To port my game I ported a game engine to android (Part I)

February 21, 2014

tl;dr: I ported a game of mine to Android the LÖVE engine using the Android NDK to port a game of mine to Android. The port works pretty well and you can get games on Google Play with it. Making it open-source helped to get highly valued contributions and was tested much better than I could have ever done myself. SDL2 is magic. You can get it from https://bitbucket.org/MartinFelis/love-android-sdl2. This article is the first part that describes the initial steps of how I ported the engine to Android.

Introduction

Last year I participated in the 26th installment of the Ludum Dare event. The theme was minimalism and I ended up with a nice game that fit the theme quite well both in terms of controls and visuals. Already then I thought that it would work well on a touch device.

For the game I used an awesome framework to make 2D games in Lua, namely LÖVE that I have been using since my very first game jam experience (fond memories!). There were some efforts to port an older version of the engine to Android which I could not get to run unfortunately.

Foreign Languages

I thought I could use the opportunity to learn something new. So I set out to play around using C# and MonoGame. Doing most of my stuff in Linux I could not create assets under Linux which was a big problem for me. Also having additional costs to actually get it to run on Android did not help to convince me. I totally see the service provided by Xamarin as worth its money, however for just wanting to play around and in combination with the asset problem this simply did not seem worth continuing to explore.

Next up was libgdx. It’s a very powerful framework that enjoys big popularity. I also got a first prototype running but it took me quite some time. Not having been exposed to Java enough I had problems with it’s objects everywhere type of thinking. Also being spoiled with LÖVE and Lua it felt too verbose for the simple things I was trying to do.

On September 18th 2013 I ordered two books: OpenGL ES 2 for Android: A Quick-Start Guide and Android NDK Beginner’s Guide. I ended up reading the latter much more. Being a native C/C++ programmer this wasn’t too surprising but still this marks a date where I still considered Java (in the end I gifted the Android OpenGL ES 2 book to a friend of mine who is working hard on a new game using libgdx – you should check it out!).

First Native Steps

I first started off using the testgles2.c example in SDL2. I was surprised how easy it was to port a SDL2 program to Android using the NDK. I made some random changes to get a feel for it but ultimately I removed all the rendering code and only colored the background that reacted on touch events, i.e. when a touch was registered it would turn red, otherwise the color decays to black.

After reading some about porting libraries to Android using the NDK I felt brave enough to port Lua to Android. It was pretty straight forward once I figured that you had to explicitly link against it in the SDLActivity class.

Already then some signs were read correctly:

First I ran scripts that I loaded from hard coded strings but then I found out about SDL2’s SDL_RWops. It massively facilitates reading and writing of files including those found in the asset/ folder. I exported some functions to Lua (including SDL.Log that is still found in LÖVE for Android) which allowed me to call an update function in Lua and also a function that gets called when a touch event was detected:

That was roughly the second day I played around with the SDL2 and Android!

Bits of Android LÖVE

I then ventured out to actually port LÖVE knowing that the most basic components should work (SDL2 + Lua + an apparently existing GLES port of @slime73). Worst case sound wouldn’t work and maybe some image types could not be loaded.

I took some inspiration of the older port made by @schattenkindnet. I completely rewrote the NDK build script and split it up in several somewhat independent native projects with their own Android.mk file. This allowed me to focus on one library at a time and also I did not have to recompile everything only because I had modified the big global Android.mk file.

I had it compiling on December 5th but I ran into some nasty issues with the OpenGL extension managing tool/library glad. It tried to locate the addresses of the OpenGL functions using SDL_GL_GetProcAddress() which in turn would calls eglGetProcAddress. That function however returns NULL for functions that are required in the initialization of glad. However with NULL as a result it would be interpreted as a failed initialization of glad, hence the whole graphics module of LÖVE would simply not work (and all this took me ages to figure out and I spammed the code of LÖVE with gazillions of SDL_Log() calls in the C code and SDL.log() statements in the Lua boot code ). Eventually the fix was to not only rely on SDL_GL_GetProcAddress() but also to manually check for the addresses using the good old dlsym function.

On December 8th I had the first working nogame screen on Android (it actually features the nogame screen of the then unreleased LÖVE 0.9.0):

This concludes the first part. There were some more bumps that waited to be fixed but I’ll write about those another time. Thanks for reading this far.

Continue to Part II…