I've got about six pages of the next design document ready, but instead of posting that content today I thought I should probably back up a bit and explain (hey, it's Game Programming 101, right?) the overall theory on what's going on here.
When it comes to writing a big project, there are as many different approaches as there are developers. Over the course of my career I've found two practices that work well for me: top-down design, and bottom-up development. Mentally I picture the overall process as a giant letter V, and you can picture yourself drawing the letter as you proceed with your work.
When you begin, your pencil is in the upper-left of the letter: it's on the left because our timeline runs left-to-right, and it's at the top because the first thing we're worried about is the Big Picture for what the application is going to do. This is what my last hideously lengthy post was all about: a very rough sketch of how the game is going to be played, describing the major components and the general rules that will keep things moving. This is where about half of my projects stop: I get halfway through this process, and before I can go any further I realize there's some horrid fundamental flaw in the game:
- It's too complex to code
- It's too hard to explain to users
- It requires too many skills that I can't normally do myself (beautiful graphics, custom audio, etc)
- It's too repetitive. And it's too repetitive
- It's too similar to something else that already exists (my motto: if you can't improve it, don't rewrite it)
If by some miracle the new design proves worthy, then we're ready to start working our way down this side of the V towards the point. All during this time, we're going to be writing more and more designs--each more specific and detailed than the last. The idea is, we now know exactly how the game should work--what do we need to provide, in order to make the game work that way?
That's where I'm working today. The design spec I'm writing right now talks about those Modifier and Instant cards, and how I can make them work in the game. (If there wasn't a computer involved, this would be easy: just write "Sacrifice a creature. Deal X damage to all enemy creatures, where X is the sacrificed creature's power" on a piece of paper and everyone knows how to play. But for a computer, you have to find a way to encode that description as rules that the machine can follow.) These kinds of things--I'm calling them Effects--are critical to getting this game to work.
There are several design documents that that need to be written at about this level of detail. And when that's done, we'll move another step closer to the bottom of the V--trying to figure out what kinds of supporting technologies we'll need in order to make these Events work, and so on. At every step, we get more detailed and the problem narrows down to a more specific piece.
Finally we reach the bottom of the V, and we're about half-way through the project, without having written a single line of code (except for an interface written in a word document). See? And you thought it was all coding. :) You know you're at the bottom of the V--done with design, ready to code--when you either (a) are utterly confident that you can write this thing with your eyes closed given the current design, or (b) are so fucking sick of writing documentation that you can't stand it any more. I've done (b) many times, and it's usually a warning sign that the thing is too complex and you need to back up a bit and try again--but, of course, that never happens. Instead, I'll usually get a few more steps along and just abandon the overly difficult project in favor of something else.
Anyway, here we are ready to write code. We're at the bottom of the V now rather than the top: this signifies that, just as we were writing low-level design documents a minute ago, we're now ready to write low-level code. These are the most fundamental building blocks of the game, and most programmers have many of them sitting around already: memory management suites, hash tables, text manipulation suites, generic 2D and 3D engines and so on. If you're doing this as part of a corporate project, this stuff probably exists already and all you have to do is hunt it down; if you're doing it at home, you either home-roll what you need or you download someone else's engines and try to make them work for you. Either way, you don't have anything game-specific here--it's really just assembling your building blocks. (Personally, for C++ home projects I use "banshee"--it's a suite of toolkits that I spent three years developing in my spare time. For java projects I tend to rely on the hiptop's API and the java built-in toolkit.)
We're slowly moving up the right edge of the V. Now we start assembling those basic building blocks into some of the lower-level pieces of the game engine:
- a class that can load, save and represent in-memory a playing board
- a function that can scan through a set of game rules and select an appropriate piece
- a history process that lets the player undo and redo changes to the game state (take back a chess move, say)
Each of these pieces, it should go without saying, is best tested right now--while it's still separate and small and has a nice clean interface. That way you don't get surprised later when your application is leaking memory, and you find out only after weeks of painstaking study that it's your hashtable class--you have to be confident in your tools, or the result will suck.
Now things accelerate, and we're nearing the end. We're starting to write bigger and bigger pieces--bigger in scope, not in the amount of code required. We plug in the build-a-game-board piece with the draw-a-game-board piece and now we can see the current game on screen. Plug in the history engine and now you can take moves back and watch the pieces move around in response.
Finally we reach the top-right of the V, and the app is just about done. It's time for the finishing touches that turn an app into Something Compelling--and this is the fun part. Plug in the final audio and graphics (your multimedia team has been working in parallel, right?), and watch the game transform itself. Activate that high-score system, and plug in the main menu. Wrap it up in an installer and think about how to market it.
That's the overall plan. As you can tell, there's a lot left to do on Hero before I even think about writing code.