Game Object Factory: Distributed Factory

When creating game objects within your game, you will likely want to start using new or malloc all over the place. This is bad! Every object should have a clear owner, and there should be a single interface for creating any object. Take a look at this code:

The above code does work, although it creates a giant mess of file dependencies. Suddenly one would require a header file for all the various object definitions in order to use the new operator everywhere. Furthermore, handling of attaching the object to some sort of owner will have to be done everywhere that the new keyword is used.

A factory should be used to create game objects in a unified way. Here’s an example of the simplest form of an object factory:

However there are some problems with this type of factory. One is that the factory will still have annoying file dependencies requiring the user to make another include, and modify the switch statement each time a new game object is designed. Examine the following:

The above example shows the usage of the object factory when strings are mapped to types of objects. This setup is the ideal interface one would desire, as a single include to the ObjectFactory header is all that is required to create any type of object. The previous examples were mapping integers of an enumeration type to object types, which would require modification to the switch statement run in the enum, as well as manual updating to the enumeration itself.

So now that we’ve identified the ideal interface for creating game objects, we still need to make sure that the game objects created have a clear owner. Mapping of strings to game object types will need to be implemented, and cutting down on file dependencies of the the GameObjectFactory file itself is still something to be solved as well. By using a map (perhaps std::map) or hash table we can use a string identifier to fetch some value. Here’s what we want our factory to look like:

By mapping a string to a creator function of the type of object desired, all file dependencies except that of those required to utilize the table (map in the above example) are eliminated. Furthermore, whenever a new game object type is designed, all that is needed to be done to ensure compatibility with our factory is a single registration call.

There are some details about the Create function that should be discussed. The Create function is specific to each type of game object, and the interface for each Create function needs to be identical. To ensure this, each type of game object should have a single class called the creator. The creator object for each class derives from a base Creator class to ensure a clear and consistent interface.

What we’ve now created is called a distributed factory. All file dependencies are hidden by registration in using a hash table data structure to provide the mapping of typeless strings to actual types of game objects. The creation of objects has a unified interface, and there’s a single access point (the object factory) that allows the creation of all types of game objects that are registered within its data table of types. There’s one last small problem to solve: who owns the created objects? This answer can of course vary, but luckily there can be a single point of object management, like so:

And there we have it! A properly structured object factory. To further the awesome might of the factory, one could easily add in deserialization to the factory, since the factory is already working with abstract strings as type identifiers. Serialization, however,  is for a future post!

Factories like this also interface very well with scripting languages :)

Additional reading:
C++ for Game Programmers: Noel Llopis – Chapter 13


3 thoughts on “Game Object Factory: Distributed Factory

  1. Philip

    I don’t think this is relevant because the Object factory is dynamically creating objects on the heap, whereas the fiasco linked to seems to apply to objects constructed on the stack that are created when the program begins.


Leave a Reply

Your email address will not be published. Required fields are marked *