By André Pasquali,
Game Engineer at Kokku

The concept of Design Patterns did not originate directly in computing. Its origin dates back to the book “A Pattern Language: Towns, Buildings, Construction” (1977), written by the architect Christopher Alexander and his collaborators. In this work, Alexander described recurring solutions in civil architecture, patterns that were tested and approved for common problems in the construction of cities and buildings.
A famous example is the “Light on Two Sides of Every Room” pattern, which proposes windows on two walls to improve natural lighting and comfort. This simple yet effective approach illustrates how patterns can elevate the quality of a space and be applied in various contexts.
Years later, Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (the Gang of Four, or GoF) adapted this concept for software engineering. In their book “Design Patterns: Elements of Reusable Object-Oriented Software” (1994), they formalized 23 object-oriented patterns, divided into creational, structural, and behavioral categories.
We can draw a direct parallel: in civil architecture, the “Light on Two Sides” pattern improves the physical environment consistently. In software, the Observer pattern serves a similar role: it ensures efficient communication between parts of the system, allowing them to “receive light” (information) without having to request it manually.
Just as in architecture, where a pattern can be used in residential, commercial, or public buildings, in software, a Design Pattern can be reused in multiple systems and contexts.
The Journey of Patterns in Games

The explicit adoption of Design Patterns in game development began gaining prominence in the 2000s, although similar practices had been used informally since the 1990s. The open-source code of games like Doom (1993), released by id Software in 1997, reveals architectures anticipating patterns such as State and Observer, applied for AI control and HUD updates. Although the code does not explicitly mention Observer, its architecture reflects common event-driven patterns found in game engines. For example, WAD maps allow almost anything in the game to be overridden, creating a reactive system similar to Observer, where multiple subsystems “watch” for changes in the data files. The engine also employed Binary Space Partitioning (BSP) to split maps into a binary tree for efficient rendering, updating only what changes, much like Spatial Partitioning, a structural pattern that optimizes iterative and selective processing. This shows that object-oriented solutions for recurring problems were already in use, even without formal naming conventions.
Another industry veteran, Robert Nystrom, author of Game Programming Patterns, emphasizes that “for me, good design means that when I make a change, it’s as if the entire program was crafted in anticipation of it.” This philosophy of designing for anticipated changes is well illustrated by the Command Pattern, a core component of input and scripting systems. In engines like Unreal Engine, it enables actions to be scheduled and undone, key features for internal editors and replay systems.
John Carmack once highlighted that “If you’re willing to restrict the flexibility of your approach, you can almost always do something better.” This insight reflects a broader philosophy in game development: thoughtful constraints and deliberate structure often lead to more efficient and maintainable systems.
Additionally, the Factory Method pattern is commonly used in games for dynamically creating enemies and items, while Skyrim (Bethesda) uses patterns like Strategy to manage AI behavior variations, as documented in technical studies and modding tools.
In summary, although design patterns originated in enterprise software, their adoption in game development was driven by concrete architectural and scalability needs. These examples align with Kent Beck’s philosophy that “programs should be flexible, but only in ways they will actually change”, a principle that remains central for teams building AAA games today.
Seven Essential Patterns for AAA Games
Below, we highlight seven patterns widely used in modern game projects. Familiarity with them is essential for structuring gameplay systems, artificial intelligence, interfaces, and interaction pipelines that meet the constant demands for performance and evolution in AAA productions.
1. State

Problem: In game systems, objects like NPCs often need to exhibit varied and dynamic behaviors depending on different situations (for example, patrolling, being alert, attacking). Using extensive conditional structures (if, switch) to handle these variations quickly makes the code complex, hard to maintain, and error-prone.
Solution: The State pattern proposes encapsulating each behavior into a distinct class representing a specific state. The object holds a reference to its current state and delegates behavior to the corresponding state classes. This eliminates lengthy conditionals, making the code easier to extend and maintain, while allowing explicit and clear transitions between states.
Application in games: In games like Hitman and Metal Gear Solid, the State pattern is widely used to control NPC AI logic. For example, an enemy may be in a patrol state, switch to alert when detecting a threat, and finally enter an attack state when directly confronted. This modular approach allows complex behaviors to be implemented in an organized and scalable way, facilitating testing and adjustments during development.
2. Strategy

Problem: In games, it is often necessary for an object to choose between different behaviors or algorithms to perform a task, such as varying attack strategies, movement, or decision-making. Implementing this with conditionals can lead to inflexible, hard-to-maintain, and difficult-to-extend code.
Solution: The Strategy pattern proposes encapsulating each algorithm or behavior in a separate class that implements a common interface. The object using the algorithm holds a reference to one of these strategies and can dynamically switch between them at runtime, promoting flexibility and making the system easier to extend.
Application in games: In titles like StarCraft and XCOM, the Strategy pattern is fundamental for AI. For example, a unit can switch between offensive, defensive, or evasive strategies depending on the game context, choosing the best approach for the current situation. This flexibility allows for varied and adaptive behaviors without complicating the main code. It’s important to note the difference between State and Strategy: while State handles an object’s internal state and its transitions, Strategy enables the object to choose and swap between different external algorithms for a task without altering its fundamental state.
3. Factory Method

