Game Programming Patterns

Apoorv Mishra
14 min readDec 20, 2022

Game programming patterns are a set of reusable solutions to common problems that game developers encounter when creating games. These patterns are designed to improve code quality, reduce complexity, and increase the flexibility and maintainability of game projects.

Unity is a popular game engine that provides a wide range of tools and features for game development. In this blog, we will explore some of the most useful game programming patterns that can be applied when working with Unity.

The programming patterns covered here are:

  1. Singleton
  2. Observer
  3. Command
  4. Factory
  5. Component
  6. Pool
  7. Service Locator
  8. State
  9. Memento
  10. Data-Driven
  11. Strategy
  12. Template
  13. Decorator
  14. Chain-of-responsibility
  15. Flyweight
  16. Facade
  17. Adapter
  18. Mediator
  19. Iterator
  20. Visitor
  21. Bridge
  22. Command

Singleton pattern

The singleton pattern is a design pattern that ensures that a class has only one instance, and provides a global point of access to it. This pattern is often used in game development to manage global game state, such as the player’s score or the current level.

To implement the singleton pattern in Unity, you can use the “MonoBehaviour” singleton pattern, which involves creating a MonoBehaviour script that can be attached to a GameObject in the scene, and then accessing the script through the “FindObjectOfType” method.

Observer pattern

The observer pattern is a design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. This pattern is useful for decoupling objects and allowing them to interact with each other without knowing about each other’s implementation details.

In Unity, the observer pattern can be implemented using events and delegates. A class can define an event, and other classes can subscribe to that event and execute a method when the event is raised. This allows objects to communicate with each other without having a direct reference to each other.

Command pattern

The command pattern is a design pattern in which an object is used to encapsulate all information needed to perform an action or trigger an event at a later time. This pattern is useful for implementing undo/redo functionality, or for separating the execution of an action from the object that invokes the action.

In Unity, the command pattern can be implemented using a “Command” class that defines a method for executing the action, and a “CommandQueue” class that stores a list of commands and executes them in order. This allows you to easily add and remove commands from the queue, and execute them at any time.

Factory pattern

The factory pattern is a design pattern that provides an interface for creating objects in a super class, but allows subclasses to alter the type of objects that will be created. This pattern is useful for creating objects that have similar properties, but differ in some aspects, such as the type of enemy in a game.

In Unity, the factory pattern can be implemented using a “Factory” class that defines a method for creating objects, and a number of “ConcreteFactory” classes that override the method and create objects of a specific type. This allows you to easily create different types of objects without having to modify the factory class.

Component pattern

The component pattern is a design pattern in which an object is composed of multiple smaller objects, called components, that each handle a specific aspect of the object’s behavior or appearance. This pattern is useful for creating modular and reusable code, and for separating concerns within an object.

In Unity, the component pattern is implemented using the “MonoBehaviour” class, which is the base class for all scripts in Unity. Each MonoBehaviour script represents a component that can be attached to a GameObject and defines a specific aspect of the object’s behavior.

For example, you can create a “MovementComponent” script that handles the movement of a character, a “AnimationComponent” script that handles the character’s animations, and a “HealthComponent” script that handles the character’s health. Each of these scripts can be attached to the same GameObject, allowing the object to have multiple behaviors.

Pool pattern

The pool pattern is a design pattern in which a pool of objects is maintained and objects are reused instead of creating new ones when needed. This pattern is useful for optimizing performance by reducing the number of object allocations and deallocations, which can be expensive operations.

In Unity, the pool pattern can be implemented using a “Pool” class that maintains a list of inactive objects and a method for creating and activating new objects when needed. When an object is no longer needed, it can be deactivated and returned to the pool for reuse.

This pattern is commonly used for objects that are frequently created and destroyed, such as bullets or enemies in a game. By using a pool, you can reduce the overhead of constantly allocating and deallocating objects and improve the performance of your game.

Service locator pattern

