Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is the Entity Component System architecture object oriented, by definition? It seems more procedural or functional to me. My opinion is that it doesn't prevent you from implementing it in an OO language, but it would not be idiomatic to do so in a staunchly OO way.

It seems like ECS separates data (E & C) from behavior (S). As evidence:

The idea is to have no game methods embedded in the entity.

And:

The component consists of a minimal set of data needed for a specific purpose

Systems are single purpose functions that take a set of entities which have a specific component


I think this is not object oriented because a big part of being object oriented is combining your data and behavior together. As evidence:

In contrast, the object-oriented approach encourages the programmer to place data where it is not directly accessible by the rest of the program. Instead, the data is accessed by calling specially written functions, commonly called methods, which are bundled in with the data.

ECS, on the other hand, seems to be all about separating your data from your behavior.

share|improve this question

Introduction


Entity–component systems are an object-oriented architectural technique.

There is no universal consensus of what the term means, same as object-oriented programming. However, it is clear that entity–component systems are specifically intended as an architectural alternative to inheritance. Inheritance hierarchies are natural for expressing what an object is, but in certain kinds of software (such as games), you would rather express what an object does.

It is a different object model than the “classes and inheritance” one to which you’re most likely accustomed from working in C++ or Java. Entities are as expressive as classes, just like prototypes as in JavaScript or Self—all of these systems can be implemented in terms of one another.

 

Examples


Let’s say that Player is an entity with Position, Velocity, and KeyboardControlled components, which do the obvious things.

entity Player:
  Position
  Velocity
  KeyboardControlled

We know Position must be affected by Velocity, and Velocity by KeyboardControlled. The question is how we would like to model those effects.

 

Entities, Components, and Systems


Suppose that components have no references to one another; an external Physics system traverses all Velocity components and updates the Position of the corresponding entity; an Input system traverses all KeyboardControlled components and updates the Velocity.

          Player
         +--------------------+
         | Position           | \
         |                    |  Physics
       / | Velocity           | /
  Input  |                    |
       \ | KeyboardControlled |
         +--------------------+

This satisfies the criteria:

  • No game/business logic is expressed by the entity.

  • Components store data describing behaviour.

The systems are now responsible for handling events and enacting the behaviour described by the components. They are also responsible for handling interactions between entities, such as collisions.

 

Entities and Components


However, suppose that components do have references to one another. Now the entity is simply a constructor which creates some components, binds them together, and manages their lifetimes:

class Player:
  construct():
    this.p = Position()
    this.v = Velocity(this.p)
    this.c = KeyboardControlled(this.v)

The entity might now dispatch input and update events directly to its components. Velocity would respond to updates, and KeyboardControlled would respond to input. This still satisfies our criteria:

  • The entity is a “dumb” container which only forwards events to components.

  • Each component enacts its own behaviour.

Here component interactions are explicit, not imposed from outside by a system. The data describing a behaviour (what is the amount of velocity?) and the code that enacts it (what is velocity?) are coupled, but in a natural fashion. The data can be viewed as parameters to the behaviour. And some components don’t act at all—a Position is the behaviour of being in a place.

Interactions can be handled at the level of the entity (“when a Player collides with an Enemy…”) or at the level of individual components (“when an entity with Life collides with an entity with Strength…”).

 

Components


What is the reason for the entity to exist? If it is merely a constructor, then we can replace it with a function returning a set of components. If we later want to query entities by their type, we can just as well have a Tag component which lets us do just that:

function Player():
  t = Tag("Player")
  p = Position()
  v = Velocity(p)
  c = KeyboardControlled(v)
  return {t, p, v, c}
  • Entities are as dumb as can be—they’re just sets of components.

  • Components respond directly to events as before.

Interactions must now be handled by abstract queries, completely decoupling events from entity types. There are no more entity types to query—arbitrary Tag data is probably better used for debugging than game logic.

 

Conclusion


Entities are not functions, rules, actors, or dataflow combinators. They are nouns which model concrete phenomena—in other words, they are objects. It is as Wikipedia says—entity–component systems are a software architecture pattern for modeling general objects.

share|improve this answer
1  
The main alternative to class-based OO, prototype-based OO, also seems to couple data and behaviour. Actually, it seems to differ from ECS just as much as class-based OO does. So could you elaborate what you mean by OO? – delnan Sep 17 '13 at 14:23
    
To add on to @delnan's question, are you disagreeing with the snippet of the OO wikipedia article I quoted? – Daniel Kaplan Sep 17 '13 at 16:32
    
