Game Programming Patterns
Game Programming Patterns
Define functionality as data
Track, Queue, or Log Requests
Support undo and redo operations
Replay a game by simply issuing all the same commands at the right times
Encapsulate a request as an object
Make method call real / tangible
Take some concept / logic / operation and turn it into a piece of data
Partially applied function
Allow for input buttons to change what they affect.
Define a base class that represents a trigger-able game command.
Create sub-classes for each of the different game actions.
Input handler would have pointers to commands for each button and just delegate to the commands.
If there is a purpose for a button to do nothing a command which does nothing can be used, this pattern is called "NULL Object".
Directions for Actors
This paves the road for an AI class that simply emits command objects.
Allows for AI modules for different actors or mix and match for different kinds of behavior.
Akin to a queue or stream of commands.
Require that a command receives an actor to execute on.
Input handler would now return a command when a button is pressed because it can't execute the command immediately without knowing the current actor.
A class that knows the current actor can then call on the input handler for a command and execute the command passing the current actor.
Allows the player to control any actor in the game by just changing the actor passed to the command.
Some code produces commands and places them in the stream. Other code consumes commands and invokes them.
Undo and Redo
This is the most will-known use of this pattern.
Each command will not only know what it changed but it will also remember how to reverse the change.
This is different from the abstraction accomplished by "Directions for Actors" in that the command needs to know which actor its changing.
Require that a command has knowledge of all changes.
Define another operation each command class needs to implement "undo()".
The command is responsible for remembering the previous game state.
To allow the player to undo, we keep the previous command or a history of commands.
To allow redo simply execute the next command as normal.
If a new command is made after one or multiple undo operations then discard all commands in the redo history.
The Memento pattern, but since commands tend to modify only a small part of an object's state, to snapshot the rest of its data seams like a waste of memory.
Persistent data structures are another option. Every modification to an object returns a new one leaving the original unchanged. Through clever implementation these new objects share data with the previous ones so its much cheaper than cloning the entire object.
Using a persistent data structure, each command stores a reference to the object before the command was performed, and undo just means switching back to the old object.
Lots of different command classes can be managed by having a good base command class.
The Execute method of the command class
An Object may respond to a command, or it may decide to pawn it off on some subordinate object. If this is true its called the "Chain of Responsibility pattern".
Some commands are stateless chunks of pure behavior. In cases like that, having more than one instance of that class wastes memory since all instances are equivalent. The Flyweight pattern addresses this.
Stateless chunks of pure behavior
Use sharing to support large numbers of fine-grained objects efficiently
Typically called once per frame.