The service locator pattern is a design pattern in which a central registry, called a service locator, is used to locate and retrieve objects that provide a specific service or functionality. This pattern is useful for decoupling objects and allowing them to access services without knowing the details of the service implementation.

In Unity, the service locator pattern can be implemented using a “ServiceLocator” class that maintains a list of services and provides methods for registering and retrieving them. Other objects can then use the service locator to access the services they need, without having a direct reference to the service implementation.

This pattern is useful for managing dependencies between objects and reducing the tight coupling between them. By using a service locator, you can improve the flexibility and maintainability of your code and make it easier to change or swap out services as needed.

State pattern

The state pattern is a design pattern in which an object’s behavior is determined by its current state, and the object transitions between states in response to events or actions. This pattern is useful for encapsulating complex behavior and allowing objects to change their behavior at runtime.

In Unity, the state pattern can be implemented using a “State” class that defines the behavior for a specific state, and a “StateMachine” class that maintains a list of states and transitions between them. The state machine can then be attached to a GameObject and control its behavior based on the current state.

For example, you can create a state machine for a character in a game, with states for idle, walking, running, and jumping. The state machine can then switch between these states based on player input and other conditions, such as the character’s velocity or the presence of obstacles.

Memento pattern

The memento pattern is a design pattern in which an object’s internal state is saved in a memento object, and the memento can be used to restore the object to that state later. This pattern is useful for implementing undo/redo functionality, or for saving and restoring an object’s state.

In Unity, the memento pattern can be implemented using a “Memento” class that stores the internal state of an object, and a “Caretaker” class that maintains a list of mementos and can restore an object to a previous state using a memento.

For example, you can use the memento pattern to implement an undo/redo system for a game level editor, allowing the user to undo and redo changes to the level layout. The memento can store the state of the level objects and the caretaker can use the mementos to restore the level to previous states.

Data-driven design pattern

The data-driven design pattern is a design pattern in which the behavior of an object or system is controlled by external data, rather than hard-coded logic. This pattern is useful for creating flexible and customizable systems that can be easily modified without changing the code.

In Unity, the data-driven design pattern can be implemented using asset files, such as XML or JSON files, to store the data that drives the behavior of the system. The data can then be loaded and parsed at runtime, and used to control the behavior of the objects in the game.

For example, you can use the data-driven design pattern to create a character customization system, allowing the player to choose from a variety of different options to customize the appearance and abilities of their character. The data for the customization options can be stored in an external file and loaded at runtime, allowing you to easily add and modify options without changing the code.

By using the data-driven design pattern, you can create more flexible and customizable games and make it easier to modify and update your game systems.

Strategy pattern

The strategy pattern is a design pattern in which an object, called the context, maintains a reference to a strategy object and delegates part of its behavior to the strategy. This pattern is useful for allowing objects to change their behavior at runtime and for creating flexible and reusable code.

In Unity, the strategy pattern can be implemented using an interface that defines the behavior of the strategy and concrete classes that implement the behavior. The context object can then maintain a reference to the strategy interface and delegate the behavior to the concrete strategy.

For example, you can use the strategy pattern to create a character AI system in which the character can switch between different AI behaviors, such as patrolling, chasing, or attacking, based on the player’s actions. The context object can be the character, and the strategies can be concrete classes that define the different AI behaviors.

Template method pattern

The template method pattern is a design pattern in which an abstract class defines a template method that contains a series of steps, and concrete subclasses override one or more of the steps to provide specific behavior. This pattern is useful for creating a common structure for a group of related algorithms and allowing subclasses to provide the specific details.

In Unity, the template method pattern can be implemented using an abstract MonoBehaviour script that defines the template method and concrete MonoBehaviour scripts that override one or more of the steps to provide specific behavior.

For example, you can use the template method pattern to create a dialogue system in which different characters have different dialogue options, but the overall structure of the dialogue is the same. The abstract script can define the template method with the steps for displaying the dialogue and handling player responses, and the concrete scripts can override the specific dialogue options for each character.

By using the template method pattern, you can create a common structure for related algorithms and allow subclasses to provide the specific details, improving the reuse and maintainability of your code.

Decorator pattern

The decorator pattern is a design pattern in which an object is decorated with additional responsibilities or behaviors at runtime, by wrapping the object in one or more decorator objects. This pattern is useful for adding new behavior to an object without modifying its class, and for creating flexible and reusable code.

In Unity, the decorator pattern can be implemented using a base class or interface that defines the behavior of the object, and concrete decorator classes that wrap the base object and add new behavior.

For example, you can use the decorator pattern to create a power-up system in which different power-ups can be combined to create custom effects. The base class can define the basic power-up behavior, and the decorator classes can add additional behavior, such as increasing the player’s speed or damage.

By using the decorator pattern, you can add new behavior to an object at runtime and create flexible and reusable code for your Unity projects.

Chain of responsibility pattern

The chain of responsibility pattern is a design pattern in which a request is passed through a chain of objects, each object having the option to handle the request or pass it on to the next object in the chain. This pattern is useful for decoupling the sender of a request from its receiver, and for allowing a request to be handled by multiple objects in a flexible and modular way.

In Unity, the chain of responsibility pattern can be implemented using a “Handler” class that defines a method for handling the request and a reference to the next handler in the chain, and a “ConcreteHandler” class that overrides the method to provide specific behavior.

For example, you can use the chain of responsibility pattern to create a damage system in which different types of damage can be handled by different objects. The handler can be an abstract class that defines the basic damage handling behavior, and the concrete handlers can be classes that specialize in handling specific types of damage, such as fire or poison.

By using the chain of responsibility pattern, you can create a flexible and modular system for handling requests and improve the maintainability of your code.

Flyweight pattern

The flyweight pattern is a design pattern in which shared objects are used to reduce the number of objects in a system and improve performance. This pattern is useful for optimizing the use of resources, particularly in systems with a large number of objects with similar characteristics.

In Unity, the flyweight pattern can be implemented using a “Flyweight” class that defines the shared state of the objects, and a “ConcreteFlyweight” class that stores the unique state of the objects and uses the shared state to perform its operations.

For example, you can use the flyweight pattern to optimize the use of resources in a game with a large number of enemies that have similar behaviors and appearance. The flyweight can define the shared behavior and appearance of the enemies, and the concrete flyweights can store the unique state, such as the enemy’s position and health.

By using the flyweight pattern, you can improve the performance of your Unity projects and reduce the overhead of maintaining a large number of objects.

Facade pattern

The facade pattern is a design pattern in which a simplified interface is provided for a complex system, hiding the complexity and providing a single entry point for clients. This pattern is useful for reducing the dependencies between clients and the system, and for improving the usability and maintainability of the system.

In Unity, the facade pattern can be implemented using a “Facade” class that provides a simplified interface for a complex system, and delegates the requests to the appropriate objects in the system.

For example, you can use the facade pattern to create a simplified interface for a level editor that exposes only the necessary functionality to the user, while hiding the complexity of the underlying system. The facade can provide methods for creating and modifying objects in the level, and delegate the requests to the appropriate objects in the editor.

By using the facade pattern, you can improve the usability and maintainability of your Unity projects and reduce the dependencies between clients and the system.

Adapter pattern

The adapter pattern is a design pattern in which an adapter class converts the interface of a class into another interface that is expected by a client. This pattern is useful for allowing classes with incompatible interfaces to work together, and for creating reusable code.

In Unity, the adapter pattern can be implemented using an “Adapter” class that implements the expected interface and delegates the requests to an object with an incompatible interface.

For example, you can use the adapter pattern to integrate a third-party library into your Unity project. The adapter can implement the interface expected by your project and delegate the requests to the third-party library, allowing the two to work together seamlessly.

By using the adapter pattern, you can integrate incompatible classes into your Unity projects and create reusable code.

Mediator pattern

