This article covers the design and development process of a shipping one-button mobile game - EA Air Hockey, which was released in the first half of 2006. This is not so much a post mortem as it is a dissection of the game. I was the designer and lead coder on this game, and I've taken the opportunity here to go into some detail about how the design evolved and how various technical and playability problems were addressed. Hopefully this will prove interesting or perhaps even useful for others who are tackling the same sort of design challenges.
Before embarking on a detailed discussion of EA Air Hockey, I want to acknowledge the valuable input and guidance I received from key people at EA Mobile (then Jamdat). First, credit goes to Zack Norman for signing the game in the first place, for his valuable input and suggestions throughout development, and mostly for coming up with the idea of doing an Air Hockey game. Next, credit goes to Travis Boatman, again for his valuable input through development and for his help with project administration (and for giving permission for me to publish this!). And last, but by no means least, credit goes to Adam Schwenk - my long-suffering producer who put up with all the stuff that producers have to put up with.
What is ‘Air Hockey'?
Some people know the game as shuffle puck, table hockey, shuffle board, and no doubt other name variations. Air Hockey is the game where two players each use a disc shaped "mallet" (or "hammer") to hit a "puck" around a table. The table has a perforated surface through which air is blown by a fan - the air provides a cushion for the puck, which literally floats around the table due to the reduced friction. Each player defends a "goal", which is simply a slot which is several puck-widths wide, and basically the first player to score 7 goals wins.
EA Air Hockey
The primary reason to develop a one-button game for a mobile phone is one of simple practicality: the keypads on most mobile phones are not really very good for playing games on. The trend with phones is always smaller, slimmer, flatter - and of course much of the "size" of a phone device comes from the keypad itself. Keypads are designed to look cool (e.g. RAZR), and so that you can dial a number and (maybe) text a message. Expecting anything much more than that is a luxury for many of the phones out there. Requiring only one button really nullifies this concern - no scrambling to find the right key.
The other compelling reason to create a one-button game is to appeal to the so-called "casual" gamers and the non-gamers (the "to be converted") as it's these folks who makeup the vast majority of "mobile phone users". A game that is playable with one button should contain little to scare away or embarrass such a player. I wanted to make a game that the salesperson in the cellphone store could just hand to any customer and say, "just press the OK button to play".
So, I wanted to make a game that would work on any phone on which the following statements are true:
- Program code can detect that a single key is ‘pressed'.
- Program code can detect that a single key is ‘held'.
- Program code can detect that a single key is ‘released'.
Thus, the game design I had in mind had to allow the player to control the entire game using just a single key, and where 100% of player input would resolve to pressing, holding and releasing a single button.
Now at this point, some readers will have no doubt noted that there are already games like this for mobile, and there have been for some time. In fact, some of the most successful mobile games ever already use such a system - Jamdat Bowling for example. So where's the innovation with what I had in mind? Well, the big difference is this: what I wanted to do was a "real time" game - one that is not quantized into "strength, aim, spin, watch" slices. Rather, I wanted to apply a single-button control dynamic to a game that runs in real time, and which at no time pauses to allow the player to set a strength-gauge, or an aim-meter, or anything like that. The goal was to create a fluid, controllable "action" game where the only control available to the player was a single button.
So, here's what I came up with. I am going to cover the design in terms of the primary challenges encountered, by detailing the solution to each challenge.
Timing of player shots
When the player presses the OK button, the mallet moves to intercept the puck.
Timing of shots was one of the more approachable design challenges. All that happens is that when a player presses OK, his mallet starts to move toward the puck. Shot aiming was a different matter, but the only real wrinkle with the shot timing is that pressing the button commences the shot, but the actual collision with the puck will happen at some time in the future, when the mallet (hopefully) collides with the puck. It is a subtle point, but this does cause some complications in the actual aiming logic, which I will cover below. The player must hold the button in order to continue the shot.
When the player releases the button, when a collision with the puck occurs, or when the mallet reaches the center line, the shot is canceled and the mallet returns to a more defensive position on the table (covered in mallet positioning below).
Strength of player shot
In order to provide some nuance and subtlety to the control, I modeled shot strength based in the length of time the button is held. So, if your mallet is near your goal, and you anticipate a cracking shot near the center line, you'd get pretty close to full strength. More defensive shots nearer your goal line would have less strength. Essentially, the longer you hold the button, the further your mallet moves, the stronger the shot. Note that the speed of your shot is always constant - there is no shot acceleration.
Positioning of player mallet
The player's mallet performs an oscillating arc around the current position of the puck.
Positioning the mallet has some challenges. Taking a shot can be controlled with one button in a fairly obvious way, but how to position the mallet when not taking a shot? Using just one button, there's really no alternative but for the mallet to position itself. I considered some other approaches, such as adding an "override" so that more advanced players could alter the mallet position using the d-pad arrow keys, but in the end I eliminated this logic and instead worked on ways to make the mallet move in useful ways with no player input. After analyzing how the real game is played, I realized that there are two main modes of play: offensive positioning (where the puck is in front of your mallet - i.e., closer to the opponent goal), and defensive positioning (where the puck is behind your mallet - closer to your goal). There's also a transition mode, where the best mallet position is likely to be obtained by moving the mallet so that the puck is between it and the player's own goal.
Here's what I did:
When the puck is in front of the mallet, the mallet performs an oscillating arc around the position of the puck. Essentially, a line is imagined between the center of the puck and the mallet, a position along the line is chosen (it is a fixed proportion of the line length) and then this distance is used as the radius of an arc. Then, the angle around this arc is simply oscillated and the mallet moved toward the resultant location. Since the mallet "falls back" into this oscillation mode after the player takes a shot, I was concerned that the resume position on the arc would need to know the context (i.e., where is the mallet coming from), but in practice the angle simply keeps oscillating at all times, and the mallet just "tends toward" the location currently dictated by the oscillation.
When the puck is between the mallet and the players goal, the positioning logic smoothly transitions into an alternate arc pattern.
When the puck is within a certain distance of the player's own goal and moving toward that goal line, the mallet enters a different mode. This time the mallet moves itself to a location further away from the player's own goal line than the puck, and again performs an orbiting oscillation around the puck.
In the transition between the two main modes (which appear seamless to the player - that is, the positioning of the mallet does not have any obvious discontinuity), there are some subtleties - the mallet has to make sure not to travel through the path of the puck, for example, and cause an inadvertent collision with the puck. This was more of a problem when the mallet was moving from defensive mode back to offensive mode, as the likelihood is that a collision with the puck will result in an own goal.
In both cases, the oscillation is performed in order to present alternate shot possibilities to the player. Fundamentally, this is really an application of the oscillating "aim" bar in games such as Jamdat Bowling to a game that is happening in real time.
Aiming player shots
Player shots have to take into account the path of the puck, including rebounds from the sides of the table.
Aiming was one of the most interesting challenges. Given that the player has only one button to control the game, and that we want the button to cause the player mallet to do something sensible at all times (the player may need to defend or attack, and the puck could be located anywhere on the table relative to the mallet), there are quite a few factors to take into account. After much experimentation, I was finally able to resolve the reaction of the mallet to the player's input consistently at all times. The solution to how to move the mallet resolved into an intercept problem. Essentially, the mallet moves in a direction that will result in the shortest (time wise) intercept of the puck, given the puck's current velocity and location. I am not going to get into the detail of how to solve that problem mathematically, but suffice it to say that the solution takes into account the fact that the puck is decelerating, that it may bounce off any of the edges of the table multiple times before the mallet can hit it, and that the puck might actually go into one or the other players' goals before the mallet has a chance to hit it! In practice, the intercept code proved to "feel" right to the player - it seems to intuitively move toward where a player would move the puck, including anticipating bounces and so on.
The latter point is a key factor in the controllability of the game, because it changes the notion of "aiming" into an action of "timing" - pressing the button earlier or later will result in different collision points with the puck, giving the player the opportunity to try different shots against the opponent (bank shots, etc). This works nicely with the one-button control mechanism, and again this takes your Jamdat Bowling "choose when to press the button" sort of activity and maps it onto a real time game.
[Steve Wetherill has over 20 years of experience with video game technology and has developed on platforms ranging from ZX Spectrum to Xbox, including creating the lengendary Amstrad CPC version of Jet Set Willy. He founded Uztek Games in 2002 to focus on the mobile space. Uztek completed original mobile title EA Air Hockey for EA Mobile in 2006, and is currently working on several new mobile titles for J2ME and BREW. Steve Wetherill can be found at SteveWetherill.com.]
[This is Part One of a two part article, discussing one-button design. Part Two can be found here.]