- How To Redo A Turn In Game Pigeon Forge
- How To Redo A Turn In Game Pigeon Tn
- How To Redo A Turn In Game Pigeon Tennessee
- How To Redo A Turn In Game Pigeon Without
Command is one of my favorite patterns. Most large programs I write, games orotherwise, end up using it somewhere. When I’ve used it in the right place, it’sneatly untangled some really gnarly code. For such a swell pattern, the Gang ofFour has a predictably abstruse description:
Encapsulate a request as an object, thereby letting users parameterize clientswith different requests, queue or log requests, and support undoableoperations.
How To Prepare A Wood Pigeon.In this video i show you the super quick way to Pluck and Gut your Pigeon ready for the kitchen.One of my favourite game birds,s.
I think we can all agree that that’s a terrible sentence. First of all, itmangles whatever metaphor it’s trying to establish. Outside of the weird worldof software where words can mean anything, a “client” is a person — someoneyou do business with. Last I checked, human beings can’t be “parameterized”.
Then, the rest of that sentence is just a list of stuff you could maybe possiblyuse the pattern for. Not very illuminating unless your use case happens to be inthat list. My pithy tagline for the Command pattern is:
A command is a reified method call.
“Reify” comes from the Latin “res”, for “thing”, with the English suffix“–fy”. So it basically means “thingify”, which, honestly, would be a morefun word to use.
Of course, “pithy” often means “impenetrably terse”, so this may not be much ofan improvement. Let me unpack that a bit. “Reify”, in case you’ve never heardit, means “make real”. Another term for reifying is making something “first-class”.
Reflection systems in some languages let you work with the types in yourprogram imperatively at runtime. You can get an object that represents the classof some other object, and you can play with that to see what the type can do. Inother words, reflection is a reified type system.
Both terms mean taking some concept and turningit into a piece of data — an object — that you can stick in a variable, passto a function, etc. So by saying the Command pattern is a “reified method call”,what I mean is that it’s a method call wrapped in an object.
That sounds a lot like a “callback”, “first-class function”, “function pointer”,“closure”, or “partially applied function” depending on which language you’recoming from, and indeed those are all in the same ballpark. The Gang of Fourlater says:
Commands are an object-oriented replacement for callbacks.
That would be a better slugline for the pattern than the one they chose.
But all of this is abstract and nebulous. I like to start chapters withsomething concrete, and I blew that. To make up for it, from here on out it’sall examples where commands are a brilliant fit.
Configuring Input
Somewhere in every game is a chunk of code that reads in raw user input —button presses, keyboard events, mouse clicks, whatever. It takes each input andtranslates it to a meaningful action in the game:
A dead simple implementation looks like:
Pro tip: Don’t press B very often.
This function typically gets called once per frame by the game loop, and I’m sure you can figure out what itdoes. This code works if we’re willing to hard-wire user inputs to game actions,but many games let the user configure how their buttons are mapped.
To support that, we need to turn those direct calls to jump()
and fireGun()
into something that we can swap out. “Swapping out” sounds a lot like assigninga variable, so we need an object that we can use to represent a game action.Enter: the Command pattern.
We define a base class that represents a triggerable game command:
When you have an interface with a single method that doesn’t return anything,there’s a good chance it’s the Command pattern.
Then we create subclasses for each of the different game actions:
In our input handler, we store a pointer to a command for each button:
Now the input handling just delegates to those:
Notice how we don’t check for NULL
here? This assumes each button will havesome command wired up to it.
If we want to support buttons that do nothing without having to explicitly checkfor NULL
, we can define a command class whose execute()
method does nothing.Then, instead of setting a button handler to NULL
, we point it to that object.This is a pattern called NullObject.
Where each input used to directly call a function, now there’s a layer ofindirection:
This is the Command pattern in a nutshell. If you can see the merit of italready, consider the rest of this chapter a bonus.
Directions for Actors
The command classes we just defined work for the previous example, but they’repretty limited. The problem is that they assume there are these top-leveljump()
, fireGun()
, etc. functions that implicitly know how to find theplayer’s avatar and make him dance like the puppet he is.
That assumed coupling limits the usefulness of those commands. The only thingthe JumpCommand
can make jump is the player. Let’s loosen that restriction.Instead of calling functions that find the commanded object themselves, we’llpass in the object that we want to order around:
Here, GameActor
is our “game object” class that represents a character in thegame world. We pass it in to execute()
so that the derived command can invokemethods on an actor of our choice, like so:
Now, we can use this one class to make any character in the game hop around.We’re just missing a piece between the input handler and the command that takesthe command and invokes it on the right object. First, we change handleInput()
so that it returns commands:
It can’t execute the command immediately since it doesn’t know what actor topass in. Here’s where we take advantage of the fact that the command is areified call — we can delay when the call is executed.
Then, we need some code that takes that command and runs it on the actorrepresenting the player. Something like:
Assuming actor
is a reference to the player’s character, this correctly driveshim based on the user’s input, so we’re back to the same behavior we had in thefirst example. But adding a layer of indirection between the command and theactor that performs it has given us a neat little ability: we can let theplayer control any actor in the game now by changing the actor we executethe commands on.
In practice, that’s not a common feature, but there is a similar use case thatdoes pop up frequently. So far, we’ve only considered the player-drivencharacter, but what about all of the other actors in the world? Those are drivenby the game’s AI. We can use this same command pattern as the interface betweenthe AI engine and the actors; the AI code simply emits Command
objects.
The decoupling here between the AI that selects commands and the actor codethat performs them gives us a lot of flexibility. We can use different AImodules for different actors. Or we can mix and match AI for different kinds ofbehavior. Want a more aggressive opponent? Just plug-in a more aggressive AI togenerate commands for it. In fact, we can even bolt AI onto the player’scharacter, which can be useful for things like demo mode where the game needs torun on auto-pilot.
By making the commands that control an actorfirst-class objects, we’ve removed the tight coupling of a direct method call.Instead, think of it as a queue or stream of commands:
For lots more on what queueing can do for you, see Event Queue.
Why did I feel the need to draw a picture of a “stream” for you? And why does itlook like a tube?
How To Redo A Turn In Game Pigeon Forge
Some code (the input handler or AI) producescommands and places them in the stream. Other code (the dispatcher or actoritself) consumes commands and invokes them. By sticking that queue in themiddle, we’ve decoupled the producer on one end from the consumer on the other.
If we take those commands and make them serializable, we can send the streamof them over the network. We can take the player’s input, push it over thenetwork to another machine, and then replay it. That’s one important piece ofmaking a networked multi-player game.
Undo and Redo
The final example is the most well-known use of this pattern. If a command objectcan do things, it’s a small step for it to be able to undo them. Undo isused in some strategy games where you can roll back moves that you didn’t like.It’s de rigueur in tools that people use to create games. The
I may be speaking from experience here.
Without the Command pattern, implementing undo is surprisingly hard. With it,it’s a piece of cake. Let’s say we’re making a single-player, turn-based game andwe want to let users undo moves so they can focus more on strategy and less onguesswork.
We’re conveniently already using commands to abstract input handling, so everymove the player makes is already encapsulated in them. For example, moving aunit may look like:
Note this is a little different from our previous commands. In the last example,we wanted to abstract the command from the actor that it modified. In thiscase, we specifically want to bind it to the unit being moved. An instance ofthis command isn’t a general “move something” operation that you could use in abunch of contexts; it’s a specific concrete move in the game’s sequence ofturns.
How To Redo A Turn In Game Pigeon Tn
This highlights a variation in how the Command pattern gets implemented. In somecases, like our first couple of examples, a command is a reusable object thatrepresents a thing that can be done. Our earlier input handler held on to asingle command object and called its execute()
method anytime the right buttonwas pressed.
Here, the commands are more specific. They represent a thing that can be done ata specific point in time. This means that the input handling code will be
Of course, in a non-garbage-collected language like C++, this means the codeexecuting commands will also be responsible for freeing their memory.
The fact that commands are one-use-only will come to our advantage in a second.To make commands undoable, we define another operation each command class needsto implement:
An undo()
method reverses the game state changed by the correspondingexecute()
method. Here’s our previous move command with undo support:
Note that we added some more state to the class.When a unit moves, it forgets where it used to be. If we want to be able to undothat move, we have to remember the unit’s previous position ourselves, which iswhat xBefore_
and yBefore_
do.
This seems like a place for the Memento pattern, but I haven’t found it to work well.Since commands tend to modify only a small part of an object’s state,snapshotting the rest of its data is a waste of memory. It’s cheaper tomanually store only the bits you change.
Persistentdata structures are another option. With these, every modification to anobject returns a new one, leaving the original unchanged. Through cleverimplementation, these new objects share data with the previous ones, so it’smuch cheaper than cloning the entire object.
Using a persistent data structure, each command stores a reference to theobject before the command was performed, and undo just means switching back tothe old object.
To let the player undo a move, we keep around the last command they executed.When they bang on Control-Z, we call that command’s undo()
method. (If they’vealready undone, then it becomes “redo” and we execute the command again.)
Supporting multiple levels of undo isn’t much harder. Instead of remembering thelast command, we keep a list of commands and a reference to the “current” one.When the player executes a command, we append it to the list and point “current”at it.
When the player chooses “Undo”, we undo the current command and move the currentpointer back. When they choose “Redo”, we advance thepointerand then execute that command. If they choose a new command after undoing some,everything in the list after the current command is discarded.
The first time I implemented this in a level editor, I felt like a genius. I wasastonished at how straightforward it was and how well it worked. It takesdiscipline to make sure every data modification goes through a command, but onceyou do that, the rest is easy.
Redo may not be common in games, but re-play is. A naïve implementation wouldrecord the entire game state at each frame so it can be replayed, but that woulduse too much memory.
Instead, many games record the set of commands every entity performed eachframe. To replay the game, the engine just runs the normal game simulation,executing the pre-recorded commands.
Classy and Dysfunctional?
Earlier, I said commands are similar to first-class functions or closures, butevery example I showed here used class definitions. If you’re familiar withfunctional programming, you’re probably wondering where the functions are.
I wrote the examples this way because C++ has pretty limited support forfirst-class functions. Function pointers are stateless, functors are weird andstillrequire defining a class, and the lambdas in C++11 are tricky to work withbecause of manual memory management.
How To Redo A Turn In Game Pigeon Tennessee
That’s not to say you shouldn’t use functions for the Command pattern in otherlanguages. If you have the luxury of a language with real closures, by all means,use them! In some ways, the Command pattern is a way ofemulating closures in languages that don’t have them.
I say some ways here because building actual classes or structures forcommands is still useful even in languages that have closures. If your commandhas multiple operations (like undoable commands), mapping that to a singlefunction is awkward.
Defining an actual class with fields also helps readers easily tell what datathe command contains. Closures are a wonderfully terse way of automaticallywrapping up some state, but they can be so automatic that it’s hard to see whatstate they’re actually holding.
For example, if we were building a game in JavaScript, we could create a moveunit command just like this:
How To Redo A Turn In Game Pigeon Without
We could add support for undo as well using a pair of closures:
If you’re comfortable with a functional style, this way of doing things isnatural. If you aren’t, I hope this chapter helped you along the way a bit. Forme, the usefulness of the Command pattern really shows how effective thefunctional paradigm is for many problems.
See Also
You may end up with a lot of different command classes. In order to make it easier to implement those, it’s often helpful to define a concrete base class with a bunch of convenient high-level methods that the derived commands can compose to define their behavior. That turns the command’s main
execute()
method into the Subclass Sandbox pattern.In our examples, we explicitly chose which actor would handle a command. In some cases, especially where your object model is hierarchical, it may not be so cut-and-dried. An object may respond to a command, or it may decide to pawn it off on some subordinate object. If you do that, you’ve got yourself the Chain of Responsibility pattern.
Some commands are stateless chunks of pure behavior like the
JumpCommand
in the first example. In cases like that, having more than one instance of that class wastes memory since all instances are equivalent. The Flyweight pattern addresses that.You could make it a singleton too, but friends don’t let friends create singletons.