Skip to content

Command Pattern

Notes from Game Programming Patterns1

Encapsulate a request as an object, thereby letting users parameterize clients with different requests, queue or log requests, and support undoable operations.2

Robert Nystrom’s simpler definition:

A command is a reified method call. (“Reify” = make something real or tangible - i.e., turn an action into an object.)

  • Instead of calling a method directly, wrap the call in an object.
  • The object can be stored, passed around, queued, serialized, or executed later.
  • Functionally similar to a callback, closure, or first-class function, but in an OOP form.

A hardcoded input system like below is rigid because actions are hard-wired.

if (isPressed(BUTTON_X)) jump();
else if (isPressed(BUTTON_Y)) fireGun();

Create a Command base class:

class Command {
public:
virtual ~Command() {}
virtual void execute() = 0;
};

Then derive specific commands:

class JumpCommand : public Command {
void execute() override { jump(); }
};

Each button maps to a Command*:

Command* buttonX_;
Command* buttonY_;

Now you can bind any button to any action and even swap them at runtime.

Earlier commands assume a global player object. We want to decouple the command from who performs it.

Pass an actor reference into execute():

class Command {
public:
virtual void execute(GameActor& actor) = 0;
};

Example:

class JumpCommand : public Command {
void execute(GameActor& actor) override { actor.jump(); }
};
  • Works for any actor (player, AI, NPC).
  • Input handler or AI module becomes producer of commands.
  • The actor or dispatcher becomes the consumer.
  • Enables:
    • Player <-> AI control switching.
    • Queuing or networking commands (e.g., multiplayer replay).

Each command can reverse its own effect.

class Command {
public:
virtual void execute() = 0;
virtual void undo() = 0;
};
  • Maintain a history stack of commands.
  • Undo = call undo() and move cursor back.
  • Redo = advance cursor and execute() again.
  • Common in:
    • Strategy games (rollback)
    • Editors / tools
    • Replay systems (record commands instead of state snapshots)
class MoveUnitCommand : public Command {
Unit* unit_;
int xBefore_, yBefore_, x_, y_;
public:
MoveUnitCommand(Unit* unit, int x, int y) : unit_(unit), x_(x), y_(y) {}
void execute() override {
xBefore_ = unit_->x();
yBefore_ = unit_->y();
unit_->moveTo(x_, y_);
}
void undo() override {
unit_->moveTo(xBefore_, yBefore_);
}
};
  • Commands are classes (limited first-class function support).

Use closures:

function makeMoveCommand(unit, x, y) {
let xBefore, yBefore;
return {
execute() {
xBefore = unit.x();
yBefore = unit.y();
unit.moveTo(x, y);
},
undo() {
unit.moveTo(xBefore, yBefore);
}
};
}

The Command pattern is effectively a way to simulate closures in OOP languages.

PatternRelation
Null ObjectDefine a no-op Command to avoid null checks.
Event QueueCommands can be queued and processed later.
MementoAlternative undo strategy (state snapshot).
Persistent Data StructuresEnable cheap undo by sharing structure.
Subclass SandboxDefine base command helpers for easy reuse.
Chain of ResponsibilityRoute commands through object hierarchies.
FlyweightShare stateless command instances.
Singleton (anti-pattern)Don’t use - unnecessary here.
ConceptDescriptionExample
Reified CallTreat an action as dataCommand object
DecouplingSeparate input/AI from executionInputHandler → Command → Actor
Undo/RedoStore inverse operationsexecute() + undo()
SerializationSend command streams over networkMultiplayer replay
Functional VariantClosure-based commandsJS functions
Common PitfallForgetting to track old statexBefore, yBefore

The Command Pattern is for turning behavior into manipulable data. It’s invaluable for:

  • Input handling
  • Undo/redo systems
  • AI action control
  • Replay and networking
  • Modular, decoupled architecture
  1. Command · Design Patterns Revisited · Game Programming Patterns. https://gameprogrammingpatterns.com/command.html. Accessed 21 Oct. 2025.

  2. Gamma, Erich, editor. Design Patterns: Elements of Reusable Object-Oriented Software. 39. printing, Addison-Wesley, 2011. Addison-Wesley Professional Computing Series.