Gamasutra: The Art & Business of Making Gamesspacer
Rapid Game Prototyping: Tips for Programmers
Printer-Friendly VersionPrinter-Friendly Version
View All     RSS
April 25, 2014
arrowPress Releases
April 25, 2014
PR Newswire
View All
View All     Submit Event





If you enjoy reading this site, you might also want to check out these UBM TechWeb sites:


 
Rapid Game Prototyping: Tips for Programmers
by Herman Tulleken on 01/19/14 01:44:00 pm   Featured Blogs

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.

 

In November 2013, two colleagues* and I made 30 games. Although I have done some game prototyping before, working on so many games in such a short period gave me some insights I did not have before. As I said to a friend, it’s like watching a television series in a few days, instead of watching each episode week by week – you just see different things.

In this article, I collect some of these observations in the form of a set of tips. I kind-of assume you are already familiar with the classical How to prototype a game in 7 days, which describes prototyping from a more general point of view. In some ways, this is a programming-specific extension to the ideas presented there.

(*Their names are Jonathan Bailey and Eduard Beukes. If you want to read more on our protoyping endeavour, see How we made 30 games in 30 days.)

A. Rapid is a State of Mind

Making something very quickly is a lot of fun. Day-to-day (“proper”) development can be slow progress, with the final products months (or years) away. Tinkering with an idea in your spare time gives you insight, but its outcome is vague.

Building a rapid-prototype gives you immediate satisfaction. It gives you focus; it allows you to channel energy, and gear up.

But you need to get out of development mode, and out of tinkering mode. You have to know you will throw work away, and waste some effort. You have to know that sometimes you don’t need the best decision – you just need to make it straight away. You have to let go of perfection and details.

You have to get to the core.

Know and remember the goal

The reasons for building a prototype are varied. Here are a few examples:

  • To have a finished game at the end of a fixed time (such as in a jam).
  • To have the core of a game that is fun (such as in a pre-preproduction phase of a project).
  • To select the best idea from a set of alternatives.
  • To test the technical feasibility of an idea (where the idea can be anything from a full game to a graphics technique or AI algorithm).

The best way to work and make decisions depends on this goal. Be clear about what the goal is, and remind yourself frequently.

If a task is not moving you closer to your goal, don’t do it.

Find the essence of your idea, and schedule enough time for it

An essence can be a mechanic, a style, a theme, a setting, an emotional experience. Find it, and, separate it from the supporting elements.

When you schedule, assign time accordingly. If your essence is a new mechanic, you want to have enough time to explore it; you don’t want to spend all your time building levels or coding atmospheric shaders.

Take creative risks, but avoid technical risks

If a game prototype fails, it should be because it’s boring, not because of a technical problem. (Except of course when the goal is technical prototyping). You want your prototypes to be finished, and allow you and your team to explore the essence, and pass this on to players.

  • Avoid tricky, sophisticated data structures and algorithms.
  • Avoid sophisticated systems and architectures.
  • Avoid trying to make things too fast.
  • Avoid technical feats that do not improve gameplay.

B. Planning and Process

Think about content

Ask yourself a few questions about the content your game will need to get a feel for its scope.

  • How much do you need to build?
  • How will you inject variety?
  • At what stage during development should it go in?
  • What fallbacks can be used? If you run out of time, have a plan to get essential content in. Will it work to make the boss simply a pink version of the level-enemies? Could boxes work instead of characters?

Plan

  • Work out a rough plan, and put down some time estimates.
  • Check your plan against the goal, and remove things that do not take you closer to your goal.
  • Check your plan against the essence of your idea, and verify that you allocated enough time to explore the essence.
  • Identify the sections where your estimates are likely to be out. Keep fallbacks in mind; consider reducing their impact / role / complexity. Think of placeholder strategies (see below).

Follow an implementation strategy, but adapt it to follow the ebbs and flow of the creative process

Here is the order I would suggest you follow. It puts the most important things first, keeping in mind (typical) dependencies.

  1. Get something on screen
  2. Implement top level game
  3. Get user controls in
  4. Implement a minimalist level
  5. Implement toy logic
  6. Implement game goal
  7. Implement AI
  8. Implement feedback
  9. Refine

Prototyping is not coding a specification, though. Remember that there will be false starts, and that you will have to adapt. When necessary, change the plan and update the schedule.

Know and avoid time drains

