EDIT: Galactic Fire is now available in the WP7 App Marketplace!
This week, I hit a major milestone by submitting Galactic Fire, my first complete game, to the Windows Phone 7 App Marketplace. Soon, Galactic Fire will be available world-wide and had a remarkable budget of $0 with one guy working on it part-time.
This feat follows no fewer than a dozen incomplete or otherwise failed part-time projects spanning a variety of platforms and technologies over a 5-year span of time, so it seems a good time to reflect on the techniques that differentiated Galactic Fire from the graveyard of software that didn’t ever ship. This is the list of things that personally helped me ship.
1. Learn One Thing At A Time.
Many of my projects started out with a mixed focus. I wanted to learn a ton of stuff, and I wanted to learn it all at the same time. It wasn’t enough to make a game that was fun! No, whatever project of the moment also had to use software stacks and languages that I would also learn along the way.
For me, botching this rule looked an awful lot like, “Let’s start a new game! New C++ project! Let’s throw Boost in there. And work luabind in there. And maybe some Win32/DirectX stuff! Or OpenGL! Or LibSDL! It’ll be cross-platform and it’ll be great!” To set context, I’ve been working in .NET/C# land for the overwhelming majority of my professional career. I haven’t worked with any of those technologies in a professional capacity, but games have to use that stuff, right?
Yeah, no. I stuck with stuff I was already familiar with (C#, XNA). The net effect of using familiar technology was bounding my problem domain; instead of learning the nuances of another language, I instead spent a lot of time focusing on the stuff I really, really needed to know, but didn’t know I needed at the time. For example, writing code designed to work in a polling system (game loop!) rather than the familiar eventing model, collision detection, physics, and a butt-ton of linear algebra and trigonometry. Oh, and tuning a game to be fun is certainly a non-trivial investment of time.
This allowed the things that I needed to know to surface more quickly, and had me spending more time on game mechanics and polish than, say, implementing my own content pipeline. There’s no denying that there are amazing learning experiences to be had working in an unbounded problem domain, but actually finishing something in that environment was an impossibility for me.
2. Art and Sound Are Not Blocking Issues. No, Seriously, Shut Up, They Aren’t, Stop Thinking About Them.
A non-trivial number of projects were killed because art and sound seemed so integral to actually finishing a legit game development project. These kinds of projects all kind of started the same way: “Oh, I know! How about an old-school RPG? Set in the future! With lasers, and stuff! We’ll need a robot, and it’ll need a rifle, and it’ll probably need to transform and look super rad from 9 different angles!”
Those projects never got off the ground because I was hung up on art. Before getting into the tools available for alleviating the art problem, it’s super important to drive home the point that I could have gotten the entire goddamn thing done with placeholder assets. I wasn’t creating a fun game with gripping narrative from start to finish because I didn’t have a robot when floating cubes or white squares would have sufficed. I didn’t need art and there was a shit-ton of work to be done elsewhere. Art was never in the way of finishing something great. It was an easy and convenient excuse to get hung up on and prevent myself from getting back to the hard problems that were waiting with the real work.
The very first iterations of Galactic Fire were about a red cube flying through a cornflower blue screen, shooting red cubes at other angry red cubes. It was pretty sweet.
Once I got to a point where I needed to legitimize the operation, there were some great options available. Daniel Cook of Lost Garden / Spry Fox fame is awesome, wants everyone to make a game, and left a bunch of assets to use in a game (with attribution, of course)!
If I really needed something a bit more custom, I would have still rolled a game using these as placeholder assets and then handed off the sprite sheets to a professional. If all went well, moving from prototype art to final art should just a matter of replacing assets.
Also, particle effects really, really legitimize an operation. I very clearly remember the day when enemies stopped simply disappearing on death and started exploding. Seriously worth the time investment.
For sound, these were the options available to me:
- Generate some sweet 8-bit sounds. sfxr is great and produces familiar sounds.
- If you’ve got Apple hardware sitting around, Garage Band in either iOS or OSX flavors has something you can use.
For Galactic Fire, I had some sfxr sounds and authored my own background music track, but ended up cutting it before release. By the end of the project, I had become so sick of the same sounds that I absolutely required a change. By the end, I ended up using a combination of out-of-box Garage Band sounds and a drum machine, using a closed high-hat for laser fire and a kick pedal for explosions.
3. Cut Scope.
I learned that game mechanics aren’t free. I mean that in a big way. Developing a feature isn’t the biggest part of what needs to be done to complete it. Take my plight to heart, and consider that even the smallest feature has to be communicated to the player in some way that doesn’t introduce cognitive dissonance.
Consider the following trivial game mechanics:
- How do we let a player know that an enemy bullet is, in fact, a hostile projectile and not a power-up? Do we pulse the bullet, making it bright red and obviously visible? Are the color schemes for power-ups and enemies substantially different? Once the code has been written for a bullet, these questions have to be answered.
- If the player can shield on demand, but the shield has a cool down, how do we communicate the cool down when the player shields too soon? How do we show how long a shield lasts?
- If the player can place a turret at a cost, how do we communicate the final placement of the turret and what constitutes valid versus invalid placement areas? How do we show the firing range of a turret? If it costs money, how does the player get money? How do they know how much it costs, and what happens if they don’t have enough money? If it can be sold, how? If it can be upgraded, how?
Every game mechanic requires a tremendous amount of deliberation and polish to prevent it from appearing as random noise to a player, and the great games that stick in your mind made this work look easy. Polishing a game mechanic to the point that a player will enjoy takes an order of magnitude more investment than the implementation of the feature itself.
While working on Galactic Fire, I added a ton of features that were heavily influenced by friends, other games, or whatever was going on that way. Tower defense mechanics, ship upgrades, bosses, weapon power ups, shields, invulnerability. You name it, it was in scope. Without any intervention, I’d never stop introducing new features that I felt provided the differentiation in the market that my game needed.
In shipping Galactic Fire, I cut scope by about an order of magnitude. All the stuff that was half-baked and required substantially more investment before making sense to players was shelved. Gone, or saved for a rainy day, a sequel, another game, or whatever. They exist now only in old YouTube videos highlighting features that seemed super important at the time.
Throughout development and play testing of Galactic Fire, I had a small handful of core gameplay mechanics that were consistently fun to everyone that play tested. Flying the ship around was fun, and seeing a large number of enemies blow up was fun. These were the tenets that I stuck to when cutting all the other features.
I started with dual-stick controls on the Xbox 360, then gravitated towards accelerometer input on the phone with an auto-aiming cannon. I removed tower-defense mechanics, and just spawned in a bunch of brain-dead AI that chased the player. And the game was just as much fun (arguably more so!) as it was when I had piles and piles of unfinished feature work.
4. Don’t Make Frameworks.
While writing the game, I didn’t know what I needed, but still felt compelled to make a framework that handled everything I might ever need for this game and the next. At one point, I even scrapped every single line of code to rewrite everything based on my lessons learned.
It was a dumb idea, I wouldn’t advise it. First priority is make a game and roll with the punches. Don’t make a library; get things done in whatever way you see fit and tally up lessons for the next project. Arriving at this conclusion came largely from looking through older open source games (Quake 3, Abuse!). I learned that you don’t need a message queuing infrastructure to display tutorial messages when “char* tutorialMessage;” can accomplish the same goddamn thing in the hands of a sufficiently motivated hacker.
Grokking these four lessons was the single biggest difference between my failed projects and shipping Galactic Fire. The game isn’t perfect and it isn’t what I envisioned at the start, but it’s done and I can hand the game to a broad audience of people who will start having fun with it right away. If you’ve got a backlog of failed game projects, these principles might help.