3

I've been recently assigned to code a Entity-component-system based framework. As I'm not experienced in that matter, I have a simple question: Can I assume, that an entity can have maximum of one component of each type? I mean like:

int COMPONENT_COUNT; //number of different components available

class Entity
{
    COMPONENT* component_list[COMPONENT_COUNT];
}

then adding a component would be like

component_list[component.id]=&component; //can't add more components of this type

Is that a correct assumption? I can't think of any situation when an entity would need two or more components of the same type.

Oti
  • 98
  • 1
  • 7

3 Answers3

9

I'm going to bring up my holy bible and say, yes, an entity should only have one component type! It is blasphemous to do otherwise!

Thou shalt not create entities with more than one component of the same type or else thou shalt face eternal damnation.

I'm normally pretty loose about this stuff but when you allow your system to have more than one component of a given type attached to an entity, that complexity spreads to every single corner of your systems.

Now every system has to work against the assumption that there could be more one component of the same type attached to an entity for any component type, at which point you're constantly faced with design questions like what a physics system should do when an entity has 14 position components attached. And what happens when a rendering system finds an entity with 15 motion components but only 4 sprites, expecting a matching motion component for each sprite component? Which motion components are used for which sprite?

Life becomes a whole lot simpler when you just say, "one component instance of one component type per entity."

If you want to aggregate, then just make your component a collection of something. Instead of Bone component, make it a Skeleton component which stores a list of bones. Instead of a Pixel component, make it an Image component which stores a collection of pixels. That's all fine, and doesn't require you to violate and defile the sacred commandment above.

  • 4
    While I appreciate the shared wisdom, I do not appreciate the sarcasm. – starikcetin Apr 28 '18 at 21:01
  • Well cheers. My intention was not to be sarcastic but I enjoy some colorful language here and there. I'm not particularly good at precise technical conversations of this sort. –  Nov 26 '18 at 09:52
  • But fundamentally the issue is that if an ECS allows a variable-number of components of a particular type to be associated to an entity, then you'll inevitably get a cascade of complexity throughout the codebase of a kind that generally needs to be handled in some form or another in every single system implemented. That complexity may be worth it if the need to attach multiple components of a particular type is an unusually common case in a particular software. But most of the time I think it's a rarer case you can handle by simply attaching an aggregate component type ... –  Nov 26 '18 at 09:54
  • ... like `Skeleton` as opposed to multiple `Bone` instances, and most of the time (I would never say always), I think that should be good enough, and that keeps the complexity isolated to a handful of component aggregate types instead of spreading the complexity throughout the entire codebase. But apologies for the slightly dogmatic language. The reason I chose to express things that way is that I think if someone considered the pros and cons in this regard (system-wide complexity vs. isolated), then this question probably wouldn't be asked. I feel like lots of people new to ECS [...] –  Nov 26 '18 at 09:57
  • [...] get tempted in this route because they think up a few possible rare cases where it might be useful to attach more than one component of a particular type to an entity only to then consider expanding the entire architectural design to handle those rare cases, in which case I'd strongly advise against it until it's pretty clear that those cases aren't rare cases and that the software actually calls for this type of fundamental capability in the ECS more often than not. In this case it's like, "Don't optimize (pessimize) productivity for the rare case at cost to the common case." –  Nov 26 '18 at 10:02
3

Well, there isn't a holy bible of entity component systems. But many implementations I'm aware of don't make any provision for this, they allow entities to have or not have some kind of component but don't support multiplicity. Likewise, from a design perspective it seems like a rather bad idea (lots of complexity for naught). You could make it work, but neither you nor I can come up with a use case. KISS and YAGNI apply, this is a reasonable assumption. And if you do later need to add a component twice or thrice, it's easy to emulate by having two or three different kinds of components. Only with variable arity you need to change the innards of the system, but that seems even more outlandish.

0

Urho3D allows multiple same type components - and their components derive more than once sometimes - ie StaticModel from Drawable from Component

When you make a new component type - you can add as many of them as you want to a "Node" (same thing as Entity). This was pretty much a nuisance when using Urho - always thinking about "Wait, how many of these things does this Node have?".. For what?

Like others have mentioned, seems hard to justify all those extra for/while loops that go for 1 iteration always.. With Urho I got around it by just making it my own rule to never add more than one component of a type to the node... just too confusing otherwise

  • 1
    Note that Urho3D is actually EC, not ECS. In EC approaches, it's fairly common to see the same component added more than once to a certain entity, at least in my experience. (whether this is a good thing or a bad thing is another matter) – Tim Čas May 17 '23 at 18:06