Certain things just suck up a disproportionate amount of time. It’s useful to recognise these, and make sure you schedule enough time, have fallbacks, and keep it even simpler than you would other parts of the game. (Typical time drains depend of course on the type of game; the examples below are just to give you a sense of what I mean).

Controls. In actions games, controls can take a long time to get playable (never mind to getnice).

Balance. In simulation games, balancing takes a long time. Keep the number of systems low; keep the number of variables low. And leave enough time to balance them out.

GUI. In information-heavy games, the GUI can suck up all your time. Finding audio can take a long time – don’t add it unless it’s essential, or you already know where the sounds you need are.

Animation. Animation can slurp up a lot of time: consider using snap poses, or gliding when appropriate.

Procedural content generation. Tweaking algorithms for content generation can be time consuming. Unlike other algorithms, the specifications for content generation algorithms are hard to make objective.

Consider using serial development (programming pipelines)

For teams with more than one programmer, it’s common to divide a project up in components, and dish each one out to a separate programmer, so that everyone works in parallel.

There is another method, and it is worth trying it out once or twice and see if it works for your team.

With this approach, most of the code passes through all the programmers, in a staggered fashion. The first programmer will implement the broad strokes of the project; the next one will start filling in details, and so on. Instead of owning a piece of the code, each programmer owns the entire project for a time slice (these slices may overlap somewhat, of course). It works especially well if you use a lot of placeholder code.

The nice thing about the approach is that it reduces discussions about interfaces. In your time slot, if you need an interface change, you make it. It won’t break other programmers’ code because you are the only programmer. (It still works with overlapping slices, but you need more care, and a plan.)

The down side is of course the design you end up with may be quite bad. It does not matter, though, because the design is not important. It seems a bit wasteful, since there are times where some programmers don’t program.

(Of course, this is meant to split off programming tasks; it would be a shame if you do this with other creative activities. In many prototyping projects programmers are also game designers; this does not apply when you have your design hats on!)

Don’t get stuck

Several things can make you feel stuck: bugs, tricky-to-implement code, unusable and fiddly controls, sheer amounts of content, level design.

When you are in the mud, get out of it, and move on. Here are a few things you could do when stuck:

  • Ignore tricky bugs that do not ruin gameplay.
  • Cut culprit features; reduce content.
  • Use a simpler placeholder algorithm or approximation.
  • Use brute force with lookup – a handy technique to design correct, fast algorithms quickly at the expense of memory and some extra time spent outside the main loop (maybe even outside the game altogether).
  • Fake it. Monsters that respond to players look more intelligent than monsters that don’t, regardless of how intelligent they actually are.
  • Hard-code it. A long array of monster sequences is much easier to code than a sophisticated wave generation algorithm.
  • Hide it.

C. Code Design and Implementation

Use placeholder code

Use placeholder code wherever you can so that you can move onto core gameplay earlier. Once you have that nailed, you can systematically replace placeholder code with code that does a better job. What is nice about this approach is that once you have all the systems in and working with your core gameplay, it is much easier to prioritize tasks according to their gameplay impact.

Here are some typical candidates for placeholder code.

Controls In some games, controls are extremely important. But if second-rate controls won’t cripple the player’s experience, and it’s faster to implement, implement that first. For example, in many sliding puzzle games, the best controls allow you to use the mouse (or finger) to slide around objects. This can be a difficult scheme to implement. On the other hand, mouse selection with arrow keys or buttons can be quick to implement, allowing you to get onto other gameplay elements faster.

Feedback Feedback is important, it provides information and improves the experience. But first do something simple: dialogs and messages, colour changes, flashes or beeps.

AI AI is difficult: it’s hard to predict whether any given strategy will work. The following can be use for AI placeholders before you start implementing the final algorithm:

  • Random AI.
  • AI using simple heuristics can stand in for look-ahead AI, or vice-vera, whatever is easier.
  • Greedy algorithms.
  • AI that cannot play all possible moves.

Procedural Content If your game relies on procedural content; you can use the following types of stand-ins:

  • Fixed content.
  • Purely random content.

Approximation Crude approximations can often be very useful. Here are some examples:

  • Using collision spheres instead of collision meshes.
  • Using linear approximations for curves.

Use design Shortcuts

[USE WITH CARE] You should avoid god-like classes in production code, but in prototypes, they can save a large amount of time. Instead of having a monster and player that extends from actor, dump all the code in actor, and use the familiar switch-atrocity instead of polymorphism.

Mistrust any data structure that is more sophisticated than a dynamic list, especially if you need to implement it yourself. Focus on simple, safe, and easy to understand data structures and algorithms.

Avoid false design shortcuts

  • Rules for naming and organisation in prototypes don’t change.
  • Unnecessary exposure of data (using public fields) can bite you even in the short span of a day or two. It’s simply not that easy to remember whether setting health to zero will kill a monster, or whether you also need to destroy it yourself.
  • States machines (or anything that keeps track of states) almost always need more states than you think. If you try to use a shortcut instead of an appropriate abstraction, there is a big chance that you will get entangled in a buggy if-else mess.

Manage your tweakables

  • Make the game easier to fine-tune by keeping tweakables in one place.
  • Not every value needs to be tweaked; don’t be afraid to make them constants. But put them in a central place. Do not use magic numbers.
  • Carefully name your tweakables.
  • When you design a tweakable system, make sure that the exposed variables have clear and linear effects. Subtle tweakables are best hidden away (or left until the end). It’s better to make a system that is clear to understand, but cannot be controlled completely.

Write readable code

Throwaway code should not be engineered to the highest standards possible.

However, it still needs to serve the purpose of communicating your intention, especially if you work in a team. A muddle of code can waste a lot of time. The most useful things to do when writing code for rapid development:

  • Name things properly.
  • Be organised.
  • Avoid deep hierarchies and complicated dependencies.
  • Keep methods damn short.
  • Limit the number of “smart” classes. A smart class is anything that handles game logic. In smaller, volatile projects, it’s better to centralise logic and reserve helper classes for presentation. It makes it easier to make drastic changes. As long as you keep methodsshort.

Use implementation patterns

An implementation pattern is a standard way of doing things. As an example, here is the implementation pattern of a game’s main file:

public void Start()
{
   Reset()
}

public void ResetGame()
{
   currentLevel = 0;
   ResetLevel();
}

public void ResetLevel()
{
   DestroyObjectsFromPreviousPlay()
   InitialiseVariables()
   BuildLevel()
   InitGameState()
}

public void Update()
{
   ProcessGameFlowInput(); //Reset or next level

   if(gameOver) return;

   ProcessGamplayInput(); //player controls
   UpdateContinuousGameState(); //movement, AI, etc.

   gameState = GetGameState();

   if(gameState == GameState.Win) WinGame();
   if(gameState == GameState.Loose) LooseGame();
}

private void NextLevel()
{
   currentLevel++;
   ResetLevel();
}

private WinGame()
{
   ShowMessage("You win");
   EndGame();
}

private LooseGame()
{
   ShowMessage("You loose");
   EndGame();
}

private EndGame()
{
   gameOver = true;
}

By using standards, you will reduce the time you need to spend on thinking, and then quibbling over alternatives. Implementation patterns are useful for production code too, but prototyping patterns are different: they emphasise simplicity and clarity, rather than OOP re-use and efficiency.

You can often set up patterns as templates that you can use during prototyping. If you can, do it!

(You collect or design these standards between prototyping stints – see below).

As another example, here is an implementation pattern for changing a variable’s value smoothly over time.

