iPhone
Adding Save Game to Battle for Vesta
by john on Mar.08, 2010, under iPhone
One of the most requested features for Battle for Vesta is the ability to save a game. This is an entirely reasonable request. Playing the game all the way through can take some time and it is inevitable that you’ll get interrupted by a phone call or some other distraction and find yourself wanting to pick up where you left off.
Also, over the last few updates the game has gotten a lot harder. I find myself getting shot much more frequently and making it through the last few missions is really difficult. Sometime I just want to replay the mission that I just died on rather than start over from scratch.
I started thinking that the retry functionality was the low-hanging fruit and that I should implement it first. Then after some thought it occurred to me that I could kill two birds with one stone. The simplest way to do this was to save the starting conditions at the start of each level and then add a new way of starting the game, a “retry” button. Pressing the retry button would start the game up on the same mission that was last played. So if you die or get interrupted you can always go back to the start of the last mission you were playing.
It turns out that this requires very little code, but it took me a bit of googling to find the bit of the iPhone framework that does what I need. It turns out that there is a persistent dictionary for the iPhone called NSUserDefaults that allows you to store key/value pairs. It also handles persisting them to flash so you don’t even have to worry about the filesystem. So now I have some simple code to save a game in my startLevel() function:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setInteger:level forKey:@"levelKey"];
[prefs setInteger:myLevels.goodRemaining forKey:@"goodRemainignKey"];
[prefs setFloat:shieldPower forKey:@"shieldKey"];
[prefs synchronize];
and some complementary code to pull that information back up when a user hits the retry button:
void retry()
{
gameOver = false;
if (isHit && deathCounter <= 0)
{
isHit = false;
uKills = 0;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSInteger retryLevel = [prefs integerForKey:@"levelKey"];
NSInteger retryGoodRemaining = [prefs integerForKey:@"goodRemainignKey"];
float retryShield = [prefs floatForKey:@"shieldKey"];
if (retryLevel == nil)
{
shieldPower = 6.0f;
level = 1;
energyCollected = 0;
}
else
{
shieldPower = retryShield;
level = (int)retryLevel;
energyCollected = 0;
myLevels.goodRemaining = (int)retryGoodRemaining;
}
startLevel();
}
}
And that's about all it took to add both save and retry to Battle for Vesta. I'll be submitting this update to the App Store today, so you'll be able to use this feature soon.
I should mention that my Googling eventually led me to the the iCode blog which had a helpful walkthrough of how to use NSUserDefaults and which convinced me that it was the correct (and simplest) way to implement what I wanted. However the blog states that the synchronize message is not needed. In my experience it is needed as I tried it without it and it didn't work.
Battle for Vesta, OpenGL, and 12 Years of Portability
by john on Jan.12, 2010, under iPhone
About 12 years ago I had a CS assignment to write an asteroids game called Blaster over the course of a week using OpenGL. Technically we were using Brian Paul‘s Mesa3D library on Macs that didn’t have any hardware graphics acceleration. The assignment only had a few requirements, such as 3D asteroids that broke into smaller asteroids when you shot them and other simple asteroids gameplay features that you would expect. Most implementations were pretty vanilla, as time constraints and performance problems limited what could be done. Each time the class was taught somebody would go overboard and make a fancy version of the game that performed well, had some particle effects, and perhaps an enemy ship and then give it a name such as Super Blaster.
I started working on my 3D asteroid code first. While we could simply use a GLUT primitive for the asteroids and get full credit I thought it would be fun to try to write a 3D fractal routine for the asteroids. That went quicker than I had thought it would and soon I had some very dangerous looking asteroids floating around the screen. It seemed a pity to shoot them in a 2D plane.
I had recently picked up a freebie Rubik’s cube at a job fair. Some company whose logo has long ago faded from my cube was claiming that they were only going to hire geniuses and were using a 3x3x3 cube to symbolize that. I was wondering how to make a compelling 3D asteroids game and staring at the cube when I had a realization: a 3D implementation would be fundamentally different from a 2D one in how you handle the edges of the world. In traditional asteroids you can fly to the edge of the screen and you’d pop out on the opposite site. In 3D with a first person view you still needed to have some sort of world boundary or you’d need a limitless number of asteroids to fill the area. In order to get the same wrapping effect in 3D I imagined that the world was the Rubik’s cube and my ship was always in the center of it. If I moved forward in reality all of the asteroids would be moved backwards. If an asteroid left the bounds of the cube it would “wrap” to the other side.
I coded this up pretty quick and began to play with it. Then I had another realization: It takes a lot of asteroids to fill a 3D space.
In a 2D asteroids game if you’ve got ten asteroids on the screen, that is a lot to have going on. In 3D asteroids if you have 10 asteroids in the world you’re luck if you ever see one, and hitting one doesn’t happen by accident much. So I increased the number of asteroids a great deal (around 100) and then things began to look like something. But then I faced another problem. Shooting 100 asteroids isn’t fun, it is work. Finishing a level would take forever and would definitely not be fun. Clearly I needed an objective other than clearing the world of asteroids. So I put in some enemy ships and gave them some simple AI. The objective became to shoot the enemy ships while dodging the now plentiful asteroids, which you could shoot if you wanted to.
I wrote this on a 16MHz Mac Performa using software rendering. Moving all the objects around didn’t create a performance problem, but making the screen very large did. But it ran fast enough to be playable in a 320×200 window on my Performa and luckily it was graded on a 300 MHz machine that could run it fullscreen at 640×480.
I got a good grade and one of the TA’s even got me into the SGI lab and we did a quick port to an SGI machine. By quick port I mean about 30 minutes to get the input stuff moved over. Other than that it just ran, and ran quickly at high resolution.
A few years later I had a ThinkPad for work which had a mediocre graphics chip in it, but that was better than nothing, right? I ported the game to Windows and suddenly it flew. I had to implement some timing routines to slow it down to 60 fps.
Here’s a screenshot of it running on Windows:
As you can see I’ve changed the original ship design for reasons that should be fairly obvious. For those that can tolerate the ugliness of an old Angelfire page you can find a working download of the Windows port and complete source code here. About that same time I did a quick port to Linux as well.
Now here we are 12 years later and I have more computer in my pocket than I had on my desktop in college. The iPhone has more powerful processor, more RAM, more storage, and a decent graphics chip. Once I got a dev kit I began porting the game. It took about a day to get a stripped down version of it working on the iPhone. So my college project began its journey from Blaster to being Battle for Vesta. The main change was the move from display lists to vertex arrays for OpenGL ES. That didn’t mean that I had something I could put on the App Store, but it meant that rather than starting from scratch I had a core engine around which I could build a game worth putting into the App Store. One thing worth noting is that the bulk of the code is still C++. I have yet to learn Objective C and really didn’t have any need to do so for this project.
Several weeks ago I ported the iPhone version over to Python. This involved a lot of searching and replacing to remove the C++ syntatic sugar but didn’t require an substantial changes to the OpenGL code. That effort took about 8 hours and allowed me to quickly experiment with different collision detection optimizations in Python, which was much easier than doing the same experiments in C++. I’ll admit to having become a Python bigot and that my C++ skills are not what they once were. Having a Python port also allows me to use my strange pySight and wiiMote stuff that runs in Python to control the game. That version runs on Mac, Linux and (I assume) Windows.
Now imagine if instead of OpenGL (ok, Mesa3D) we had used some early version of Direct3D for my graphics class. Not only would everything I wrote have been deprecated five times over by now and what platforms would it run on?
There really is something to be said for open standards and libraries built on those standards. While there isn’t enormous value in an ultraportable 3D asteroids game the same principles apply elsewhere. If you are writing something that is going to have a useful life beyond a couple of years you should consider carefully the core technologies that you use to build it. Don’t be distracted by buzzwords and whatever the most recent flash in the pan is. Even if what you are working on seems like a throwaway code, writing it for portability can allow for opportunities that wouldn’t otherwise be available.
For the curious here’s what it looked like on the iPhone at version 1.0. Now it has some textures to liven things up. [EDIT:] I’ve lowered the price today to $0.99 in case anybody wants to try it out on a whim.
Piracy and iPhone Game Marketing
by john on Jan.05, 2010, under iPhone
So Battle for Vesta has been live in the App Store since December 28, 2009. In that time I’ve posted about it in forums, promoted it on this blog and Facebook and Twitter, given away a lot of promo codes, and posted on a lot of forums. I created www.battleforvesta.com and posted a trailer and videos of gameplay on YouTube and Vimeo. I’ve also emailed dozens of iPhone app review sites. So far one of them has been kind enough to send an automated acknowledgment of submission email, in which the site admits that it might never even look at my game and even if the game gets looked at it probably won’t get reviewed. There has been no response at all from the others.
In short, while I haven’t done a perfect job of marketing my game, I’ve done as well as I knew how to at the time and have learned some lessons. I’ve also set up Google alerts so that if the game gets mentioned anywhere I know about it and can respond appropriately.
Marketing an iPhone game is incredibly difficult right now. The market is crowded (much of it is crap) and it is very hard for casual users to discover new apps that might interest them. With this in mind I’ve priced the game at $1.99, so that it can be an impulse buy. While I think the game is worth more than that, I didn’t want the price to be a barrier to people that were merely curious about it.
So after being live on the App Store for a week I’ve sold about 30 copies and about the same number of people have turned in promo codes. I’m not ecstatic about those numbers, but I’m not surprised either. I will say that I’m a bit disappointed in the unwillingness of people to rate and/or review the game, especially if they’ve been given a promo code and agreed to.
This morning my Google alert told me that the game had started to show up on pirate sites. I had expected this and I was actually a bit surprised that it didn’t happen the day the game came out. In less than an hour one pirate site indicated that the game had been downloaded more than 30 times. No, I’m not going to link to any of them. I will note that I am amazed that they show up on the second page of a Google search for the game. Odd that pirate sites seem to have so much credibility with Google.
I’m trying to figure out exactly what it is that annoys me about this situation. I think there are a few aspects to this.
One is that $1.99 is cheap. That’s less than coffee money. If it entertains you for 30 minutes total you’ve gotten your money’s worth and then some. I’ve played it for countless hours and I fire it up just for fun every day. So I hardly think that price is an excuse.
Secondly, if $1.99 is really going to break the bank, ask me for a promo code. If you claim that you’ll post a descriptive review (I don’t even ask that it be positive) then I’ll give you one. I know full well that the chances of you actually posting that review are about 1 in 10, but that’s the way Web 2.0 works, right? If you pirate the game and love it there is no legitimate channel for you to rate the game, review it, or give feedback. So now not only am I out a sale (which I was willing to give up) but I’m also out any chance of your love of the game helping to make it go viral, or even your criticisms of the game being used to improve it.
Finally, it is immensely frustrating to put all the above mentioned effort into marketing this thing through legitimate channels and get very little response. Yet the game gets downloaded as much in an hour from a single pirate site as it did in a week legitimately. This makes me wonder if somehow the pirates know something that I do not. They’re able to make my game more popular in an hour than I am.
Finally, if this is just kids who somehow saved up $200 for an iPod touch and don’t have any pennies left to fork over for a game, I guess I can understand. Almost. ($1.99!) I’d still rather give it to you for free than have you steal it from me. But somehow I suspect that the majority of this isn’t being done by penniless kids at all but is perpetrated by people that can easily afford the game and just get some perverse joy out of cheating me.
While I’m at it, the first four people to comment on this article will get a promo code emailed to them.
Battle for Vesta – Live on the App Store
by john on Dec.28, 2009, under iPhone
Battle for Vesta is now for sale on the App Store for $1.99. I suggest that you buy it. And tell all your friends to buy it. Seriously. Two bucks is cheap, and the game is great.

