Despite the good advice on just using a library or someone else’s solution to getting game center working, sometimes I’m just stubborn. Well it wasn’t actually completely stubbornness as it was more of a “don’t have an alternative” situation. Tilt to Live uses AGON for it’s leaderboards and awards system. It has served us well and never faltered. Despite that, Game Center has arrived to rain on it’s parade so-to-speak. To give TTL hopefully more life in the long run I decided to implement Game Center alongside AGON over the past week. It was trying, painful, and sometimes down right frustrating. Trying to get 2 closed and incompatible systems working is wrought with trial and error and lots of hackery :).

Below are just some things you may find useful if you’re considering game center in an update

1. Game Center is not a full solution

Namely, there is no offline support to speak of. Another biggie that I grossly underestimated is a lot of the ‘fault tolerance’ is on the game developer to implement. Scores don’t make it to the servers? Save them for the next time. Awards not work online? Save them. User has no internet connection? Save them. User is age restricted from using Game center? Save it again.

Are you on a 3G with 3.x iOS? Don’t use game center. Are you on a 3GS with 4.0? Don’t enable game center. Are you on a 3G with 4.1? Despite GC not having an API to detect THIS case, you need to disable it because GC doesn’t work with it.

This is where services like OpenFeint and AGON shine. They offer seamless offline support with minimal hassle. I actually ended up leveraging AGON’s offline support to help deal with the score submission failures for Game Center. This saved a lot of time, and in OpenFeint from what I hear it’s even easier. In conclusion, If you don’t have any award or leaderboard solution implemented already it may be a good idea to use one with offline support first before concerning yourself with game center.

2. Be mindful of when you send scores and awards

If you have a fast paced game, you may want to store any scores or new award unlocks until the main gameplay is done, THEN send it off to Game Center. It creates a noticeable pause mid-game. Other social gaming platforms deal with this in different ways, but I remember early on seeing some OF games do a “mass” unlock at the end game sessions and such. Nowadays I believe it’s well known to just commit the changes in 1 transaction during some low key point in the game.

3. Keep your descriptions short

This is a sad one for us, because Tilt to Live thrives on witty descriptions and jokes for it’s awards. We’ve opted to keep them the same in-game (using AGON) but we’re modifying the GC ones so that other users can see the descriptions in full in the GC app.

4. Be sure to login from your app

While the Apple documentation stated there was some way to log into the sandbox through the GC app with a test account, my mileage varied. So the sure-fire way for me to do it was to log out from the GC app, then log in from within our game. Not seeing your awards or scores? Make sure you’re logged in from your game.

5. Wait a bit after modifying your leaderboards/awards

Apparently there is some time before your GC app updates with the latest awards and stuff. I’m not exactly sure how this works or if there is some cache that has to be updated to pull the latest info down. Either way, if you’re not seeing any changes you are not going crazy.

6. Multi-tasking support can be hell

It was hell for me for several days because of one tiny issue: The simulator does not post GKPlayerAuthenticationDidChangeNotificationName messages. Not realizing this I was going mad wondering if I had my implementation wrong or whether there was a bug in GameKit itself. After discovering this was limited only to the simulator I soon found sanity in my testing of multi-tasking support. Having users change names, log in and out, all while your app is running can be daunting so approach this case with care. It seems Fruit Ninja dodged a bullet here by not fully supporting multi-tasking :P.

It’s been busy, busy, busy as of late. We’re in full swing trying to get Tilt to Live HD ready for the iPad. It’s looking amazing thus far and plays a lot better than just the 2x mode for the original Tilt to Live. Frostbite mode just went out the door a few days ago, and the response has been positive so far. We’ve been getting some responses from users saying the game has become too easy in the other modes. I haven’t tweaked anything in the other modes for ages so my hunches to why users are believing this are:

  • It’s been a while since they’ve played and when they came back it was like riding a bicycle and they instantly got into the flow of the game.
  • Performance has degraded on the lower end devices (particularly when running iOS4), which slows the game down and as a result makes it ‘easier’.

I’ve tested the game on a 2nd gen ipod touch with iOS4 and it seems to run fine performance-wise. So it’s something I guess I’ll just keep on my mind when doing further updates to the game. Maybe revisiting Code Red mode and making it even harder could be a possibility to appease the hardcore users.

