Why is it a bad idea to store methods in Entities and Components? (Along with some other Entity System questions.)

This is a followup to this question, which I answered, but this one tackles with a much more specific subject.

This answer helped me understand Entity Systems even better than the article.

I've read the (yes, the) article about Entity Systems, and it told me the following:

Entities are just an id and an array of components (the articles says that storing entities in components isn't a good way of doing things, but doesn't provide an alternative).
Components are pieces of data, that indicate what can be done with a certain entity.
Systems are the "methods", they perform manipulation of data on entities.

This seems really practical in many situations, but the part about components being just data classes is bothering me. For example, how could I implement my Vector2D class (Position) in an Entity System?

The Vector2D class holds data: x and y coordinates, but it also has methods, which are crucial to its usefulness and distinguish the class from just a two element array. Example methods are: add(), rotate(point, r, angle), substract(), normalize(), and all other standard, useful, and absolutely needed methods that positions (which are instances of the Vector2D class) should have.

If the component was just a data holder, it wouldn't be able to have these methods!

One solution that could probably pop up would be to implement them inside systems, but that seems very counter-intuitive. These methods are things that I want to perform now, have them be complete and ready to use. I don't want to wait for the MovementSystem to read some expensive set of messages that instruct it to perform a calculation on the position of an entity!

And, the article very clearly states that only systems should have any functionality, and the only explanation for that, which I could find, was "to avoid OOP". First of all, I don't understand why should I refrain from using methods in entities and components. The memory overhead is practically the same, and when coupled with systems these should be very easy to implement and combine in interesting ways. The systems, for example, could only provide basic logic to entities/components, which know the implementation themselves. If you ask me - this is basically taking the goodies from both ES and OOP, something that can't be done according to the author of the article, but to me seems like a good practice.

Think about it this way; there are many different types of drawable objects in a game. Plain old images, animations (update(), getCurrentFrame(), etc), combinations of these primitive types, and all of them could simply provide a draw() method to the render system, which then doesn't need to care about how the sprite of an entity is implemented, only about the interface (draw) and the position. And then, I would only need an animation system which would call animation-specific methods that have nothing to do with the rendering.

And just one other thing... Is there really an alternative to arrays when it comes to storing components? I see no other place for components to be stored other than arrays inside an Entity class...

Maybe, this is a better approach: store components as simple properties of entities. For example, a position component would be glued to entity.position.

The only other way would be to have some kind of a strange lookup table inside systems, that references different entities. But that seems very inefficient and more complicated to develop than simply storing components in the entity.

• Alexandre are you just making a lot of edits to get another badge? Because that's naughty naughty, it keeps bumping a ton of ancient threads. – jhocking Jun 20 '17 at 20:30

I think it's totally fine to have simple methods for accessing, updating or manipulating the data in components. I think the functionality that should stay out of components is logical functionality. Utility functions are just fine. Remember, the entity-component system is just a guideline, not strict rules you need to follow. Don't go out of your way to follow them. If you think it makes more sense to do it one way, then do it that way :)

EDIT

To clarify, you're goal is not to avoid OOP. That would be pretty difficult in most of the common languages used these days. You're trying to minimize inheritance, which is a large aspect of OOP, but not required. You want to get rid of the Object->MobileObject->Creature->Bipedal->Human type inheritance.

However, it's OK to have some inheritance! You're dealing with a language that's heavily influenced by inheritance, it's very difficult to not use any of it. For example, you can have a Component class or interface that all your other components extend or implement. Same deal with your System class. This makes things a lot easier. I strongly recommend you take a look at the Artemis framework. It's open source and it has some example projects. Open those things up and see how it works.

For Artemis, entities are stored in an array, simple. However, their components are stored in an array or arrays (separate from the entities). The top level array groups the lower level array by component type. So each component type has its own array. The lower level array is indexed by entity ID. (Now I'm not sure if I'd do it that way, but that's the way it's done here). Artemis reuses entity IDs, so the max entity ID doesn't get larger than your current number of entities, but you can still have sparse arrays if the component is not a frequently used component. Anyway, I won't pick that apart too much. This method for storing entities and their components seems to work. I think it would make a great first pass at implementing your own system.

The entities and components are stored in an separate manager.

The strategy you mention, making entities store their own components (entity.position), is kind of against the entity component theme, but it's totally acceptable if you feel that makes the most sense.

• Hmm, that greatly simplifies the situation, thanks! I thought that there was some magic "you're gonna regret it later" thing going on, and I just couldn't see it! – jcora Jul 19 '12 at 22:54
• Na, I totally use them in my entity component system. I even have some components that inherit from a common parent, gasp. I think the only regretting you would do is if you tried to work around not using methods like that. It's all about doing what makes the most sense to you. If it makes sense to use inheritance or put some methods in a component, go for it. – MichaelHouse Jul 19 '12 at 22:58
• I've learned from my last answer on this subject. Disclaimer: I'm not saying this is the way to do it. :) – MichaelHouse Jul 19 '12 at 23:01
• Yeah, I know how daunting it can be to learn a new paradigm. Luckily, you get to use aspects of the old paradigm to make things easier! I've updated my answer with storage info. If you look at Artemis, check out the EntityManager as that's where things are stored. – MichaelHouse Jul 19 '12 at 23:44
• Nice! That's going to be a pretty sweet engine when it's done. Good luck with it! Thanks for asking interesting questions. – MichaelHouse Jul 20 '12 at 21:35

