Saturday, July 18, 2009


Being fascinated with computers and also with programming them, back when I was a teenager and the TRS-80 and VIC-20 were the height of technology, I was intrigued by text adventures like Willie Crowther's seminal "Adventure" and its more-widely-known successor and imitator, "Zork". Not only were these games fun and challenging to play, I also was driven by wondering how they were written.

Clearly it couldn't be that each room, each prompt, each action was its own bit of code; even a few dozen rooms with a couple of interrelated puzzles would be thousands of lines of code, which was unfathomable in those days. So instead there must be some kind of general-purpose engine for handling rooms, objects, and all the multiple-word commands used to work through them, along with an impressively large data structure that somehow encoded all of these things and the relationships between them.

This seems pretty trivial today, but at a time when writing a program to sort a list of cities by average temperature was a tricky proposition (since you couldn't keep the whole list of cities in memory at one time), the idea of coding something like Aventure was a bigger puzzle than the game itself.

When a friend got a Commodore 64 with its amazingly roomy 39,000 or so bytes of usable memory, I spent an embarrasingly large amount of time programming it. I couldn't afford my own computer, so I wrote out BASIC code longhand on legal pads and then went over to his house and keyed them in while he did other things. I would often have to save them halfway-keyed and hope next time I came over he (or his younger sister) wouldn't've erased them, so I didn't have to start over. I would write down what happened so I could debug them later at home and come back with changes.

It was during that time that I decided to make a stab at a text-like adventure game, but having not yet cracked the mystery of how to make something like Adventure, and wanting to make a game that was different every time, I made one with a 10-by-10 grid of rooms with random contents. I would randomly thus build this "dungeon" and place doors in random places (some secret); the programming to make sure that no part of the dungeon was inaccessible was actually the trickiest part. Each room would then be seeded with contents: some would be empty, or have a monster, or some treasure, or a trap, or a puzzle. Monsters would have to be fought (in a rather simplistic simulation of D&D combat in which your choices were only to attack or flee) to obtain treasure or the chance to continue. Traps had a chance of doing damage and might also contain treasure. For puzzles, the trick was having something that could be algorithmically generated, so there were a few "canned" puzzles which could be built from random numbers, such as "what is the next number in this sequence", and very little in-game pretext for why you had to answer them; they also yielded treasure. Treasure could be traded in for increases in your stats.

At that, it was a mildly amusing pastime, not unlike a lot of the games of the time in that it was repetitive and purposeless and yet fun (heck, I can't count how many hours I spent playing Depth Charge), though a bit clunkier than many (the random map part was particularly troublesome despite my efforts to improve it). But I decided to add a few more features and then a few more and then a few more and it started to get pretty silly.

Having a matrix of rooms with each having a room type (0=empty, 1=treasure, 2=monster, etc.) I started to make additional room types that I would only have appear once each in the grid somewhere. (Basically, the routine would put a random "regular" room type in each room, and then go back and randomly assign each of the "special" rooms once.) These started fairly simple and grew more elaborate. First, a room that let you gaze into a pool and see what was in some other randomly-selected room before you got there. There was a random teleporter room. Stuff like that.

That's when I started to get silly. I had a room with a bigger monster whose treasure was a captured sorceress-princess, and if you defeated the monster, you could free the princess. But I made it goofy. If you rescued the princess, she would smell you, turn her nose up at your nasty odor (you had, after all, been bashing your way through a dungeon), and then give you a paltry sum of gold and leave. However, another one of the special rooms was a shower, and if you went into it and used it, "You are clean and fresh-smelling" would appear on your SCORE from then on, and if you rescued the princess in that case, she would kiss you and teach you a spell before leaving which you could use in later combats.

The last thing I added was a room with a computer in it, and when you used it, the screen cleared and you got a menu in a different color. So there was a game within a game, and one of the menu items was, in fact, an Asteroids-like game, which actually worked. Nothing you did in-character on this computer actually had any effect on the larger game, it was just there for the sake of having an entire game within the game, and the silliness of that.

That's about as far as I got before the game imploded or got erased or something, and I never tried again. I was never terribly satisfied with the fact that, for all the goofy special rooms, it was never anywhere near to a general-purpose engine for the kind of game that inspired it. And I was also never happy with my inability to think of a name for it. At some point I called it Zirconia because I couldn't think of anything but the computer wouldn't accept "I don't have a name yet.bas" as a filename, and then I never managed to find something better. But it was a terrible name and I never considered it anything but provisional.

I still don't really know the inner workings of Zork's engine (called ZIF) but I bet I could go find an explanation online in five minutes, though that wouldn't have the satisfaction of figuring out a technique myself. Not that I really have time to think something like that through these days, let alone implement it, and even if i did, how silly would that be? ZIF of course can run on cell phones and practically on watches nowadays, and there are web-based games a thousand times more complex, and today a console game will spend more computing power on getting the quality of the reflectivity of an eyeball on a single character in the background right than entire games used back then.

No comments: