There has been a lot of discussion regarding the Anatomy structure in the past few weeks and many different ways for implementation have come up. In this post, I aim to summarise these discussions and also finally settle on an implementation.
The basic architecture
On the quest to move away from a simple Health Points system to a more natural and realistic setting, we decided on having a basic Anatomy system which just defines the body and it’s parts. The various systems of the body will be represented by AnatomyX systems (where X stands for Circulatory, Skeletal etc).
These AnatomyX systems will each deal with damage incurred by a part independently. Depending on the magnitude of damage dealt, type of damage (sharp, blunt and more) and some probability, each system will slap on their own effects like BoneBreaking, Bleeding and such. These effects can then cause visible effects like speed reduction or can even be lethal.
This allows future contributers to easily define more systems if they can independently perform these functions.
The next question was how to use entities in all this. The Entity Component System (ECS) is the fundamental architecture behind Terasology.
- Following this, it seemed natural to have entities for each body part. The main creature would contain a list/tree of these entities. These entities could have AnatomyX related components like BoneComponent if they were to be relevant to the AnatomySkeletal system and so on. Components would be attached to each anatomy part by the AnatomyX systems about the effects active on them.
- Pros - This will possibly be helpful down the road when positional damage (actually hitting different anatomy parts on the model) is introduced. It also feels right at home with the ECS system.
- Cons - This can lead to Entity bloat because for each creature entity, we are basically introducing several more entities. With a lot of creatures in play together, this can easily cause performance issues in lower-end computers.
Entities, in general, are much heavier than components (which are plain java objects). Handling too many entities at once can cause performance issues. This is called entity bloat.
- An alternate implementation would be to forego entities altogether and use tags to mark components (basically strings). We could have a two-way map to mark which anatomy parts are relevant to which systems. We attach the system effects to the main entity and store which parts are affected in the BoneBreaking effect (for example).
- Pros - This is much efficient than using entities.
- Cons - Implementation seems a bit - not how things are done in Terasology - kind of way
What I’ve decided
I’ve decided to go with the tags approach, as performance can’t really be sacrificed. The main entity will have an
AnatomyComponent with a list of anatomy parts. There will also be additional system components like a
BoneComponent which would contain a list of the parts relevant to the Bone system. These components make it possible for damage events to be caught by the AnatomyX systems using a simple component filter.
AnatomyX systems will, for now, have a incremental single-state effect, meaning different severities like a hairline fracture, then bone breaking and finally bone shattering. This can be implemented by using a HP per system, triggering different severity effects at different health levels.
The effect component will be added on the main entity and it would contain all the parts affected by that particular effect. Following this, to know the status of parts, the AnatomyX systems can be queried.