Svelto ECS is now production ready

Six months have been passed since my last article about Inversion of Control and Entity Component System and meanwhile I had enough time to test and refine my theories, which have been now proven to work in a production environment quite well. During these months of putting in practice my ideas, I had the chance to consolidate my analysis and improve the code. As result Svelto ECS framework is now ready.

Let’s start from the basics explaining why I use the word framework, which is very important. My previous work, Svelto IoC, cannot be defined as a framework; it’s instead a tool. As a tool, it helps to perform Dependency Injection and design your code following the Inversion of Control principle. Svelto IoC is nothing else, therefore whatever you do with it, you actually can do without it in a very similar way, without changing much the design of your code. As such, svelto IoC doesn’t dictate a way of coding, doesn’t give a paradigm to follow, leaving to the coder the burden to decide how to design the game infrastructure.

Svelto ECS won’t take the place of Svelto IoC, however it can be surely used without it. My intention is to add some more features to my IoC container in future and also write another article about how to use it properly, but as of now, I would not suggest to use it, unless you are actually aware of what IoC actually means and that you are actually looking for an IoC container that well integrates in your existing design (like, for example, to create a MVP based GUI framework). Without understanding the principles behind IoC, using an IoC container can result in very dangerous practices. In fact I have seen smell code and bad design implementations that actually have been aided by the use of an IoC container. These ugly results would have been much harder to achieve without it.

Svelto ECS is instead a framework and with it you are forced to design your code following its specifications. It’s the framework to dictate the way you have to write your game infrastructure. The framework is also relatively rigid, forcing to follow a well defined pattern. Using this kind of framework is important for a medium-large team, because coders have different levels of experience and it is impossible to expect from everyone to be fully able to design well structured code. Using a framework which implicitly solves the problem to design the code, will let all the coders focus only on the implementation of algorithms, knowing with a given degree of certainty, that the amount of refactoring needed in future will be more limited than it would have been if left on their own.

The first error I made, with the previous implementation of this framework, was to not well define the concept of Entity. I noticed that it is actually very important to have clear in mind what the elements of the project are before to write the relative code. Entities, Components, Engines and Nodes must be properly identified in order to write code faster. An Entity is actually a fundamental and well defined element in the game. The Engines must be designed thinking about managing Entities and not Components or Nodes. Characters, enemies, bullets, weapons, obstacles, bonuses, GUI elements, they are all Entities. It’s easier, and surely common, to identify an Entity with a view, but a view is not necessary for an Entity. As long as the entity is well defined and makes sense for the logic of the game, it can be managed by engines regardless its representation.

In order to give the right importance to the concept of Entity, Nodes cannot be injected anymore into Engines until an Entity is explicitly built. An Entity is now built through the new BuildEntity function and the same function is used to give an ID to the Entity. The ID doesn’t need to be unique, this is a decision left to the coder. For example as long as the ID of all the bullets are unique, it doesn’t matter if the same IDs are used for other entities managed by other engines.

The Setup

Following the example, we start from analysing the MainContext class. The concept of Composition Root, inherited from the Svelto IoC container, is still of fundamental importance for this framework to work as well. It’s needed to give back to the coder the responsibility of creating objects (which is currently the greatest problem of the original Unity framework, as explained in my other articles) and that’s what the Composition Root is there for. By the way, before to proceed, just a note about the terminology. While I call it Svelto Entity Component System framework, I don’t use the term System, I prefer the term Engine, but they are the same thing.

In the composition root we can create our ECS framework main Engines, Entities, Factories and Observers instances needed by the entire context and inject them around (a project can have multiple contexts and this is an important concept).

In our example, it’s clear that the amount of objects needed to run the demo is actually quite limited:

The EngineRoot is the main Svelto ECS class and it’s used to manage the Engines. If it’s seen as IEntityFactory, it will be used to build Entities. IEntityFactory can be injected inside Engines or other Factories in order to create Entities dynamically in run-time.

It’s easy to identify the Engines that manage the Player Entity, the Player Gun Entity and the Enemies Entities. The HealthEngine is an example of generic Engine logic shared between specialized Entities. Both Enemies and Player have Health, so their health can be managed by the same engine. DamageSoundEngine is also a generic Engine and deals with the sounds due to damage inflicted or death. HudEngine and ScoreEngine manage instead the on screen FX and GUI elements.

I guess so far the code is quite clear and would invite you to know more about it. Indeed, while I explained what an Entity is,  I haven’t given a clear definition of Engine, Node and Component yet.