'That' article is not one I particularly agree with, so my answer will be somewhat critical I think.

This seems really practical in many situations, but the part about components being just data classes is bothering me. For example, how could I implement my Vector2D class (Position) in an Entity System?

The idea isn't to ensure that nothing in your program is anything other than an entity ID, component, or system - it's to ensure that entity data and behaviour is created through composing objects rather than either using a complex inheritance tree or worse trying to put all possible functionality into one object. To implement these components and systems you will certainly have normal data like vectors which are, in most languages, best represented as a class.

Ignore the bit in the article that suggests this is not OOP - it is just as OOP as any other approach. When most compilers or language runtimes implement object methods, it is basically just like any other function, except there is a hidden argument called this or self, which is a pointer to a place in memory where that object's data is stored. In a component based system, the entity ID can be used to find where the relevant components (and thus data) are for a given entity. Thus the entity ID is equivalent to a this/self pointer, and the concepts are basically the same thing, just rearranged a little.

And, the article very clearly states that only systems should have any functionality, and the only explanation for that, which I could find, was "to avoid OOP". First of all, I don't understand why should I refrain from using methods in entities and components.

Good. Methods are an effective way of organising your code. The important thing to take away from the "avoid OOP" idea is to avoid using inheritance everywhere to extend functionality. Instead, break the functionality up into components that can be combined to do the same thing.

Think about it this way; there are many different types of drawable objects in a game. Plain old images, animations (update(), getCurrentFrame(), etc), combinations of these primitive types, and all of them could simply provide a draw() method to the render system [...]

The idea of a component based system is that you wouldn't have separate classes for these, but would have a single Object/Entity class, and the image would be an Object/Entity that has an ImageRenderer, the Animations would be an Object/Entity that has an AnimationRenderer, etc. The relevant systems would know how to render these components and so there wouldn't need to be any base class with a Draw() method.

[...] which then doesn't need to care about how the sprite of an entity is implemented, only about the interface (draw) and the position. And then, I would only need an animation system which would call animation-specific methods that have nothing to do with the rendering.

Sure, but this doesn't work well with components. You have 3 choices:

• Every component implements this interface and has a Draw() method, even if nothing gets drawn. If you did this for every bit of functionality then components would look pretty ugly.
• Only components that have something to draw implement the interface - but who decides which components to call Draw() on? Does a system have to somehow query each component to see what interface is supported? That would be error-prone and potentially tricky to implement in some languages.
• Components are only ever handled by their owning system (which is the idea in the linked article). In which case, the interface is irrelevant because a system knows exactly what class or object type it's working with.

And just one other thing... Is there really an alternative to arrays when it comes to storing components? I see no other place for components to be stored other than arrays inside an Entity class...

You can store the components in the system. The array isn't the issue, but where you store the component is.

• +1 Thanks for another viewpoint. It's good to get a few when dealing with such an ambiguous subject! If you're storing components in the system, does that mean that components can only ever be modified by one system? For example, the drawing system and movement system would both access the position component. Where do you store it? – MichaelHouse Jul 20 '12 at 2:50
• Well they would only store a pointer to those components, which can, as long as I'm concerned be somewhere... Also, why would you store components in systems? Is there an advantage to that? – jcora Jul 20 '12 at 5:15
• Am I correct, @Kylotan? That's how I would do it, it seems logical... – jcora Jul 20 '12 at 11:25
• In Adam/T-Machine's example, the intention is that there is 1 system per component, but a system could certainly access and modify other components. (This hinders the multithreading benefits of components, but that's a different matter.) – Kylotan Jul 20 '12 at 15:02
• Storing components in the system allows better locality of reference for that system - that system only (generally) works with that data, so why go all over your computer's memory from entity to entity to get it? It also helps with concurrency because you could put a whole system and its data on one core or processor (or even a separate computer, in MMOs). Again, these benefits diminish when 1 system accesses more than 1 type of component, so that should be taken into account when deciding where to split component/system responsibilities. – Kylotan Jul 20 '12 at 15:06

A vector is data. The functions are more like utility functions - they're not specific to that instance of the data, they can be applied to all vectors independently. A nice way of thinking about it is: Can these functions be rewritten as static methods? If so, it's just utility.

• I know that, but the problem is that calling methods is faster and can be done on the spot by a system, or anything else that might need to manipulate an entity's position. I explained that, check it out, also, the question has a lot more to it than just this, I believe. – jcora Jul 19 '12 at 22:53