I was reading about component-based entity systems and I was wondering why there is usually a large EntityBuilder class with methods like CreatePlayer()
, CreateEnemySpaceship()
, and CreatePowerup()
, all creating an entity, attaching some components, and returning the entity.
The class has the potential to get quite large given enough different entities and having to search this large code-file can eventually become quite cumbersome. Also, with this system, since all entities are of type Entity, to determine what something actually is, you would have to add some sort of TypeComponent to the entity which may contain a string like "Player", "Enemy", and "Powerup". Now you lose some benefits of strong typing and have to rely on personal memory more (bad in my opinion).
Another problem with this setup is the inability to use function overloads based on what type the entity is. Instead one would have to use hashtables based on some identifying component which is a bit ugly.
I was wondering, instead of having these large builder classes and cumbersome ways of determining what an entity really is, why not just have separate classes for each entity? Well, that is what we were doing but they resulted in large and complex hierarchies, right? Well, I'm not advocating large hierarchies. Rather, move every method from this monolithic builder class to a separate class deriving from Entity and place that code in the constructor. No multiple-inheritance. No large trees. Example: Both Ship, Spaceship, and EnemySpaceship would all derive from Entity and only Entity.
This could be useful for determining the types of entities when a collision occurs and how to proceed with handling the event. The classes themselves would basically be empty except for the constructor logic in how to construct the entity (attaching components and whatnot). This solution seems to be a lot more extendable as well, considering if one would ever need to modify the creation process of an EnemyEliteFighterSpaceship, rather than searching through some large builder class, just go to that class file.
Am I missing something here? I suppose, if all else, my real question would be of an elegant way to determine what an entity is when it collides with another entity so some action could be taken (increase score, play sound, etc.). I initially tried setting up some sort of TypeComponent but it just seems a bit hackish as opposed to simply deriving from the base Entity class. Also, deriving from a base entity class gives strong-typing and type-safety support, gets rid of the public static builder class, and allows for polymorphic behavior and ease of determining an entity's type.
So I'm wondering, with all these positives and no perceivable negatives (other than .. more files? organization trumps file count in my opinion), why do most component systems favor these large builder/factory classes rather than my proposed approach?
avoid asking subjective questions where ... there is no actual problem to be solved: “I’m curious if other people feel like I do.” ... we are being asked an open-ended, hypothetical question: “What if ______ happened?” ... it is a rant disguised as a question: “______ sucks, am I right?”
\$\endgroup\$