An Entity is defined through its Implementers and Components. A Svelto ECS Component defines a shareable contextualized collection of data and events. A Component can exclusively hold data (through properties) and events (through the Svelto ECS Dispatcher classes) and nothing else. How the data is contextualized (and then grouped in components) depends by how the entity can been seen externally. While it’s important to define conceptually an Entity, an Entity does not exist as object in the framework, and it’s seen externally only through its components. More generic the components are, more reusable they will be. If two Entities need health, you can create one IHealthComponent, which will be implemented by two different Implementers. Other examples of generic Components are IPositionComponent, ISpeedComponent, IPhysicAttributeComponent and so on. Component interfaces can also help to reinterpret or to access the same data in different ways. For example a Component could only define a getter, while another component a setter for the same data on the same Implementer. All this helps to keep your code more focused and clean. Once the shareable data options are exhausted, you can start to declare more entity specific components. Bigger the project becomes, more shareable components will be found and after a while this process will start to become quite intuitive. Don’t be afraid to create components even just for one property only as long as they make sense and help to share components between entities. More shareable components there are, less of them you will need to create in future. However it’s wise to make this process iterative, so if initially you don’t know how to create components, start with specialised ones and the refactor them later.
As I said, Components do not hold just data, the also hold events. This something I have never seen before in other ECS framework and it’s a very powerful feature, I will explain why later, but for the time being, just know that Components can also dispatch events through the Dispatcher class.

The Implementer concept was existing already in the original framework, but I didn’t formalize it at that time. One main difference between Svelto ECS and other ECS frameworks is that Components are not mapped 1:1 to c# objects. Components are always known through Interfaces. This is quite a powerful concept, because allows Components to be defined by objects that I call Implementers . This doesn’t just allow to create less objects, but most importantly helps to share data between Components. Several Components can been actually defined by the same Implementer. Implementers can be Monobehaviour, as Entities can be related to GameObjects, but this link is not necessary. However, in our example, you will always find that Implementers are Monobehaviour. This fact actually solves elegantly another important problem, the communication between Unity framework and Svelto ECS.
Most of the Unity framework feedback comes from predefined Monobehaviour functions like OnTriggerEnter and OnTriggerExit. One of the benefit to let Components dispatch events is that in this way the communication between the Implementer and the Engines become totally natural. The Implementer as Monobehaviour, dispatches an IComponent event when OnTriggerEnter is called. The Engines will then be notified later and act on it. When you need to communicate events between Implementers and Engines, as opposite between Engines and Engines, you can also use normal events.

It’s fundamental to keep in mind that Implementers MUST NOT DEFINE ANY LOGIC. They must ONLY implement component interfaces, hold the relative states and act as a bridge between Unity and the ECS framework in case they happen to be also Monobehaviours.

So Components are a collection of Data and Events, Implementers define the components and don’t have any logic. Hence where all the game logic will be? All the game logic will be written in Engines and Engines only. That’s what they are there for. As a coder, you won’t need to create any other class. You may need to create new Abstract Data Types to be used through components, but you won’t need to use any other pattern to handle logic. In fact, while I still prefer MVP patterns to handle GUIs, without a proper MVP framework (which doesn’t exist for Unity yet), it won’t make much difference to use Engines instead. Engines are basically presenters and Nodes hold views and models.

OK, so, before to proceed further with the theory, let’s go back to the code. We have easily defined Engines, it’s now time to see how to build Entities. Entities are injected into the framework through Entity Descriptors. EntityDescriptor describes entities through their Implementers and present them to the framework through Nodes . For example, every single Enemy Entity, is defined by the following EnemyEntityDescriptor:

This means that an Enemy Entity and its components, will be introduced to the framework through the nodes EnemyNode, PlayerTargetNode and HealthNode and the method BuildEntity used in this way:

While EnemyImplementor implements the EnemyComponents, the EnemyEntityDescriptor introduces them to the Engines through the relative Enemy Nodes. Wow, it seems that it’s getting complicated, but it’s really not. Once you wrap your head around these concepts, you will see how easy is using them. You understood that Entities exist conceptually, but they are defined only through components which are implemented though Implementers. However you may wonder why nodes are needed as well. While Components are directly linked to Entities, Nodes are directly linked to Engines. Nodes are a way to map Components inside Engines. In this way the design of the Components is decoupled from the Engines. If we had to use Components only without Nodes, often it would become very awkward to design them. Should you design Components to be shared between Entities or design Components to be used in specific Engines? Nodes rearrange group of components to be easily used inside Engines. Nodes are mapped directly to Engines. specialized Nodes are used inside specialized Engines, generic Nodes are used inside generic Engines. For example: an Enemy Entity is an EnemyNode for Enemy Engines, but it’s also a PlayerTargetNode for the PlayerShootingEngine. The Entity can also be damaged and the HealthNode will be used to let the HealthEngine handle this logic. Being the HealthEngine a generic engine, it doesn’t need to know that the Entity is actually an Enemy. different and totally unrelated engines can see the same entity in totally different ways thanks to the nodes. The Enemy Entity will be injected to all the Engines that handle the EnemyNode, the PlayerTargetNode and the HealthNode Nodes. It’s actually quite important to find Node names that match significantly the name of the relative Engines.