@tieTYT: The Wikipedia quote is talking about encapsulation and information hiding. I don’t think it is evidence that data–behaviour coupling is required, only that it is common. – Jon Purdy Sep 17 '13 at 17:31
    
@delnan: I don’t mean anything by OO. Object-oriented programming, to me, is exactly what it says on the tin: programming with “objects” (as opposed to functions, rules, actors, dataflow combinators, etc.) where the particular definition of object is implementation-defined. – Jon Purdy Sep 17 '13 at 17:34
    
@JonPurdy Well what part of ECS crosses that line to make you say it's an "object-oriented architectural technique"? I don't think I understand what that line is. – Daniel Kaplan Sep 17 '13 at 18:40

Entity component systems (ECSs) can be programmed in an OOP or functional manner depending on how the system is defined.

OOP way:

I have worked on games where an entity was an object composed of various components. The entity has an update function which modifies the object in place by calling update on all its components in turn. This is clearly OOP in style - behaviour is linked to data, and the data is mutable. Entities are objects with constructors/destructors/updates.

More functional way:

An alternative is for the entity to be data without any methods. This entity may exist in its own right or simply be an id which is linked to various components. This way it is possible (but not commonly done) to be fully functional and have immutable entities and pure systems which generate new component states.

It seems (from personal experience) that the latter way is gaining more traction and for good reason. Separating entity data from behaviour results in more flexible and reusable code (imo). In particular, using systems to update components/entities in batches can be more performant, and completely avoids the complexities of inter-entity messaging which plague many OOP ECSs.

TLDR: You can do it either way, but I would argue that the benefits of good entity component systems derive from their more functional nature.

share|improve this answer
    
More traction especially since the whole point of components was to get away from intractable OOP hierarchies, good description of the benefit. – Patrick Hughes Jun 11 '14 at 5:50

NO. And I'm surprised how many people voted otherwise!

Paradigm

It's Data-Oriented a.k.a. Data-Driven because we are talking about the architecture and not the language it's written in. Architectures are realizations of programming styles or paradigms, which can usually be unadvisably worked around in a given language.


Functional?

Your comparison to Functional/Procedural programming is a relevant and meaningful comparison. Note, however, that a "Functional" language is different from the "Procedural" paradigm. And you can implement an ECS in a Functional language like Haskell, which people have done.


Where cohesion happens

Your observation is relevant and spot-on:

"...[ECS] doesn't prevent you from implementing it in an OO language, but it would not be idiomatic to do so in a staunchly OO way"


ECS/ES is not EC/CE

There is a difference between the component-based architectures, "Entity-Component" and "Entity-Component-System". Since this is an evolving design pattern, I have seen these definitions used interchangeably. "EC" or or "CE" or "Entity-Component" architectures put behavior in components, whereas "ES" or "ECS" architectures put behavior in systems. Here are some ECS articles, both of which use misleading nomenclature, but get the general idea across:

If you're trying to understand these terms in 2015, make sure someone's reference to "Entity Component System" doesn't mean "Entity-Component architecture".

share|improve this answer

Data-Oriented Entity Component Systems can coexist with Object-Oriented Paradigms - firstly, Systems themselves tend to be object-based: we're likely to create custom systems based on existing built-in ones, and there is VERY likely to be a base System class, or interface, depending on your preference. And secondly, Components can be both POD (plain old data) and ALSO Objects (with a Class and Methods), and the whole thing is still 'data oriented', provided that Component Class Methods only manipulate data owned by the object they are touching - it's ok to have 'dumb data classes with methods that manipulate that data' and call that a Component, but avoid Virtual Methods, because if you have them, your component is no longer purely component data, plus those methods cost more to call. Example would be vec2 or vec3, a data container, with some methods that could be useful when working with that data, that may manipulate the data in that object container, but don't do anything to any external data by default. It's ok to do this, but you should be custom-allocating your components and managing component memory yourself. Sourcecode on request.

http://bitsquid.blogspot.com.au/ <-- useful!

share|improve this answer
2  
this post is rather hard to read (wall of text). Would you mind editing it into a better shape? Also, it would help if you explain to readers why they may find linked blog article useful and relevant to the question asked... – gnat Jul 5 '15 at 11:59
    
...in case if you're somehow related to that blog (are you?), it would be also desirable to disclose affiliation – gnat Jul 5 '15 at 12:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.