Note: this introduction is about entity systems. But, even if you don’t know what these are, or haven’t implemented them yourself, it’s pretty basic and if you have general Javascript experience you will probably qualify more than enough to answer.
I am reading articles about Entity Systems on the T=machine blog.
The author, Adam, suggests that an entity should just be an id, that can be used to obtain it’s components (ie, the actual data that the entity is supposed to represent).
I chose the model where all entities should be stored in “one place”, and my primary suspects for implementing this storage are the array-of-arrays approach many people use, which would imply dynamic entity id’s that represent the index of a component belonging to an entity, while components are grouped by type in that “one place” (from now on I’ll just call it “storage”), which I plan to implement as a Scene. The Scene would be an object that handles entity composition, storage, and can do some basic operations on entities (.addComponent(entityID, component) and such).
I am not concerned about the Scene object, I’m pretty sure that it’s a good design, but what I am not sure is the implementation of the storage.
I have two options:
A) Go with the array-of-array approach, in which the storage looks like this:
//storage[i][j] - i denotes component type, while j denotes the entity, this returns a component instance
//j this is the entity id
[
[ComponentPosition, ComponentPosition, ComponentPosition],
[ComponentVelocity, undefined, ComponentVelocity],
[ComponentCamera, undefined, undefined]
]
//It's obvious that the entity `1` doesn't have the velocity and camera components, for example.
B) Implement the storage object as a dictionary (technically an object in Javascript)
{
"componentType":
{
"entityId": ComponentInstance
}
}
The dictionary approach would imply that entity id’s are static, which seems like a very good thing for implementing game loops and other functionality outside the Entity System itself. Also, this means that systems could easily store an array of entity ids that they are interested in. The entityId variable would also be a string, as opposed to an integer index, obviously.
The reason why I am against array-of-arrays approach is that deleting entities would make other entity ids change when a single entity is deleted.
Actual implementation details may wary, but I would like to know which approach would be better performance wise?
Things that I am also interested in (please be as cross-platform as possible, but if needed be, use V8 as an example):
- How big is the overhead when accessing properties, and how is that implemented under the hoof? Lets say that they are being access from inside the local scope.
- What is
undefinedin memory, and how much does it take? I ask this, because in the array-of-arrays approach all of the inner arrays must be of the same length, and if an entity doesn’t have a certain component, that field is set toundefined.
Don’t worry about the Array. It is an Object in JavaScript i.e. no “real” arrays, it’s just the indices are a numeric “names” for the properties of the object (dictionary, hash, map).
The idea is simple, an Array has a length property that allows for loops to know where to stop iterating. By simply removing an element off the Array (remember, it’s an Object) the length property doesn’t actually change. So…
if(array['two'])because, a field can actually hold the falsy values of undefined, null, 0, “”, false and evaluate as false. Always check withif('two' in array);for(key in array)always useif(array.hasOwnProperty(key))so you don’t iterate over a prototype’s property (the parent’s in a manner of speaking). Also, objects created by a constructor function might loop with the ‘constructor’ key also.