Skip to content
ConcordConcordConcord

Why ECS? Why Concord?

There are various reasons why people choose ECS for their projects, there is a very large FAQ for ECS made by the author of FLECS, but we can go through some of the reasons here as a starting point:

Yeah it’s a trend, most game engines are moving towards ECS as their pattern of choice, big names in the industry are using the pattern and more people are following this trend (Unity, Unreal Engine, Overwatch (video), etc).

This is not a good reason to use Concord but it does help that more people are writing documentation and guides about ECS and how to use it to organize your game code.

But this is also a downside, ECS is NOW being used by more game engines, but OOP has been the king for way longer and is the more prevalent solution used in the market.

Concord isn’t here as part of the trend, and doesn’t intend to follow what other ECS frameworks do. It instead presents it’s own interpretation of ECS and makes a heavy focus on the ease of use and development.

So to follow this discussion, a reason people choose ECS is so that they can get away from the ugly parts of OOP.

The ugly part being inheritance and all the problems it comes with. A possible solution would be mixins or decorators, but most people agree that the problems are still there.

So that’s when they start to consider composition over inheritance. This is a very common pattern in OOP where you put objects inside objects instead of trying to define their behavior in term of inheritance. And ECS is very close to this pattern, remember how we put Components inside of our Entities? That’s composition.

But in “Composition over inheritance” we would still define our behaviors in our objects, and we would still need to forward our events to each component. So that’s when people start to consider ECS, behaviors existing outside of the object/entity helps organize the code more neatly.

Concord does make use of OOP and the metaprogramming functionality in Lua, to help implements ECS, and does still allow you to work with Components and Systems as if they were objects. So if you are escaping from the “bad parts” of OOP, your OOP knowledge will not be wasted while using Concord.

Well this is the argument most game engines make to sell you ECS as the best architecture.

Remember our behaviors and data are stored separately? This helps keep our data small. Remember how we don’t make distinction between entities and instead rely on filtering? This allows us to pack our entities close together in memory so that we don’t have to jump around so much when looping through them in our systems.

Unfortunately this doesn’t apply to Concord because in Lua land we can’t benefit from all of this, our representation of Components, Entities and Pools doesn’t provide an advantage towards objects. Yeah Concord is fast for the majority of use cases, but this is not its selling point. You can probably write faster code without a library, and there are plenty alternatives that focus on speed.

Lua although fast, is not used for optimization purposes, and the same applies to Concord. Concord tries to be reliable, easy to use and feature complete, it is not an optimization.

We actually made an experiment making a super efficient ECS library, but it was awful to code with and one line of code could throw all the optimizations away. In our opinion, although it’s possible to make a super-fast ECS library and speed does make a huge difference, it’s not worth it when working in Lua where JIT optimization is hard.

If you have tried or heard about “The Elm Architecture” or “Redux” you may find the unidirectional data flow in ECS familiar.

If we think about our Entities and Components as our Model or State, and Systems as our Update or Reducers, then the only way to mutate our Model/State is through an Event processed by our Update/Reducer.

This unidirectional data flow and the concept of using reducer functions as a way to update state is a proven concept and widely used in Functional Programming.

This mental model has worked really well for Front-end Web developers, and is a very good way to reason about how our systems update over time while keeping our state as our only source of truth and purely as data. If you are already familiar with these architecture you’ll be able to pick up Concord and ECS in general, with relative ease.

In addition to that, if we combine ECS with immutable data structures for Components and Entities, then we wouldn’t be too far away from “The Elm Architecture” and all its benefits like Time Traveling debugging.

Unfortunately immutable data structures aren’t cheap and the Lua garbage collector is not tuned for them. Concord doesn’t use immutable data structures, but if you treat your Components as just data, it does allow you to recover state through serialization and deserialization.

If you find this mental model intuitive and start to reason only through this paradigm you’ll find yourself writing code in a more structured way. There are very specific ways to do things in ECS and Concord will push you towards these patterns.

This is however at the expense of a higher learning curve with a big payoff in maintainability and reusability of your code. Concord keeps this risk low by allowing you to write code outside of Concord without extra hurdles.

In the long run we hope you’ll find yourself at home using Concord, without needing these escape hatches, in order to accomplish this we try to ease this learning curve through guides, documentation and tooling that will hopefully make working with Concord a great experience.