tl;dr: In the first part of this article I wrote about the motivations and the first steps I made to port the LÖVE engine to Android. Here I write about some technical difficulties that were solved and a few very interesting features the port now has. Also I created a small incomplete list of people who have contributed to this port.
I was really stoked when I saw the nogame screen the first time on my phone. A big helper for this was the GLES port of @slime73. There was almost no change required to get this far. The next thing up was to load an actual game. For this I had to somehow load the game. Undearneath LÖVE use physfs and comes with a custom wrapper for it. After some experiments I figured out that the Android NDK supports standard file I/O to the sd-card if you give the App write permissions to external storage (i.e
android.permission.WRITE_EXTERNAL_STORAGE). With this knowledge in hand I implemented loading of the game found in
/mnt/sd-card/lovegame. This allowed me to start my game on the phone without having to change a single line of the original Ludum Dare submission:
— Martin Felis (@fysxdotorg)
Running the game unveiled a bug in the GLES code when pushing new transformations but the fix was simple. From that on the game “just worked”. Including audio for which I did not have to change a single line of code!
Now the port seemed it a very capable state. Something essential that was missing was creating a game Android package of the LÖVE engine + game into a proper Android package. I could already load games that were placed to
/mnt/sdcard however LÖVE games are usually distributed either with the LÖVE binaries as OS specific packages or as
.love files which is simply the game project folder packed into a zip file. Also LÖVE can directly load .zip files to run the games contained in them.
On Android on the other hand Apps can only open files that are stored in the
assets/ folder. Luckily SDL2 allows accessing files in the assets folder without much hassle using the SDL_RWops. To create a packaged I simply added the
game.love file to the assets and when starting the App it would open the file using SDL_RWops and copy it to the internal storage and then load it using the standard LÖVE code. While this worked well this has the huge drawback that games would consume twice the memory: in the package’s
asset/ folder and then in the internal storage. I could have tried to delete the latter when exiting the app but this didn’t work reliably enough.
Instead inspired by a hint of @slime73 I switched to the inofficial 2.1 code of physfs (which can be obtained using the official physfs merurial repository). Physfs 2.1 comes with PHYSFS_mountMemory that allows to load archives from memory instead of actual files, which works perfectly. I still have to copy the game from the
assets/ directory into a memory buffer but it is much nicer and also uses less overall memory in the app statistics. (Physfs unfortunately introduced a bug but that is avoided in my port using a small hack).
Another improvement that I wanted to do was to use LuaJIT instead of stock Lua. I had started with the latter as I wanted to first get things work and clean up things later. LuaJIT (which is also the now default in LÖVE) has quite a performance advantage in many cases over standard Lua — even on ARM. Setting up LuaJIT for the LÖVE port was quite a hassle. It comes with its own build system that I did not manage to integrate into Android’s NDK build system unfortunately. Eventually I resorted to adding the LuaJIT binaries to the repository along with a small script that builds it using the LuaJIT build system and the required Android specific parameters.
When testing LuaJIT with the LÖVE code unfortunately I had worse performance than using standard Lua. It took me a long time to figure out what might be the cause for it. To be honest I am still not entirely sure what exactly, however when reading this thread I tried the older 2.0.1 version and I could finally enjoy the performance gains. One nice thing about Android is that the JIT part of LuaJIT actually works.
As far as I know Apple sadly prohibits code generation on iOS which makes JIT impossible (see comment about iOS at http://luajit.org/install.html).
The build system for the external libraries was created using @schattenkindnet‘s older port. Some of the libraries that LÖVE uses have been updated since then and so I went on to update them. For some it was a lot of work to figure out which compiler flags were actually required or parts of the files were created during the build system which then again made me cross compile code using autotools (scary!) and extract files. Openal-soft was also challenging as it used CMake for which a CMake Toolchain script had to be used to create the proper configuration header files.
Eventually I ended up with all the files required such that I could use Android’s
ndk-build to build everything (except LuaJIT). In the same time I also made sure that I link against all LGPL libraries dynamically whereas everything else is linked statically to reduce the binary size. Updating the libraries was worth it as also fixed audio performance.
It wouldn’t be a proper mobile game engine if it didn’t have a touch API. I received a patch by piernov which fixed this. Eventually this code was replaced by the
love.touch that was introduced to the experimental repository shortly afterwards and aims to be compatible with a future iOS port.
Additionally to the more or less technical things above the LÖVE port has a few very nice additions:
Accelerometer as Joystick: instead of adding a special sensor API read the accelerometer using SDL’s joystick API. This involved fixing a bug in SDL2 which was done by Jairo Luiz
Icon: Seppi (@josefnpat) created a fantastic logo out that mixes the Android with the LÖVE logo:
File Association: Since beta2 the Android LÖVE App adds a (somewhat experimental) file association. At least using Chrome mobile it lets you download
.love files from the web such that you can open them from your Downloads activity. Also
.love files attached to emails can be opened directly using the LÖVE App. Large parts of this was also made by Jairo Luiz
Game Editing on Device: Since LÖVE uses Lua and the code gets compiled/interpreted on run-time it allows for editing the game on the device itself without a host computer. Heck! It would even be possible to create whole games on the Android device without a PC!
Sensible Default Mappings: A touch event is reported as a left mouse button event. The back key maps to the
escape key. For simple games this is sufficient to make it work.
I am currently working on getting my game released on the Google Play Store. It has been approved already and but I at the moment I am cleaning up some edges. But I hope to release it soonish to the public. Follow me on twitter or subscribe to the blog and you’ll get notified.
Also publishing the LÖVE App via the play store would be an idea. Maybe with some kind of launcher to simplify running of different games?
This all was only possible due to the fantastic works of others. Even though the risk is extremely high that I will forget valuable contributors I want to list some (let me know if I missed someone or something):
It’s been now a long time, since I decided to write a certain game and talked a lot about it with friends. However I must confess, now after a few years, I still haven’t managed to finish a game. I wrote a lot of code and both bugs and documentation is so far not the problem. Instead there are a couple of demons that slow down the process that I would like to introduce to you (you probably know them already):
Efficiency Demon: This one is always in the back of my head. It tries to convince me not to use virtual functions as they are somewhat slower than normal function calls. However this approach makes things a lot more complicated and I spent time to circumvent the usage of “the single most important feature of C++” by using probably less efficient detours. Additionally following strictly the rule: first make it run, then optimize would encourage me to take a deeper look in profilers, which would be definitely a knowledge I wish to possess. There are a couple of nice quotes to this one on the Wikipedia page on program optimization – I guess I am not the only one having this demon.
Engine Demon: Instead of tackling simply completing the game logic/event managing/input handling part, I try to generalize what I just coded and put it into a part that I call “engine”. This “engine” is some kind of container of reusable code that I will most certainly need in the future. The catch is just: I do not yet know what exactly I will be needing in the future. Actually neither whether I need the generalized case nor the specialized I wrote in the first place. There is a very well written article (write-games-not-engines) from Josh Petrie which talks about this one. This demon is sometimes called Premature Generalization.
Beauty Demon: The Beauty Demon is related to the Engine Demon. It makes you want to clean up your mess (a.k.a. code). You just hacked in some features and now you want to polish it a little. So you polish. Then you realize you should add documentation. So you add it (and look at the beautiful caller graphs that Doxygen creates automatically for you). Then you realize that you could create of this feature set a library against which you can link dynamically – oh yeah, this is great, because then you can do this for all the other games you will write and reuse it. Oh, and the build system it got a little messy. How about … Yeah, you get it. You do a lot of things which are actually very useful. However they do not complete your game.
Just-that-feature-and-then-I’m-done Demon: I coded hard. The prototype works. And I am very happy. So I relax and think: Awesome, I’ll be done soon with the whole game and I can finish the rest tomorrow. There is a huge difference between a prototype and putting it into your game. I had a few nice parts, such as an event system and entity management system and so on which worked very well on them selves. But when I actually tried to make a simple game with it, I had to rewrite a lot of it and it was a lot harder than I expected. So unless the code is not in your game don’t think anything is done! (Please note that this is not an argument against writing prototypes – they are very important because you realize what the actual problem is and what kind of difficulties you run into!)
A long time ago, I read this very inspiring article ‘How do I make games?’ A Path to Game Development.When I look back, I must admit, I skipped quite a few steps suggested there. So last week I started to abuse my “engine” to create an Asteroids clone. So far controlling the ship, destroying asteroids and getting killed works, but there are still some areas untouched (menu, game-over screen, etc.). It took me a lot longer than I expected and I currently have a lot of quirks on making things work.
So far it is not efficient, not an engine, not beautiful and there is still a lot of work to be done. But I’ll stay on that rocky road and bring it home.
Thought game development is fun? It is – but getting it done is actually quite hard!
It seems as if there haven’t been too many updates here lately. I’ve been quite distracted with studying and getting the simulation of multi body systems into my head. And by doing so I stumbled over a few quite amazing papers and dissertations that seem to cope pretty much everything you need to know for a fully fledged physics engine (assuming you have some spare time).
For example the dissertation of Brian Mirtich (which you should be able to download here or here) covers just about everything from advanced collision detection to collision response. Even the calculation of inertia tensors in 3D is contained and the appendix covers all the math basics such as quaternion arithmacy and a rigid body primer. The whole thing wheighs a bit over 250 pages and is freely available. It still requires a lot of math knowledge, but as a math major I hope I have enough knowledge.
The method he describes in his thesis is the so called impulse based simulation which is stated in contrast to analytical methods as they are used in David Baraffs papers (as far as I understand). Instead of trying to fulfill all constraints simultaneously, instead if a constraint is violated it applies an impulse to the constrained bodies so that the constraint stays fulfilled within the next integration time horizon.
A more recent version of Mirtich’ aproach can be found at the site of Jan Bender (www.impulse-based.de). He also wrote a dissertation over impulse based simulation (however in German) which has less math in it. The best is: his code is available under the zlib license! There is also a lot of documentation in English available, so go check it out!
Oh, and of course I have not just been doing multi body simulation stuff. I was playing around with Blender already for a while to have a nice visualization for my thesis. And I finally made a model for a character in a game I have been planning already for ages. Now I added a little movement to the model. Here you have it:
Be nice, she is a little older (and my first animation). You can get the full resolution version here.