Problem: In game systems, it is often necessary to create varied objects (such as enemies, weapons, or items) flexibly, without the client code needing to know the specific concrete classes, which would cause tight coupling and make maintenance and extension difficult.
Solution: The Factory Method pattern defines an interface for creating objects, delegating the responsibility of instantiation to subclasses. This allows client code to operate with abstractions, while subclasses decide which concrete class to instantiate, promoting flexibility and extensibility.
Application in games: In games like Skyrim and The Witcher 3, the Factory Method is widely used for the dynamic spawning of enemies, weapons, and items, adapting creation based on the environment, difficulty, or ongoing events. This approach allows the creation system to evolve without impacting the code consuming these objects, facilitating updates and customization.
4. Observer

Problem: In complex game systems, various components need to automatically react to state changes of a central object, such as updates to a character’s health or mission progress. Implementing this with tight dependencies can lead to excessive coupling, making maintenance and evolution difficult.
Solution: The Observer pattern allows multiple objects (observers) to register to receive notifications of changes in another object (the subject). When the subject’s state changes, all observers are automatically notified, promoting decoupled and efficient communication.
Application in games: In titles like God of War and Breath of the Wild, the Observer pattern is used to dynamically update the HUD interface, mission system, and other elements that need to react to real-time events, such as changes in inventory or player status, ensuring synchronization without creating direct dependencies between components.
5. Command

Problem: In games, many actions need to be encapsulated so they can be stored, undone, replayed, or scheduled. Handling these directly as function or method calls can be complex, making control and flexibility difficult.
Solution: The Command pattern encapsulates a request or action within an object, allowing these actions to be treated uniformly. This enables storage, delayed execution, undo/redo, and composition of commands, facilitating the management of complex interactions.
Application in games: This pattern is widely used in input and scripting systems, as well as in level and gameplay editing tools like the Unreal Editor. In games like Super Mario Maker, Command allows players to record, replay, and edit action sequences, enabling features such as undo/redo and demo recording. The pattern is also used for macro execution in some strategy games, where a sequence of actions is triggered by a single command.
6. Builder

Problem: In games, building complex objects with multiple optional configurations, such as characters with different equipment, weapons with various modifications, or levels with varied elements, can result in confusing and hard-to-maintain code, especially if all construction logic is mixed together.
Solution: The Builder pattern separates the construction process of an object from its final representation, allowing step-by-step and modular creation. This separation facilitates generating complex and flexible variants without overloading client code, making construction more organized and scalable.
Application in games: This pattern is fundamental in engines that support advanced customization, enabling modular construction of characters, weapons, or levels. In RPGs like Fallout 4, the Builder can be used to assemble complex weapons, where the client code simply specifies components (stock, sight, magazine), and the Builder handles building the final cohesive object.
7. Decorator

Problem: In games, it is often necessary to dynamically add specific functionalities to individual objects, such as temporary buffs, power-ups, or equipment customizations, without altering the basic structure of those objects. This helps avoid subclass proliferation and maintains flexibility.
Solution: The Decorator pattern allows objects to be “wrapped” with new functionalities at runtime, combining additional behaviors in a modular and transparent way. This enables adding, removing, or combining extra features without modifying the original object’s code.
Application in games: This pattern is widely used to implement systems of buffs, power-ups, and equipment customization, as seen in Diablo and Cyberpunk 2077. For example, an item can be decorated with magical effects or temporary attributes, allowing multiple modifiers to be combined and managed efficiently.
Why Use Design Patterns in Games?
Developing complex software like AAA games is similar to designing a sophisticated vehicle: you can build every component from scratch, but efficiency comes from reusing tested and optimized solutions. Likewise, Design Patterns act as proven “components” that prevent reinventing the wheel in software systems.
To manage complexity in AAA game systems, development teams adopt well-established Design Patterns that facilitate modularization, maintenance, and scalability of code. The Gang of Four (GoF) patterns remain a key reference, providing effective solutions to recurring problems in object-oriented architectures.
The use of Design Patterns in games can be compared to applying proven construction methods in the real world: you wouldn’t reinvent a bridge every time you need to cross a river, instead, you use established techniques adapted to the context.
Similarly, design patterns serve as a true manual of best practices for software development, saving time, reducing rework, minimizing bugs, and improving communication among team members.
For example, by understanding the Builder pattern, a programmer can quickly grasp the structure of a complex character creation system without knowing all the project-specific details.
This journey of Design Patterns, from civil architecture, through enterprise software, to AAA game development, demonstrates how effective solutions transcend disciplines, adapting to the materials and contexts unique to each field: bricks and concrete in architecture, classes and objects in software, and gameplay systems in game productions.