Design Patterns: Factory Pattern for Game Developers
What is the Factory Pattern?
The Factory Pattern operates on a simple main principle:
Objects do not construct themselves.
If your objects make up of other complex objects (and do not make use of an engine or dependency injection frameworks), you have to assemble them, like in a assembly line at a factory. This is handy if your objects consist of many, many other objects and possess some kind of nested structure.
For every Object (or class, to be more precise), there is an ObjectFactory.
However, the if the object model has a structure, the factories that create them must also reflect that structure; it can be simplified a little by . But I’ll get to that later.
Ideally, the factory has its own “object layer” describing in and outputs as an additional abstraction layer. This sounds bloated (and it can be if you’re not careful), but ensures the factory is safe from any game play changes, which will save a lot of effort and time in the long run. You only have to translate between two object models in order to use it. A good factory pattern implementation that helps with development typically does not change much and gives you a solid framework.
Admittedly, you can go overboard with this pattern by creating adding system complexity as well.
How to Implement
A first design of a factory pattern I created for my game CamoTactics, which was still a little inefficient at the time. Even though it could handle the production of many different game objects, and it did this really well, I still consider it a bad example in terms of code quality as it was difficult to maintain.
A more advanced pattern of much higher quality is used in AstraX, which drives a highly configurable and powerful procedural generator. Object model and the respective Factories in this game roughly look like this:
Note: In AstraX, man-made/technical Satellites are treated as tiny space station
The Factory classes on the right produce the game objects listed on the left using procedural generation. What objects they produce is grouped together where it makes sense and color coded in the diagram. Because the factories are structured like this, they can make use of the same random generators, ensuring an identical world is produced with the same seed. On the StarSystemFactory class there is a method called generate( Settings ) to produce a fully functional system ready to be explored.
Sign-up for a Premium Account to see this content
Restricted Section of ~394 Words
What I did not mention so far is the above presented system is a blend of Factory Pattern and Abstract Factory Pattern, which also borrows some ideas from the Prototype Pattern.
You can indeed blend different design patterns together as needed.
When to use
- game objects
- object-oriented procedural generation
- adding statistics to object creation
- breaking down creation of nested object models into smaller chunks that are easier to handle
- a child object that needs a common parent e.g. to inherit a common configuration
- typical usage in software development: creation of services, data access objects…
When not to use
- If you do not expect your game to have a long life expectancy (e.g. prototypes)
- Using a Factory Pattern for every class of minuscule importance (e.g. sort mechanisms for a list implementation). There is no need to add factories to every single object you create.
- Squashing two different factories from two different use cases or systems into one (e.g. Creating a radar sensor for a plane. What do you do if you need that sensor for a car? A sensor system is different from a vehicle system)
Tipps
- When to use Factory Pattern? A good rule of thumb is: is this object of higher importance? This is the case with most game objects (Players, Vehicles, Enemies, Weapons that possess logic or may interact with others). In software development terms, these are Business Objects that should be created using a factory pattern.
- Factory patterns should work per use case or system. Group together systems and all of its subsystems e.g. a VehicleFactory can output Vehicle and Wheel. In a second step, and only if the necessity arises, separate into VehicleFactory and WheelFactory.
- Ergo, factory patterns can grow incrementally, so they are good for iterative development processes
- A badly designed object model will result in a badly designed factory pattern. This is not the pattern’s fault.
Hope this article helps on your gamedev journey!
Do you have any feedback or questions? Feel free to let me know in the comments!
I appreciate the opportunity to help or improve.