As we have seen, entities can easily be created explicitly in code passing a specific EntityDescriptor to the BuildEntity function. However, some times, it’s more convenient to exploit the polymorphism-like feature given by the IEntityDescriptorHolder interface. Using it, you can attach the information about which EntityDescriptor to use directly on the prefab, so that the EntityDescriptor to use will be directly taken from the prefab, instead to be explicitly specified in code. This can save a ton of code, when you need to build Entities from prefabs.

So we can define multiple IEntityDescriptorHolder implementations like:

and use them to create Entities implicitly, without needing to specify the descriptor to use, since it can be fetched directly from the prefab (i.e.: playerPrefab, enemyPrefab):

Once Engines and Entities are built, the setup of the game is complete and the game is ready to run. The coder  can now focus simply on coding the Engines, knowing that the Entities will be injected automatically through the defined nodes. If new engines are created, is possible that new Nodes must be added, which on their turn will be added in the necessary Entity Descriptors.

The Logic in the Engines

the necessity to write most of the original boilerplate code has been successfully removed from this version of the Framework. An Important feature that has been added is the concept of IQueryableNodeEngine. The engines that implement this interface, will find injected the property

This new object remove the need to create custom data structures to hold the nodes. Now nodes can be efficiently queried like in this example:

This example also shows how Engines can periodically poll or iterate data from Entities. However often is very useful to manage logic through events. Other ECS frameworks use Observer or very awkward “EventBus” objects to solve communication via events. Event bus is an anti-pattern and the extensive use of observers could lead to messy and redundant code. This is why I find the idea to dispatch events through Components quite ingenious. Most of the time Engines need to communicate Entity based events. If the Player hits an Enemy Entity, the PlayerGunShootingEngine needs to communicate to the HealthEngine that a specific Entity has been damaged. Doing this communication through the Entity Components is the most natural and therefore less painful way to do it:

The example above dispatches a isDamaged event or isDead event through the Component. Other Engines will listen the same event, through the same Component, therefore they will get the ID of the Entity in their callbacks, which can be used to query other nodes, like this isDead listener:

The unique feature to be able to receive the added and removed nodes in Engines through the interface functions Add and Remove has been maintained in this version of the framework. This functionalities is still of fundamental importance both to use custom data structures to hold nodes and to add/remove listeners from component events. If the Add and Remove functions are used, the user must never assume when a node will be added in to the engine and write code consequentially.


IRemoveEntityComponent needs a dedicated paragraph. This Component is a special Component partially managed by the framework. The user must still need to implement it through an implementer, but all it’s needed to implement is:

the removeEntity action is automatically set by the framework and once called, it will remove, from all the engines, all the nodes related to the entity created by the BuildEntity function. This is the only way to execute the Remove engine method. A standard example is to use in a Monobehaviour implementer like this:

but can be used also in this way:

the removeEntity delegate will be injected automatically by the framework, so you will be find it ready to use.


I understand that some time is needed to absorb all of this and I understand that it’s a radically different way to think of entities than what Unity taught to us so far. However there are numerous relevant benefits in using this framework beside the ones listed so far. Engines achieve a very important goal, perfect encapsulation. The encapsulation is not even possibly broken by events, because the event communication happens through injected components, not through engine events. Engines must never have public members and must never been injected anywhere, they don’t need to! This allows a very modular and elegant design. Engines can be plugged in and out, refactoring can happen without affecting other code, since the coupling between object is minimal.

Engines follow the Single Responsibility Principle. Either they are generic or specialized, they must focus on one responsibility only. The smaller they are, the better it is. Don’t be afraid of create Engines, even if they must handle one node only. Engine is the only way to write logic, so they must be used for everything. Engines can contain states, but they never ever can be entity related states, only engine related states.

