It's the conceptual organization. The Entity is defined by data (components) that bring along behavior (systems). So an entity executing at runtime (say you're making Pacman and it's the Red Ghost) is an object and is defined by the combination of data and behavior.
The underlying implementation is irrelevant basically. You could implement the ECS in an OOP style and the same it true. You could do it in a functional style and it would be true. You could do it in straight bytecode for some obscure hobby VM and it would be true.
Unlike traditional OOP, the data and behavior are decoupled though. Similar to data and functions.
That is, you can add components that don’t get operated on by any particular systems because the entity doesn’t have the other prerequisite components and you can have systems that don’t operate on the components. You can have many systems operate on one particular component and many components operated on by a system.
In OOP, the data and the operations are packaged to whether as one. You also typically have encapsulation and it’s considered bad practice for one class to operate on another classes data directly.
It seems that both models achieve similar things, but they’re far from the same thing. Just like how procedural or functional programming achieve similar things to OOP, and you can do OOP in these paradigms or these paradigms in OOP. There’s a lot of cross over, but that doesn’t make them all the same thing.
If anything, I’d say that ECS are a relational model but with a very limited query system compared to something like SQL.
> Unlike traditional OOP, the data and behavior are decoupled though. Similar to data and functions.
Except the data and behavior aren't decoupled. The components are decoupled from the systems, but the systems are still very much dependent on the components. Just like a method is usually dependent on the instances data or a function is dependent on the data passed in.
> That is, you can add components that don’t get operated on by any particular systems because the entity doesn’t have the other prerequisite components and you can have systems that don’t operate on the components. You can have many systems operate on one particular component and many components operated on by a system.
You can have a member that isn't operated on by any methods and methods that don't operate on members.
At the level your talking about there isn't much difference between a function and a method. It's mostly syntax.
method(instancedata);
verses
instancedata.method();
Really we're getting caught up in implementation details because a class definition isn't the be all of how to define an object. There is really no reason we couldn't define objects in a programming language through composition.
ECS very much is a relational model and you're right it's very limited in comparison to things like SQL because it's trying to model something very simple. Game Objects! The relations defined are exactly what brings data and behavior together under to create the runtime object we call an Entity under the pattern conventions.
> Just like a method is usually dependent on the instances data or a function is dependent on the data passed in.
Just like a C function operating on a C struct. So, what, in your opinion, is the difference between procedural programming and OOP?
> It's mostly syntax.
Which is why I think there is more to OOP than a classes attributes and it’s methods. There is also inheritance, encapsulation levels, the fact that an objects identity is its attributes (the object is its data, an entity has its components but is separate from them), the fact that an object is a singular thing which it’s methods operate on (as opposed to how systems operate on collections of components, imagine a class system where a method operated on all instances of that class!).
Sure at the end of the day it’s all the same and we’re just arguing semantics, but that was my point and what I lead with: it’s an overly broad definition. If definitions are too broad then they really don’t add any value, but I believe a distinction between OOP and ECS is useful because they are used in different ways.
But fundamentally I don’t disagree, I even once wrote a blog post about how all of the OOP principles exist in an ECS! I just don’t believe that thinking of them as slightly different implantations of OOP is useful because of how their properties differ.
I actually wrote way back at the start about encapsulation and inheritance (along with message passing). So I'm not sure my definition really is overly broad.
I'm also mostly talking about the runtime consequences of the things that most people worry about at the time of programming.
The underlying implementation is irrelevant basically. You could implement the ECS in an OOP style and the same it true. You could do it in a functional style and it would be true. You could do it in straight bytecode for some obscure hobby VM and it would be true.