ID:83278
 
Imagine a group of runners who have set out to run a marathon. They train for months to get ready, and come the big day they gather at the starting line wearing their Nike's, tank-tops, and running shorts. They're hydrated and ready to go.

The starting gun fires and off they run. Some are determined to run the fastest, others want to pace themselves and run efficiently, while others are going to pull themselves through on shear willpower. The problem is that no one knows where the finish line is. In fact, no one thought far enough ahead to make an actual finish line. The guy in charge of the route figured that everyone would simply stop once they had run "a marathon", because everyone would be able to tell when that had happened.

Some people turned back at around 5 miles, right when word reached them that there was no exact finishing line. Others turned back after about 10 miles when the road split and no one knew which way they were supposed to go. At around 20 miles hardly anyone could see each other or knew where the race was, and they became despondent and gave up. At 30 miles people were too tired to continue, and just didn't care. Some people, determined not to give up, continued to run until they saw the sign for Wichita, Kansas. How long have we been running, anyway?



Starting to write the code for a program, without first completing its design, is like running a marathon without a finish line. How will you know which roads to avoid? How will you know when you're finished? How will everyone know when to get together, fill their glasses, and toast your success?

It's easy to make mistakes when planning, though. So how will we know what to plan?

A program, at its core, is just input and output. If a program can accept input from the user and then output the correct results, then the program is working properly. So to plan our program, what we need to determine is the input and output.

"But what about our Jutsus! What about our class structure, and storyline!" Yes, those things are important, but not at the moment. The sorts of things that we need to plan are "The user will enter a combination of key strokes to execute a jutsu", or "A user will be able to select his class", or "When the player finishes entering his character's name, the opening movie will begin to play and introduce the story". These statements tell us exactly how the user will interact with our program, and they give us concrete systems that need to be programmed. If we were to write a list of such statements, then all we'd need to do to finish our game would be to go down the list checking off items until they were all gone. Then our game would be finished, Cheers!

All we need to know now is what to put on that list. The answer: Everything. Everything that a user can do needs to be on that list, in every combination. Here's an example illustrating why:

Let's say our list had these two entries: 1) players can double click another player to start a turn based battle; 2) players may not leave battle until one or the other is dead or runs away. 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. We forgot that when the program is in the state where two players are battling, each player still has the ability to input a window closing command. So we need to write another line: 3) if a player becomes disconnected while in battle, he has one minute to reconnect, after which the other player wins. 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.



This list of actions that the player can take is what's known as a Functional Specification, or Func Spec for short. Func Specs come in many different forms, and most of them don't look anything like the one I'm going to show you. Think of this as an introduction for the BYOND developer. (Here's more in-depth article on Functional Specs).

When planning this article, I started writing a spec for a simple program with which I could illustrate the concept. My first attempt was the Snow Monkey Simulator (which illustrated a different concept). The concept that I finally came up with was a 'Game Chat' environment. The current spec, which may someday become an actual BYOND program, is version 12 (I think) and can be found here.

Notice how this spec has several categories. At the top is the name of the project, and a brief description of its purpose and Core Functionality. This is the statement of why the project exists in the first place. Everything else flows from and supports this functionality.

Next is the main body of the spec (simply titled "Specification"). Notice how most of the statements start by mentioning that this is something initiated by the user. The specification describes what the user can do, and how our program will respond. (I will admit the first several entries are not very good. In my quest to document EVERYTHING, I forgot to write in understandable English. Future versions may remedy this.)

After the main body, you'll notice three other sections. Ever got a great idea for a cool feature? Ever put that feature into your game, only to see your original project bloated by hundreds of non-essential features, while your saving system still doesn't work? Programmers will never give up on a feature, so we need to put them somewhere where we know they'll be safe. The ideas under consideration, for future versions, and even the section on forbidden ideas, will do just that.

The ideas under consideration are features I feel would support the core functionality, but either are not needed or not yet concrete. Some of these features, like the filters, will definitely be added to the spec; all they're waiting on is a statement of exactly how the user will interact with them.

Ideas for future versions are really good ideas that would support the core functionality, but are not essential. These are put on hold until future versions, so we can get a 1.0 release out the door.

Finally, there are the ideas which WILL NOT be put into the product. These are ideas which are really cool, and we don't want to forget, but detract from the core gameplay, or would sink the project. This category is also for ideas other people think are cool and will try and lobby to be added to the spec, yet you think are detrimental to the project.

These three sections are a must have.



To wrap up, let me say this: You need a functional spec, because it is your game. Before any code has been written, before any art has been drawn, before any sound has been recorded, you need to take the nebulous ideas floating around in your head and translate them into concrete rules. Once you have this document you have a much better chance of completing your game.

As an added bonus, you also have a much better chance of getting people to help you! Imagine if you could go to the forums, and instead of saying "I need an experienced coder and iconner and mapper", you could post a link to your document and say "This is what I need done". A programmer will be a lot more willing to work with you if they know, up front, exactly what needs to be done and how much time it should take.

So next time you're tempted to open Dream Maker, even if you're going to work on a project you've already started, take the time, instead, to sit down and start a functional spec. The half hour you spend writing in a human language will save you months of writing computer code.
"So we need to write another line: 3) if a player becomes disconnected while in battle, he has one minute to reconnect, after which the other player wins."

Most modern games only give you a few seconds. =p

It's a very good and often overlooked point though. Until recently my current project was actually missing a few on-logout events which could potentially glitch up the game.

Due to the nature of this type of bug, more often than not there wont even be a runtime error flagging them down. They can be very troublesome to locate and patch if you don't take necessary precautions ahead of time.
It's almost criminal that this post will be overlooked. Planning is 80% of the job.
"Finally, there are the ideas which WILL NOT be put into the product. These are ideas which are really cool, and we don't want to forget, but detract from the core gameplay, or would sink the project. This category is also for ideas other people think are cool and will try and lobby to be added to the spec, yet you think are detrimental to the project."

This is such a great design route to take. Various times in the past I had created a small project and the core idea ended up being completely different than what I intended due to players suggesting "cool" ideas.

Great article Iain, I added a link to this on my blog as a guide line to game development. This should hopefully help me with future endeavors.
Thanks for the post! As someone who only follows the programming world from a hobbyist standpoint its good to have information on how this is actually done. I've taken so many computer science related courses, and none of them have covered this aspect of programming.

Incidentally, how about an article about UML and programming (or anything else that's used)? I could use an article about how to effectively diagram a program before its built. In a database class I had once we designed the databases in Visio and I was amazed at how much more effective my database designs became. Anything like that for programming?
Rockinawsome wrote:
As someone who only follows the programming world from a hobbyist standpoint its good to have information on how this is actually done.

I guess I come across as sounding professional, but you should know that I have no professional experience or formal training when it comes to programming. I'm just a hobbyist as well, albeit one who's been doing it for a long time now.

Incidentally, how about an article about UML and programming (or anything else that's used)?

I never liked UML, and that's probably because I don't understand it. Perhaps the problem is that it's redundant for me; I do a lot of planning via diagrams on paper.

In a database class I had once we designed the databases in Visio and I was amazed at how much more effective my database designs became. Anything like that for programming?

Like I said, I don't use UML, but I do stress the design process. I like to think that the programming phases of my projects are completed on paper before any line of code is ever writen. If you're trying to design your program as you're writing the code, you're basically doomed.
This article presents a very unrealistic view of design. It sounds like having a design document makes you feel safe and happy so you write them without really knowing what they can and should do for you. Because programmers need a finish line? Really?

My response to this article quickly became large enough to warrant a blog post instead of a comment, here's a link to that post.