- Home /
Entity-Component-System
I come from an OOP background, and I'm trying to make a proper effort to write code that really embraces the ECS design pattern. Something that I've been reading is that Components are meant to be just data, and Systems run the code that acts on Components. Should I really be separating the code from the data like this in Unity? If so, how do people recommend I go about creating a System?
Cheers Joe
ECS is the paradigm in Unity (sort of), but ECS is still OOP. It's just an architecture inside. Ins$$anonymous$$d of using inheritance for everything, it favors using composition when possible.
Separating code from data isn't a bad idea per se, what do you want to do? You should usually want to decouple stuff like that as it is so you have the smallest list of dependencies as possible. Your game shouldn't depend on data, but it should use it.
I was reading the t-machine article on ECS http://t-machine.org/index.php/2007/11/11/entity-systems-are-the-future-of-mmog-development-part-2/ in which he says "Common misconception #1 – Entity Systems are part of OOP", it seems like everyone has their own interpretation of the design pattern with slight differences.
That's an interesting article! Thanks for sharing it. $$anonymous$$y response was less about it being a part of OOP (as an architecture) though. ECS is virtually impossible without OOP code. The OOP paradigm he talks about is just an 'old' way of doing things. It used to be right to subclass everything. Some people call that the OOP paradigm. I've never been a fan of the term as it's very confusing when you're talking about what is literally OOP code (ECS would definitely be), and what is an OOP architecture. TonyLi gets to the heart of question quite well though.
@Wuzseen yeah I think I get what you mean, a lot of people have been championing composition over inheritance for years, and as you say when I inherit from $$anonymous$$onoBehaviour I'm taking advantage of OOP program$$anonymous$$g.
Answer by TonyLi · Mar 21, 2014 at 03:15 PM
I don't think that the writer intended to imply that components are just data. Rather, each component addresses a very specific, narrow concern, such as "Hit Points" or "Navigation".
In an OOP approach, you might have a parent class that defines Hit Points, Navigation, and a slew of other concerns.
In a component-based approach, each concern is a separate class. This allows you to compose an entity of exactly what it needs. For example, an Orc would be composed of Hit Points and Navigation, but a Wall would only be composed of Hit Points since it's stationary and never needs to navigate anywhere.
Another advantage of component-based design is that each component is small and focused, so it's easy to write and maintain, its purpose is very clear, and it's decoupled from other code.
But to answer your question: No, don't separate code from data. Separate concerns. Your Hit Points component would have data (current and max hit points) and code to manipulate that data, but nothing else.
I actually did intend to imply that, in my reading about ECS on t-machine he says:
Nor do Components contain methods. Ins$$anonymous$$d, you have an external system for each aspect, and that external system contains all the methods that can be invoked on any Entity that possess the Component that marks it as being compatible with this system.
As I said in reply to a comment on my question, I think there's just many different interpretations to ECS with subtle variations. I have no problem putting code in a Component, it's what I've been doing up until now, just wanted to make sure that I should be doing that.
Sorry, I meant $$anonymous$$$$anonymous$$artin on t-machine. But you're right -- even he writes that there isn't a consensus on the terms. If I recall correctly, Jason Gregory, in Game Engine Architecture, discusses a very data-driven approach to component-based design, where entities are basically just tables of data. But, given how $$anonymous$$onoBehaviours are designed, it seems to me that Unity was designed with the idea that a component should have both code and data related to a specific concern (e.g., Nav$$anonymous$$eshAgent for navigation).
Ahhh I see sorry. Awesome, I haven't got to that part of GEA, I really ought to finish reading it. I suppose if you REALLY want to do this with $$anonymous$$onoBehaviours, you could just put the code in a second $$anonymous$$onoBehaviour. In particular I was thinking about trying to put any code that requires two different component types, in a $$anonymous$$onoBehaviour on its own. $$anonymous$$g. I have a bullet component with damage, and an NPC component with health. Then a third script on the bullet which listens for the Bullet script to fire off a "I hit something" event, at which point it looks for the NPC component on the thing that was hit, and applies the damage if it was found.
Answer by sebas77 · Oct 05, 2015 at 05:51 PM
Since I recently blogged about the argument, I'd like to add my answer. The question is old, but still relevant for other people. I can see the confusion. As mentioned in the previous answer, Unity doesn't really implemented an Entity Component System design, at least not the one designed by Adam Martin.
Unity framework design should be called Entity Component, since it misses the concept of "System". Systems in Unity cannot be designed by the programmer, but they are part of the Engine itself, so they are not extensible.
All the logic in Unity should be written inside focused MonoBehaviour. Every MonoBehaviour should have just one functionality, or responsibility, and they shouldn't operate outside the gameobject itself. They should be written with modularity in mind, in such a way they can be reused independently on several GameObjects. Monobehaviours also hold Data. The design obviously follows the basic concepts of OOP.
Modern design tends instead to separate data from logic. See for example the MVC or MVP patterns. Data, Views and Logic should be separated to achieve a better code modularity.
The real problem about Unity Entity Component design is that it's impossible to put two entities in communication in a reasonable way that doesn't lead to use various Anti-Pattern.
Unity inverts the control of the creation of the entities, thus the coder doesn't have any control on the creation of them. Inverting the creation control is a good thing, but Unity doesn't do it in a proper way. Not being able to inject dependencies in the Entities is a limitation that forces coders to use many anti-patterns in order to overcome all the intrinsics limitations. Basically the cleanest option is to use Singletons in order to share information between entities.
That's why it's quite hard to manage and maintain big projects with Unity. I wrote a lot about these problematics in my blog. So if you want you can continue reading my thoughts there:
http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-i-dependency-injection/
http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-ii-inversion-of-control/
http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-iii-entity-component-systems/
Svelto ECS has now been released : http://www.sebaslab.com/ecs-1-0/
Svelto ECS has now been released: http://www.sebaslab.com/ecs-1-0/
Just wanted to say thank you for recording your thoughts. "Not being able to inject dependencies in the Entities is a limitation that forces coders to use many anti-patterns in order to overcome all the intrinsics limitations." Seeing you say that validates a lot of my frustrations with writing what I consider clean, organized OOP code. I want to check out ECS when I find the time.
Your answer
![](https://koobas.hobune.stream/wayback/20220613140825im_/https://answers.unity.com/themes/thub/images/avi.jpg)