Home


Search

Back issues

Guestbook

Community

Related links

Subscribe

FAQ

XYZZYnews

Lessons Learned the Hard Way

Tried-and-true advice for creating your first game

by Jim Aikin

One of the things I love about the IF community is the do- it-yourself vibe. If we took a survey, I'll bet we'd find that more than half of the folks who play text-based adventures have at least thought about writing their own game, or even drawn a map. Many of us have downloaded a software development system at one time or another, if only out of curiosity -- to see just how tough it would be to turn our wild-eyed ideas into a real game that others could enjoy.

In January of '99 I decided to take the plunge. Six months later, my game -- a large, puzzle-studded story called Not Just an Ordinary Ballerina -- is in beta, and the bug reports are rolling in. Along the way I did a lot of things wrong, and a few things right. If you've ever thought about going this route, maybe I can save you a little pain by sharing some of the lessons I've learned. Not so much about the specifics of programming or dreaming up effective puzzles -- though I learned a lot about that too -- but about how one approaches the process. And if you're happy as a clam letting others do the hard work of making games, maybe you're curious about the sort of contortions programmers put themselves through.

The ideas below do not all originate with me. I've benefitted immensely from reading online essays by others. But now that I've done it myself, I have a keen appreciation for what those other writers were talking about. I've been using Graham Nelson's Inform software, by the way, but all of what's said below should be just as applicable to developers using other systems.

1. You can't beta-test your own code.

You can (and must!) alpha-test your own code, to make sure it does what you intended it to do, and to spot all the errors you can. But in a thousand little ways, not to mention a few big ones, you will fail to notice problems that others will stumble over.

These problems come in several flavors.

First, you'll miss some obvious verbs. I implemented 'shoot revolver', but never considered the obvious synonym 'fire revolver'. (And here's a technical point of the sort that programmers have to foozle over: 'shoot' and 'fire' are not true synonyms. The input 'shoot thief' is NOT the same as 'fire thief', so each verb needs its own grammar, even though both end up triggering the same action.)

Second, since you know how the puzzles are supposed to be solved, you won't think of three-quarters of the ways that your players will try to poke and prod at the objects they encounter. Since there are no objects in Not Just an Ordinary Ballerina that can be pushed over or pushed from place to place, it never occurred to me to test 'push trash can'. The only pushable objects, as it happens, are number buttons. When my testers tried pushing the trash can, they gleefully reported that the game responded, "Sorry -- please enter one digit at a time." Big oops.

Third, you probably have an idea about what order players will solve the puzzles in. And you're probably wrong. They may (depending on how you've designed the game) find the rusty iron key and opened the creaking door before or after they've crossed the swamp and met the talking alligator. This may have important consequences. The alligator might fail to notice something obvious about the player's appearance. Worse, the game might easily become unwinnable.

Fourth, quite likely your room descriptions will refer to objects that testers will want to pick up, examine, open, climb onto, eat, and so on. Since you know those objects are strictly scenery, you may be tempted to just write the room description and get on to the more interesting part of the code. Your testers will mercilessly demand that you finish the job.

And by the way, writing a short but convincing explanation of why the player can't carry the garbage can over to the broken drain pipe and climb up on it is likely to tax your ingenuity. You may end up deciding that it's easier and more realistic to implement that action as an alternate solution to the drainpipe puzzle.

2. Do a complete walkthrough before beta-testing begins.

I had tested each of the puzzles and rooms individually after I finished coding it. So of course I knew everything would work, right? Wrong. In my walkthrough I found three fatal errors -- bugs so serious they would render it impossible to win the game.

One error was a door that I'd forgotten to give a name. During the initial phase of development, I had left all the doors standing open so I wouldn't have to constantly be unlocking and opening them while I was running around in my little world. It was only in the walkthrough that I tried "open lamp store door" and got "You can't see any such thing." That one was simple to fix; the other two were much worse.

3. A good beta-tester is a gift from the Almighty.

Good testers will bring up all of the issues I've just touched on, and more. They will point out things that confused them. They will tell you when they get, as one of my testers said, "very, very, VERY annoyed" by a puzzle or some other condition that you've set up (either deliberately or accidentally). They may also, if you've done a good job, cheer you on by telling you how much they like the game. This will help a lot when you're suffering an acute attack of embarrassment because you forgot to implement any exits at all from one of the rooms, or failed to notice that when objects were dropped from the top of the telephone pole, they STAYED at the top of the pole (hanging in mid-air, one presumes) rather than plummeting to earth.

Treat your testers courteously. Tell them you appreciate their hard work. Respond in a timely manner to their bug reports, and thank them for finding problems. To whatever extent you can, don't be defensive. Even if you think a tester has suggested something ludicrous, something that would weaken the game, I recommend responding, "That's an interesting idea. I'll think about it." Not that any of MY testers have suggested anything like that -- I'm just saying, if they did.

4. Be as systematic as humanly possible.

Draw maps. Make charts. Keep lists. I did as much of this as I could, but inspiration kept getting in the way. My lists would become obsolete, and then I had to decide whether to take the time to update the list, or whether to spend the time actually working on the game. Months later, I'm sitting in front of the computer thinking, "Did I call that object Winter_Coat, Coat, or Overcoat?" I'm wasting more time opening up various files of source code and searching for text strings than I would have if I'd kept a good, alphabetized list.

Yes, I did draw a good map. But the names of the rooms in the map don't always correspond with what I called certain rooms in the code. Bad idea. Hair-pulling ensues. Also, for quirky reasons, I drew the map upside down, with south at the top. If there are no rooms with mixed-up exits, it's a miracle.

