user4937236
user4937236

Reputation:

ECS and appropriate usage in games

I've been reading about Entity-Component-Systems and i think i understand the basic concept:

Entities are just IDs with their Components stored in Arrays to reduce cache misses. Systems then iterate over one or more of these Arrays and process the data contained in the Components.

But i don't quite understand how these systems are supposed to efficently and cleanly interact with one and another.

1: If my entity has a health component, how would i go about damaging it? Just doing health -= damage wouldn't account for dying if health goes below or equal 0. But adding a damage() function to the component would defy the point of components being only data. Basically: How do systems process components which need to respond to their changes and change other components based on their changes? (Without copy-and-pasting the damage code into each system which can possibly inflict damage)

2: Components are supposed to be data-only structs with no functions. How do i best approach entity-specific behaviour like exploding on death. It seems unpractical to fill the Health component with memory-wasting data like explodesOnDeath=false when only one or two out of many entities will actually explode on death. I am not sure how to solve this elegantly.

Is there a common approach to these problems?

Ease of modification (for ex with Lua scripts) and high chances of compatibility are important to me, as i really like games with high modding potential. :)

Used Language: C++

Upvotes: 1

Views: 602

Answers (1)

Bluescreen
Bluescreen

Reputation: 154

I am also new to the field, but here are my experiences with ECS models:

How do systems process components which need to respond to their changes and change other components based on their changes?

As you correctly pointed out, the components are just containers of data, so don't give them functions. All the logic is handled by the systems and each new piece of logic is handled by a different system. So its a good choice to seperate the logic of "dealing damage" from "killing an entity". The comminication between the DamageSystem and the DeathSystem (with other words, when should an entity be killed) can the be based on the HealthComponent.

Possible implementation:

You typically have one system (The DamageSystem) that calculates the new health of an entity. For this purpose, it can use all sorts of information (components) about the entity (maybe your entities have some shield to protect them, etc.). If the health falls below 0, the DamageSystem does not care, as its only purpose is to contain the logic of dealing damage.

Besides the DamageSystem, you also want to have some sort of DeathSystem, that checks for each entity if the health is below 0. If this is the case, some action is taken. As every entity does sth on their death (which is the reason why your explodesOnDeath=false is not a bad idea), it is usefull to have a DeathComponent that stores some kind of enum for the death animation (e.g. exploding or just vanishing), a path to a sound file (e.g. a fancy exploding sound) and other stuff you need.

With this approach, all the damage calculation is located at one place and seperated from e.g. the logic of the death of an entity.

Hope this helps!

Upvotes: 1

Related Questions