Separation of Behaviour and Rendering - e.g. Destroyed Entities

Hi, it’s me and my board game again.

I’m looking for tips on the separation of behaviour and rendering in the ECS world. All of my game logic so far is pure data, and now i’m looking at ways to elegantly display that data without having to change the game logic.

In the old OOP world of Unity’s past, i’ve kept my game logic model in a separate out-of-unity dll, and had the in-unity display logic listen to events fired by the model, updating themselves accordingly.

However, In ECS, where events are really just short-lived components, this solution isn’t really possible without the model knowing about View entities and adding components to them.

I could attach rendering components the existing entities (Transform, Mesh components, etc), and systems that update the them (e.g. when a piece is moved on the board, LocationViewSystem update it’s Transform based on its in data board Location.). However, this doesn’t always work well,

One simple example: i’m looking at the age old problem of displaying corpses - in the game logic, a piece that is “taken” has it’s entity destroyed, but I still need to show the piece being destroyed visually, I don’t want the game logic to “wait” for the death animation, as that is creating a dependency on the view logic.

So far, I’ve come up with a few possible solutions:

  1. Create Event Entities, emitted by the model with data about the model entities that fired them. The view can define systems that iterate over these events and map those to View entities.

  2. Adapt the Model to support joint model-view entities - specifically, don’t destroy Piece entities when they are taken, but instead add or remove components to stop those entities from being processed by systems that act on Living entities. For example: by adding a Destroyed component and SubtractiveComponent<Destroyed> properties in system groups.

  3. The concept of having separate Worlds for logic and rendering is something that is mentioned briefly in the documentation, but i’m not sure what that looks like structurally.

Any wisdom from the ECS vets here on achieving this separation?

This is also something that I’m looking forward to see how it works. I know EntityManager has a method to do it (MoveEntitiesFrom), which should be used when you have entities ready to enter in the “view” world, so you move from one world to another.

[mention|bTdNHCnXGjDOtP9jfwX0YA==] wrote a gist to show how worlds can be used to separate systems. You can see it here. Also read his post about this gist here .

1 Like

I personally think that combination of 2 & 3 is a right way to go, meaning destroying entities in many cases should be postponed and different worlds will make it easier to separate entities that should be separate. Devs have promised to roll out a sample of using 2 worlds for logic and presentation. For now everything that is related to removing and adding component and creating entities is a lot of hassle, so here is waiting for devs to fix that too.

That being said data separation is not as important in ECS as separtion of responsibilities in OOP in many cases it is benefitial to actually keep the data on one entity in order to not manage entities linking other entities

I think the cleanest solution would be 1) + 3). Have separate worlds for simulation/logic and rendering/view. Then pipeline those so that the rendering world operates on a copy of the simulation entity data from the end of the previous frame, while the simulation world runs the next frame. This way simulation and rendering can update in parallel, which should result in a better utilization of all the cores. Downside is the one frame lag between simulation and rendering.

Also use events as entities to communicate changes that happened during the last simulation frame.

Would be nice to see an example of this kind of architecture from Unity!

1 Like