Monday, June 11, 2018

c# - Is there any reason not to make all my components a single class?


What would be the downside to using a generic all-encompassing Component class versus specific classes (PositionComponent, InputComponent, et cetera) for each component in an entity/component system?



By 'generic' I mean:


class Component {
String name; // component name, like "position"
Map attribs; // Attributes like "x" and "y" stored here.
}

Where a 'specific' component might be:


class PositionComponent {
int x, y;
}


I feel like creating a separate class for each component means tons of 3-5 line classes in my code-base.



Answer



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 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.)


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...