Android development pain


We’ve been for a while developing the game iBasket at Ideateca. It’s been a real hit on iPhone/iPad. But the pain was about to come in the porting-to-Android stage.
After porting the code from C/Objective-C to Java, and leaving it on stable state, the game performed really poorly. The framerate regularly dropped from 50 to 5-10 frames per second. After some profiling session, we found that Cocos2D’s Label object was a real pain. So we decided to look for alternatives and started playing around with some custom code. But surprisingly, it did not solve the problem. We finally found, that the label object was not the cpu sinker but the String.format function instead. What an oddity isn’t it ?!?!?!?. After removing String.format calls from the game loop, we achieved a nice constant framerate which lead to a totally playable game in mid to low end devices like HTC Magic and HTC Hero. That was a great day, since we could release a game not devoted to be played in Nexus One or HTC Evo, but in all android devices. And aditionally, the Label object proudly got back to our widget toolchest. Lessons learned: String.format is evil on Android. As of Android 2.2 froyo, the String.format hell has been bug reported and solved. So, lessons learned 2: always test developments in the latest available platform stable versions as well.

After releasing the game to Android Market, we reveived some user complaints in the form of bad game rates regarding texture malfunctioning on some devices like Samsung Galaxy S and Droid-X. The fact is that some textures get duplicated, others totally rubished and yet others not visible at all. As they always were the same textures, that gave us some hints to find solutions for this new gotcha. After playing around with the profiler again to make sure we were not getting out of memory, we decided to take directly a look at Cocos2D Texture2D implementation. Everything was right, of course, but finally, we discovered that those devices which didn’t show textures properly had a buggy glGenTexture implementation. This function is supposed to return into the parameter array non zero unsigned integer values which will bind textures to opengl. But the fact, is that Java lacks of unsigned types, and, thought it is not stated that the function will return values starting from one incrementally, the values returned were totally random. So, by changing the optional use of glGenTexture function by our own one, we’ve magically solved this annoying problem. We’ve achieved the milestone of supplying with a functional iBasket version playable in *all* Android devices. Again, a good day for us. At least, until the next time.
BTW, Sansung Galaxy S is Android 2.1-update 1. I can’t exactly tell the version of the DroidX, since I’ve not one handy .