ID:99872
 
Keywords: design
Some people on BYOND seem to have an odd view of the design process. There's nothing wrong with putting a lot of emphasis on design, but we need to be clear about what design is and what it does for you so you don't go overboard. Hopefully this will put a more practical slant on things.

What Do we Mean by "Design"?

There are two types of design we can talk about:

Game design - designing the gameplay elements, what the players do, and what their experience is like

Software - two parts:
Requirements - Formal description of what the program will do
Design - Technical notes about the implementation details (in very low-level detail: function names, variable names, etc.)

This post focuses on the benefits of game design and software requirements, but not so much about the process itself. Much of this is written in response to IainPeregrine's Functional Specifications article. All quotes are from that article.

Iain's article proposes that programming without a design is like running a marathon without a finish line. He asks:

> How will you know when you're finished? How will everyone know when to get together, fill their glasses, and toast your success?

Is that really the problem?

I don't like the marathon metaphor because saying that you'll run a marathon defines the task. You want to run ~26 miles. You'll know you're done when you've run 26 miles. You might not have exact ways of measuring but you can use landmarks and your knowledge of how fast you run to estimate - but that's not the problem. The problem isn't that programmers need a finish line so they know when to stop. What happens if they don't stop and they run to Kansas, what's the programming equivalent of that? They added too many features to a game? The game is too polished?

The article also focuses a lot on what a design document is without explaining why they are helpful. I think it also misses the mark on why they're helpful.

> You need a functional spec, because it is your game.

My point exactly.

What Are We Designing?

When designing a game you know what the goal is (ex: make an RPG) and you might know some details (ex: it will be set in outer space), just like when you're running a marathon you know that you're going to run ~26 miles. The problem is that you don't know how to get there, how to make an RPG. There are lots of features your game could have, but which ones do you want it to have? Here is a better metaphor:

Suppose you want to go to Wichita, Kansas. You go to google maps, search for "Wichita, KS", see where it is, then run out the door and hop in your car. You have identified your goal (Wichita) but you don't know how you're going to get there. You'll have a lot of options (roads you can turn onto), how do you know what turns to make? If you don't plan your route you might make a lot of wrong turns and waste a lot of time.

Planning a route is the equivalent of designing a program. You might have requirements for your trip to Wichita. You might want to stop in certain towns to see museums or eat at certain restaurants. Similarly you might have requirements for your space RPG: you want it to feature both ship-to-ship combat and crew-to-crew combat by boarding another ship. Design is a way to specify and formalize these requirements for the program.

How Does Design Help?

Design has one big purpose that manifests itself in two ways. The big purpose is that you don't want to waste time. The first way that design works to achieve this is by forcing you to make decisions and stick with them. Ideas are easier to work with when they're in your head or on paper - it's easy to change your mind. If you've already written code to implement a feature and you change your mind about how it should work, you might have to re-write a lot of code.

Design also saves time because you can work through problems before encountering them. This is similar to the first point. You might think about two features for a while, decide on how you want them to work, implement them, and then realize that they conflict and you need to re-work them both. The design phase gives you a chance to see this problem and work on a solution so you don't waste time and have to throw away work.

Back to the Metaphor

The driving metaphor also handles these concepts. Suppose you're driving from Las Vegas to Wichita (link). You can take I-70 or I-40, they're about the same. You believe I-70 to be the more scenic route so you decide to take it. If you waited until you were driving to make that decision you might already be on your way to I-40 and need to turn around.

Suppose that you decide to take I-70 and you also decide to stop in Lubbock, TX. If you're going to take I-70, Lubbock is ~700 miles out of the way. If you take I-40 it's only ~200 miles out of the way. If you make both of these decisions before you start driving you can see the potential problem and resolve it in a way that doesn't involve driving 500 more miles.

Back to Programming

There are two kinds of problems: big ones and little ones. The big problems are the ones you want to catch in the design phase, the little ones can be dealt with as they come up.

> Now consider that a malicious user joins your game, double clicks one of your players, waits until it's his turn in battle, and then logs out. Now your regular player is stuck in battle unable to do anything.

This is a little problem. Implementing a solution won't require that you un-do existing work. This problem won't waste your time. A metaphorical note: a little problem would be finding a place to stop for lunch on your way to Wichita. The highway will have signs about local places to eat. You don't need to plan the stop in advance, you can look for a place when you get hungry.

You need to expect to deal with the little problems as they come up. There's no way to anticipate them all. You'll spend more time trying to anticipate little problems than you would spend dealing with them as they occur. Here's why:

> Once we take into consideration all input available to the player at every state in the program, then our programming job will be much easier, and we won't be sabotaging ourselves in the future.

Assuming the player can move in four directions and perform a single action, there are 510 = 9,765,625 different sequences of 10 actions that can be performed. Try verifying that none of those sequences lead to a problematic outcome! Think about how much harder this problem gets as we increase the complexity of the game. All we can do is hope for the best that the problems that result from the nearly-endless possible sequences of actions are all little problems, not big ones.

Conclusion

A design is a plan. Before performing an action you should always do some amount of planning. If the action is simple and familiar, like opening a door, you don't need to do much planning. If the action is more complicated or more foreign to you, you might want to do more planning. Because of these factors design cannot be formulaic. The same level of preparation that goes into a weekend vacation isn't appropriate for a trip to the moon. You know where you're going and how familiar you are with that territory, so you're the one who needs to decide how much design is appropriate.
A good read, you certainly speak with an air of authority, and I rather enjoyed what parts of Miner Adventure I could access, but your confidence in defining such an all-encompassing word as, "design" leaves me curious about what your qualifications are.

