Dapple Update (pun intended)

I haven’t really been posting much this week because I’ve been working on Dapple. I thought I’d provide a little update on what I’ve been doing. I’m working on a Dapple Update. Yes, the word update is confusing in this first paragraph. Let me try that again: I’m working on version 1.1 of Dapple and Dapple Lite.

There were a couple of key things I wanted to address with Dapple’s first update:

1) Reduce app footprint to under 10MB

When an app is over 10MB, users with a cell phone connection aren’t able to download the app directly. Apps that are over 10MB require a Wi-Fi connection to download. I think this is potentially costing me quite a few downloads, mostly of the Lite version. I want the Lite version to be something that people can download on a whim. If they have to wait until they have Wi-Fi access, they might never download it.

Dapple and Dapple Lite were both about 13.1MB, so I needed to reduce them by nearly a 1/3. When I looked at the sizes of my various directories, it became clear that the music and SFX files were the ones causing the problem. Dapple has about 13-14 minutes of music that plays in the game. That amounts to significant file sizes. There are also 14 SFX files.

I’m going to get a little bit technical here, so if you don’t care for this stuff, just skip ahead a bit. The iPhone does have a hardware audio decoder. You can use it to hardware accelerate your MP3, AAC, etc decoding. However, it can only operate on one file at a time. This means if you’re ever going to play more than one sound at once, you have to use two forms of audio decoding. For Dapple, I use AAC compression for the background music, but all the SFX files need to be in a non-encoded format: Linear PCM. This means that the SFX files are huge, because they’re basically 16-bit uncompressed audio data.

For v1.0 of Dapple, all the music was encoded as AAC, 128kbps, constant bit rate, so that it sounded really good. I decided I would try to reduce the bit rate as much as possible without sacrificing the audio quality too much. By switching to a variable bit rate, I was able to compress the files much more without too much of a quality reduction. By doing this, I was able to reduce the music file sizes from 8.7MB to 6MB! Almost there already!

That was the easy part, now I needed to deal with my SFX. The iPhone documentation infers that if you’re not using a hardware decoded format you should be using Linear PCM or IMA 4:1. IMA4 (which I’ll refer to is as from now on) is a compression format for audio that results in a nearly 4:1 compression (it’s actually closer to 3.75:1). I converted all of my SFX files to IMA4 and was surprised to discover that none of them played. This is because there’s no native support for IMA4 on the iPhone. You can use it, but you have to write your own decompression code. I ended up scouring the net looking for information on the IMA4 data format, how the compression works, and how to decompress it. I found several partial resources, none of which were complete enough to just let me implement it. It took me two solid days of some pretty hardcore coding (it was really fun, actually), but I finally got IMA4 working in Dapple. The nice thing about IMA4 is that the file gets decompressed when it’s loaded into memory, and is then played as Linear PCM. This means there’s no performance hit, except on file load. (I’ll link to some of the IMA4 resources I found at the bottom of the post)

IMA4 was a huge win. My SFX files totaled about 2.2MB on disk before compression. After compression, they’re just over 600KB, with almost no loss in sound quality.

So, after rebuilding and zipping, both Dapple and Dapple Lite sit at about 9.5MB! Hooray! What’s next?

2) Fix an audio bug

This is the only bug that’s come up more than once since the game launched. If a user is playing their own iPod music while playing Dapple, then locks their device, their iPod music stops playing. This was a problem in how I was managing audio sessions in the game. This has now been fixed.

3) Add a Feedback Button

I want to make it easier for people to provide me with feedback on the game. I changed the Main Menu around so that the “Credits” button now says “Extras”. This opens a new menu which has “Feedback” and “Credits” in it. The feedback button, when clicked, launches the Mail program and lets the user send me an email. Hopefully people will use it to request features, complain about things they don’t like, etc.

4) Add a computer-controlled opponent for 2 Player Mode

This is a request I’ve had from a lot of different players, so I decided to try to put it into the first update. As of last night, I can actually play a game against a computer opponent. It’s pretty cool. However, the computer opponent is really stupid right now.

The way Dapple already works is that when a player starts their turn, the game searches the board and picks a random spot that will make a match. This is stored for when the hint arrow needs to be displayed. I figured I could make use of that code and just make a computer opponent execute a move there on its turn, instead of displaying a hint arrow.

This lead me to an interesting discovery: it works, the computer can play, but the computer opponent sucks at the game. In 10 games I played against the computer last night, I won every single game. What I found interesting about this is that this proves that making random moves in Dapple isn’t nearly as effective as thinking your plays through. I’ve had a small number of negative reviews (either on the web, or on the App Store), and the complaint is usually that they feel like playing randomly yields the same results as thinking their moves through. With a random computer opponent pitted against a player who thinks their moves through, the human player will almost always win. To me, this is proof that the game can be learned, that you can get better at it, and that strategy will win over randomness. Up until now, that’s what I believed, but I couldn’t prove it…

So today my goal is to try to encode some of the choices I make when looking for the best play to build a heuristic that the AI opponent can use. Then I’ll need to tune how much it uses that heuristic for various difficulty levels. Should be fun!

With any luck, I should be able to submit Dapple and Dapple Lite v1.1 by Monday.

Owen

IMA4 Resources:

  • www.wooji-juice.com – A good starting point, as this article walks through the high-level steps required to get IMA4 decompression working. However, this article leaves out a lot of steps that are necessary to get things working. It is also not very clear on the differences between mono and stereo audio streams and how that affects the packets.
  • wiki.multimedia.cx – Contains useful optimizations that allow you to avoid doing byte->float conversions to do floating-point math.
  • wiki.multimedia.cx – Has some useful information on byte/nibble structure of the packets
  • www.koders.com – Actual C code for doing the decoding. This is for quicktime IMA4, so some of the logistics of how you extract chunks of data won’t work, but the actual math for decoding each nibble into a 16-bit frame should be the same for you.