Some Reading Links

Whenever I have time to kill I go browsing through my RSS feed to catch up on things. I decided to share a few of my usual reading links. Maybe you’ll find something of interest in this pile as I tried to focus on reading links that are outside the iphone development community. A lot I’m sure are common go-to places for a lot of indie devs regardless of platform.

Cliffski’s Blog

I feel like just about anyone that has any semblance of what goes on in the indie world is at least aware of Cliff Harris and his musings on his blog on both his own games and the industry as a whole.

Fullbright

Steve Gaynor’s [Bioshock 2] video game design blog. Always a good read and has valuable insights into not only the design of mechanics in games but about the medium of games overall.

Shawn Hargreaves

For a time I worked mostly in XNA and C#. While most of his recent posts are about gearing up for windows phone 7 and other XNA tech, his technical but easily readable posts were extremely helpful not just in XNA, but any platform you may be starting out on. Great learning for those that don’t have true game industry experience (like me). His credits include Extreme-G (N64), Moto GP (Xbox/PC), and several other racing games.

Mark Sibly

Ok, not many updates for this blog but that’s not the point. Creator of Blitz Basic and Blitzmax. For those that don’t know anything about it, Blitzmax is a very nice cross platform language (PC/Mac/Linux) for developing 2D (and 3D) games. It’s a very small and friendly community, but one I spent a lot of time in when I first started getting serious about making independent games. The tech he currently is working on seems like really exciting stuff: A language that allows you to target HTML5, flash, XNA, Android, iPhone, native GL for game development. Very ambitious, but very exciting to keep tabs on!

Beautiful Pixels

Great graphics and game development blog. I believe he recently went to work for Google on Chrome OS. Great posts to browser through, and I’m sure some very useful ones in the coming future. Despite having a lot of ‘game oriented’ blogs on my feed, I tend to follow developers outside the game industry as well. And now that he’s at Google, I’m sure lots of good will come of it :).

Game Architect

A great blog on finding the ‘hard to find in a book’ answers to questions that come up during development. Like what’s a good way to keep you from creating a crazy object hierarchy but still have flexibility. Great thoughts on middleware as well.

Grey Alien Games

I’ve been following Jake Birkett for several years now as I was going through high school and college. His success as an indie was very inspiring. Great place to read for motivational and lifestyle posts as well as general independent game development. He was also a very involved community member in the Blitzmax community, writing a pretty successful game framework to allow developers to more quickly make indie casual games on the PC.

Lost Garden

If you haven’t heard of this site and Danc by now, then…I don’t know what more to say.

Pandemonium

Andy Patrick’s blog. Great info from an experienced developer. He previously worked at Rare on Kameo and Viva Pinata. Hasn’t had an update in over a year but some good content on programming things like cameras, game programming in a garbage collected environment, and tool recommendations. One article I really liked was going over how to implement infinite undo/redo in an game editor.

Sell More Games

Great site has articles focusing more on the marketing and business side of indie game development. Mostly geared towards the PC market, but I feel all of it is still applicable to the iPhone market.

Make it BIG in games

I believe I’ve referenced Jeff Tunnell’s blog entries before, but it’s worth listing again.

Gausswerks Design Reboot

Another great game design blog. Less on the technical and more on the design and art of games. I’m ashamed to admit I don’t read enough of these articles.

Ahh, my first idevblogaday post! For those that don’t know, idevblogaday is a group of indie dev bloggers started by Miguel Á. Friginal of @mysterycoconut games to get developers blogging more regularly. So we’ll see how that goes :]. After finishing the initial release of Tilt to Live I had been wanting to gather up my thoughts on what I had learned about making a game that is heavily dependent on accelerometer controls. Sadly, this was on the back burner for the longest time. I eventually got contacted by Noel Llopis of Snappytouch and through some e-mail conversations with him I was able to get some of my ideas finally in writing. So now, I figured I’d take that and present it to everyone to see, learn, and laugh at my horribly awesome code.

Some Background

I want to give a quick and dirty history of Tilt to Live (TtL). This is not a post-mortem quality account (That will come later), but something so readers have a context of how TtL evolved and where it came from code-wise. TtL was the first app I wrote for an iDevice platform, ever. First time using a mac regularly, first time using XCode, first time using Objective-C. There were a lot of firsts. Typically when I’m learning something I don’t bother with style or best practices, or platform specific conventions. I learn all that as I go. TtL has come a very long way from the first iteration of it.

Then

The first signs of things to come! The green dots are what are considered the ‘nukes’ in today’s TtL.

..and now:

 

While the game is pretty, thanks to Adam’s Awesome Art (AAA quality!!!), the code at times can feel like one giant ugly beast. Usually  when I’m in an environment I know well, I write a prototype, then start over and write the game ‘correctly’ so the code can be maintainable throughout. Not so with TtL, this game evolved straight from prototype hack-a-thon to full on production code. The code base went through lots of rewrites, refactoring, and dubious ‘fixes’ to keep things somewhat on the side of sane. On the bright side, I now have a much clearer idea of what ‘maintainable’ code shouldn’t look like and a lot of design decisions I know to make earlier on in the coding process to avoid some clunkiness in the future. There’s certainly something to be said though for making it ‘just work’ because in the end, no one gives a damn (except the author) how it’s written as long as the game is fun :].

With that said, I’d like to talk about some of the design issues we came across while developing TtL’s tilt controls.

Design issues with tilt controls

Our main area of focus on ‘controls design’ was how to present calibration to the user. Overall, we had a very minimalistic approach to the game’s user experience. We wanted minimal taps to get into the game, and once in the game, all you did was tilt to interact. Naturally, having calibration be automated seems like the ultimate in minimalist user-experience. The user doesn’t even experience it. It’s supposed to “just work”. So how did our calibration work initially? Well, when the game counts down on ‘3,2,1’ and the ‘1’ disappears the game calibrates at that point in time as the neutral position. Also, when the player unpaused the game, it would recalibrate. Sounded great, and it worked great…if you understood how it worked. From playtesting we found:

  • Users would get confused as soon as they change their play position (from say, in lap to on top of a table) without pausing the game. It was a cause of frustration for them.
  • The more savvy players immediately looked for options to calibrate because the terminology was engrained in them from previous iPhone games. Without options to calibrate they felt frustrated that they could not control the way they’d like to play.
  • In more social settings rather than isolated playtesting, the game would be played haphazardly. This caused all sorts of havoc on our auto-calibration scheme. The player would either lay the phone down, swing it down to their side as they’re talking to their friend while the count down is going on and then when they’d swing it back up again to play the calibration is royally screwed up. This didn’t make for a good first impression either. Ouch.

So what happens when we decided to tell users that pausing and unpausing the game would recalibrate the game before they played? We did that as a quick way to emulate ‘custom calibration’.

  • For the group of users who understood the technical need of calibration instantly got it.
  • Everyone else pretty much said “What ees des calibration meen?”. Yes, in bad fake accent and all.

Well, since we wanted to appeal to more than “hardcore” (I use that word very loosely here) iPhone gamers we had some take aways from the testing:

  1. On auto calibration: Without proper feedback, the user can set the calibration very wrong, making them think the game is broken.
  2. On custom calibration: Some users get it, but with a near infinite number of choices to the user, it’s hard to expect a non-gamer to know what the best setup/calibration would be.
  3. On choices in general: Experienced users like it, nay, demand more options. The fewer decisions a user has to make on how to “play” your game, generally the more accessible it is. A powerful concept in the mobile space, especially with non-precise/noisy physical inputs like accelerometers.
  4. In respect to TtL’s design specifically: TtL’s gameplay requires accurate tilting controls or the game falls flat. Other games that require less precision can certainly get away with auto calibration.

So after brainstorming a few ways to present a new calibration screen, Adam had a pretty unique idea compared to most tilt-based games at the time:

While we thought it was a good idea and it playtested well, we didn’t think the preset choices would resonate with users as much as it did.

“The game has some of the best options I have found for customizing the tilt controls.” -Nate Adcock, iphonelife.com

“For those of you worrying about manual calibration, don’t.” -nodpad.com

“Unique to this game is a calibration option that provides three default control schemes that should satisfy most positions that you’d like to hold your device in.” -Ben Briggs, gamesuncovered.com

 

