Game Structure Template
From WorkCDN
When looking to create better speed games (or even just start a new project), it can be frustrating and counter-productive to be constantly reinventing the wheel for things like menu structures, save game systems, level loading, cutscene creation, and minigame organization. This document attempts to lay out one way of doing things. It's not the Best Way (tm), but we think it has merit to be a Good Way. The structure here is laid out with the intention to be ported and used in any language that supports object-oriented programming and polymorphism.
Contents |
Everything's a Minigame
In heavily object-oriented programming languages, it is sometimes said that "everything's an object". We don't take that mantra to the extreme here, but within reason, we consider everything to be a minigame. We count games to be nothing more than a collection of smaller minigames. So the main game play is not the only minigame -- but even things like skill-point allocation for RPGs, inventory management, cutscenes, or even the menus are "minigames". We consider it all to be a collection of minigames, and some of them may be more boring or interesting than others. We recognize that there are debatable points with this, but for the sake of this discussion, "everything's a minigame." The smoothness and enjoyability of game peripherals can make or break the game experience for players, and it can help for us to recognize that they need to be fun and streamlined similarly to the main game play.
Every screen that the player sees is drawn by a "minigame", and they can link together in a somewhat loose (but defined) way.
Template Goals
This game structure template is different than a game engine -- it defines a generic game structure that is a framework from which to hang your game, and should be applicable regardless of engine, language or platform. It likely won't work for every game, and it certainly won't be helpful to use for all games, but for games that are looking for a good structural starting point that incorporate a number of common features, we hope that it will be of assistance. This document attempts to lay out a rough framework that accounts for features including:
- Cutscenes
- Save games
- Dynamic game experience that changes
- Hierarchical menu system
- Game preferences
- Distributed development model to accommodate several simultaneous developers (as is often the case in a speedgame)
Template Overview
Firstly, I’d like to make it clear that this is to be considered an RFP. Please add in feedback, and offer suggestions for clarification. The primary value of these templates and the corresponding object models is to make the creation of a game framework easier and the communication about its parts more consistent. For this to work, everyone in the project needs to understand and agree to the model and the terminology used for the project. It’s very likely that we’ll never be able to create a model that everyone would agree to on every detail, but if it’s close enough, everyone should be able to lay aside their opinions and work within the common framework for the duration of the project.
The choices for organizing game types are varied. We could organize them by how they appeal to us (action, logic, etc.) or by how they are played (FPS, RTS, etc.) or a host of other options. Additionally, many games fail to fall into a single genre - in fact, I believe that some of the most fun games are the ones that purposely give varied types of gameplay. Because of this, for this effort we’re going to focus first on an overall template that deals with the framework that the traditional game concepts fit within, and then break out individual sections that deal with the details of the various game types.
Despite all the differences in game types, there are certain key framework portions we can expect regardless of genre. Some fringe games might bend these, but for the purposes of effectively creating a game in a short period of time, I think we can assume that each framework should allow follow certain standards.
Game Shell Object
The first of these would be the concept of a wrapper - or game shell - that manages all the broader settings important to a functional game, but usually thought of outside the traditional elements of the gameplay experience. Specifically, the game shell would manage things like the technical game settings (volume level, screen resolution, etc.) and current game initialization settings (difficulty, starting level, etc.) as well as providing for external game control mechanisms, like loading and saving games. From an object standpoint, this GameShell class would contain a member object of the actual game object, stored under something like CurrentGame. The fact that the object representing the actual game experience is stored as another class would hopefully allow for easy serialization, construction and deconstruction of the individual game object instances, leading to an inherent save and load game capacity - at least that should be the goal.
To follow with the object model, it would make sense to make the core engines which drive the shell level experience (splash screen, title screen, credits, etc.) to be code within the object itself. Assuming that this is the case, the Game Shell should have a series of methods to load and save games, play the opening sequences, manage a menu, and exit the game. There will likely need to be several more functions, but these can be discussed in more detail in the actual implementation section of the object model.
Game Object
As mentioned above, the core game engine would be stored as an object in the game shell. This core object would store all the game state information that the individual game experience modules would need to reference to act as part of the game - things like inventory items, score, location, and lives, as well as more intangible game state information, like story points passed, and actions taken. The actual suite of objects stored would depend on the game.
From a code standpoint, the Game Object would act as a director; not actually providing the interface, but rather acting as a broker connecting the various gameplay experience modules together and managing their use of the shared game state settings. The Game Object would contain the main game engine that would drive progress for the game. This core engine can vary greatly in its complexity depending on the genre. For something simple like a classic platformer, the engine simply needs to manage the linear progress through the levels. It spins up a level, hands it its settings, and lets it go. When the level returns it takes the return to determine the sate of the level (generally level_won or level_lost), and then determines what to do next (reset and replay the level, move to the next level, play a cut scene, etc.) For something a more complex, like Roger Robot, that engine needed to determine things like game state to figure out when to play a cut scene, and which one. It had to track inventory items and coordinates to determine where a player could go, and it had to manage interfaces within interfaces.
While the best model to follow in creating a management engine for a game like Roger Robot is still up for debate, we can say with certainty that it needs to provide the capacity to spin up other engines in a managed and standard way, and act as a centralized management system of all game state information. In addition, as much as possible, the core engine should contain the configuration information for the game state progress points. So, using the platformer example, individual levels should not store the information on which level comes next after them – they should really need to know very little about how the game is organized – rather the state engine should have the master list of which level follows which in order. One model that seems like it would apply for the core engine would be a finite state machine: http://en.wikipedia.org/wiki/Finite_state_machine
Gameplay Modules
These game engines that are spun up by the core engine are actually the portion most people would think of as the real gameplay experience. Because they are autonomous engine instances, it’s easy to have several different types of them in a game (like we did with Roger Robot.) These modules go beyond the typical “game” interactions, however, to include any portion of the game experience. So in Roger Robot the “Gameplay Engine Modules” would be the navigation engine, the cutscene engine, the asteroids game engine, and the trade game engine. Each module should be designed as an engine, able to present a variety of its specific experiences based on a configuration file. For instance, in Finding Keepers, all 50 of the three-match game variations presented are produced from one engine. Likewise each of the cut scenes is generated from the one (different) engine as well. I would argue that the configuration file should actually be non-compiled files, such as .xml, and the handling of loading and parsing of configuration files would be included as functions in the base Game Module class. The Game Module base class should also contain a basic API for the Game Manager to spin up and shut down Game Module instances. Other than that, the derived specific Game Module classes can be as distinct as they need to be. On the other side, there is nothing stopping the Game Modules from sharing code as well. If we create a good Menu class, there’s no reason it couldn’t be shared among the engines.
Object Model Recap
Properties are examples, more will likely need to be added as we work things out.
class GameShell
- method Run()
- class Settings
- properties screen, screen
- properties volumemusic, volumesfx
- properties lastsavedgame, lastcompletedlevel
- method NewGame(initparams)
- method LoadGame(gamefile)
- method SaveGame(gamefile)
- method Exit()
- class Game
- method Play()
- method Pause()
- method Quit()
- class Inventory
- method AddItem(item, allowdups)
- method RemoveItem(item, allowdups)
- method CheckForItem(item)
- method CountItem(item)
- method CopyInventory() [As a way to provide the inventory to engines that don’t want to commit their inventory changes until the engine exits]
- method OverwriteInventory()
- class States
- properties Score, Difficulty, Location
- class StateFlags
- method AddFlag(item)
- method RemoveFlag(item)
- method CheckForFlag(item)
- method CopyStates()
- method OverwriteStates()
class GameModule
- method Play()
- method Pause()
- method Quit()
Object Model Revamp
Here's another attempt to create the game structure:
- class GameTimer
- //clockTime represents a tick counter tied to real clock times, and cannot be paused.
- property clockTime
- // gameTime represents a tick counter tied to a game-specific clock, which can be paused.
- property gameTime
- // Restarts the gameTime counter so that it starts from 0 relative to the current time.
- method gameReset( )
- // Pauses the gameTime counter so that it no longer advances with normal time.
- method gamePause( )
- // Resumes the gameTime counter so that it continues to advance with normal time.
- method gameResume( )
- class ScreenManager
- // Pushes a new user interface screen onto the stack, to take control -- useful for sub-menus, inventory screens, or starting new games.
- method pushScreen( screen )
- // Replaces the current screen with a different screen -- useful for splash screens to transfer control to a main screen
- method replaceScreen( newScreen )
- // Pops the current screen off of the stack to return control to a higher level -- useful for closing windows, ending games, or quitting games.
- method popScreen( )
- class Screen
- method setup( )
- method show( )
- method hide( )
- method sendKeyHit( keyCode )
- method onKeyHit( keyCode )
- method tick( time )
Question: How to return values from a pushed sub-window? Chris suggests possibly through a stack of messages / values -- I *really* like that idea!

