Last weekend I left bought a Samsung Galaxy Nexus and said goodbye to Windows Phone. The first thing I wanted to do was port The Fantastic Fivesome to Android using MonoGame. I have used MonoGame to port games to Windows 8 Metro and iOS, so how hard would it be to head on over to Android? Really hard it turns out.
To do this I would need
Luckily Xamarin.com has a bundled installer that gives you the first three things. For some reason I had a few problems with the installer so I had to install the Android SDK manually, which is always a bit difficult.
After a while I somehow got a blank Monogame Android project up and running in Visual Studio. The next step is typical for all XNA to MonoGame ports:
1. import the XNB files into the Assets folder, make sure you maintain your directory layout.
2. Import all your code.
3. Refactor your name space to whatever your new namespace is. In my case I went from Fivesome_WP7 to Fivesome_Android
4. Try get it to build. There’s a chance it will build. There’s also a very high chance it won’t. This is where you have to use your programming skills to make it work.
For me there wasn’t too much to do. The Fantastic Fivesome is a pretty simple game, I had to convert the WAV files to MP3 files to reduce the package size, write some clever code to get the backgrounds and characters to draw properly on different resolutions and finally I had to create an asynchronous loader.
Originally I drew some text saying “Loading” and then loaded all the assets on the main thread and once complete would exit from the loading state and enter into the gameplay state. This meant the application would spend a lot of time in the Update() function and wouldn’t hand back to the OS until after it was finished loading. It was acceptable on the Xbox360, iPhone and Windows Phone, but not okay on Android.
Loading textures on Android is very slow, I think it’s a low level file IO problem and may be compounded by the fact that there is no texture compression support in MonoGame Android , which means the textures are larger. Loading was so slow, and the code was spending so much time in the Update function of my game that the OS thought the game had hung. A dialog box would appear saying “It seems The Fantastic Fivesome is no longer responding.” and asked the user if they wanted to wait or close the game. I don’t want people exiting my game! Especially since it hadn’t hung. I had to come up with a fix!
On the Xbox I believe you can run the loading code on one thread and the UI updating code on another, which means you can display a sexy loading animation. I don’t think the Mono Framework allows you to do that so I had to come up with a workaround. Luckily I am the king of workarounds. If I were a snake I would wrap myself around things and then begin coding.
So my solution was to load one texture every time Update() was called. I had to rework my loading code a bit. So I fired up the code and it still prompted me to shut down my game because it wasn’t responding. I put in some traces and discovered Draw wasn’t being called. That is what happens when an Update call takes too long to complete. So I rewrote the code so that it wouldn’t load a texture until a Draw() call had happened. That solved the problem and to my way of thinking I was ready to submit to Google Play.
I have a package for Mr. Google
I read through Xamarins guide on preparing an application for release. I did all the annoying things, made a private key (whatever the hell that is) and then read something disheartening.
TFF takes up 130 MB, contains 200 mp3 files and over 500 fairly large textures. The only way to get it under 50 MB would be to quarter the resolution. I did try that but the results were horrible.
My package is too big for Google to handle
So it turns out I need to split the game up, so that the code is in the main App file, and the textures are in an expansion pack. The expansion pack will be a ZIP file, and it will be stored in the shared directory. That’s really annoying, because it means people can unzip it on their computers and look at my textures. Fuck you, don’t look at my textures. I might write a note in there for jerks who decide to unzip it. Or maybe I should write a virus, that will infect peoples computers if they dare to poke around looking at my game’s art assets. If only I knew how to do that.
1. Try to integrate Matthew Leibowitz’s Expansion Library into my game. I tried messing with this a little bit, but didn’t really get far.
2. ZIP up all my textures and place them my devices Shared Storage.
3. Extend MonoGame’s ContentManager.OpenStream method, so that it will try load assets from a ZIP file inside of the ShareStorage location.
4. On launch check if the Expansions files exist, and haven’t been modified in some sort of way, by some sort of asshole. Continue if they are there, download them if they aren’t.
5. Kaching kaching money time.
I’m going to do a port of Get Rich or Die Gaming for Android instead, the game will easily fit into a 50 MB APK so let’s see if I can get it onto Google Play.