Once the concepts explained above are well understood, the problem about designing code will become secondary. The coder can focus on implementing the code needed to run the game, more than caring about creating a maintainable infrastructure. The framework will force to create maintainable and modular code. Concept like “Managers”, “Containers”, Singletons will just be a memory of the past.

Some rules to remember:

  • Nodes must be defined by the Engine themselves, this means that every engine comes with a set of node(s). Reusing nodes often smells
  • Engines must never use nodes defined by other engines, unless they are defined in the same specialized namespace. Therefore an EnemyEngine will never use a HudNode.
  • Generic Engines define Generic Nodes, Generic Engines NEVER use specialized nodes. Using specialized nodes inside generic engines is as wrong as down-casting pointers in c++

Please feel free to experiment with it and give me some feedback.

Notes from 21/01/2017 Update:

Svelto ECS has been successfully used in Freejam for some while now on multiple projects.  Hence, I had the possibility to analyse some weakness that were leading to some bad practices and fix them. Let’s talk about them:

  1. First of all, my apologies for the mass renames you will be forced to undergo, but I renamed several classes and namespaces.
  2. The Dispatcher class was being severely abused, therefore I decided to take a step back and deprecate it. This class is not part of the framework anymore, however it has been completely replaced by DispatcherOnSet and DispatcherOnChange. The rationale behind it is quite simple, Components must hold ONLY data. The difference is now how this data is retrieved. It can be retrieved through polling (using the get property) or trough pushing (using events). The event based functionality is still there, but it must be approached differently. Events can’t be triggered for the exclusive sake to communicate with another Engine, but always as consequence of data set or changed. In this way the abuse has been noticeably reduced, forcing the user to think about what the events are meant be about. The class now expose a get property for the value as well.
  3. The new Sequencer class has been introduced to take care of the cases where pushing data doesn’t fit well for communication between Engines. It’s also needed to easily create sequence of steps between Engines. You will notice that as consequence of a specific event, a chain of engines calls can be triggered. This chain is not simple to follow through the use of simple events, also some it’s not simple to branch it or create loops. This is what the sequencer is for:

This example covers all the basics, except the loop one. To create a loop would be enough to create a new step that has as target an engine already present as starting point of an existing step.
A Sequence should be created only inside the context or inside factories. In this way it will be simple to understand the logic of a sequence of events without investigating inside Engines. The sequence is then passed into the engines like it happens already with observables and used like this:

  1. The Concept of EntityGroup has been added. This is a bit of an abstract concept, but useful in some specific cases. It allows to define an Entity as a Group of Entities. It works exactly like a normal Entity, but the use case is different. It must not be seen as a single Entity, but as an Entity that groups the information of a set of Entitites. As a normal Entity, it is made out of nodes and implementers, however the nodes are stored in a separate set inside the Nodes database. In this way, you can have an EntityGroup called like EnemiesOverMind (sorry I just came with the example while I am typing) that has an OverMindNode implemented through an implementer that is NOT a Monobehaviour. the same node is then used in the normal EnemyEntity, however the same implementer used for the group will be used for the EnemyEntity too (through the extraimplementers parameter of the EntityDescriptor constructor). In this way, effectively, the EnemiesOverMind and the EnemyEntity share the same OverMindNode through the same implementer. Doing so, you can now create the OverMindEngine that will query the only the OverMindNode present in the EntityGroup database. Changing a value in this node, will change the value of all the nodes injected in the normal Enemy Engines. This is a simple way to be able to handle shared data between entities without being forced to iterate among all the entities that share the same data.
  2. The IComponent interface was never used by the framework so I removed it, you can keep on using it for the sake to optimize the GetComponents call in a BuildEntity.
  3. Added a new GenericEntityDescriptor class, now it’s possible to create Descriptors without building a new class everytime (it depends by the number of nodes used).
  4. Since the Tickable system has been deprecated, the TaskRunner library should be used to run loops. TaskRunner comes with a profiler window that can be used to check how long tasks take to run. This has been copied and adapted from the Entitas source code. You can Enable it from the menu Tasks -> Enable Profiler. Similarly  you can enable an Engine Profiler from Engine -> Enable profiler to profile adding and remove nodes into Engines. It will look more or less like this:

In future, I may implement some of the following features (feedback is appreciated):

  • Entity pooling, so that a removed entity can be reused
  • Some standard solution to handle input event in engines
  • Using GC handles to keep hold of the Node references, all these references around can make the garbage collection procedure slower

Note, if you are new to the ECS design and you wonder why it could be useful, you should read my previous articles:

