Post Overview
In this blog post, we'll explore how a 3D puzzle game—Dungeon Command—implements the Command Design Pattern to manage player movement, board rotation, and other critical actions.
The goal is to show how the Command Pattern brings clarity, flexibility, and an easy undo mechanism (Undo/Redo) to a game where every move matters!
What Is Dungeon Command?
Dungeon Command is a 3D puzzle game in which you guide a character through a tile-based environment.
Here are some key points:
- Core Mechanic: Move the player character across the board and rotate the entire scene.
- Objective: Collect all items in the level while navigating around barriers and solving spatial puzzles.
- Unique Feature: The ability to rotate the entire board, changing the layout completely and opening new paths.
Why Use the Command Pattern?
The Command Pattern is excellent for separating "what to do" (the commands) from "when to do it" (the invoker).
In games, it helps in several ways:
- Clear Separation of Concerns: Input handling is not mixed with game action logic.
- Easier Undo/Redo: Each command knows how to undo itself, simplifying history management.
- Support for Asynchronous Operations: Some actions take time (like a board rotation animation), and the Command Pattern can handle that elegantly.
- Extensibility: It's easy to add new commands without changing the overall structure.
- Testability: Since each command is independent, you can test them in isolation.
Command Pattern Implementation
The game defines an interface for commands, allowing execution and undo functionality.
Here's an example of the ICommand interface used in the game:
public interface ICommand {
bool Execute();
void Undo();
}Concrete Commands
MoveCommand
Role: Moves the player in the four cardinal directions.
Key Points:
- Stores the previous position for undo functionality.
- Checks for collisions with barriers and board boundaries.
- Activates tiles when the player steps on them and collects items when encountered.
Usage: Triggered when the player presses W, A, S, D.
RotateBoardCommand
Role: Rotates the board (clockwise or counterclockwise).
Key Points:
- Implements IAsyncCommand to manage rotation animations.
- Prevents new rotations while one is in progress.
- Performs an automatic undo if the rotation leads to an invalid state.
- Recalculates barriers after the rotation.
Usage: Triggered by Q (counterclockwise) or E (clockwise).
PlayerController as the Invoker
The PlayerController is the "brain" that reacts to user input and calls the appropriate commands.
Executed commands are stored in a stack to support the undo feature.
public void ExecuteCommand(ICommand command) {
if (command.Execute()) {
commandHistory.Push(command);
}
CollectableManager.Instance.CheckLevelComplete();
}How to Play
Dungeon Command is controlled using the following keys:
- Movement: W, A, S, D
- Board Rotation: Q (counterclockwise) and E (clockwise)
- Undo Last Action: Z
- Reset Level: R
Game Flow
The gameplay loop consists of the following steps:
- Move around the board with WASD.
- Stepping on a tile activates it; some barriers may appear or disappear.
- Rotate the board with Q or E if you need new pathways.
- Collect all items to finish the level.
- If you make a mistake, press Z to undo.
- Press R to reset the level if you want to start over.
Technical Details
Command History and Undo
Executed commands are stored in a Stack<ICommand>.
On undo, the most recent command is popped, and its Undo() method is called.
Asynchronous commands handle undo differently, awaiting completion of the ongoing animation:
private IEnumerator ProcessUndoMove() {
isUndoing = true;
ICommand lastCommand = commandHistory.Pop();
if (lastCommand is IAsyncCommand asyncCommand) {
asyncCommand.Undo();
while (!asyncCommand.IsCompleted) {
yield return null;
}
} else {
lastCommand.Undo();
}
isUndoing = false;
}Board Rotation
When the board is rotated:
- Tile positions are recalculated based on the rotation direction.
- Barriers switch orientation (horizontal ↔ vertical).
- The player's position is adjusted to the nearest tile center.
- Barriers are updated according to the new layout.
Conclusion
The Command Pattern provides a structured and extensible way to manage actions in Dungeon Command.
It allows for easy expansion, improved maintainability, and a built-in undo system.
Did You Like the Command Pattern?
If you found the Command Design Pattern interesting, stay tuned for upcoming posts!
I will share more examples of design patterns in video games to show how they can bring order and organization to development.
Thank You for Reading!
If you have any questions or suggestions, leave us a comment—I'd love to discuss them with you.