If this is coming from a fellow who's dabbled a bit in game design, that's a valid perspective, but something I'd regard differently than a fellow who's done professional software design for years.

It's the difference between, "sure, that's a good way of looking at it, but who's to say what's really odd about ideas of design" and "oh, well he's done this kind of thing a lot, and probably tried the alternative, so I guess he'd know what it takes."
You're a quick reader! =)

Geldonyetich wrote:
"who's to say what's really odd about ideas of design"

This blog post started as a comment on Iain's article, but quickly grew into an entire blog post. The "odd" view I talk about refers to statements like these:

From Functional Specifications:
These three sections are a must have.
Once you have this document you have a much better chance of completing your game.
The half hour you spend writing in a human language will save you months of writing computer code.

Which imply that design is some simple, formulaic process - take 30 minutes to answer a short questionnaire about your project and shave months off development time! It just doesn't work like that.

Edit: There was also a comment I read (but forget where) suggesting that a complete design was of such great importance that the complete design should precede implementation. My aim was to show that design, as far as programming goes, is meant to catch some problems, not all. By trying to catch all problems you'll waste more time in the design phase than you would spend fixing problems as they come in the implementation phase.

Edit #2: I'm glad to see that I'm not the only person who revises comments several times after posting them. They need a preview feature for people like us!
Forum_account wrote:
Edit #2: I'm glad to see that I'm not the only person who revises comments several times after posting them. They need a preview feature for people like us!

Indeed, chronically so do I ;)
Yeah, it was probably me who said a complete design should precede the code. For that matter, I think I picked up the idea from a comment from the Ultima Online 2 devs.

However, I'm changing my tune lately. There's a certain problem with visualization that gets in the way of having a complete design before writing the code. Maybe the UO2 devs knew what they were doing well enough to pull that off, but I sure don't!

So I'm in general agreement with here that the design is a plan, it's necessary to know how the greater wholes of the thing you're trying to build will fit together, but aside from that you're free to more or less muddle through.

It's dicey, though, as you may not know until it's too late what a greater whole is versus an intricate detail that can be put off. This can result in the floor being pulled out from under you unexpectedly.
Geldonyetich wrote:
There's a certain problem with visualization that gets in the way of having a complete design before writing the code

Since no article about software engineering is complete without a quote from The Mythical Man-Month:

"Plan to throw one away; you will anyhow"

Sometimes the easiest way to figure out how to write a piece of code is to try, screw up, and learn from your mistakes.

When you are planning to create an RPG you try to predict what problems will come up. If you don't have much experience in making RPGs you'll probably fail to predict most problems. You could spend months theorizing about what issues you could run into, or you could jump in, start working on the RPG, and see what issues come up. That's not to say the design phase is useless, but sometimes it's not the best way to spend your time.

Yeah, it was probably me who said a complete design should precede the code.

I think it was something tsfreaks said in this thread, but I'm not sure. I've seen the notion of a "complete design" thrown around a few places here, I'm sure that wasn't the only time. I kind of mentioned this in the post but should stress it more:

Your design is never complete. I did mention how taking "into consideration all input available to the player at every state in the program" is not feasible. For this reason your design cannot be complete, you can't possibly account for all contingencies. If you believe your design to be complete you're in for a rude awakening when you hit a problem that you hadn't anticipated (assuming you're even on the lookout for problems).

A complete design would also take into account the evolution of the program. Like considering all input available to the user there are a million directions the project can go in, you can't cover them all. This is especially true in an environment like BYOND. The evolution of your game will be heavily driven by player feedback. This issue illustrates the same paradoxical situation that leads to the idea of planning to throw one away: if you knew what the players wanted you could make that, but how do you know what the players want? Often the easiest way is to make something, listen to player feedback, and adjust the game accordingly.
Assuming the player can move in four directions and perform a single action, there are 5^10 = 9,765,625 different sequences of 10 actions that can be performed. Try verifying that none of those sequences lead to a problematic outcome!

This gets to the heart of my article, only in reverse. Consider a 5 by 5 tile room with a button in it. The button is activated by stepping on it, and ends the program immediately. In this program there is absolutely nothing else. Now, give the player these 10 actions to perform and count the number of different sequences. Sure, if he moves left, then right, then up, etc., then that is different from another sequence started by moving down, so there are a lot of sequences. Now count the number of outcomes after those 10 actions: 2.

1: The player moves around and at some point steps on the button. The program closes.

2: The player moves around ten times and doesn't step on the button. The program is still running.

See what we did there? We collapsed those thousands of different sequences into single actions based on transitions of state. A good designer can turn his game idea into a flow chart and chart out every possible transition. This is how Regressia and every program I've made after it has started: with a series of flow charts.

I guess all of this is nothing but an academic exercise if a developer still have not taken control of the BYOND suite, and are letting control flow wander like spaghetti through a 5^10 different objects.
Using flowcharts for verification is similar to cyclomatic complexity. When the function has no side effects you can prove correctness by verifying the correctness of each path through the function. This would let you verify that movement is correct by considering only the four moves instead of worrying about all possible sequences.

The problem is that movement has a side effect: your position changes. If you have a 5x5 room and the player starts in the middle you can verify that the up, down, left, and right moves work. However, the sequence "up, up, up" moves you off the edge of the map. The side effect of movement leads to a situation that is problematic and outside of the function you're dealing with.