Right now I'm debugging. Do I have an up-to-date "to do" list of fixes that need to be implemented? Nope. I look at a complaint in a bug report, start fixing it, think of three more things I really OUGHT to do, do two of them while I'm thinking of it, get up to make a cup of tea... and two days later I can't remember whether I did the third one. Doubtless you'll be better organized than this.

One system that did work well for me, early in the design process: I created a flow chart showing the order in which the puzzles needed to be solved. The beginning of the game is at the top of the page, and various lines flow down the page with cryptic names showing where the puzzles are in the logical flow. For example, you have to solve the fallen beam puzzle in order to get at the object with which to solve the rats puzzle, and until you've dealt with the rats you won't have access to the model train. So there's a vertical line running down the page that has the beam near the top, the rats in the middle, and the train near the bottom.

This kind of chart will show you instantly if you've created a circular logic situation, in which you have to solve A before B, B before C, and C before A, thus rendering the game unwinnable. It's also a good way to check that you're giving your players a variety of puzzles that they can work on at any given time. If you've got one long line running down the middle of the page, with no side- branches, players are likely to get bored.

5. Some coding will become obsolete long before the game is finished.

Especially if you're developing your first game (or maybe your second or third -- ask me again next year), your concept will grow and change in major ways as you go along. Ideas -- both organizational ideas and actual puzzles -- that seemed good at the time will prove unworkable. New ones will occur to you, but may prove difficult to implement, given what you've done already. Efficient ways of organizing the development process will occur to you only after you've spent weeks blindly blundering forward and making a mess of your code.

6. Consider the design of any complex software object VERY carefully.

I learned this the hard way. Here's a simple example, which could be elaborated tenfold:

If the player has switched off the TV already and then pulls the plug, you don't want the software to report, "The TV screen goes blank." The screen is already blank. But if the TV is on when the plug is pulled, "The TV screen goes blank" is the desired output. So the cord object needs to send a message to the TV object, saying, in essence, "I've been pulled." The cord itself doesn't print out a message at this point, because it doesn't know what the current state of the TV is.

The TV object decides whether to print a message. It reports back to the plug object -- probably returning a 'true' from the function that was called by the plug object if it printed a message and returning a 'false' if it didn't. If the plug object receives a 'false', it knows that it still needs to print its own message, but if it receives a 'true', it knows that the player has already been given the correct message.

No, wait a minute -- what about the SCREEN object? Is that different from the TV object? If so, shouldn't the TV object tell the screen object to go blank and then report its state to the player? How many layers of code will the pull-the-plug action have to pass through?

A couple of the objects in my game can get into as many as a dozen different states. In trying to keep track of it all and print out the proper messages (while learning Inform at the same time) I wrote some really messy code. I may end up having to rewrite a couple of objects from scratch before I release the game. I hope I won't have to, because I'm no longer 100 percent sure what some of those functions are doing. Which reminds me...

7. Comment your code. Comment your code. Comment your code.

8. The combinatorial explosion is real.

I love that term, and throw it into casual conversation whenever I can. What it means to a game designer is this: Every time you add one object to the game, you have to consider how it may need to interact with every other object in the game. In essence, by adding one object you're potentially DOUBLING the number of interactions that may need to be allowed (or disallowed, with appropriate "you can't do that" messages). Add two objects, quadruple the number of interactions. Add three objects, multiply by eight. In practice, the problem isn't quite that bad, but it's entirely bad enough.

At some point in the development of my game, I decided that one of the puzzles would involve climbing up a stepladder, so I added a stepladder object that could be carted around. Then I realized that the stepladder would create an unintentional solution to a second puzzle (which involved a hole in the ceiling), so I had to decide whether I wanted to allow that, and if not, how to prevent it. By now the stepladder can be used in four different ways -- and if my testers suggest any others, I'll have to implement them as well.

I could go on about that darn ladder all afternoon: If the player sets the ladder down and then types 'up', that's the same as 'climb ladder'. But if the location happens to be one where there's also a flight of stairs you can go up, will the player climb the ladder or go up the stairs? What happens if the player tries to climb the ladder while playing the bagpipes (which requires both hands)? It's messy.

For EVERY container, you have to think about ALL of the objects that players may try to put into it. Got a coffee cup in your game, and a can of gasoline? Be careful, because somebody is going to type 'pour gas into cup' followed by 'drink'. The response, "Ah, fresh-brewed French roast" is not going to endear you to players. And what happens if they carelessly put a full cup of coffee in the rucksack? Will it spill? Are you going to give every other object in the game a soaked_in_cold_coffee variable? I hope it won't come to that.

For everything breakable, you need to think about all of the ways it can get broken. If you have a fire source, you have to consider that the player may try to ignite any other object in view. The default response, "That's plainly not flammable," is fairly silly in response to 'burn the scrap of paper'.

Ultimately, full verisimilitude is not achievable -- not in a text game and not in any other kind of IF, either. There will ALWAYS be objects in your software- modeled world that the player will try to pick up, examine, taste, or smell, only to learn, "You smell nothing unexpected," or, worse, "You can't see any such thing." But if you do your job right, your miniature universe will be deep and involving enough that players won't really mind. They'll have plenty of other things to try.

Jim Aikin is the senior editor of Keyboard magazine, and an expert on music software and hardware. He is also the author of two science-fiction novels, Walk the Moons Road (Del Rey, 1985) and The Wall at the Edge of the World (Ace, 1992).


[right arrow] Go to the next page in this issue
[left arrow] Flip back to the previous page
[top arrow] Go to the XYZZYnews home page
This site is maintained by Eileen Mullin
Legal information