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.

Let me first start off by saying how great it feels to be genuinely “busy”. I’m talking about the “excited-and-can’t-wait-to-get-started-or-get-finished” type of busy. I’m slowly finding out that the days are flying by with me barely noticing. Each morning, I’m looking forward to getting to work (yes, even Mondays). So either I’m strange or have found something I truly love doing :). Anyway, I don’t have any technical insights for this week’s post, just more of a status update on something I’ve been tinkering with. Noel of SnappyTouch fame has a similar article about version control, so definitely got check it out to get another (and more experienced) perspective.

The Issues With SVN

As see in some of my previous posts, I use SVN for version control but I figured I’d give an update to my ‘branching’ method. It utterly failed. What’s my current workflow? Branches and merging are much more the exception than the rule right now in my current code base. After a full release of Tilt to Live I’ll branch again to start 1.n+1 but won’t branch for any other issues or experiments. I tried for a while getting SVN to merge things, but I found myself missing files, deleting things that didn’t need to be deleted, and sometimes accidentally working in the wrong branch. Doing an “svn switch” had weird issues where it would sometimes not switch the entire structure but only the root folder I switched from (grrr…).

In any case, branching and merging caused more problems than it solved using SVN. So I went to the ‘merge only on releases’ approach, but that was riddled with issues as well becomes the changes were so large it would cause all sorts of conflicts. I eventually gave up and just ‘branched’ the branches into tag folders to save the bits that were released. Not a bad method, but not exactly how I wanted to work and SVN was forcing me to do things it’s way.

So I have 2 things I’m looking for in a version control system:

  1. Painless branching/merging with decent history tracking between branches
  2. A good GUI client

I kept looking into alternatives, and the two that kept cropping up were git and Mercurial. I liked the idea of git, but the problem was no decent GUI support. Both, according to what I’ve read, seem to satisfy the first requirement, so it came down to GUI clients. I’m fully capable of using a command line and willing to as long as it’s and not on Windows or overly tedious, but I still prefer quickly glancing at a GUI to get a sense of what’s going on.

The Experiment With Mercurial

Enter Mercurial. Over the weekend I decided to take mercurial for a spin. And the GUI issue? MacHG seemed up to the task, and is free to try for non-commercial use (donation ware). @SnappyTouch, not sure if you’ve given macHG a look over but it’s definitely seems as robust if not more so than Versions :). I took about 30-40 minutes to go through the quick start guide for mercurial and once I had things down on the command line and understood what the terminology meant, I installed macHG to see if I could use this in a development environment. After a few false starts I was up and running. Surely, mercurial is rather different from SVN since it’s a distributed version control, but from my perspective it worked just the same, if not better than a central one. The biggest bonus was branching (in mercurial it’s usually called cloning) and merging were very painless. It was just as easy as committing changes.

For my test run, I was in the middle of prototyping our next project but wanted to use some framework code to help kick start things. I created a repository with the framework in it, cloned it and started developing the prototype on top of it. As I worked and modified the framework bits I would commit and periodically merge the framework back into ‘main’ repository once I knew it was working and tested. No hassle, no conflicts. To further see if there’d be any pain points, I worked in the ‘main’ repo for a bit of code clean-up while the cloned version was also modified. Still no issue, and it was intuitive as to wtf was merging and changing. As for MacHG, it works very similar to Versions except has full on support for merging, tracking changes, etc. It’s very well done.

The Current Downsides

The downside? It’s a local repository. My SVN repo is hosted with dreamhost so I can get to my code from just about anywhere. But in practice, I have an iMac and no macbook so the only place that code would be useful would be on my iMac. Accessing SVN from multiple machines was crucial a few months ago since I was still transitioning between Windows PC dev and OSX dev, and some of my tools are windows only. But VMWare Fusion and Dropbox solved that issue pretty quickly. If I really need a hosted mercurial solution I may look into Fogcreek’s Kiln since I already use FogBugz. Another downside: doesn’t seem to be any svn:external equivalent. I don’t use it currently for iPhone dev but I did extensively on the PC for shared code bases and such so it’s something I’ll have to try to figure out or look up as I’m sure others have worked around this already.

