Sunday, February 06, 2005
Losing Your Limits Without Losing Your Mind
It was 1982, and anything was possible.
I had started programming at the age of twelve on the Singlair ZX80. That machine had all of 1K of RAM, and no "memory-mapped video" ... which meant the screen blanked out every time the CPU had to do something other than constantly refresh the screen. There was room for maybe one page of code, total. It made game programming pretty hard.
My dad pre-ordered the Commodore 64, which I dreamed about for weeks. I was designing videogames and adventure games on paper while I waited, anxious to get going during summer vacation on a games that were going to be equal or better to anything else out there. Unfortunately, by the time the C-64 was actually released, school had started. That didn't stop me from spending my evenings and weekends on the machine, learning how to harness the machine's incredible power. I'd go until late at night, the stereo next to my machine playing softly (to avoid my parent's wrath, and I usually didn't feel like wearing headphones).
My programming skill at the time was still pretty rudimentary. The ZX80's version of BASIC was pretty minimal - and you couldn't write more than a page of code for the thing anyway. While I was learning to put pictures on the screen, I was also learning to do string manipulation to do a text parser for an adventure game. I'd tried this on the ZX80, but the awful memory limitations prevented me from doing anything really interesting. But I had an idea of HOW I would do it, as soon as I had the machine with enough capability to meet my vision. In 1982, with the Commodore 64, these limitations were removed. Time to get going!
The problem was that I was still in spaghetti-code-ville writing in BASIC, and hadn't quite gotten the grasp of how to avoid hardcoding everything, or how to properly re-use code. So my attempts at adventure games were really ugly - every room effectively had it's own section of code that had to handle everything that might be done in the room. I did have the sense to break out my rudimentary text parser into a subroutine, so the rooms didn't have to repeat the parsing logic. But still my code looked something like this:
900 PRINT "YOU ARE IN A FIELD BY A BABBLING BROOK RUNNING"
910 PRINT "NORTH AND SOUTH. YOU CAN FOLLOW THE BROOK"
920 PRINT "OR FOLLOW A PATH EAST INTO THE WOODS."
930 IF LANTERNLOC=5 THEN PRINT "YOU SEE A LANTERN LAYING ON THE GROUND."
935 IF SWORDLOC=5 THEN PRINT "SOMEONE LEFT A SWORD HERE."
949 REM GET COMMAND ROUTINE
950 GOSUB 9000
960 IF CM$ = "GO NORTH" THEN GOTO 1100
962 IF CM$ = "GO SOUTH" THEN GOTO 1200
964 IF CM$ = "GO EAST" THEN GOTO 1300
966 IF CM$ = "GET LANTERN" AND LANTERNLOC=5 THEN GOSUB 9600
966 IF CM$ = "GET SWORD" AND ITEMLOC(1)=5 THEN GOSUB 9620
968 IF CM$ = "INVENTORY" THEN GOSUB 10000
970 IF CM$ = "LOOK" THEN GOTO 900
999 GOTO 950
It worked, and in theory I could have created an entire adventure game this way on the Commodore 64. There was enough memory to handle it, and CPU limits aren't exactly a bottleneck for text adventures. But just because I could do it didn't mean I should do it. Fortunately it was pretty clear to me that this was the wrong way to do things, and that I'd have a nightmare trying to make a game larger than eight rooms using this kind of programming.
A friend of mine, Kevin McCarthy, was staying the weekend with me. We were doing some "Midnight Programming" on adventure games that night (term cribbed from a book I'd already started to read by then, "The Soul of a New Machine"). Kevin was starting to lose it already, as it was pretty late. Then I had the little breakthrough in understanding of making the rooms data-driven so that one routine could handle all possible locations. A simple idea, but a pretty big step for a 13-year-old who was still a beginning programmer.
I turned the descriptions into an array of strings with an index into them based on room number. I also built an array of exit names, exit locations, and indexed them based on room number. I quickly whipped a map of about a dozen rooms and exits. Only the first six had any detail - the remaining rooms had one-line descriptions like, "THIS IS ROOM #9.". But I linked them together with exits, and wrote some code where rooms were handled with a single subroutine.
Kevin was only barely conscious by the time I ran the code. We had a couple of false starts where we encountered syntax errors, which we rapidly corrected. The radio started playing a song by Saga, "Wind Him Up" - curiously, a song about a compulsive gambler. And then... it all worked. It ALL worked. The song became victory music as we walked around our hastily-constructed map, finding that everything was working perfectly, and that making a change or adding a room took an insignificant change instead of the monstrous task it had been before. I had figured out how to create an adventure game. Kevin and I congratulated each other;I made a couple more tweaks to our proto-game and enjoyed a few more minutes of playing around in it. Then we saved our work, and got some sleep before beginning a great Saturday of hitting the local Arcade and playing some Dungeons & Dragons (it's funny how my view of what constitutes a great Saturday hasn't changed much).
The next few days had me furiously working on what was probably my first "complete" game, the adventure game with the vastly overused title, "Dungeons of Doom." It even had some sound effects, color, and some minor animation. I think it had somewhere around 40 rooms altogether. Next was "The Secret of Red Hill Pass", which clocked in at well over twice the size of Dungeons of Doom - not to mention a much smarter parser and many more advanced capabilities.
I bring all this up because I just heard that Saga song again, and it brought back the old memories. Nice motivation when I'm banging my head against the wall trying to learn the Torque engine (I'm a beginner again) while working on a cool new game. Of course, there's probably a point or two here somewhere. Here's my take:
It's now 2005, and anything is possible.
We live in an age now where the possibilities of computers for entertainment have far surpassed most of our wildest imaginations in 1982. Sure, we'll bump up against the limitations of our platform from time-to-time, but that's not the big issue anymore. Instead, we sometimes forge ahead so quickly to exploit the capabilities of the technology that we don't step back and question whether or not we should.
Sure - we can make our game fully 3D and give the player an unparalleled level of control and realism. But is that really the best way to go? Is it the best for the game and the gamer, or would 2D gameplay actually provide a better experience? You can now deliver a game to the user with 500 different weapons and 300 unique levels --- but do you have the tools, experience, and manpower to do it? And even if you do, is it really going to be better than a game with 5 weapons and 30 unique levels?
Step back, evaluate, simplify, and organize. Just because the old limits are gone doesn't mean you are you in any way obligated to go beyond them. It just means that now YOU are the one in charge of imposing your own constraints and framework to your games. Make sure you are doing the right thing, and doing it in the right way.
And if you find yourself hardcoding very similar chunks of code, think hard about whether or not it would actually save you time to make it data-driven.
Labels: Adventure Games, programming, retro
Comments:
Links to this post:
<< Home
Man, I wrote that at like 2:00 AM - I probably shoulda been coding instead of writing, but it was kinda fun being in that zone.
BTW, I wrote that BASIC code on a C-64 emulator - I even wrote the subroutines which it called. Just to make sure my code was vaguely correct.
Nowadays, it seems silly that I didn't understand such basic principles, but ah well.
BTW, I wrote that BASIC code on a C-64 emulator - I even wrote the subroutines which it called. Just to make sure my code was vaguely correct.
Nowadays, it seems silly that I didn't understand such basic principles, but ah well.
Awesome.
Wouldn't it be neat to have a formal list (on a web page) of every non-trivial piece of software you've ever worked on, with screenshots?
Also, I totally agree with step back, evaluate, simplify, and organize. "Simplify" is a HUGE thing for me with game design and other projects. I wish I could more successfully apply the principle to my life as a whole.
Oddly, the Game in a Day contest is a cool chance for me to explore some more basic simple ideas, but a BAD place for me to be coding data-driven stuff. :)
But aside from that, data-driven development rocks. My rule of thumb (when working with a full team - it's somewhat different when it's just me) has generally been that the third distinct time I adjust a value (or add to a table of hardcoded values) is when I should be moving it out into data. Naturally, you can often predict what pieces of data these will be, and implement them data driven in the first place.
Another rule of thumb is that the *first* time an artist stands and looks over your shoulder and says "Make it more blue" is when you should be pushing things out of code into data so they can do their OWN dang tweaking.
I've been thinking about doing my own blog, and data-driven game production would be a top topic for me to hit.
-- stay
Post a Comment
Wouldn't it be neat to have a formal list (on a web page) of every non-trivial piece of software you've ever worked on, with screenshots?
Also, I totally agree with step back, evaluate, simplify, and organize. "Simplify" is a HUGE thing for me with game design and other projects. I wish I could more successfully apply the principle to my life as a whole.
Oddly, the Game in a Day contest is a cool chance for me to explore some more basic simple ideas, but a BAD place for me to be coding data-driven stuff. :)
But aside from that, data-driven development rocks. My rule of thumb (when working with a full team - it's somewhat different when it's just me) has generally been that the third distinct time I adjust a value (or add to a table of hardcoded values) is when I should be moving it out into data. Naturally, you can often predict what pieces of data these will be, and implement them data driven in the first place.
Another rule of thumb is that the *first* time an artist stands and looks over your shoulder and says "Make it more blue" is when you should be pushing things out of code into data so they can do their OWN dang tweaking.
I've been thinking about doing my own blog, and data-driven game production would be a top topic for me to hit.
-- stay
Links to this post:
<< Home