Also, www.BattleforVesta.com is live now. Link to it.
A Salesman in Three Dimensions
by john on Oct.08, 2009, under iPhone
Or, When Less Information Is More
Until now the asteroids game has had a pretty robust radar system. It displayed a blue dot for each item of interest on the screen and you could easily navigate to any of them. With it you could tell what was in front of you and what was behind you, and what the item was in.
Since the object of the game is to clear all the items (which can be either asteroids with hidden crystals or enemy ships) having all this information available to players seemed like a good idea. But sometimes you can give people too much information. Look at the video from the previous post. There is a swarm of 10 blue dots when the game begins. My experience is that most people have no idea what to do with those dots.
The problem the player is trying to solve is in a sense a traveling salesman problem: you fly around in space and attempt to visit each item once. Of course the items are moving, and you can shoot at them, and some of them shoot at you, but roughly it is a three dimensional traveling salesman problem. Of course giving the rough location of all the items in the area via radar didn’t help the player solve the problem efficiently. In fact, it probably hindered the player since distance was hard (arguably impossible) to determine accurately. So how do you help the player?
A reasonable (but not optimal) strategy for the traveling salesman problem is to simply head to the nearest node that hasn’t been visited, and then from that node select the next node that is nearest. The game now aids a player in doing this. The radar tracks one object at a time. So when the game begins, the nearest item of interest is tracked by the radar, and will continue to be tracked until it is gathered or destroyed. So the player only gets one blue dot at a time, which should help in understanding what it is the radar does, since before it could easily look like a giant nonsensical mess of blue dots.
In addition to this all items of interest get green brackets around them in the heads up display. So if two or more items of interest are visible at the same time they’ll all get brackets, but only one of them will get the blue radar dot.
In the screenshot below there is an energy crystal and an enemy ship both within view. Both are given green heads up brackets, but the blue radar dot is only visible for the energy crystal at the moment.

If anybody (especially beta testers) has any input on this idea, I’m all ears.
Looking for Beta Testers for iPhone/iPod Touch Game
by john on Sep.23, 2009, under iPhone
I have a much improved asteroids mining/3d space combat game that I’d like some feedback on. If you are interested in trying it out, leave a comment here and enter your real email address in the correct field and I’ll get in touch with you with further instructions. Thanks!
