By Jeff Plummer
Welcome to the first installment of several papers about software architecture and games. It is my goal in these articles to introduce game coders to some simple software engineering strategies customized to improve games development. More importantly, however, I hope to imprint the idea that design decisions do not exist in a vacuum. Every design choice has ramifications that will not only affect the system’s quality, but also determines what choices are available in the future.
The first few papers will focus on the somewhat abstract concept of software architecture. This is a particularly interesting subject to me because there is no other part of a software system that has as much impact as its architecture. Developing a robust architecture helps to ensure the system can grow and change as future needs dictate. Hopefully after completing this series of articles, you have some new insights that can help you in your own projects.
-Jeff
Plummer
Software architecture is a very young science, and still expanding and changing in terms of process and definition. And while the discipline of software architecture will continue to evolve, the one truth all designers can agree upon is that a system’s architecture is profoundly important in terms of overall quality. This paper will attempt to inform the reader of one process for developing an architecture for games and simulations.
Before we delve into the process of designing an “architecture”, let’s begin by defining what we mean by software architecture. For the purposes of this paper architecture will be defined as “a high-level design that shows the separation of logic into sub-systems, and the mechanisms that facilitate the communication between those sub-systems”. The architecture should make obvious to the software engineers the “how, what, where, and why” of any code they will write during the development of the system.
To give a concrete example, consider the simple “document/view” architecture. The architecture tells developers that any data the system uses should be stored in the document, and any visualization of that data should be created as a view. All views will have access to the document’s data, and they will receive update messages whenever the data has been modified. Application developers using the “document/view” architecture for their project have an understanding of how and where to write their code.
Games and simulations are very unique software systems in that the user may not be the primary originator of system interaction. A simulation or game will execute complex actions whether the user/player inputs an operation or not. Consider Doom™, a single player first person shooter (fps) where the player moves around a simulated world and destroys various monsters. The game will continue whether the player enters a command (move, shoot, etc.) or not. Monsters will move and attack, sound effects will play, the graphical interface will change, etc. This means the transactional design process most books teach is notably incomplete.
The first step in planning an architecture is to understand the requirements. Most literature suggests creating use cases to capture the functional requirements of the system. Use cases define the interactions between actors external to the system, and the system being developed. By bending the rules slightly and treating the clock as an actor, the transactional use-case diagram should be sufficient for capturing the functional requirements.
To
illustrate the process, consider the real time strategy game Starcraft™ (if you haven’t played Starcraft™,
then chances are you have been living in a cave near

Fig. 1
Treating the clock as an actor we can create use cases to represent actions that occur on a regular basis. This diagram shows that the clock will initiate the drawing of the various views. We can see that on a regular basis, the main view will draw the visible terrain, and draw the various visible objects.

Fig.
2
The process of capturing requirements in use cases is not a complicated task. The internet has hundreds of resources to help developers write meaningful use cases. At the architectural level, use cases needn’t be very detailed or complex. The goal is simply to understand interactions, so the architect can construct an architecture that will support those KINDS of interactions.
In the real game, the player and clock will initiate several more interactions, but for the purposes of brevity, those interactions will be ignored. Developers should note, however, that defining use cases for a game is not a difficult or time consuming task. Use cases will not only help in designing the architecture, but will be very useful in the development process as well.
At the end of this stage all the various interactions should have been defined, and a subset of those interactions have been selected for further analysis. For the purposes of this paper, we can assume all use cases were defined, and the trees in figure 1 & 2 were selected for further analysis.
Games and simulations are very large and very complex software systems utilizing several subsystems. At this stage the architect should define and describe the possible subsystems required to implement the selected use cases. Many possible subsystem combinations are possible, and will depend greatly on preference, and any third party components the system may use.
To illustrate this point consider the use case where the player gives a unit an order. The in game sequence is simply the player presses a command button, and the unit receives the corresponding order. This simple use case can be implemented by several different subsystem configurations.

Fig. 3
Figure 3 shows a common configuration found in many game programming books and game projects. Players interact with game systems visually, so the architect might choose to place the code capturing user interface (UI) events in the graphics subsystem. Many developers may actually prefer this configuration because it’s easy to work with. Content developers can add new buttons and menus as easily as adding any other visual object in the game.
This configuration does have a few drawbacks. UI coding is a very different technical specialization that graphics. Combing such different logic into the same subsystem could cause problems with division of labor during development, and have even greater repercussions in terms of flexibility and expandability in the long run. It also may seem conceptually awkward that all UI events travel through the graphics engine. Buttons and menus may make sense as graphical objects, but what about joystick or voice input data.

Fig. 4
The configuration in figure 4 attempts to separate the UI code into a different subsystem while still remaining simple to content developers. GUI objects like buttons and menus can still be accessed and created through the graphics engine. Content developers can also access user input directly rather than through the graphics engine, which makes sense conceptually because input devices like joysticks, etc. have nothing to do with graphics.
While this configuration makes a lot of sense logically, it also has a few drawbacks. First, it is not consistent. The path a UI event travels through the system is different depending on the type of input. This may seem like a small concern, but inconsistencies at the architecture level often result in much larger problems at the coding and maintenance phases of a project.

Fig.
5
Figure 5 is an interesting approach to the problem; it removes the notion of GUI objects all together. User input is sent directly to the object subsystem, and that code can tell the graphics subsystem to draw a button or a menu if necessary. This design has the benefit of consistency. All forms of user input events travel the same path through the system.
While the configuration in figure 5 is more uniform, it is also more abstract conceptually. A single button requires the interaction from three different subsystems. This means the architect must pay particular attention to the communications mechanism used for interactions between subsystems. An insufficiently robust interface could limit flexibility and reusability later on down the road.
Hopefully at this point, readers have gotten a taste for what software architecture is, and an idea of how to start the process of designing an architecture for a game system. At the very least I hope developers can come away with the notion that every design has strengths and weaknesses. It is not my intention to advocate any particular design, but rather to teach potential architects to look at problems in new ways. It is very important that the architect evaluates and understands the decisions he/she makes concerning design.
Jeff
Plummer is a master’s student in Computer Science finishing up his last
semester at
|
Send your hate mail to or visit him on the web at http://members.cox.net/jplummer |
|
|
All material is copyright © Jeff Plummer, and may not be reproduced or redistributed without the expressed written consent of the author. |
A Big White Bear production |
Bass, Len. Paul Clements, and Rick Kazman. Software Architecture in Practice.
Addison-Wesley, 1998.
E. Berard. Essays in Object-Oriented Software Engineering. Prentice Hall, 1992.
Rollings, Andrew and Dave Morris. Game Architecture and Design. The Coriolis
Group, 2000.
“Domain Specific Software Architectures.” Aug. 2003.
URL: http://sunset.usc.edu/classes/cs578_2003/13-Domain-Specific%20Software%20Architectures%20(DSSA).pdf