To Each His Own

If you’re looking to try out a version control alternative, but think ‘git’ is a bit too bleeding edge without a decent GUI client, mercurial seems like a mature and well supported option (particularly on the GUI client front). I’ll definitely be using it for my ‘play area’ and see if it grows on me before I use it on a longer term project. But as is usually the case, it comes down to your own workflow and whether you’re tools are shaping your workflow instead of them helping you get your task done the way you want it to be done.

We sent off Tilt to Live HD to Apple for review today. I couldn’t send it off until around 3 PM today because my internet was down (since 6 AM) due to a less then stellar ISP here in Alabama. *sigh*. But that won’t get me down, I’m super excited that TTL HD will be on the ipad app store in a few short weeks! Right now I’m busy trying to cut and edit footage together for a launch trailer. We’re trying something new with this version of the game by creating a seamless ‘upgrade’ experience from a ‘lite’ version of the app to a full version, very similar to what you see on PC casual portals or XBLA. You can even upgrade mid-game and have the unlocks start showing up in the very same game session!

Invalid Product IDs

With the launch news aside, I had a pretty straight forward experience getting the IAP functioning in the game. There are some small caveats and nuances to avoid getting the dreaded “Invalid Product IDs” error while retrieving product info from Apple’s server, and that part was very frustrating. After quadruple checking everything I could find that would cause this error, it finally dawned on me that I had never deleted the app completely from my iPad since:

  • switching app IDs, provisioning profiles, and the like
  • Implementing the IAP system

I did a full delete then re-install and everything started working! Although I’m not fully convinced that this cleared up the issue, but hey, if someone else runs into this problem maybe it’ll help them :).

Hide-n-Seek with the IAP Screen

There was another issue that didn’t seem to be well documented that I stumbled across. In certain situations when the player was on this screen…