private IEnumerator ChangeSomething(thingToChange, initialState, finalState)
{
   float timePassed = 0;
   Set(thingToChange, originalState);
   bool finalStateReached = false;

   DoThingsAtStartOfChange();

   while(!finalStateReached)
   {
       timePassed += Time.deltaTime;

       if(timePassed >= time)
       {
          timePassed = time;
          finalStateReached = true;
       }

       Set(thingToChange, Lerp(originalState, finalState, 
          timePassed / totalTime);

       yield return null;       
   }

   DoThingsAtEndOfChange();
}

D. Before, After, In-between

If you build prototypes regularly, you can put yourself at a great advantage by doing some stuff in-between prototyping stints.

Reflect

After you finish with a prototype, do a post mortem, and identify the good and the bad. Review your notes shortly before your next prototyping project.

Build a library of code that enables rapid prototyping

This is different from your library that’s shared between production projects. You can use techniques that are a bit slow, or make some platform assumptions, or uses other technology that you cannot normally use for production code.

As an example, we rendered the grid in many of our games by drawing on a texture pixel-by-pixel, instead of using sprites. This method is fine for prototyping, but too slow for the final product.

Identify implementation patterns, bug patterns and time sinks

After a few prototypes, you may begin to see some patterns emerge. Make a list, and use this to inform what to put in your library.

Can you codify implementation patterns as templates in your library? Could you design better data structures to avoid some bug pattern? Can you give yourself a head start on a time sink by adding to your library?

Further Reading


Related Jobs

Infinity Ward / Activision
Infinity Ward / Activision — Woodland Hills, California, United States
[04.24.14]

Principal / Lead Rendering Engineer
Gearbox Software
Gearbox Software — Plano, Texas, United States
[04.24.14]

Graphics Programmer
Turtle Beach
Turtle Beach — San Diego, California, United States
[04.24.14]

SENIOR C# SOFTWARE ENGINEER
SOAR Inc.
SOAR Inc. — Mountain View, California, United States
[04.24.14]

Unity 3D MiniGame Programmer (and Designer)






Comments


Rakib Solewalker
profile image
A right post, just at the right time for me. Thanks!

John Woznack
profile image
I'm all for prototyping of games, but I do not believe in writing "prototype" (or throw-away) code.

In my experience, prototype code is always forced into production. Rarely will the software engineer(s) be given time to re-code a prototype for production use. When the decision makers see a prototype they like, they invariably believe that 90% of the game code is done and it just needs some artwork before final release.

As a tech lead, I've always gotten puzzled looks from managers whenever I have tried to explain to them that the prototype code is in no way ready for production and release, and that the team will need many months of development to re-engineer it into a releasable form. And when I try to explain to them how a releasable video game requires a lot of code not related directly to gameplay, in their minds they always imagine that those parts are trivial, and should take just a "month or so".

So I would recommend not building a repository of _prototype_ code, but rather building a repository of well tested video game code that makes it quick and easy to build a "prototype" game. Then the "prototype" game can just as easily be quickly repackaged into a full, releasable game.

Herman Tulleken
profile image
Yes, it is indeed true. I have seen other advice that recommends to prototype using tech that *cannot* be used for production (Lisp? :P) to avoid this issue, but that too comes at a price (since many programmers are way faster in their everyday production tech-environment).

And I agree that if the road for a successful prototype at a company is to move straight into production then a separate repository of code can be counter productive.

But in other cases, having a big library of quick-fix code that works on *my machine* can help you flesh out ideas much faster. (A production quality library is obviously more expensive to write and will contain thus fewer features).

And I also think it's any tech manager's responsibility to know if something seems 90% complete there is *at least* another 90% still on its way.

Jonathan Kraber
profile image
Is throw-away code that bad?

Maybe it's just because I'm new to the industry, but for me, when I whip out a prototype with bad code, it at least gives me a better vision of how all of the systems in the game should work together and on their own. It also allows me to predict some of the issues I'll have when making the actual game. The result of this is, of course, that I make better decisions when I write the actual code.

Does this become less of a problem when you become an experienced professional?

John Woznack
profile image
Apologies for not being clearer in my original comment. I was speaking from the point of view of a software engineer as an employee at a video game development company. And in that situation, I would say "Yes": When you're at a job getting paid to write game code, throw-away code is bad (IMHO).

Look at it from your employer's view: Do you really want to have a software engineer that writes code intending it to be thrown away and re-written again and again? Not only is that a waste of time and money, but it's a drag on the rest of the team who now have to wait for you to rewrite your code.

Now, when you're on your own time, you can do whatever you want. In fact, as a tech lead, I would totally encourage you to, at home, write test code, fiddle around with sample/example code, experiment around with various code snippets that help you learn the odd SDK, or how to use the various tools, or test performance theories on different platforms. That's what distinguishes true gurus from everyone else: They spend their own time honing their skills and getting familiar with the tools and techniques of their trade.

Jonathan Kraber
profile image
Ah, I get it now. Thanks for the advice. I'll definitely take that into consideration in the future.

Glenn Storm
profile image
Awesome! Thank you, Herman.

Florian Putz
profile image
Nice read! Something I would add to this and definitely encourage people to do is to use libraries and/or tools like unity as much as possible - there is still enough code to be filled in - even if your team consists of more than one programmer ;). I wouldn't recommend to roll your own engine during the process of prototyping. The gameplay and assets can always be transferred to your own tech later on if you really want to do that.


ps: great to see SA's gamedev scene growing. Always enjoyed my stays in joburg.


none
 
Comment: