Ok, that title is kind of misleading. But for those who caught the reference, *high five*. I actually pulled gyroscope support from our latest Tilt to Live update. I had it implemented into the game at one point but through beta testing eventually killed the feature. I just wanted to go over the details as to why it went the way of the dodo bird.

Gyroscope != Accelerometer

Alright this a biggie. With the gyroscope on iPhone you can detect the orientation of the device in any position. This is great and actually not a limiting feature. You can calibrate the device in any position. Hell, you can calibrate the device while hanging upside from a jungle gym on a pre-school playground and it will work without a hitch. But there is a subtle difference as to how your tilt offset is calculated. The gyroscope offsets are calculated off of absolute orientations, where as using the accelerometer offsets are calculated off of relative orientations to a gravity vector.

Before I go any further, let me explain why I went down this dead path for tilt controls. When you calibrate a device off of the accelerometer there is a ‘gymbal lock’-esque problem when the device is 100% vertical. Any horizontal tilt cannot be detected because you’ve lost this degree of freedom since one of your tilt axis is aligned with gravity (what the accelerometer works off of). When the gyroscope was announced I naively thought, “Hey we can probably make the perfect tilt controls now that work in any position!” I got the ‘any position’ part down, but it was far from perfect.

Complexity in the UI

Another ding against gyroscope was due to the nature of how it worked, I couldn’t find a way to automatically turn it on and off without a large chance of the user becoming confused. As a result, I needed to create some UI interface to enable gyroscope controls. And wow, it was a hard one. Trying to explain the nuance of how the gyroscope works, without getting technical so that the user can make an informed decision as to whether they want it or not was…a bit weird. How weird? When you have to write up text that says this:

You’re probably doing it wrong.

We found it pretty funny and in line with the rest of the humor of Tilt to Live. But it just wasn’t easy to explain. Complexity in the UI was actually one of the main reasons we decided to pull it. We didn’t want Tilt to Live’s calibration to become this screen of knobs and switches, even when you’re doing a custom setting.

We weren’t kidding. Cars = bad

Step 1. Calibrate using gyroscope

Step 2. Play the game. (You so happen to be in a moving vehicle)

Step 3. This vehicle takes a right hand turn

Step 4. Owned.

The handset, in “real world” space is actually rotating when the car turns, but in local space relative to the car it isn’t. Bad news for people who are now wondering why their little arrow turned suicidal after they got off that exit ramp from the highway.

This issue ultimately clinched it. Having to calibrate not only the orientation but the actually direction a player is facing was too much. There was too large of a margin for error.

Gyroscope is awesome, we just weren’t meant to be….

With all that said, playing around with the gyroscope was awesome. It allowed me to play Tilt to Live in one-handed portrait mode because of the freedom it provided with calibration. But that freedom is very short-lived as soon as I get up, turn in my chair, or any other minor movement.

In the end, if you’re making a tilt-based game mechanic gyroscope may be of a more limited use when you actually stop and think about it. Unlike me, who did very little thinking and went ahead and tried it :). I did have a period in there where I was completely convinced that there was an elegant solution to combining the accelerometer data and the gyroscope data to create a fully working “hybrid” of sorts. It never came to me, but I’m sure someone out there much smarter than me that could write a proof proving or disproving this problem and make my head explode.

Lot’s going on in OML-Land. TTL HD is out the door. TTL HD 1.1 is already in Apple’s queue (fixing a horrible crash for our international users). TTL 1.5 (iPhone) is in testing right now. On top of some R&D type stuff I’m messing around with so we can transition to our next project more smoothly.

So retina graphics are all the rage at the moment. If you were lucky to develop your game assets all in a vector-based format, supporting retina graphics was a bit easier. Luckily for us, Tilt to Live was all done in Adobe Illustrator. With a few tweaks to how sprites are rendered on the iPhone I had retina working in an afternoon.

Now, retina is all dandy until you get back onto the iPad.  If you are using the [UIScreen mainscreen].scale method to detect retina, be weary for iPad users. Things get a bit tricky on the iPad because:

  1. If you’re using the @2x trick, this doesn’t work on the iPad. This caused a few problems because some of our asset metadata relies on this as well so it caused a few minor headaches.
  2. Users can toggle the x2 mode mid-game.

At first I thought I could code to allow the iPad to load the retina graphics for a spiffy looking Tilt to Live. But the realization of #2 stopped me from pursuing it. Plus, with Tilt to Live HD on the app store now with even better graphics there really wasn’t a need to do it.

So if you plan on allowing iPad users to load retina graphics, it doesn’t exactly come as easy as it is on the iPhone 4. You may pretty much have to treat it in a similar fashion as a screen resolution change on a PC. This sometimes involves unloading textures, putting a loadscreen up, etc.

Next week I may go over some of things I came across implementing tilt controls with a gyroscope, which wasn’t exactly straightforward…

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 recently made a post on our official OML blog about what Adam and I are playing. Taking a look at that list you’ll find that the vast majority of games I play are multiplayer oriented. A lot of biases, inspirations, and design decisions that go into my game designs are influenced by multiplayer games.