Players and reviewers alike seemed to respond positively to our approach of essentially what is just a common preset list. The regular setting works for the vast majority of play cases and top-down works great for the purists. Sleepy was a rather experimental one that has mixed results. It works for me, but if you ask a group of players to play in a “sleepy” position you’ll most likely get a higher variance of orientations than what “regular” and “top-down” imply. I don’t think our technical implementation of tilt controls was any more accurate than the next game’s, but I feel because the user was able to more accurately set the game up successfully with a reduced number of choices their experience was much more positive.

Technical issues with tilt controls

Design issues aside, the technical side of my approach to tilt controls had a few issues I had to overcome as well. The first and biggest issue was a limitation of how I went about calculating the tilt offset. As the calibration of the iPhone approached a purely vertical orientation, detecting horizontal motion reduced to zero pretty much. To counteract this, I added an additional control scheme for when the device was in such a position and require the player to move the ship by “steering” the iPhone instead of tilting. Not the most ideal situation, and with the advent of the iPhone 4’s gyroscope this could probably be mitigated. There are certainly ways to implement tilt controls on the 3G/3GS where this isn’t an issue, but I haven’t had much time to experiment with them yet. I’ll certainly post an update on my findings as I get to them.

The 2nd issue was noisy accelerometer data. I had experimented with filtering the raw input, as per Apple doc recommendation, but in the end I let the input through unfiltered and just altered the rendering of the ship. Rendering the ship’s orientation based on the raw data caused the ship to shake uncontrollably as if it was hyped up on speed. Also this would make it impossible to use any weapons that required aiming. Solving it was pretty basic as I just added an interpolation function that would ease the ship to the current desired orientation over a couple of frames and adding a dead zone so that players can sit still without spinning wildly. I’ve played a few tilt-based games where the players’ avatar had an orientation and no dead zone was implemented. Be nice to your players, add a dead zone at the very least damnit.

A 3rd but minor issue was with sampling rates. I sample the accelerometer at 30hz and TtL runs at 30FPS. When (not if) the FPS start dipping the accelerometer data seems to get a bit out of sync and you start seeing small jolts of movements from the accelerometer data that came in between some of the frames. TtL doesn’t do much in managing varying frame times (shame on me), but this problem hasn’t brought much pain so I’m not looking at it worth fixing yet.

Well how does it REALLY work?

For those that are still reading this and are curious to see how it’s implemented I’ve attached a sample XCode project with the implementation that TtL uses. I took a GLSprite sample project and mutilated it until it resembled a sufficient “tilt controls sample”. The approach I had in mind was to make the iphone function as a “reverse” joystick. I’m not even going to try to explain WTF that means in text so here’s a poorly drawn illustration:

I  interpreted the accelerometer data in a way that would project a vector that always pointed away from the screen of the device. I would use this to find the difference vector between it and the ‘neutral’ position (blue) and finally project this onto the 2D plane of the screen to give me a velocity. The green arrow is what the player’s velocity was set to. So when the neutral position and inverted accel data are very close to each other, the player’s velocity is clamped to zero (deadzone).

 

You’ll find in the sample project that all the relevant accelerometer logic is implemented inside the TiltPlayer class in the ‘accelerometer:didAccelerate” method. Inside the TiltPlayer’s ‘update’ method it handles the smoothing of the icon’s rotation to reduce jitter. The rest are just supporting classes for rendering and other boilerplate code. So for those that wish to just see the pertinent code without firing up XCode, here it is:

[code]- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
/* while not ideal, most of the relevant code is stuffed in this method for clarity. A lot can be computed once
and saved in instance variables, preferences, etc instead of re-calculating each frame
*/

// hard coding our ‘neutral’ orientation. By default this is the orientation of
// having the device tilted slightly towards your face.
// if you wanted strictly a ‘top down’ orientation then a (0,0,-1) vector would be put here.
// to create a new ‘neutral’ position you can sample the UIAcceleration parameter for a single
// frame and set that to be the new nx,ny,nz for the remainder of the app (aka calibrating).
const float nx = -0.63f;
const float ny = 0;
const float nz = -0.92f;

// this quaternion represents an orientation (I like to think of it as a 3D vector with 0 rotation in this case)
// that points straight out from the device’s back away from the user’s face.
Quaternion neutral(0,nx, ny, nz);
// take a straight up vector and rotate it by our ‘neutral’ orientation
// to give us a vector that points straight out from the device’s screen (at the user’s face)
Quaternion neutralPosition = neutral * Quaternion(0,0,0,1);

/* now with our ‘neutral’ quaternion setup we:
1. take the incoming accelerometer data
2. convert it to a 2D velocity projected onto the plane of the device’s screen
3. and rotate it by 90 degrees (since we are landscape oriented) and feed it to our player’s
velocity directly.
*/

// convert our accel data to a Quaternion
Quaternion accelQuat(0, acceleration.x, acceleration.y, acceleration.z);

// now rotate our accel data BY the neutral orientation. effectively transforming it
// into our local space.
Vec3 accelVector = (accelQuat * neutralPosition).v; // we only want the 3D vector at this point

// now with our accel vector we wish to transform it into our standard (1,1,1) coordinate space
Vec3 planeXAxis(1,0,0);
Vec3 planeYAxis(0,1,0);
Vec3 normal(0,0,1); // the normal of the plane we wish to transform our data into.

//project this movement onto our X/Y plane by removing
// the accel part that is along our normal
// note: Vec3 * Vec3 = dot product of the 2 vectors.
Vec3 projection = accelVector – normal *(accelVector * normal);

// now decompose that projection along our X and Y axis that represents our 2D plane
Vec2 accel2D(0,0);
accel2D.x = planeXAxis * projection;
accel2D.y = planeYAxis * projection;

const float xSensitivity = 2.8f;
const float ySensitivity = 2.8f; // yay magic numbers!
const float tiltAmplifier = 8; // w0ot more magic numbers

// now apply it to our player’s velocity data.
// we also rotate the 2D vector by 90 degrees by switching the components and negating one
// since we are in a landscape orientation.
vx += (-accel2D.y) * tiltAmplifier * xSensitivity;
vy -= accel2D.x * tiltAmplifier * ySensitivity; // we do a (-) here because the accel y axis is inverted.
}
[/code]

if you want to download the XCode project, you can grab it here. [note: updated with Mikko’s more concise version below]

That’s it for now. As always, feedback is welcome and if anyone takes that code and improves it, it’d be nice to know :].

*Update*

Thanks to Mikko Mononen for making the code much more concise! Below is the altered method with Mikko’s contribution:
[code]
– (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
// A much more concise version courtesy of Mikko Mononen http://digestingduck.blogspot.com/
Vec2 accel2D(0,0);
Vec3 ax(1, 0, 0);
Vec3 ay(-.63f, 0,-.92f);
Vec3 az(Vec3::Cross(ay,ax).normalize());
ax = Vec3::Cross(az,ay).normalize();

accel2D.x = -Vec3::Dot(Vec3(acceleration.x, acceleration.y, acceleration.z), ax);
accel2D.y = -Vec3::Dot(Vec3(acceleration.x, acceleration.y, acceleration.z), az);

const float xSensitivity = 2.8f;
const float ySensitivity = 2.8f; // yay magic numbers!
const float tiltAmplifier = 8; // w0ot more magic numbers

// since we are in a landscape orientation.
// now apply it to our player’s velocity data.
// we also rotate the 2D vector by 90 degrees by switching the components and negating one
vx += -(accel2D.y) * tiltAmplifier * xSensitivity;
vy += accel2D.x * tiltAmplifier * ySensitivity;

}
[/code]

