Skip to content
This repository has been archived by the owner on Mar 25, 2020. It is now read-only.

ECS framework

pointcache edited this page Jan 15, 2017 · 10 revisions

ECS stands for Entity-Component-System. There are several interpretations of this paradigm and this is what URSA thinks it is:

  • Entities are mere identifiers for a collection of Components.
  • Components only hold data, and simple properties (like converters, getters)
  • Systems don't communicate with each other, communicating through components.

Layman explanation in context of Unity:

Unity looks like an ECS, because it has "Entities"(gameObjects) and "Components"(MonoBehaviors), however the way they did it, is far from pure ECS approach, it is rather a "Component based system". First of all to have a pure Entity, all the components must belong to it, in Unity that is not the case. Unity tends to use a vast amount of GameObjects to represent an entity, if its a player rig, there are a lot of bones that each is a separate entity. This leaves the burden to identify the "root" entity on the developer, forcing him to create special root accessor scripts/controllers that gather references and make sense out of underlying hierarchy.

Thus in Unity there is no native clean way to abstract an arbitrary bunch of GameObjects into an "Entity". Next problem is the mixing of logic(system) and data(component). Unity explicitly teaches developers to encapsulate their code into scripts, however due to locality of those scripts they often end up being very tightly coupled, creating complex dependencies that are hard to maintain. While in some scenarios that is a desirable effect (selling encapsulated asset), in most it is not, and can be avoided by using ECS approach.

In URSA we solve those problems with 3 concepts.

  1. Component
  2. Entity
  3. System

Component in URSA, is what you would think of as an ECS component. It is implemented on top of MonoBehavior, and self registers in ComponentPool, allowing systems to easily iterate over them. Components, with exception of Config type, require an Entity somewhere on top, as their parent. Entity allows you to access components, no matter where in hierarchy they are located, which effectively abstracts us from knowing the details of GameObject composition of any entity. Components that belong to entity can easily access their entity and allow systems to access other entity components, just like you can access MonoBehaviors on a GameObject. All of that without having to know how the hierarchy is done.

While being very powerful ECS URSA doesn't force you to use it's components exclusively, MonoBehaviors can be used inside entities for graphics and other purposes that don't involve "abstraction" of the entity, that is - don't take on themselves responsibility to drive gameplay.

Systems are standard MonoBehaviors, as with many things in URSA, it is how you use them, not how they are forced upon you. Systems never communicate with other systems. Each system is interested in some components. Systems work in Update(), every frame iterating over components they get from Pool . If a system requires certain data to work it always get's it through the Pool, be it Config, or any other component, Pool<GraphicsConfig>.First .

In URSA, class Entity act's as an identifier for all of its children GO's, abstracting un

Additional read https://github.com/pointcache/JECSu

Clone this wiki locally