beyond-all-reason / beyond-all-reason/RecoilEngine

Unit Componentization through ECS

Open
#2,316 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
679
Forks
290
Avg merge
3d 2h
Merged PRs (30d)
40

Description

The idea with this task is to provide a place to discuss the componentization of unit, so currently implemented mechanisms can be better combined, or disabled. Also, currently the engine uses `entt` as an ecs backend mainly (or only?) for pathing.

Also, whether ECS or a different entity system, or just stick to CEG can be discussed here.

The alternative could be components integrated into unit `Update` and `SlowUpdate` through immediate events. ECS generally requires events to be asynchronous. I think this is where CEG comes from, see for example https://github.com/tomvandig/eccg, but have no idea tbh :D

Currently the Unit system has a very tight integration of subsystems, where (mostly) everything gets interleaved inside `unit->Update` and `unit->SlowUpdate`.

Also, it depends on a very inflexible class hierarchy that doesn't allow creating arbitrary combinations easily, as such, there are these immediate problems:

- Metal extractor has to be a subclass of building
- Builder behaviours have to be a subclass of movable unit.

Also, other "integrated" behaviours like Transport, Command and Resource management are tightly embedded in the Unit class and subclasses.

The main problem I see with this, is ECS is supposed to be data only components, and then subsystems are supposed to be working on them in tight loops. This means, to decouple from `unit->Update` and `unit->SlowUpdate`, we will likely need to move when things happen, for example (just an example, not a proposal):

- resourceProductionSystem->Update()
- unit->Update()
- unit->SlowUpdate()
- metalExtractorSystem->Update()
- reclaimSystem->Update()
- terraformSystem->Update()
- repairSystem->Update()
- buildSystem->Update()

This will mean things would happen in a different order.

So, would be really good to hear what people think and try to come up with a plan or a goal, about how to move forward.

We can write pros/cons of each approach:

- ECS:
- pros:
- very efficient looping
- high decoupling leading to more flexibility
- cons:
- likely will be somethat backwards incompatible
- requires a big refactor
- CEG: Entity components without systems, or just light systems (integrated into Update and SlowUpdate)
- pros:
- could maintain 100% backwards compatibility
- a bit less refactoring
- cons:
- not very efficient in the end
- also requires big refactoring

There will be more pros/cons, and this can be updated as they come up, this is just an initial (barebones) list.

I think there might be a way forward providing some backwards compatibility, by first laying groundwork by creating entity classes more tightly integrated into the unit graph, and then creating a sybsystem that can take over through a flag, later the flag could be deprecated and finally end with a more pure ECS.

See for example https://github.com/beyond-all-reason/RecoilEngine/pull/2283 as an example of groundwork that introduces components for extractor behaviours but doesn't really change current logic ordering and doesn't really have a System in charge. A subsequent PR to that one could move all logic processing to a System loop, thus becoming "pure".

Contributor guide

Open the contributing guide

Research direction

Start by reading the Unit Update and SlowUpdate flow and the extractor-component groundwork in PR 2283. Review how entt is currently used for pathing and compare the ECS and CEG options described here. Done means reaching an agreed migration plan and goal; this issue does not define a bounded implementation or acceptance test.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
game-dev
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.