So I’m using OpenAL to do the audio in Tilt to Live. Over the course of development audio became the bottleneck of my game, both in size and in performance. The following could help you if you’re experience audio performance issues and are somewhat new to OpenAL. Let me preface this with: Don’t blindly optimize. Measure, Measure, MEASURE! Know what your bottleneck is before trying to tune code!

  1. Don’t make more than 32 sources objects in OpenAL. Of course, this number may vary from device to device and what generation the device is. Making any more than the limit the device support makes openAL fail silently, and at this point you’re wasting cycles.
  2. Load your audio buffers and create your source objects ahead of time and re-use them. This is a big one. Don’t generate and delete source objects in the middle of your game update. Instead, it’s much faster to just grab a ‘free’ source that is not playing a sound any longer and attach it to another buffer. I was pre-loading my audio-buffers, but creating/deleting sources on the fly in Tilt to Live. Then I started ‘pooling” and I got a decent gain out of re-using source objects.
  3. Keep OpenAL calls to a minimum. Especially in tight update loops, don’t repeatedly call openAL functions that don’t change frame-to-frame. I found that a good portion of my time was spent doing something as simple as ‘alSourcei()’ on each source ID per frame was causing a significant slow down.
  4. Don’t query openAL state if you don’t have to. In my case, I wrapped openAL Sources in objects with properties to get volume,pitch, etc. Initially those properties simply called the openAL equivalent and returning it instantly. This was hurting my frames due to some some innocent looking “backgroundMusic.volume += someVal” happening each frame along with other audio sources doing the same thing. Save any state you can in instance variables, and as a last resort hit openAL when you need to.
  5. As for size, you should consider compressing your sound FX and music to a reasonable size. If you’re like me, you hate giving up quality; especially if you listen to the full quality one and then the compressed one. It can seem like night and day. But in reality, when your users won’t have a full quality audio file to compare it to, they will not notice the difference.

As a sidenote, you can look at my first dev tip for batch compressing audio files.

So we’re at the last mile (it’s a long mile..) of development on Tilt To Live. Adam and I are starting to get some pre-release buzz built up around the game as we put our finishing touches into place. With the holidays around the corner, I will be out of commission until mid January. Marketing is a whole other beast we’re trying to deal with and learn as we go.  With a market as vicious and saturated as the App Store, it’s been one challenge after another!

As many have stated, to succeed in the app store these days requires a a good bit of marketing muscle. The ‘gold rush’ is pretty much over and the app store is now similar to any overcrowded market. I’ve been reading up on marketing in general and also seeking out articles on the app store specifically. App Gamer had a very interesting piece for newcomers to the app store regarding PR and marketing.

Have a great holiday (to those that are celebrating) and see you guys in the new year! We’ll be starting off that year with a great game and hopefully many more to come!

Tilt To LiveIt’s been a while since my last post. As things started entering crunch mode and the whole holiday rush was happening I unfortunately let my blogging schedule slip as a result. It’s still going to be irregular for the next month or so as I’m trying to finish up Tilt To Live. The official Tilt To Live site has launched with a few screenies and more info though! It’s a basic info site at the moment, but I’ll be sprucing it up as time goes on. Starting to ramp up some pre-release hype around the game but it’s proving to be challenging :].

A second take on Multi-threaded asset loading

FrustrationAfter much reading, experimenting, more reading, and just plain frustration I’ve toned down the multithreading goodness on asset loading for tilt to live. The main cause for this decision was speed. I seem to have miscalculated the amount of time it takes to load images. It was somewhat of a compound problem. Firstly, loading textures with libpng was on average 4 times slower than the standard UIImage/CGContextDrawImage! I’m not entirely sure if my implementation of libpng was inefficient in some way, but it was taken from several samples and documentations on loading pngs. Secondly, loading textures on a background reduces the speed by another 2 fold!

I’ve finally implemented texture atlases, so I got a bit of a speed boost on rendering. Although, I now have a 1024X1024 textures. Using libpng on a background thread took ~8 seconds to load a single 1024×1024 png image. I put the image loading on a main thread and it reduced it to 4 seconds on average. A great improvement, but with 2-3 large textures this was still unreasonable. After doing some profiling with the basic GLSprite sample on Apple’s iPhone developer site, I decided to revert back to the UIImage/CGContextDrawImage approach and it allowed me to load 1024×1024 textures in a little less than a second. Alright, progress! I’ve reduced a 20 second load time down to about 4-5.

As a result, I removed all background texture loading from the game. To further reduce the initial launch time I see that I can defer one of the 1024×1024 atlas textures til later as it’s only needed when the main game is up. That’ll be another second shaved. This is definitely one of those times where a supposed ‘good’ thing that was implemented has come back to bite me in the ass….

unlock_lightning

Lessons Painfully Learned

The slickness of having background loading while the game is giving the user some feedback is nice, but ultimately not worth a larger load time. The discrepancy here is that on a 3G iPhone the load time is huge with background threads, but on a 3Gs it’s very fluid and barely noticeable. So if I was making a 3Gs-specific app then this is definitely something to look further into and optimize a bit more. But with the goal of trying to reach as many different gen devices as possible, I needed to compromise and give up some of the ‘flare’ for speed. Right now the target release date (or at least submitting to Apple for approval) is in January 2010.

In the meantime, follow us on Twitter and Facebook to get the latest news on the game!

…looks like I’ll be hitting a bit of crunch time in the coming weeks. Blog entries will probably be dwindling over the next month or so as I try to put the finishing touches on Tilt To Live. On that note:

No matter how much energy you feel like you have and no matter how motivated you are at seeing a project to the end, you still need to take breaks from it. Going non-stop at it for days on end is a one way street to burnout and reduced quality.

I hit my limit on Sunday where I felt if I worked on any more of the game it’d have more bugs than features by the end of the session. Was nice to take the day off and just relax to some good music and video games :). Weird how many times I’ve heard the above repeated and yet still fell into the same trap. It kind of sneaked up on me I guess. Oh well…

Tilt To Live

Almost there!

App Store Games

As I’m zeroing in on finishing Tilt To Live some of the bigger assets are coming through from Adam and the game size has grown a lot faster than it has in past few months. One of the unstated goals of mine was to keep the game under 10 MB. Why? You are not allowed to download apps, podcasts, or videos that are larger than 10 MB over 3G. You are required to connect to wi-fi in order to do it on your iPhone. Alternatively, you can use a PC/Mac and just sync the said data to your phone/iTouch, but who bothers to do that?

Having a 10MB limit on an “unlimited” data plan sucks, but I’m not here to discuss that. This limit possibly poses a constraint on iPhone developers who want their games to be widely available. I just started digging into this, but haven’t really found anything conclusive on downloading habits of iPhone users beyond a few small-sample surveys and articles.

In either case, the question I wanted to answer was:

Do you stand to lose a significant amount of potential sales/downloads for apps over 10 MB?

I decided to do some unscientific data gathering and some manual data mining with good ‘ole excel :].

The Process

I fired up iTunes and after fumbling about in the iTunes app store I was able to get to the Games top 100 free and paid section. This was actually my first time digging around in the itunes desktop app store, as I download and buy 100% of my apps and podcasts directly from my phone. Connecting my iPhone to my computer is a rare event indeed…

Not having released a game yet on the app store I didn’t have any data on hand that’d prove useful for this. I took a rather low-tech approach and just consulted the all mighty top 100 lists of the app store. I took the top 100 games in the paid list and the free list and compiled them separately to try to find two things:

  • How many 10MB+ games exist in the top 100?
  • How are those 10MB+ games distributed in the top 100?

So the caveats to using the top 100:

  • From my understanding, I’m only seeing the US top 100?
  • It’s not representative of the HUGE library of other apps that are still somewhat successful but not the over-night hit sensation that a lot of the upper rung apps are
  • I don’t have a good idea of the size distribution of games that aren’t in the top 100, so I may be missing the big picture. So any experiments seeking to find a distribution has a very limited view “window” of what is actually going on.
  • This data includes iTouch devices, but since they lack 3G this could possibly skew the data.
The Results

First, I’ll explain what I thought the results would be. Before doing any of the number crunching I hypothesized I would find that the most successful apps are under 10 MB and any app that happens to be over 10 MB would be weighted towards the lower rungs of the list.

Let’s first take a look at the free games in the app store. Below is a table showing the number of apps above 10 MB split into top N lists.

Top N Free Games

[table id=2 /]

We find in total that there are only 18 out of the top 100 free games that go over the 10 MB limit. Not exactly conclusive, but it shows that majority of top 100 free games are available over the air (OTA).  As you decrease the size of the list the number of 10MB+ games starts to dwindle naturally, but when you look at the percentages the amount of those 18 stays relatively the same until you hit the coveted top 10. The only 10MB+ free game in the top ten is Real Racing GTI, a promotional game for Volkswagen that weighs in at a rather hefty 59.3 MB!

Now how does the distribution of these “heavy” games look in the top 100 free list?

Distribution of 10MB+ Free Games

[table id=3 /]

Hmmm…The distribution of 10MB+ games is pretty even all the way up to the top, with a slight dip in the mid section.

Let’s look at paid games.

Top N Paid Games

[table id=4 /]