The mediator pattern is a design pattern in which a mediator class acts as a middleman between a group of objects, allowing them to communicate with each other indirectly and reducing the dependencies between them. This pattern is useful for decoupling objects and improving the maintainability of the system.

In Unity, the mediator pattern can be implemented using a “Mediator” class that defines the communication methods and maintains a list of the objects that it mediates. The objects can then communicate with each other through the mediator, without having a direct reference to each other.

For example, you can use the mediator pattern to create a messaging system in which different objects can send and receive messages without knowing about each other’s implementation. The mediator can define the methods for sending and receiving messages and maintain a list of the objects that are registered to receive messages.

By using the mediator pattern, you can improve the maintainability of your Unity projects and reduce the dependencies between objects.

Iterator pattern

The iterator pattern is a design pattern in which an iterator class provides a way to access the elements of an aggregate object sequentially, without exposing the object’s internal representation. This pattern is useful for allowing clients to iterate over a collection of objects without knowing the details of the implementation.

In Unity, the iterator pattern can be implemented using an “Iterator” class that defines the interface for iterating over the elements of the aggregate object, and a “ConcreteIterator” class that implements the iterator for a specific type of aggregate object.

For example, you can use the iterator pattern to create a system for iterating over the elements of a game level, such as objects, enemies, or checkpoints. The iterator can define the interface for accessing the elements of the level, and the concrete iterator can implement the iterator for the specific type of level.

By using the iterator pattern, you can allow clients to iterate over a collection of objects in a uniform way and improve the reuse and maintainability of your code.

Visitor pattern

The visitor pattern is a design pattern in which an object, called the visitor, performs operations on the elements of an object structure, without changing the structure’s class. This pattern is useful for separating an algorithm from the object structure on which it operates, and for allowing the algorithm to be modified independently.

In Unity, the visitor pattern can be implemented using a “Visitor” interface that defines the operations that can be performed on the elements of the object structure, and a “ConcreteVisitor” class that implements the operations for a specific type of object structure.

For example, you can use the visitor pattern to create a system for applying effects to game objects, such as applying a damage effect or a buff effect. The visitor can define the interface for applying the effects, and the concrete visitor can implement the specific effects for each type of object.

By using the visitor pattern, you can separate the algorithms that operate on an object structure from the structure itself and improve the reuse and maintainability of your code.

Bridge pattern

The bridge pattern is a design pattern in which an abstraction is separated from its implementation, allowing the two to vary independently. This pattern is useful for creating flexible and reusable code, and for decoupling the abstraction from the details of the implementation.

In Unity, the bridge pattern can be implemented using an “Abstraction” class that defines the interface for the abstraction and a reference to an implementation object, and an “Implementation” interface that defines the interface for the implementation and concrete classes that implement the interface.

For example, you can use the bridge pattern to create a system for rendering game objects, allowing the objects to be rendered using different techniques, such as sprite rendering or 3D rendering. The abstraction can define the interface for rendering the objects, and the implementation can define the interface for the rendering technique, with concrete implementations for each technique.

By using the bridge pattern, you can create flexible and reusable code and decouple the abstraction from the details of the implementation, improving the maintainability of your code.

Command pattern

The command pattern is a design pattern in which an object, called the command, represents an action or request and encapsulates all the information necessary to perform the action. This pattern is useful for decoupling the sender of a request from its receiver, and for allowing requests to be queued or undone.

In Unity, the command pattern can be implemented using a “Command” interface that defines the interface for the command and concrete classes that implement the interface and define the specific action or request.

For example, you can use the command pattern to create a system for executing actions in a game, such as moving a character or using an item. The command can define the interface for executing the action, and the concrete commands can define the specific action or request.

By using the command pattern, you can decouple the sender of a request from its receiver and allow requests to be queued or undone, improving the flexibility and maintainability of your code.

Conclusion

By using these and other game programming patterns, you can improve the structure and maintainability of your Unity projects and create more efficient and scalable games.

--

--

Apoorv Mishra

Software Developer. I love to learn new stuff everyday and write about it.