…it would hide and unhide in an annoying endless loop. It was a funny game of hide ‘n seek with the UI and the player at first, but not funny when it turns into a lost sale :[. The problem? Memory consumption issues.

I hadn’t gone through and optimized any textures or other data yet to reduce the memory consumption. It was through dumb luck that the console was on my second monitor and I noticed the timing between the UI hiding and the console scrolling with a “mem warning level 1” message out of the corner of my eye. So it appears when your app gets a memory warning as the IAP UIKit screen comes up, in an attempt to possibly not crash and burn the IAP screen unloads itself? How heavy is that UI exactly? Either way, a reboot of the iPad made the issue go away temporarily. Then once I dealt with the memory issues themselves it went away permanently.

A friend of mine sent me this list of anti-patterns common in software engineering. Being the lone developer on my team, I don’t get to see anyone else’s code except mine on a project. As a result, it’s hard to critique whether my code is “good” or not. That was one of the benefits of working at a company I suppose. Being surrounded by those with more experience than me, I would learn a lot just from an afternoon of working on a section of code that wasn’t mine. Now I tend to have to seek out code that isn’t mine to get a sense of how things are done “well” or what not to do.

It was interesting reading that wikipedia link and seeing which anti-patterns I’m currently exhibiting. A lot of this came about as I was writing up a small framework in c++ for iphone prototypes and looking at old code to recall how things were done and whether I should be using a different approach all together.

Vendor lock-in: Making a system excessively dependent on an externally supplied component

This was an unfortunate side-effect of learning objective-c and then going on to write Tilt to Live in objective-c. We’ve been really wanting to expand to other platforms, but with all the code written in objective-c it’s really hard to muster the motivation to rewrite all of it again, especially when solutions that allow you to easily port c/c++ code exist.

Magic pushbutton: Coding implementation logic directly within interface code, without using abstraction.

Another one I’m guilty of, but not entirely sure this is a bad thing in the context of real-time apps. After reading up on mollyrocket’s take on an immediate mode GUI, I’m rather liking the system I have now. It’s not purely immediate mode, but the system I have lets me do some dynamic stuff with the UI that would be a bit harder to do with an ‘abstracted’ UI system.

God object: Concentrating too many functions in a single part of the design (class)

My main “game screen” class exhibits this symptom. It came about from evolving my prototype to final production code, which isn’t a good thing most of the time. Looking at the class I can see a lot of classes I can break out to make my life easier, but I’ve just let it sit for the most part. During updates for Tilt to Live I did refactor it a lot so that supporting new gametypes wouldn’t be like gouging my eyes out with a wooden spoon.

Action at a distance: Unexpected interaction between widely separated parts of a system

This one’s a good one because due to “magic push button” and “god object”, fixing bugs tends to create a sorts of anomalies that fall into this category.

Caching failure: Forgetting to reset an error flag when an error has been corrected

I’ve run into this numerous times and it has been the source of many bugs in Tilt to Live. I used object pooling heavily and as a result, when introducing new object types into the mix or new instance variables, forgetting to add them to the reset() method would invariably cause some hiccup in animations, sounds, or even collision.

Lately, I’ve taken time out to start porting some of the framework code I’ve created over the course of Tilt to Live to c++. Having worked pretty much exclusively in objective-c for the past year, I’ve realized how rusty my c++ has become. The main purpose of the rework is so I can have a base for starting new prototypes, as I’m usually stuck with starting from scratch each time. Another benefit is being more “portable”. While developing for android would still require some considerable leg work, the option of going PC, palm, console, or some other device I think is worth it in the long run.

After reading Noel’s post on prototyping I realized I was drifting away from that mind set and getting into dangerous territory of just “thinking up a game and running with it.” Tilt to Live itself spawned into a full game from being discovered in a rough prototype. Since then we’ve just had rough documents and ideas that we wished to pursue after TTL. The past few weeks we’ve been gearing up more heavily for our next game and I’ve been getting back into the habit of whipping out fast prototypes.  I finished one prototype for an arcade/action shooter and another one over the past weekend for  a turn-based strategy game. My methods for prototyping each were very different. Ultimately, as I experiment with different tech and methods I’m trying to optimize the time from “concept” to “on the screen and working” so that we can fail quickly or move forward with the idea.

Action Shooter

With this one I had a series of prototypes I wanted to explore before we would deem it ‘good enough’. The first one was trying to see if our tilt mechanic would work. We had an idea that was a slight evolution of Tilt to Live’s controls but allowed for shooting while still avoiding annoying ‘floating D-Pads’ issue. It took about 15 minutes to do the mechanic prototype. After getting it implemented and in the hands of some friends, they actually liked the feel of the controls, which made us pretty excited about it. My next question was whether a scrolling view worked with a tilt mechanic. It made perfect sense to me in my head, but for some reason I felt that not being able to view the whole field while tilting to move (somewhat losing that 1-to-1 feel) would ruin the experience. 40 minutes later I had a camera system and some basic map trinkets scrolling by and it still felt good.

The next several hours became more of an educational exercise by implementing bluetooth multiplayer in it, and admittedly it was wasted hours in the prototype sense but very useful in a general sense. So I did go off track here a bit, but corrected myself soon after indulging in that little fun :). The tech used was the iPhone itself and objective-c as it’s hard to test very device-specific controls on anything other than the device. The next prototype in this series would be player/enemy interactions and seeing if simple enemies would suffice or would we need varied, sophisticated enemy behaviors to make it compelling (a difficult road to go down, as disposable content is not something I’m a fan of), so this’ll be a rather telling iteration.

Turn-Based Game

This was an interesting prototype to make. The game consists of a hexagonal grid where two players have bases, spawn points, and a set of different character classes. The game’s core idea was to make a very simple-to-play turn-based game but introduce interesting twists to the character classes that didn’t require some extra knowledge or rigorous ‘book keeping’ of different types of stats for each pawn to use effectively. So while the action of ‘moving’ a pawn was simple, the outcome would be varied and hopefully pose interesting choices to the players that are playing.