One thing I didn’t really account for in my original hypothesis is a difference between paid and free games. 53 paid games are over 10MB! While by a slight margin, the majority of paid games seem to ignore the 10MB rule and go for broke! Egad! This above table completely refutes my original hypothesis that most successful apps are under 10MB (Wow those last few sentences sounded super nerdy…). This is assuming you equate that success = number of apps sold * price of app = more $$$, where as in the free model this kind of breaks down. Anyway, moving on to the distribution of paid game juggernauts…

Distribution of 10MB+ Paid Games

[table id=5 /]

Interesting. While the paid app list has a majority of 10MB+ games the bulk of them live in the top 20-40 section, again, only by a slight margin. The stand out number here is the top 20 section. It appears games that are under 10MB here still win out the majority, so maybe there still is some relevance to my original hypothesis but to a much lesser extent than I imagined.

Probably not as useful, but in case you’re curious here’s a simple area graph plotting top 100 free and paid game sizes, there are some monster sized games in the top 100 so that is encouraging! Click it for full resolution.

App Store Game Sizes

The Truth Revealed?

Looking at the free games market the results decidedly point to a more “logical” trend, in my opinion, on how games are being designed. Yet, when you look at the paid games market you find that:

  • Developers don’t give a crap and make what suits them (Hurray freedom!)
  • Consumers don’t seem to give a crap either on how big it is when they are paying for a game. Maybe they even irrationally prefer bigger (in physical size, not content) games for their dollar?

While the results point to opposite trends on app store game sizes, it doesn’t really uncover if developers are consciously shooting for sub 10MB games or simply letting the chips fall where they may in either case. Could free games just not warrant enough budget to make enough assets that grow bigger than 10MB? Are free games specifically targeting “viral” game status by shooting for sub-10MB downloads to allow it to spread more easily? I also find that a good bit of the free games are also “Lite” versions (62 of the top 100 in fact). So it shows that people like to try before they buy at least. With Apple’s announcement that they’ll allow free apps with in-app purchases, hopefully things will clean up a bit. But that’s a different issue for another day.

If you’re interested in getting my scrawny little excel spreadsheet with the free/paid top 100 lists to run any fancy shmancy analytics you’re welcome to it.

significantly

I’ve made some serious progress as of late with Tilt To Live. The age old saying “I’m 90% done…” is rearing its head and  yet it feels like there’s 90% more to go! This is a bit regurgitated, but saw an interesting bit in a post on burnout and motivation at Zen Habits:

1. Achieve in increments. When you only focus on a big goal someday, it’s easy to get burned out by the daily grind. It’s like driving toward a mountain in the distance. You can drive for hours, but the mountain doesn’t seem to get any closer. And spinning your wheels gets real tiring real fast.

The solution is to give yourself a way to measure and record every little step forward you take. Here’s how:

  • Get a journal, notebook, or calendar. Writing things down is important.

While I’ve been doing the above for a while now, I’m finding the advice becoming more critical as I polish up the game and there are only smaller, less visible changes  to the gameplay or code. Along with all the milestone tracking, to-do lists, and time logs I tend to write down where I stand on the project at a high level almost on a daily basis. It gives me a good “whole picture” look at the game to see what else is coming up on the horizon or if I’m finding myself focusing too much on any single feature. Anyway, back to work… :]

Tilt To Live

I finally got rid of the stupid…

"ld: warning in <foo>.so, file is not of required architecture."

…warning when using iSimulate. If you’re not using iSimulate or a similar technology you’re losing valuable time even if you don’t use the accelerometer or GPS functions. Then again, I might not be the best spokesperson on time since I spent the weekend re-inventing the wheel.

isimulate

I have this need to make sure my projects compile w/o warnings. I let it sit for a while because I’m not an XCode expert so I knew I wanted to conditionally link it in but I couldn’t find the UI for it. The process in which they suggest you integrate iSimulate into your XCode project truly is easy, but I felt icky when it came up with warnings when you compile against the actual device.  There are better ways of doing that. Namely, conditional build settings. Of course, it requires a few more steps and a bit more knowledge of the XCode environment so I suspect that wouldn’t help their marketing. Regardless, having the iSimulate linker flags and library search paths only be added when you’re compiling for a simulator is relatively easy to setup.