I’m playing with Zay-ES and developing a simple physics engine to a Voxel Engine, so I’ll have components to interact with physics system, for example, PhysicalBodyComponent, ColliderBoxComponent, PhysicalCollisionComponent and so on. Let’s say I got 5 or 6 components (maybe more) only for physics system, and I’ll have more 4 or 5 for, say, Entity Stats, like Attack, HP, MP, Skills etc. At the end, I may have dozen of components per entity (A Monster Entity may have all physics components, all stats components and another ones).
In few months, my game will have dozen of components, say 50~100. This is a sign of bad design? There is some problem in having such a huge of components per entity?
Also another problem I’m facing is to add a bunch of components per Entity, since I’ll have to manually add each component to entity. There is some kind of "grouping components"on Zay-ES? Like I create a group called “Kinematic Object” so it’ll have components X, Y and Z, so when I add this “group” all components on this group got added. Another group would be “Flying Monter Object”, and those group will have components A, B and C and so on. This would make easy to handle many components on a game.
Sorry if this post got inconsistent, but my doubt is about having many components and if there is some features on Zay-ES to handle easy those huge amount of components.
I see no problem in having lots of components. As long as you only write to one component from one system (that is, no two systems should be writing to the same component) and read from others. Perhaps a review of the design can end up consolidating your components from many down to less. But that would require more details.
You can always create static entity factory methods, that take the parameters for all entities in the group and return a list of components. You can then add this group to the entity you want. Or just send the EntityId to the static method and hook them up there. Factories makes sense if you do the same thing many times.
It would require more details to see if you could consolidate them. I dont see an issue in a high number of components, its how they are processed that could become an issue.
I currently separate all of my components so I have a lot of control over how much data has to be sent back and forth during multiplayer games. Each slot in my inventory is a separate component for example so an inventory change doesn’t cause me to send every single item back over the pipe every time you move a single item. This of course means that my component list for my entities can be fairly large. I haven’t noticed a huge impact on performance yet, but I have a fairly simple voxel world compared to most.
Seems like something that could have been handled with a component filter?
Also note that many of the components he specifically mentioned are probably server-side only… which is also a good distinction in this discussion.
Edit: actually rereading your bit about inventory slots, I still don’t understand why you’d have to send the whole inventory again just for one item moved. Wouldn’t the moved item be the only thing with a component that changed?
If they are separate components than yes you would only update a single component that represents a single item. If you stored your entire inventory as a component than any change to that component would cause you to resend all of the contents. At least that’s what I remember from when I made the decision to do it this way 2 odd years ago. There is probably a much better way to do this if I understood the theory better.
Ah, I see… you stored all of your inventory in one giant component. Yeah, that’s kind of upside down.
Inventory position isn’t much different than world position. An entity would have a ContainerPosition component that would contain the container entityId and the x,y position in that container. If that container (the inventory in this case) is open then it grabs all of the entities with a ContainerPosition that has that entityId as the containerId.
Generally, any time you have a list of things in a component then it’s backwards… but certainly if that list of things contains entities. Children point to parent not the other way around.
I got it. This is the main point to reduce the number of components. I only need to have components to “share” data between systems, be it on ES or another system on game. So a physics system doesn’t need to share all data with other systems, just a few, like: Final position, collisions and maybe some other specific data. Other infos should kept on a internal class storage on Physics System, so I save a lot of components by doing it.
So to add one rule of thumb on ES: A component must have a data to be “shared” between system.
EDIT: Also a side question: A System may have two or more distinct entity set? Like a Physics System may have a set for GravityAffectedComponent+CollisionBox and another for CollisionBox only?
Yes. That’s right. I kind of wish someone would collect these “rules of thumb” because I always forget to.
Yeah, it happens all the time. This is why I think an ES library like Zay-ES is more flexible because it does not force a system model upon you. “Systems” with Zay-ES are just “your code”… where as other ES library force you to implement some System interface and then they hand you the entities. In that case, I imagine they need a lot more potentially ugly system to system coordination.
But I quite frequently have more than one EntitySet in a ‘system’. Physics is a pretty prime example.
The beauty of the ES is that these components are independent. Seems a shame to start tying them together in needless ways right in the classes that don’t care how they’re used.
I honestly fail to see how that is any better than a factory method, personally. At least with the factory methods, all of your entity creation stuff is together in one place where it’s easy to see. If you add some new component some day then it is easy to inject it into the right places (or not) as needed. If someday you want to add a “Warrior Chief” entity that combines some new elements then you don’t have to go touch a dozen component classes… you just add a new method.
It’s also way easier to convert it over to some data-driven approach later.
I’ve overhauled the Zay-ES wiki a bit, reorganized it, added some pages, and setup the TOC generator that I use on my other project wikis.
There is a place now for these ‘rules of thumb’ but I’ve only filled in a couple. I will likely turn them into headings so that there can be some description with them or at least link them to a more detailed breakout at some point. The rule on its own is nice in a list but often someone will want more detail.