Search Unity

I need to confirm my understanding of the ECS

Discussion in 'Entity Component System' started by LiefLayer, Jul 18, 2018.

  1. LiefLayer

    LiefLayer

    Joined:
    Jan 6, 2013
    Posts:
    65
    After watching many sample code I was still confused about the ECS pattern, in the end I decided to just read some old articles about how to make an ECS in Unity (when it, of course, was not possible) and now I think I finally understand it... still I'm not really sure. Well I'll just try to say what I think I have understand, just tell me if I'm right or wrong.
    The main problem was, at least for me, that when unity try to explain what is a component it always say "it only contains data"... but, for what I've understand, Component contains variables (also other Entities variables)... and I know, maybe it's the same thing, but my idea of data was "things that you read from a DB" (like in the MVC pattern were the model is the parts that communicates with the database).

    So, if for monobehaviour it was an Entity-Component thing (where a GameObject was an Entity, and a Component was a script with variables and logic that you should apply to that GO), with ECS you have an Entity (GameObject) a Component (script without Start and Update, just variables), and finally we have the System a single script that loop the Entities and apply OnStart OnUpdate, Collision, Trigger etc... logic.

    Example:
    I have a CameraEntity
    I have a Component that contains
    public PlayerEntity target

    the System can
    get the CameraEntity and move the target.

    Is that right, or I'm missing something?

    If that is right
    what's different from doing a monobehaviour with reference to every GameObject on the scene? (every GO with their scripts that only holds variables with getters/setters)?
    It is just a performance thing or there is something else that I'm missing?
     
  2. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,537
    Have you watched this?
     
  3. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I have but to be fair it doesn't help if English isn't your native language or rely on subs in any way :)
     
  4. LiefLayer

    LiefLayer

    Joined:
    Jan 6, 2013
    Posts:
    65
    I tried, but it's not easy to understand, not only because english is not my native language but also because it's not a simple example... it's a 1 hour and 40 video and it's easy to lose focus.
    Of course I will watch and try everything once I will need to use the new ECS, but right now I only need to undestand if I have a basic idea of the pattern or if I'm completely off.
    If I can undestand the basic idea I'm sure I will be able to learn much faster.

    Maybe you can tell me if my basic idea is right or if I'm missing the point.
     
  5. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,537
    I don't fully understand the workflow yet either, but I refer to that video a lot and just skim to parts that are relevant.

    There's really not a simple, easy, strightforward way to explain it right now. I guess ECS itself is basically a design pattern but Unity has specific, deeply integrated support for it that makes it really fast.

    Fundamentally you are required to separate Data and Behavior and in your behavior systems you rely on Unity to Inject some variables you tag - with Data types you ask for that exist. It keeps track of those data entities and returns them to you in a tidy way so that you can have big overall Behavior systems that do things to the data and in turn the scene entities.

    Code (csharp):
    1.  
    2.  
    3.         [Inject] private PlayerInput[] m_Input;
    4.  
    5.         protected override void OnUpdate()
    6.         {
    7.             for (int i = 0; i < m_Input.Length; i++)
    8.             {
    9.                 // Get inputs
    10.                 m_Input[i].LeftStickX = Input.GetAxis("Horizontal");
    11.                 m_Input[i].LeftStickZ = Input.GetAxis("Vertical");
    12.             }
    13.         }
    14.  
    15.  
    Above, the [Inject] attribute tells Unity that you want all of the Data entities of this type.

    Then, in the OnUpdate() method you do something with them, in this case populate m_Input with values from the Unity Input system. (wasd)

    In another behavior system you use those results inside that data to apply to something else, like a scene object. You can fetch an array of scene components like you could an array of struct's like PlayerInput[].

    Everything is very compartmentalized. You'll have many scripts that do few things instead of fewer large scripts that do lots of things. There are a lot of moving parts right now, there will be more cohesive support in the future and at the moment you're basically doing most of the work in code rather than making customizable prefabs and stuff very easily like the classic approach.

    The patterns are basically
    • Classic OOP (Monobehaviors, ScriptableObjects, lots of inspector use)
    • Hybrid ECS (Using MonoBheaviors for configurations and ECS for all behavioral code)
    • Pure ECS (basically do everything in code, including mesh drawing)

    So there's a lot up in the air, few clear paths forward in terms of design and generally a lot of digging that a person needs to do just to get started. You can only use blittable types right now, which means the Data structs you make are quite simple and not like you're used to with fancy Monobehavior's, tidy inspectors and custom types like Quaternions and Vector3s.
     
    Last edited: Jul 18, 2018
  6. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    I think you got the basic idea right - I say “think” because you are simplifying a lot.

    The thing that you don’t have right, is your last paragraph - while you could replicate the “concept” of how the ecs pattern works with mono behaviors (the “hybrid ecs” way is pretty close to your description), pure ECS is laying out the data hardware friendly (the documentation describes this ok, there are also a few good threads here that speak about it)

    In general, the combination of ECS, jobs, burst/math is what creates the speed gains for critical code parts.

    I am myself not very experienced in this and because it’s pre-alpha it requires some extra efffort to learn / get into it. In general I think it’s worth learning it at some point, but it should be easier once it is more mature - safe to give it some time unless you want to play around with it now, it’s good enough for experimenting...
     
  7. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    An entity in ECS is not an object (at least in unity )
    to better understand data-oriented design you have to stop thinking by objects
    in fact, it is much simpler and cleaner than oop

    Component - is a pure data (without any business logic) very similar to a database, but instead of tables entities are used to group data into meaningful sets
    Entity - is not an object and contain no data and no logic, the entity is an abstract identifier that groups different components together
    Systems - is the only place where all logic is located, systems are able to iterate over datasets (Groups) of similar entity type (Archetype) and read/write data
    EntityManager - is a special system that manages data
    Archetype - is a list of component types
    World - a thing that owns and invokes systems one by one


    here is an old but great for beginners article by Richard Lord,
    http://www.richardlord.net/blog/ecs/what-is-an-entity-framework.html
    all sample code there is in ActionScript (which is dead) but you can assume this is a pseudo code
     
  8. LiefLayer

    LiefLayer

    Joined:
    Jan 6, 2013
    Posts:
    65
    I'm sorry but I still don't understand.
    Pure data means what?
    That they only contains variables?
    That is the most difficult thing to understand for me.
    Even if they are not object for the pattern they are still C# class with variables... or am I wrong?

    Entity is the current GameObject (at least that what I understand). Where components get attached... Or am I wrong?

    In the link:

    class PositionComponent
    {
    public var x:Number;
    public var y:Number;
    public var rotation:Number;
    }

    is a component... So, like I said, it's a class with only variables, or am I missing something?

    I think the reason why I don't understand this is because I don't really understand the concept of "just data".
    In a database if I create a table the "just data" part is the actual content of the table.

    I'm sorry but can you just tell me if this
    class PositionComponent
    {
    public var x:Number;
    public var y:Number;
    public var rotation:Number;
    }

    A component is just a Class with only variables? If this is true I will just assume that "just data" mean "Class with only variables". If this is wrong try to tell me why.
     
  9. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    almost.
    in Unity ECS components are structs. struct means:
    - it has value type semantics (i.e. passing it to a method copies it instead of passing a reference)
    - it doesn't cause garbage collection
    - an array of structs has a linear memory layout and is cache friendly.

    for the rest:
    - components are 'just data' (i.e. structs with only fields)
    - systems contains all the logic (and no data)
    - entities defines which component go together. they logically have the role of a game object, but they don't "contain components". e.g. in a database an entity is the primary key
     
    chin likes this.
  10. LiefLayer

    LiefLayer

    Joined:
    Jan 6, 2013
    Posts:
    65
    Ah ok... so struct are just like struct in C, new basic type (like int, double, float etc...).
    That's why "just data", because every variable it's always a copy, never a reference.

    Ok now I think I really understand the Components part.
    And I realize why my first example was not right... because the target is a PlayerEntity so I will already have access to it in the System.

    The Entity part is still not 100% clear. If I have a PlayerEntity I need to add Components to my PlayerEntity.
    I understand the concept of primary key in a database, but how do you link Entity and Components?
    Maybe with something like:
    class PlayerEntity{
    public int id;
    }
    that you attach to a GO in the scene together with components (like in the 3 image here):
    https://github.com/Unity-Technologi...ter/Documentation/content/rotation_example.md

    And finally in my PlayerSystem (for example) I should have access to every Entity as variables.
    And get Components from Entitiies... And change the logic.

    I know that my reasoning is full of terms derived from OOP programming, but I have only done that for many years, and it is difficult to reason otherwise without using those terms.
    Thank you for your patience
     
  11. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    Entity do not have Methods
    Entity is not an object it is a struct as well
    Entity do not contain components - instead EntityManager have a knowledge to which entity component belongs
    Entity do not have even name or type

    An entity is a unique id to request data (technically it is a unique pair of two integers)

    For example, if you would like to define a potato in ECS it may look like this:

    Entity
    - PotatoComponent {}
    - SizeComponent {Value:50}
    - MassComonent {Value:25}
    - IqComonent {Value:0}

    notice a PotatoComponent that has no data, it is there to mark this entity as a potato
    there is no other way to say that this is a potato-entity
    without components, entity is nothing but ID
     
    TeHuster likes this.
  12. LiefLayer

    LiefLayer

    Joined:
    Jan 6, 2013
    Posts:
    65
    Thank you.
    In the end... I'm not sure I want to deal with structs if performance are not critical.
    I think I will just use ECS when I really need it.
    I will still try it because now that I understand the basics I want to know how to use it in a real application (not just pseudo-code), and the only way is to write some code.
     
  13. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    performance is not the only benefit of ECS

    • Extensibility - ECS forces developer to use composition instead of inheritance - what makes inheritance mess impossible
    • Separation - As long as data is clearly separated from logic, saving a game or synchronizing few clients is not a painful task anymore
    • Reusability - As long as systems do not care on what type they operate, only about data they operate on, all systems become reusable
    • Inversion of control - with Unity ECS you getting dependency injection out of the box

    so for the small game or fast prototype, it may have no difference what to use OOP or ECS, but if your game is growing, the bigger it gets the more reasonable it becomes to use ECS
     
  14. LiefLayer

    LiefLayer

    Joined:
    Jan 6, 2013
    Posts:
    65
    inheritance is not always a bad thing in game development. And unity already try to push you on composition
    It is also easy to mantain data separated from logic and reuse scripts for different objects.
    I have to say that I really like the current pattern.
    But I like the fact that they are trying to create something optional for good performance (if they will like to replace the current system they need to create something to port the current code automatically to ecs) .
    It is like multi thread. You usually dont need it.
     
  15. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    and:
    • determinism
    • potentially amazing networking