When we set out to start One Man Left, my long term goal for the company (beyond making fun games we like to play) was to be known for making fun multiplayer indie games for whatever platform we develop for. Our first game wasn’t a real-time multiplayer game, but you gotta start somewhere, right? Admittedly, I don’t seek out purely multiplayer games on the iPhone often. Searches for “multiplayer” tend to not turn up very compelling options, and it worries me. The few games that are strictly multiplayer tend to have different reactions based on how the match making works and how ‘easy’ it is to play alone. For instance, one game was bluetooth/wifi only and had no AI opponent. It had extremely low ratings and the vast majority of them were “please add a computer opponent”. Just reading this you would think that a lot of iPhone users are isolated cases where their friends don’t have an iThing. This could very well be the case, although in my personal experience it isn’t. It may also have been a case of the app description not being detailed enough.

I’ve been prototyping some co-op multiplayer game ideas over bluetooth recently and we’re really excited about the possibilities. I feel multiplayer is an awesome tool in the game designer’s toolbox. It overcomes many challenges more traditional single player games are still struggling with:

  • Want the player to have a memorable experience? Include a friend, and now it’s a shared experience that is easier to remember.
  • Want a genuinely funny game? Add some human players and watch the hilarity ensue. It becomes a breeding ground for memes, inside jokes.
  • It’s much easier for players to evoke genuine joy, exhilaration, nervousness, anger and frustration when playing with human players in close proximity.

Yes, it’s definitely a different spin on things as you can’t exactly tailor an ‘epic’ story to many multiplayer games, but it entirely depends on the goals your game is set out to achieve. In the context of mobile games, long and epic games don’t seem to be hitting the mark compared to heavier duty, more hardcore platforms.

So where are all the awesome multiplayer games, especially with a platform that is practically connected 24/7 regardless of location and time? We’ve certainly seen some early successes so far (Words with Friends, Eliminate, NOVA, Archetype, etc), but these seem to be barely scratching the surface on what this platform can do. Now with some ideas on multiplayer on the iPhone I figured there are plenty of challenges and possibly very good reasons why we aren’t seeing many successful indie games based around multiplayer just yet.


It’s no secret that networking, and making that networked experience seamless and easy to use is no small task. In fact, if you’re doing a server hosted solution where the game is happening at a central location, the cost and infrastructure is probably cost prohibitive for most indies to be sustainable. Even if it’s a P2P game, the complexities of managing a game over a network where any number of things can hinder the quality of the connection or the progress of the game can become a headache at times. You find you are coding for a lot “exceptions” in game events when things simply don’t arrive, arrive late, or aren’t even welcome.

It’s not common for a game to have multiplayer as it’s front and center offering. It’s usually tucked away as a “but wait, there’s more!” item in some bullet list description of features. As such, the convention seems to be a single player option with multiplayer being “extra”. That just adds to production time as now your game isn’t just a single “mode”.


To me it seems the number of people who wish to play a game with their friends would be close if not higher to those that wish to purchase a quick 5-minute game to kill time. But I have no data to really back this up, and as such I think my bias is getting in the way here and I could be dead wrong when it comes to the iPhone game market. Social networking sites have already shown that ‘social games’ have a huge appeal, however dubious the game is. So maybe that’s good news?


The other dilemma is the chances the player will have to actually play the game. With a game like “Words with Friends” or “Archetype” there’s always a game at a moment’s notice. Of course, the catch being that you aren’t playing with real life friends (WWF has a slight exception here due to the nature of the game). It’s difficult enough to get players to play your game on their own, but now adding the constraint that 2+ people must buy it AND must be in the same general location to play becomes even more challenging. This drives the game more into niche territory. The question is if that niche is big enough.

The More The Merrier

Multiplayer games are sticky by nature. Players won’t drop your game after a day if they have friends playing it. There’s been a lot of ‘bigger budget’ games that are multiplayer driven on the iPhone, and the whole “social gaming platform” vendors (AGON, Open Feint, Plus+, etc) are all betting on the same thing with their leaderboards and social features. So maybe I’m not too crazy to try to create something that requires more than 1 person/iPhone to fully enjoy the game. The iPad is always an option as well, and possibly a safer one if I wish to pursue a ‘multiplayer’ centric game idea.

So I’m currently playing around with some multiplayer prototypes on the iphone, and when it came down to testing stuff I ran into a problem: You can’t deploy to multiple devices at the same time. Yea it’s not exactly a ‘problem’ per say, but it’s certainly tedious doing a ‘build and run’ on the devices you want to test. So much so that I dropped 3 player support in a prototype just to save time.

I did run across this blog post by Jonathon George on the topic. You can plug in all your devices at once and just switch the ‘active executable’ in the drop down to deploy to each device. Not ideal, but works for the time being. I figured there may be a way to run multiple instances of XCode projects but I expect that gets into all sorts of messy configuration issues so I haven’t spent the time trying to do it. Wonder if anyone out there developing multiplayer games has gotten a elegant solution to this?

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:

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;