Original: http://anthonydev.tumblr.com/post/61505287390/engine-using-managers

Some time ago, I posted the blog entry above to reddit, trying to see what others thought about my approach to managing entities. The general consensus was that my setup was a little heavy handed.

So, I let the responses roll around in my noggin’ off and on for a little while.

In my game engine, the managers were essentially the “creators” that set up an instanced object for use, also making sure to create new instances when needed or grab a dead one from the entity pool for reinitialization. The biggest problem was that whenever I changed something in the initialization method of a class, I had to change its manager method to accommodate it. I knew this wasn’t right, but I couldn’t quite figure out how to eliminate that and still keep my entity pool system humming.

Recently, I revisited this approach to see how I could “fix it”. It felt completely natural to let the object Init() handle all of the setting up, but how do I tie it into the entity pool in the manager classes? Well, I now have a solution.

I refactored how I handled objects in the world in regards to the manager. Instead of passing parameters to MakeEntity(), I revamped the methods to RequestEntity().

Previously, MakeEntity() had the following routine:

Check for a dead entity in the particular entity pool. If no entities are dead, create a new instance of entity and push it into its std::vector. If a dead entity is found, pull out the entity and mark it alive. Init() the new or found instance with the passed parameters and ensure it is tied into the collision system. Return entity for any further use.

If the parameters of an object’s Init() changed, MakeEntity() parameters need to be changed. Not anymore.

Now, I use RequestEntity():

Check for a dead entity in the particular entity pool. If no entities are dead, create a new instance of entity and push it into its std::vector. If dead entity is found, pull out entity and set it alive. Ensure the entity (new or found) is tied into the collision system. Return entity.

Simple change, but it allows me to remove the complete redundancy of the manager methods while retaining the pool system. The entity is now returned and Init() can then be run independently. It did take some Init() rewriting for some classes, since some building work was done in the manager routines. I believe this is a far more proper design, since the entity itself handles its building, instead of relying on an external routine.

Refactoring the managers have allowed me to keep objects tied to their specific task, as well as strengthening encapsulation for the entities. A small, but positive change.