Game Design Document

In order to define the set of features our code has to implement, we have to think about what game we are trying to make. Game Design is a big topic of game development and I won’t go into details about it. However, a simple approach to start designing the game we want to make is filling out a Game Design Document.

A Game Design Document (GDD, for short) is a succinct document that describes the main elements our game will have. You might be asking: “Why do we need to define the game elements of chess? Chess is already a well-established game with defined rules. Why the need to reinvent the wheel?”.

Well, we’ll do it mainly for two reasons:

First, our chess game might not implement all the standard chess rules that already exist. Nowadays, there are a ton of different chess modalities that operate on modified rules. You can see a list of them in this article [1]. You might decide to create your own chess variant. Or you might create a chess game with totally new mechanics. How about a chess RPG in which pieces can level up their stats and abilities? It’s important to clarify and document your vision in a GDD because creativity is temporary.

Alt text
Chesslocke: Chess with RPG elements. Taken from [2]

Second, a game is not just a collection of mechanics. Other aspects like art, sound effects, music, and user interface are equally important to enrich the player experience. These elements must be described in the GDD so your vision of the game becomes something tangible.

Here’s a GDD template you can use for your game. Here’s an example of a GDD for a game.

Exercise
Create the GDD for your game.

Software Prerequisites

As programmers (and engineers, in general), a fundamental skill we must develop is turning user requirements into technical specifications. Going back to the building analogy, a customer might ask an architect for a house that is big, well-lit, and warm inside. The architect or engineer in charge of building the house must be able to turn those subjective characteristics into something tangible and objective he can pursue. This might involve setting numerical dimensions, placing transparent surfaces in strategic spots, and choosing materials with special thermal properties.

Once we have a clear vision of what game we want to make, it’s time to turn those game elements into technical software prerequisites.

The Problem

The problem is what the program needs to solve. As stated in Code Complete [3], the problem should be explained in a short, simple description from the point of view of the user. That is, it should not describe the problem using technical terminology or referring to implementation details. It should focus on “What should be solved?” and not on “How should it be solved?”.

Example

The program should create a MySQL database hosted in the cloud that stores information about the income and expenses of the company and updates it by receiving requests from users.

The program should create and update a register of the income and expenses of the company.

Our problem would be:

Create a chess game with standard rules that is playable in the web browser.

Requirements

The requirements are the functionality the program needs to have in order to solve the problem we defined earlier. The same rules that apply to the problem also apply to requirements. Try to stay away from technical details and establish them from the point of view of the user.

Despite the fact that requirements shouldn’t bother with technicalities, requirements should still be objective and measurable. That way we can tell with confidence if the program accomplishes the objectives. This is what separates user requirements from software requirements.

Example

  1. The program has to store a lot of information ❌
  2. The program must update the register quickly. ❌

“A lot” and “fast” are some words you might hear from a user, but you can’t tell how much “a lot” is or how fast “quickly” is.

  1. The program has to store 30 entries. ✅
  2. The program must update the register in less than 500 milliseconds. ✅

The requirements for our program (for now) are:

  • Generate legal moves for any board configuration. Legal moves should follow chess rules according to the FIDE’s Laws of Chess.
  • Verify if a move is legal when done by the player. If so, move the piece.
  • Display the state of the game on the screen using a 2D minimalistic art style for pieces.
  • Reproduce background music during the game and menu.
  • Reproduce sound effects for key events in the game.
  • Generate automatic draws for ‘stalemate’ and ‘dead position’ situations.
  • Automatic recording and display of moves in Algebraic notation.
  • Allow user interaction to move the pieces, resign, explore the menu, and change settings.
  • Show on the screen critical information of the game to the user like pieces captured, movements done, legal positions to move when holding a piece, etc.

One important thing to consider is that requirements might change as the project evolves. Therefore, our code architecture must be able to handle changes to some degree without crumbling the whole program.

Code Architecture

The last step is to define the code architecture. The code architecture is a high-level overview of the program as a whole. It’s the blueprint of the house we want to make. The architecture lays out the modules that make up our program and how those modules communicate with each other. The architecture also describes specifications, constraints, and assumptions that apply to the entire system.

The level of detail needed to create an architecture depends on several factors. A rule of thumb is to be as detailed as possible so you have a clear picture of how everything works and how to implement it.

However, sometimes you need to get your hands dirty with the source code to really see the big picture. So don’t be afraid to experiment a bit before you start doing the architecture. It is advisable to make a small prototype of the whole thing to clarify your ideas and then face the big monster.

By the time I’m writing this, the general structure of the chess game we are developing is the following:

--- title: General architecture --- flowchart TD UI[User interface] UI ~~~ Game AudioManager ~~~ Game Game --> MoveGeneration Game --> InputHandler Game --> MoveRecord
As we can see, the User interface module and the Audio Manager will sit on top of the rest of the structure. Considering they are the modules closest to the final user, they are the highest in the architecture and probably will be implemented at the end. In the middle sits the Game class, which will implement the core game loop. That is the sequence of repeated actions that occur in our game. Finally, at the bottom, we have the Move Generation module, the Input Handler, and the Move Recorder. These modules address the rest of the requirements we specified above. The Game class will interact with them to provide and retrieve relevant information about the game as the core loop is running.

I’ll break down each module’s architecture in the following entries of the blog. We’ll discuss the top-level decisions I made and how they affect the code we create.

References