Multithreading Gameplay Logic (Part 3)

In part 1 of Multithreading Gameplay Logic I talked about how one could use an entity component system to achieve concurrent game play logic. One of the major problems I had with this method was the inability to update a parent entity's components prior to the child entity. After some late night coding I came with a somewhat straight forward method.

In the presentation covering Multiprocessor Game Loops in Uncharted 2, Jason Gregory explains how they handled object hierarchy. They chose to use a simple system in which they maintain "update buckets". Each bucket is delegated to ticking a certain hierarchy of game objects suck as a bucket for vehicles;  characters , weapons and so on. Because of the fact that there are a relatively few amount of components that require transform information , i.e the input component , I chose to extend the ComponentServiceProvider , now to be referred to as ComponentTickBus, class with an enum called "execution mode". There are two options for a tick bus' execution mode, Default and Hierarchical. The default mode works and schedules the same as the previous method, but the hierarchical mode is where things get interesting.

The entity world is split into multiple layers known as TickTaskLevels. Each of these TickTaskLevels represents a single bucket and contain a ComponentTickBus instance for all available component types. After an entity creates a new attachment , or is detached, it determines it's new TickTaskLevel. All Components who's tickbus' execution mode is hierarchical , removes themselves from the old tick task level, and registers itself with the new tick task level. As an added detail, component tick buses who's execution mode is default are auto registered into a "global tick task level".

All of the component's now follow the same graph based execution order defined in Part 1, but are now done on a per TickTaskLevel basis, with level i +1 waiting on all of the tick tasks in level i.