17 thoughts on “Svelto ECS is now production ready

  1. Hi Sebastiano,

    After hitting a wall with a project after about a year’s worth of bolting on new features at the request of a client, I’ve entered dependency hell. I began weighing the pros and cons of a different framework other than what Unity3D’s engine tries to enforce, which led me to your blog. I noticed various other ECS implementations have been mentioned in the comment sections of your articles.

    What would you say is the primary shortcomings/drawbacks for using other ECS frameworks such as EgoECS and Entitas relative to yours from what you can tell? Do they enforce a strong SOLID design ethic? I am working with a new team (knowledgable to code and OOP, web framework like MVC, etc but not Unity) and want to enforce good design practices without becoming a Computer Science lecturer while also not making the project convoluted and heightening the learning curve. One of the best parts of Unity is its low bar to entry, and I don’t want to lose that.

    Thank you for your investigation and dedications to this topic. I am glad I stumbled across your blog.

    1. I assume you read all my articles on the argument, starting from the IoC ones. I haven’t used EgoECS or Entitas, I assume both are good. My ECS implementation has got 2 unique features, one is the fact that components are not objects and the other one that components can use dispatcher. I also like the Nodes design a lot.
      I think that communication between systems is the biggest problem to solve in an ECS framework and I usually discard frameworks that solve this problem with an EventBus (a singleton to dispatch messages).
      We have been using my ECS in robocraft for several months now and we wrote more than 80 engines so far. I have already found a couple of new design challenges to solve: the first one is about the code re-usability and how to address it. I will write new articles when I have the time, still a lot of stuff to talk about.

  2. Hello, I really admire your Svelto ECS. It’s hard to get your head wrapped around it at first but it is probably the best ECS framework for Unity at the moment with creator who knows what he’s doing exactly.

    I’m creating a roguelike in Unity and I want to use your system (ECS seems to be perfect fit for such project as everything is modular). However there is much dispute online about handling the game world itself using the ECS.

    You are an expert/guru in my eyes when it comes to ECS so I wanted to ask you about how would you recommend handling it? The world is made from chunks, those chunks are made from tiles. Creating an entity for each tile would have really cool advantages allowing nice composition of components that would define that tile. However with HUGE amount of tiles this solution ends up rather unefficient (100×100 map, which isn’t that big when you consider an open world, is already at 10k entities).

    Also, nearly all engines and entities are more or less connected to the map (visual representation, coordinates, pathfinding, collision checks, terrain destruction, and much much more) and that is why people suggest using a singleton approach, keeping the map functionality separate from ECS and just using the singleton object from any place where needed (methods like IsObstacle(), GetPath(), DestroyTile(), PlaceTile() etc). This seems to be somewhat dirty solution in my eyes and I was wondering what would be the “proper way” of doing it.

    Should the whole map be a single entity used by most of the engines? Only the engines can have the logic so this could lead to lots of repeated code (for example simply checking “what is on that tile” which would most probably end up in a lot of systems). Should I stick to the singleton approach like others suggested? What would you do?

    Also sorry if my message is confusing. I spent some time reading into it and it left a mess in my brain.

    1. Hello and thanks for your message. Let’s be clear, there is a lot of hostility around frameworks that step away from the Unity logic. I don’t want to be too blunt, but the truth is that whatever force you to use stateful global objects must be avoided like the pest. Obviously many of the unity users never really have created something truly complex, so for them tools like IoC containers or frameworks like ECS ones are seen as “over-engineering” since you can get things done also using singletons.
      While it’s true that you can get things done using whatever you want, it’s not true at all that solutions like the ones I advocate must be over-engineered. Sure, many frameworks out there actually implement way too much and that’s why my libraries are kept as simple as possible. Now an update to Svelto.ECS is long due and I hope I will work on it very soon now, so keep an eye here. Svelto.ECS is currently used on several projects and, so far, I haven’t met a situation where the framework makes things more complicated than should be.
      About your specific case, well Entity Component Systems are or can be data driven, so actually you can see the whole map as an entity, but it really depends by what you want to achieve and that’s why I need more information about it. For the number of tiles, it depends how much memory a tile takes in memory. if I tile takes, for example, 64 bytes, 640k for 10k tiles is not that much amount of memory to store :).
      About the map functionality, also that depends. If I understood correctly, you need to be aware of which tile you stepped on. Let’s take a step back. Using ECS doesn’t mean that you can’t inject “services” inside engines (by constructor). Therefore, if you wish, you can create a MapManager and inject it in the engines that are going to need the Map Manager Services (without the necessity to use a singleton), however I am sure there are many way you can solve the same problem just using Engines.
      For example you could have the MainCharacterOnMapEngine that knows the Map node and the MainCharacter node , inside the update you can use the main character node, to know the main character position and see on which tile it actually is. If, for example, you are on a tile that slows the character down, you can set in the MainCharacter node a multiplier value that will be used by the CharacterMovementEngine (or something like that).
      I hope this example makes sense, it could be better, but I would need to see what you have in mind to understand what direction is better to take. Using ECS is a paradigm shift, you need to think in a different way, totally inverted, so at first, solutions are not obvious to see and that’s why people may think it’s not worth it. However on the long run it will make things easier.

      1. I was a lead programmer in a rather big game project (full time job, not a hobbyist after-hours thing) and I know for sure your system is not “over-engineering”. The project ended up in a total mess of a code, full of managers and singletons (multi-responsibility, thousands of lines of code per class). It wasn’t a problem at the beginning but further in the project it became a nightmare to extend and maintain. I guess that I lost at least 3-6 months fixing/patching/extending/refactoring (then fixing again) because of poor design choices. I would really love to go back in time and slap myself in the face for not doing it more properly.

        That’s why you won’t get a single drop of hostility from me. I know that I need solutions like yours to make my work easier in the long run 🙂

        But I digress…

        Injecting a map service into engines seems to be the easiest solution, however it does seem similar to regular singleton/manager usage, taking away the logic from the engine into it’s own class. If this is still an elegant solution then I would probably lean towards this as it “feels” right. However, if it’s also possible to get the same effect using engines without huge drawbacks then I’m all for that.

        However each solution I think about has some problems

        1. Each tile as entity: Entities just “float around in a big bag”. They are not ordered in any way (or at least not in the way they naturally should in case of a tilemap) and they lose the advantages of grid layout. You need to query each entity about it’s coordinates etc. Each engine wanting to know anything like “is this tile passable?” “are there items on this tile?” would either have to go through all the tiles to find the one in question (instead of simply accessing tilemap[x,y]) or build some sort of array for quick access and modify it every time a chunk is loaded/released. Both ways seem wasteful.

        2. Chunks as entity: Not as wasteful as option 1, fits in nicely with loading/releasing chunks, but still suffers from similar problems.

        3. Map as entity: no need to iterate in search for right chunk or tile – simple array access. However, this seems to be only one step away from the service solution you mentioned which makes more sense than this option

        All options additionally suffer from
        a) repeated code (both MoveEngine and PathfindingEngine check if tiles are passable. I know it’s a poor example as code for such check is very short, but I bet you can imagine situations with whole big functions copy-pasted between engines)
        b) somewhat breaking the “single responsibility” rule. Engines apart from doing their job keep implementing functions that manage the map. Such functions end up spread and repeated across many engines. It feels more natural to have all tilemap related operations in a single place instead.

        I will edit this post if I recall anything more (I got back to my roguelike project after quite long break and I’m sure I’m still forgetting something about the struggle of implementing the map in ECS)

        1. I don’t see each tile as entity as a proper solution. The map itself is just data, so the data structure of the map can be stored by just one mapComponent. If you go for the Service route, the mapService won’t need any logic. A service is usually a way to query a datastructure, nothing else. The data source of the data structure can be everything (a DB, a file, a datastructure in memory), and the service has only the responsibility to give the functions to query this data. This means that all the logic is still in the engines, that use the mapService only to be able to query the data.
          MoveEngine and PathFindingEngine, assuming they do different things, will have different code to execute in case a tile is not passable.

  3. I have just ony 1 complaint about SveltoECS is the amount of boiler plate code. Svelto is aimed at really big projects, so as long as you need something that address all the problems that it addresses, I can’t came up with a simpler syntax: every single line of code is needed :/.
    But let’s assume for a while we are not working on Robocraft(assume I’m in a small team with 6 people working on something that should last for 1/2 years at most): Isn’t there anything we can drop from Svelto in order to allow it become more intuitive and with less boilerplate?

    Svelto enforce everything upfront, good for big projects, but what for smaller projects?

    Compare the following with Svelto.ECS:

    void SpawnSomeEntity(){
    Entity entity = factory.CreateEntity();
    engine1.RegisterEntity( entity, defaultValues ); //automatically add components for engine1
    engine2.RegisterEntity( entity, defaultValues2); //automatically add components for engine2 (If not already added by engine1)

    You 1) write the engines 2) the components 3) the above function and you are done. Yes you have a lot of downsides compared to Svelto, but it is much more intuitive and fast to write.

    Coming back to map problem:

    I agree the map should be a DataStructure that can be queried (read only) by each engine.

    Now assume that we want the chance to add more and more terrain types to the map, in example the Lava Terrain type.In that case we need a LavaDamageEngine. Then we just need a component on each Character to keep track of terrain type, we use that to trigger events on Characters.

    public class TerrainEngine{

    override protected void Add(CharaterTerrainNode node){
    node.terrainTypeTracker.type = GetTerrainTypeForCurrentPosition( node.position);
    node.movementTriggerComponent.subscribers += OnCharacterMoved;

    void OnCharacterMoved(int ID){
    var node = nodesDB.QueryNode(ID);

    if( node.terrainTypeTracker.type != GetTerrainTypeForCurrentPosition( node .position))
    var newTerrainType = GetTerrainTypeForCurrentPosition( node .position);
    ResolveTerrainType( node .terrainTypeTracker.type).OnExitTerrainType( node );
    e.terrainTypeTracker.type = newTerrainType;
    ResolveTerrainType( newTerrainType).OnEnterTerrainType( node );

    ITerrainTypeEngine ResolveTerrainType ( TerrainTypeEnum type){
    case TerrainTypeEnum.Lava: return lavaEngine;

    // … more methods hided

    Ok now we reached the culprit: we want the Lava Terrain to do 1 damage every second to the character. while In my pseudo-ECS it is easy to figure out the solution:

    public class LavaTerrainTypeEngine: ITerrainTypeEngine{

    public void OnExitTerrainType( Entity e){ // I use entities: not nodes
    DeregisterEntity(e); // removes the LavaDamage Component

    public void OnEnterTerrainType( Entity e){
    RegisterEntity(e); // adds the LavaDamageComponent and check if we have DamageEventComponent

    void Tick(){
    foreach( Entity e in entitiesWithLavaDamageComponent){
    var comp = e.GetComponent();
    comp.time -= deltaTime;
    if(comp.time <= 0){
    comp.time += 1;



    However in Svelto this is not possible. We cannot add more components at Runtime since implementors are fixed, I’m a bit unsure how to handle it, however in Svelto I think lava damage is nothing more than a periodic damage, which could be viewed as adding a “pending bullet”, so in Svelto we could implement that periodic damage just by adding another Entity that will do periodic damage to the Character, however to do that we have to create all the boiler plate needed for a new entity (Nodes, Interfaces, Components, another engine).

    And I really hope that code identing don’t get messed up in comments ^^ In that case sorry but you should go for a code beautifier XD (hoping I didn’t forget any curly braces).

    1. Aehm. “>” and “<" template arguments were stripped from my comment :/. And also identation was wrong. However the point was that Implementors are good, I can see and appreciate their advantage, however there are certain behaviours that can be modelled more easily by adding dynamically components at Runtime, and this thing is not allowed with implementors (unless there's somewhere a undocumented feature of Svelto I missed). So while I believe in really big projects it is preferrable to have a Whole different entity for that, I think medium-small projects will benefit more from having separate components that can be changed at Runtime. I don't know if Svelto would allow in future the best of both worlds.

      1. Forgive me Dario, it’s a while I don’t play with Svelto.ECS. I changed it quite a lot since the last commit on github and I lost the track of it. I am working on the new github version as we speak. Once I am done, I will re-read your comments and answer them, OK? Please also be aware that, as usual, there will be some (hope minor) breaking changes 🙁

  4. Hi Sebastiano,

    I have a question, primarily about one the actual code examples above you used and the thinking behind it.
    Your TriggerDamage method seems to be within the PlayerGunShootingEngine.
    The method updates the healthcomponent.current health node to indicate it’s been damaged.
    It then fires the “isDead” or “isDamaged” dispatch to let the other engines (and systems listening) that the entity the component is attached to is either dead or has been damaged.

    I’m not a professional programmer, so I’m here to learn, but I feel that’s a violation of the S in SOLID.

    In this scenario, wouldn’t the PlayerGunShootingEngine only be responsible for determining if the enemy was hit, and then firing a “isDamaged” dispatch (along with the damage object).
    It would be up to the HealthEngine to apply damage/healing, thus it’d receive the “IsDamaged” dispatch, apply the damage and then it would contain the logic of “is this thing dead?”.
    At the moment it feels that the logic of “is this dead” is two places, PlayerGunShootingEngine and HealthEngine, which isn’t DRY either.

    Please note, I’m nod asking this to nit-pick; I’m actually concerned I’ve missed part of the concept of this approach. I don’t have a lot of experience in designing games, especially from this angle.


    1. Hi again Sebastiano,

      I was just reading through the code in the github project, and it turns out the TriggerDamage method is within the HealthEngine. This is exactly where I would expect it to be and invalidates any of my previous concerns.

      Reading through the article left me with the feeling that the example code was in PlayerGunShootingEngine, which really didn’t feel right. I’m incredibly glad I got that feeling now, as it means my thinking is in the correct zone. 🙂

      Your IOC+ECP framework is exactly the direction I was heading in my own code and I’m going to rework my current project to implement it in this manner. The two genius things you’ve done here that I would never have thought about was:
      Events fired through components. Seriously, this is awesome.
      Unity integration – this method of integration just feels right and it’s so clean!

      I’ll try to ensure I respond once I’m familiar with the framework, really looking forward to this!


      1. thanks Robert!

        I am updating the github version since it’s quite old. The difficult part will be to remember the changes I made and explain why I made them :). Also I still need to add a fundamental feature, that I will explain later. At last, I have to update the article, since it’s a bit outdated…arggh! Too much work for too few weekends in a year 😀

  5. Hi Sebastiano,

    I’ve been using it for a few days now and have to say I really like it, it feels neat that once setup I’m just writing engines (whilst only thinking about nodes), AND i get compile errors when I’ve missed a component/node/Implementor etc.
    One issue i’ve had (which I just created a hack to get around to start with) is this situation:

    I have a component, it’s job is to represent a producer of items in my game (think Farm creating wheat). It has an event that takes a data object called “ProductData” which just contains a string and an int, string = ProductName, int = Quantity.
    My producerCreateEngine creates items, then dispatches a ProductCreated event, passing in the ProductData object.

    I have an inventoryAddEngine which subscribes to events from anything that can produce things and adds them to the inventory of the entity that produced it (with all the associated checks etc).

    Problem is that the InventoryAddEngine is given the id of the ProducerNode in the event, which can be retrieved from the nodeDB. I’m then a little stuck because can’t easily get reference to the InventoryNode from the same entity. I’m loath to put the target inventory in the ProductData object, because then the producerCreateEngine will need to know information it really shouldn’t (where the product will go). For now, that’s the path I went down.

    Being able to say “.EntityOf(ProducerNode) as AnotherNodeOnSameEntityDescriptor” to retrieve other nodes from an entity would be really nice.

    As I said i haven’t put a lot of brainpower into this and I could be just looking at a design failure on my behalf here instead of a missing framework feature.

    Thanks very much for releasing this framework Sebastiano, it’s really exactly what I was looking for.

    If it helps, I can send you a list of definitions for all of the parts of the ECS system (when I get home tonight). It’s just a list of all of the main objects in your ECS (Component, Implementor etc), a quick description of what it is and a brief “this is how you use it”. For example, Implementor i’ve said something like:
    This is the concrete implementation of your IComponents to an entity that is going to be visible in the game world, It’s also where the components are linked to the data. Implementors are all (currently) monobehaviours and become Components on GameObjects in the Unity engine.
    Implementors contain references to IComponents. They can also contain public fields and properties to allow users to assign values either directly in the inspector, or via code.
    Implementors should NEVER be directly referenced by Engines (that’s what Nodes are for) and do not represent the ‘Entity’ objects to engines either, that is what EntityDescriptor is for.
    Implementors are unique in that they contain the games data.

    Having a list of all the components of the engine to reference in this format was the thing that actually got me past that initial pain of getting into the framework.

    I have some very basic relationship flow diagrams too (not UML, just basic things to show me dependencies and how things are composed):
    IComponent -(many)-> Implementor -(single)-> Unity Component (Monobehaviour).
    IComponent -(Many)-> Node -(Many)-> EntityDescriptor -(Many)-> Engine
    Those two are the big ones that come to mind.


  6. Hey again,

    So after another couple of days learning it turns out that the correct nodes were returned by the nodeDB, I caused the incorrect behaviour when I passed in the ID of the unity component instead of the GameObject when setting up the dispatcher.
    I had:
    productCreated = new Dispatcher(this.GetInstanceID());

    instead of

    productCreated = new Dispatcher(gameObject.GetInstanceID());

    So I’m happily retrieving nodes from entities now, all good!


  7. I tried to think if there are ways to avoid using the DB, there can even be shortcuts (if a class manages always events from EntityA to EntityB, why not inheriting something like EventsDispatcher ?), but for some cases we still need the DB. Overall I think this is actually the most beautifull ECS out there (and it has still some improvements to be done? Seriously?).

Leave a Reply