732 14. Runtime Gameplay Foundation Systems
virtually irrelevant in many cases. You can call your design a pure component
model (Section 14.2.1.6) or a property-centric design as you see fi t, but at the end
of the day, you’ll have essentially the same result—a logical game object that is
comprised of, and derives its behavior from, a collection of subobjects.
14.2.2.4. Pros and Cons of Property-Centric Designs
There are a number of potential benefi ts to an att ribute-centric approach.
It tends to be more memory effi cient, because we need only store att ribute
data that is actually in use (i.e., there are never game objects with unused
data members). It is also easier to construct such a model in a data-driven
manner—designers can defi ne new att ributes easily, without recompiling the
game, because there are no game object class defi nitions to be changed. Pro-
grammers need only get involved when entirely new types of properties need
to be added (presuming the property cannot be added via script).
A property-centric design can also be more cache-friendly than an object-
centric model, because data of the same type is stored contiguously in memory.
This is a commonplace optimization technique on modern gaming hardware,
where the cost of accessing memory is far higher than the cost of executing
instructions and performing calculations. (For example, on the PLAYSTA-
TION 3, the cost of a single cache miss is equivalent to the cost of executing lit-
erally thousands of CPU instructions.) By storing data contiguously in RAM,
we can reduce or eliminate cache misses, because when we access one element
of a data array, a large number of its neighboring elements are loaded into the
same cache line. This approach to data design is sometimes called the struct of
arrays technique, in contrast to the more-traditional array of structs approach.
The diff erences between these two memory layouts are illustrated by the code
snippet below. (Note that we wouldn’t really implement a game object model
in exactly this way—this example is meant only to illustrate the way in which
a property-centric design tends to produce many contiguous arrays of like-
typed data, rather than a single array of complex objects.)
static const U32 MAX_GAME_OBJECTS = 1024;
// Traditional array-of-structs approach.
struct GameObject
{
U32 m_uniqueId;
Vector m_pos;
Quaternion m_rot;
float m_health;
// ...
};
GameObjectg_aAllGameObjects[MAX_GAME_OBJECTS];