Saturday, December 17, 2011

Android Explorations


Today I bought an Android powered tablet, the Acer Iconia 7" tablet. As my friends keep telling me, I should start doing Android development, so that I can port the little crane that could to Android devices. Apart from the horrible colours and contrast of the display, I am satisfied with the device so far. Graphics performance seems way behind what an iPad2 can do though, so graphics optimizations are going to be important. Here are some things I learned about Android programming so far:

  • You need to install an SDK and an NDK.
  • As of recently, you can do native development in C without writing a single line of Java code. To do this, see the NativeActivity sample from the NDK.
  • You can do development from the command line without IDE's.
  • Instead of make, you need to use a combination of ndk-build and ant.
  • GLESv1_CM is the OpenGL ES1 library to use. CM stands for COMMON and means that it uses floating point, not fixed point.
  • Doing 'ant debug' and 'ant installd' is often not enough, as I need to do a clean before building. Are the dependencies not set up properly in the sample projects?
  • The emulator cannot do OpenGL ES2, only ES1. When doing ES1 it is super slow, even on a modern mac.
  • The equivalent of GLX for Android is called EGL
  • Android NDK by default targets the ARMV6 devices, which means software floating point emulation. This is very slow.
  • To target ARMV7 with hardware floating point (VFP), add this to jni/Application.mk: APP_ABI := armeabi-v7a
  • To see verbose output of the build process, use ndk-build V=1
  • Loading assets from native code is a painful experience. So instead I convert images to C source code, and build as a shared object. Then I use dlopen() to get to the data.
  • To debug simply run ndk-gdb --start from the project dir.
  • You can set java compiler flags on the ant command line like this: ant "-Djava.compilerargs=-Xlint:unchecked -Xlint:deprecation" debug
  • You can make screenshots with the ddms utility. Select the device and press ⌘S to grab the screen.
  • To incorporate a third party framework, all you have to do is copy the .jar file into your projects ./lib/ directory, and the build system will automagically find and use it.
  • If you want to install certain resource types without compression, then you need to edit your SDK. Change the tools/ant/build.xml file by adding a < nocompress extension="foo" /> to the aapt section.
  • Don't get confused by -msoft-float and -mhard-float, they do not toggle the hardware floating point unit. Instead they influence the convention for passing function arguments. So using -mhard-float will only get a modest speed bump, at the cost of decreased ABI compatibility.
  • in jni/Application.mk you need to keep APP_PLATFORM set to android-20 or lower. At android-21, downward compatibility breaks, and on a pre-android L device, your app will crash with a 'failed: dlopen failed: cannot locate symbol "rand" referenced by...' error.
I am using The Android NDK Beginner's Guide as reference, as well as a guide by IIvan Vučica. That last one is pretty ambitious: it sets up the development environment so that you can do Objective C for Android. However, I decided to keep it simple, and do my project in C.
There is an excellent GDC presentation from Lars Bishop of nVidia on android development.
For future reference, you need to set up some environment variables. This is what I use in my .bashrc file:
export ANDROID_NDK_ROOT=$HOME/android-ndk-r9d
export ANDROID_SDK_ROOT=$HOME/android-sdk-linux
export NDK_MODULE_PATH=$HOME/apps:$HOME/src
PATH=$PATH:$ANDROID_NDK_ROOT:$ANDROID_SDK_ROOT

Friday, December 16, 2011

First Art

Annelies made her first art today at day care. Well art, not sure if you can call it art, but she did paint a picture. Some bold use of colour! The teacher misspelled her name though.

Thursday, December 15, 2011

Nieuwe Nederlanders / New Dutchies

En met deze handdruk is Amy een Nederlandse geworden. Haar man is Nederlands, haar dochter is Nederlands, maar dankzij Amy's Nederlandse moeder is Amy nu genaturaliseerd door de deputy consul in Vancouver.

And with this handshake, Amy became a Dutch citizen. Her husband is Dutch, her daughter is dutch, but thanks to Amy's Dutch mother, Amy could be naturalized by the deputy consul in Vancouver.

Tuesday, December 6, 2011

Don't bother buying Infinity Blade II

So, after all that hype, I decided it was time to find out what Infinity Blade II was all about. I've heard things attributed to it as 'best looking game on iOS' and such, so as a game developer myself I wanted to see it. So I pay the $6.99, got my fancy noise cancelling headphones for the optimal experience, and then..... NOTHING! The game crashes during the title credits. Tried a few times, a 100% crash. I stopped ALL backgrounded apps on my iPad2, and tried again... Crash.

I've noticed this weird trend where the bigger the studio/publisher, the more crashes I see. Why do these big studios get away with publishing crap, and still rank among the top grossing titles? I noticed it with EA's SimCity Deluxe for iPad. The names don't get any bigger than that: EA, Sim City. Yet, they are unable to create a stable experience without crashing. My advice to the consumers here: forget about that big studio crap, and buy indie games. You will typically get email support from the author directly, and there is someone who actually cares about you. Don't let EA and Chair Entertainment get away with this: just stop buying from them.

And you don't have to take my word for it, there are plenty of crash reports from users. In case someone at Chair entertainment decides to do something about it, here is the log of a run where there is not a single other app running in the background:


Dec 6 18:35:18 unknown kernel[0] : launchd[11064] Builtin profile: container (sandbox)
Dec 6 18:35:18 unknown kernel[0] : launchd[11064] Container: /private/var/mobile/Applications/6CD18407-B4A9-4692-AA34-D07EBAF21381 [69] (sandbox)
Dec 6 18:35:18 unknown SwordGame[11064] : Installing signal handler
Dec 6 18:35:19 unknown SwordGame[11064] : Unknown movie state 0
Dec 6 18:35:19 unknown kernel[0] : virtual void AppleCLCD::mieEnable(bool), enable: 1
Dec 6 18:35:20 unknown SwordGame[11064] : This device is [iPad2,1], enum value 5
Dec 6 18:35:20 unknown sandboxd[11065] : SwordGame(11064) deny file-write-data /private/var/mobile/Library/Mobile Documents/8XJ6WJ8Z84~com~chairentertainment~IB2
Dec 6 18:35:21 unknown kernel[0] : launchd[11067] Builtin profile: gamed (sandbox)
Dec 6 18:35:22 unknown gamed[11067] : 18:35:22.436090 com.apple.AVConference: GKSConnSettings: set server: {
"gk-cdx" = "17.173.254.221:4398";
"gk-commnat-cohort" = "17.173.254.223:16386";
"gk-commnat-main0" = "17.173.254.222:16384";
"gk-commnat-main1" = "17.173.254.222:16385";
}
Dec 6 18:35:23 unknown SwordGame[11064] : 18:35:23.312345 com.apple.AVConference: GKSConnSettings: set server: {
"gk-cdx" = "17.173.254.221:4398";
"gk-commnat-cohort" = "17.173.254.223:16386";
"gk-commnat-main0" = "17.173.254.222:16384";
"gk-commnat-main1" = "17.173.254.222:16385";
}
Dec 6 18:35:23 unknown kernel[0] : virtual void AppleCLCD::mieEnable(bool), enable: 0
Dec 6 18:35:23 unknown SwordGame[11064] : Initialize!
Dec 6 18:35:23 unknown SwordGame[11064] : FBDelegate: !
Dec 6 18:35:23 unknown SwordGame[11064] : SetAppID to 152777738124418 / (null) / (null)!
Dec 6 18:35:23 unknown SwordGame[11064] : FBDelegate.FB: !
Dec 6 18:35:24 unknown SwordGame[11064] : GLView: 1357870
Dec 6 18:35:24 unknown SwordGame[11064] : GLView: (EAGLView: 0x1357870; frame = (0 0; 1024 768); layer = )
Dec 6 18:35:27 unknown SwordGame[11064] : Requesting product id com.chair.IB2.goldbag.25000
Dec 6 18:35:27 unknown SwordGame[11064] : Requesting product id com.chair.IB2.goldbag.150000
Dec 6 18:35:27 unknown SwordGame[11064] : Requesting product id com.chair.IB2.goldbag.750000
Dec 6 18:35:27 unknown SwordGame[11064] : Requesting product id com.chair.IB2.goldbag.2500000
Dec 6 18:35:27 unknown wifid[27] : WiFi:[344918127.366272]: Client itunesstored is background application
Dec 6 18:35:27 unknown librariand[11053] : item update observer error: Connection invalid
Dec 6 18:35:28 unknown SwordGame[11064] : Reading int value for key CurrentSlot369d86c1e1a21755d7f29b7aa7ac2065436e116d
Dec 6 18:35:30 unknown MobileMail[11062] : Received memory warning.
Dec 6 18:35:30 unknown SwordGame[11064] : Received memory warning.
Dec 6 18:35:31 unknown SpringBoard[15] : Received memory warning.
Dec 6 18:35:31 unknown syncdefaultsd[11058] : received memory warning
Dec 6 18:35:32 unknown SwordGame[11064] : Reading int value for key LocalSaves_dvb54c8b744f649484cfcae3478da0ec06
Dec 6 18:35:36 unknown com.apple.launchd[1] : (com.apple.gamed) Exited: Killed: 9
Dec 6 18:35:36 unknown com.apple.launchd[1] : (UIKitApplication:com.apple.mobilemail[0x45a2]) Exited: Killed: 9
Dec 6 18:35:36 unknown com.apple.launchd[1] : (UIKitApplication:com.apple.mobilephone[0x6ebe]) Exited: Killed: 9
Dec 6 18:35:36 unknown com.apple.launchd[1] : (UIKitApplication:com.chairentertainment.IB2[0x11fc]) Exited: Killed: 9
Dec 6 18:35:36 unknown UserEventAgent[12] : jetsam: kernel termination snapshot being created
Dec 6 18:35:36 unknown SpringBoard[15] : Application 'Mail' exited abnormally with signal 9: Killed: 9
Dec 6 18:35:36 unknown mediaserverd[43] : 18:35:36.366 AudioSessionSetClientPlayState(11064): cannot get ClientInfo
Dec 6 18:35:36 unknown mediaserverd[43] : 18:35:36.532 AudioQueue: Error 'ini?' from AudioSessionSetClientPlayState(11064)
Dec 6 18:35:36 unknown kernel[0] : launchd[11070] Builtin profile: MobileMail (sandbox)
Dec 6 18:35:36 unknown SpringBoard[15] : Application 'FaceTime' exited abnormally with signal 9: Killed: 9
Dec 6 18:35:36 unknown SpringBoard[15] : Application 'InfinityBlade2' exited abnormally with signal 9: Killed: 9
Dec 6 18:35:37 unknown ReportCrash[11069] : Saved crashreport to /Library/Logs/CrashReporter/LowMemory-2011-12-06-183537.plist using uid: 0 gid: 0, synthetic_euid: 0 egid: 0
Dec 6 18:35:38 unknown librariand[11053] : client connection is invalid: Connection invalid

Hover City at night

Hover Biker version 1.0 was just uploaded to Apple for review. Hopefully they get to it before dec 22, at which time they will stop processing submissions for a week. It would be really nice to have my game available on the app store before Christmas. I've put in a night-time level in the game, which brings the number of levels to 6 free levels, 7 premium levels and 1 tutorial level. I keep wondering how well it will do on the app store. I am hoping to replicate Little Crane's success, but as a worst case scenario, I can't see it do any worse than Panzer Class, which does not sell spectacularly, but still brings in money. But the good news is that every iPad sold by Apple this month is a new potential customer.