There are a few things to watch out for in the "generic" component approach you propose:
- It means that a component is pure data, and cannot have any behavior unless you start doing things like allowing behavior objects (function pointers, or what-have-you) to be stored in the
attribs
member or in a similar member. This is a valid possible approach for an ECS, but not all ECS's choose the "component is pure data" model, and it's certainly not the only approach.
- The generic component stores all attributes in a dictionary; this means string (or some kind of key) lookups to recover data, boxing, and non-contiguous storage. The associative container also has storage overhead. All of these have performance impacts. You are also abandoning type-safety.
- Storage of the name as a string (rather than being able to intuit it from the type of the component) also means extra overhead.
Personally, I've never seen a "generic component" like you proposed out in the wild for anything real. It seems like a terribly poor choice, if for no other reason than when you have generalized the component so much you might as well reduce the overhead by making the entity the thing that stores all those properties, and namespace them:
class Entity {
Dictionary<string, object> components;
}
// ...
var entity = new Entity();
entity.components.Add("Position.X", 1.0f);
entity.components.Add("Position.Y", 2.0f);
entity.components.Add("Position.Z", 3.0f);
entity.components.Add("RigidBody.Mass", 100.0f);
entity.components.Add("Killable.HP", 15.0f);
(But I still don't recommend it.)