About Friday mid-afternoon I decided I wanted to see this turn-based game idea Adam had in an more automated form so we could give it more play time and start getting feedback from more people. The first prototype of this game was done by Adam in Adobe Illustrator. He did it in Illustrator because he was most comfortable with manipulating graphics in that program, and also (being the artist he is) had some pretty mock ups to play on top of. It was a series of duplicating object-groups to move objects, editing text boxes to adjust hit point values, deleting and adding layers and all sorts of madness. It was slow, tedious, but the game was still pretty compelling. It also goes to show that you can prototype a game with just about anything.

Having only about 3-4 hours before leaving to the beach for the weekend I had to decide what was the quickest way for me to get a more complete version of this game’s rules running on a screen. Ideally I wanted an iPad prototype, but I had almost zero framework to work with (barring using something like cocos2D) and the tediousness of C++/Objective-C slows things down. I opted for writing a prototype in Blitzmax. I ran the simple Blitzmax IDE on my mac (Blitzmax works on mac/pc/linux) and started coding away. No header files, no include dependencies, lots of high level modules to load graphics, draw graphics, draw text, load text, load data, handle mouse/key events. I feel I eliminated like about an hour of working on ‘boilerplate’ code to get a prototype up and running on a laptop.

Not having done a hexagonal-grid based game before, it was time to hit the books and just quickly skim over the basics of how to manipulate objects in that space. This was more of the ‘technical education’ part of the prototype. And this is usually the part that takes the most time in any of my prototypes. Transforming between hex and mouse coordinates, moving and calculating distances took up the rest of the time to develop.

Oh no, so I had no prototype before the weekend! Luckily, trusty Adam was driving so I spent about 1.5 hours just putting together a state-machine type framework trying to get the ruleset and player interaction working. This is one of those dangerous situations as well, as Noel and others mention, that many can get caught up in the “technical beauty” and try to create an all encompassing FSM framework of some sort. Putting a 3 hour constraint on this really helped mitigate that urge.

Then the battery died. Oh well, instead of spending some untold number of hours cooped up in a condo instead of enjoying the weekend with friends at the beach I limited myself to 30 minutes a night right before going to bed to work on it. The awesome part was knowing how little time I had to work on it allowed me to make coding decisions much more quickly. Of course the downside is the amount of ‘shortcuts’ I took code-wise to get the prototype up and running. But the thing for me to remember is it’s a prototype, not  final code. Further practice and experience will yield better code and solutions for quicker turn-arounds in prototypes. I finished that prototype after 2 30-minute sessions, and 2 players can play it on a laptop on mac or windows.

Not having it on an ipad kind of sucked as it does have a certain novel feel to it, but that “feeling” is probably more like sugar on top than having a solid design that works on any screen.

Faster, Faster, Faster!

Indeed, getting something up and running and being able to play with it holds more answers than any time spent thinking about it in your head. Things like the Experimental Gameplay project really shows what volume of ideas can be realized with very focused, short efforts. I had been doing these prototypes all the while working on finishing up TTL HD. With this newly rediscovered “do it as quickly as possible” mentality I may be able to incorporate a weekly prototype into my schedule to break up the week of working (happily, mind you) on whatever our current long term project is. Strangely, both prototypes show promise, but it may come down to how “well” we can make whatever fun prototype we choose in a short development period since we are aiming to release at least 1 more title in 2010.

I had an issue where several international users were reporting that the game was crashing. As it turns out, using an NSNumberFormatter would return a weird character to display as the grouping separator. This would be all good and dandy, but the problem lies in the fact that I’m using bitmap fonts to render, and the look-up failed causing a hard crash.

In Tilt to Live’s case, this was in regards to how number grouping symbols are displayed in different locales. I use the comma to separate most of the number displays. Due to my ignorance, I just assumed ‘NSNumberFormatter’ would work with what I thought was a universal concept. Not so in some Arabic countries apparently. The fix? If you aren’t supporting localization just use the particular localization you are coding for, otherwise the formatter will use the iPhone’s language settings to pick a localization for you:

[code]
numberFormatter = [[NSNumberFormatter alloc]init];
NSLocale *locale = [[NSLocale alloc]initWithLocaleIdentifier:@”en-US”];
[numberFormatter setLocale:locale];
[numberFormatter setNumberStyle:kCFNumberFormatterDecimalStyle];
[numberFormatter setGroupingSeparator:@”,”];
[numberFormatter setUsesGroupingSeparator:YES];
[locale release];
locale = nil;
[/code]

It’s been hellishly busy as of late, as I’m knee deep in Tilt to Live HD.  Now on with my quick blurb:

This tip is kind of a “duh” much in the same way version control software is for most developers. The thing is I still meet a lot of developers who don’t use any form of version control. And automated builds simply weren’t even in my own tool set initially. Mostly because my build steps for projects never scaled to the complexity required to build like an iPhone application. And it wasn’t even complex. It was just a matter of remembering which command line parameters to use and which provisioning file to include and to zip it up all tidy and neat.

Now with XCode’s build and archive command a lot of this is simplified with a GUI, but that’s the crux of it. It still requires you to go through several clicks to send a build out.

My setup is pretty simple by using a makefile and the xcodebuild commandline tool. xcodebuild just allows you to build projects from a commandline very easily. Mix that with a few basic unix commands, agvtool, SVN and you have a primitive but simple build pipeline that you can execute with a single command and not thing about anything else. I’ve been using it throughout Tilt to Live’s development and haven’t had a need to really look elsewhere since it accommodates exactly what I need to do: not screw up build submissions or beta builds for testers.

Over the months my makefile has grown to include a few other ‘targets’ for faster iteration during gameplay tweaking, but the 3 essential ones were:

  • build – this just builds my app for ad-hoc distribution into a zipfile named ‘appname_versionnumber.zip’ and a debug symbols file next to it. It then moves these two into a builds folder where I keep all my builds. It works in conjunction with the agvtool so that it increments the build number and submits the new version to SVN.
  • appstore – This target does the same as ‘build’ except it builds with the app store distribution settings.
  • clean – just wipes all my intermediate object files and build temp folders if I want to build from scratch

Below is just a snippet from my current build target. It builds the projects, moves the app files and provisioning files into the current directory. Zips those two up and copies them to a build directory with the debug symbols.

[code]
build:
cd $(PROJDIR) ; agvtool -usesvn next-version -all
xcodebuild -project $(PROJ) -target Tilt_To_Live_HD -configuration Distribution

#move app files into build directory
cp -R $(DISTRODIR)/$(APPFILENAME) $(APPFILENAME)
cp $(PROVISION) $(PROVFILENAME)

#zip up the app file and move debug symbols
zip -r -y -q “$(BUILDDIR)/tilttolivehd_`cd $(PROJDIR) ; agvtool vers -terse`.zip” $(APPFILENAME) $(PROVFILENAME)
rm -rf $(APPFILENAME)
rm -rf $(PROVFILENAME)
cp -R $(DISTRODIR)/$(DEBUGSYMBOLS) “$(BUILDDIR)/tilttolivehd_`cd $(PROJDIR) ; agvtool vers -terse`.dSYM”
[/code]

I wonder if the xcodebuild tool has some commands for automating the ‘build and archive’ command. That would simplify my targets even more.

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.

While I was working at a day job for the past couple of years I was gobbling up any info I could find on going fully independent and the what it takes not only from a business perspective, but what you have to change about your personal life, ideals, and expectations in order to make it sustainable. One of things that stuck out a lot was managing my burn rate. Minimizing the amount of money leaving my account wasn’t just a matter of not buying a Starbucks coffee (I don’t even drink coffee, but you get the idea). It required some fundamental changes in the way I thought about money and how it related to my daily life. Jeff Tunnell I think articulated it very well in his article, where he talks about “Right Sizing Your Life“:

The bottom line is that you cannot live downtown San Francisco, drive a Porsche, have three kids, eat out every night, have Starbucks two times per day, charge up the credit cards, and live the way most of society tells you to. If you want this stuff, start coding in Java and go to work for IBM. But if you want to enjoy your work, feel creative every day, and make games for a living, you will have to pay a price.

Adjusting Your Daily Life

It sounds pretty obvious and seems straightforward. But it’s definitely easier said than done. The biggest problem being that if you are working a day job, if a decent one at that, you can afford a lot of extra expenses. Having a “steady paycheck” at a day job numbs that feeling of loss when I spent money. I would always spend within my means, but when my means don’t match up with what my “means” will be by the time I’m independent, I imagined I’de be in for a tough transition.

I tried all the obvious things: Stop eating out. Stop buying food/drinks at bars every weekend. Start cooking at home. Start watching less TV (canceling cable). Doing any of these cold turkey was a difficult feat. But like any sensible diet/exercise plan you should do it in moderation until you’ve achieved your goal. One of the things I noticed is when I find myself hanging around friends and socializing a lot, spending went up. It’s an obvious and natural occurrence, but I would think most people believe they are in control of how they spend their money. But in fact, at least in my case, where and how I spend my money is heavily influenced by what I am doing and with whom. You go to bars, movies, play games, eat out with friends. That’s not to say you should become an anti-social either. You just need to plan accordingly and figure out a way to fit your new goals in with your current social circle. For me, it became less of a spontaneous thing and more scheduled. If I knew I had plans later in the week to go out, I spent/saved accordingly to make it happen if it was possible.

Technology to the…rescue?

I also tried a lot of money management software with mixed success. Mint was a popular choice and one I had used initially. It’s great for tracking where you’re money is going. But it’s biggest strength may be the weakest link in trying to change your spending habits. It’s a passive way of keeping track of your money. You have to be vigilante in looking back on what you spent after the fact to see why the numbers worked out the way they are. I decided to try a different approach by creating a habit of logging expenses as I went throughout the day spending money. Since I had my iPhone with me everywhere I went, it seemed natural that there’d be an app for that.

I  used Spend [iTunes] to keep track of my spending but also try to enforce some sort of budgeting. When I think about it, the idea here isn’t so much as to just “keep a log” of what I’ve spent, but to encourage a habit where the act of spending money requires me to reflect on it for at least the briefest moment. Spending with a debit/credit card is easy, but when I have to pull out my phone, load up the app, type in a description and price, the entire time I’m thinking about the act of spending money. It becomes a bit more painful, similar to spending real cash. This had a much better impact on my spending habits than Mint did. I could more visibly see in real-time where my spending was heading and how much room I had left in my budget. I become much more aware of all the “small things” I would spend money on throughout the day like vending machines, snacks, sports drinks while working out, etc. The specific app I use isn’t important, it’s more about developing a habit to be conscious at all times of where your money is going.

Keeping At It

Having friends and family that support your goals goes a long way as well, not only in your spending habits but also in what you consider good ways to spend your free time. Fast forward a few years later, my day job is making indie games, my views on what I feel is important financially and personally has changed a lot and I feel a lot less stressed out about money in general. Just by trying to reduce my burn rate for several years I have a very clear picture of what I need in terms of finances in order to make this indie business sustainable. So in essence, I have a very good gauge as to whether I’m in trouble or not relative to how much I’m taking in. Also in an effort to reduce my costs even further, I moved back down to the deep south (Alabama). Living near DC is pretty expensive. It’s a pretty big move leaving DC behind because I loved that city. But in the end, being closer to family and life long friends in the south was a great bonus to saving a lot of money on living costs. I consider myself pretty mobile at this point in my life being single with no kids or spouse to look out for; so up and moving may not be an option for everyone.

Stepping outside the “rat race” is more than just becoming independent. You have to be willing to fight the pressure from those around you to change your thinking. Managing and minimizing your burn rate is one of many aspects of making the transition from “employee” to “self-employed”. Not the most detailed post, but hopefully will give those working-by-day-indie-by-night a few ideas to step a little closer to full-time.

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]