RPG Like entity attributes

Hi, first post on this foruns.
Recently I started delving into game development and started using MonoGame, So far so good I managed implementing a very simple (to not say rudimentary) ECS. So far works fine for my needs. The idea is going into a direction of some sort of RPG, but I stumbled in how to implement a component to hold a entity attributes. So the question is: how do you guys thinks is the best way of doint this?

A example of how I was doing before scraping everything and come here for help:

namespace ECSRPG.ECS.Components
{
    public class EntityAttributes : Component
    {
        public Dictionary<string, int> Attributes;

        public EntityAttributes()
        {
            this.Attributes = new Dictionary<string, int>();
            this.Attributes["BaseHeath"] = 20;
            this.Attributes["CurrentHeath"] = this.Attributes["BaseHeath"];
            this.Attributes["BaseSpeed"] = 32;
            this.Attributes["CurrentSpeed"] = this.Attributes["BaseSpeed"];
        }
    }
}

PS: Sorry, english is not my first language.

Always state what your natural language is so someone can assist in both English and your natural language [Usually by means of a translation service]

ECSRPG.ECS.Components

Is this…, why?

Welcome back and good luck!

:sake:

I can read and understand english very well despite not being able to express myself with perfection of a native speaker, but I’m brasilian, so portuguese. However I prefer to speak english here.

I should’ve mentioned that I’m novice on the field of C#, so my code is actually hobbist (aka trash) :smiley:

Thanks.

1 Like

I would use an interface IEntityAttribute instead of int.

public Dictionary<string, IEntityAttribute> Attributes;

You can then implement many different types of attributes and as long as they implement the interface, you can add them to the EntityAttributes.Attributes Dictionary.

Forgive me if I’m misinterpreting, but it seems as though you are reinventing variables. I have implemented my ECS components like so (though this is very simplified):

public class Health : Component
{
    public int CurrentHealth { get; set; }
    public int BaseHealth { get; set; }

    public Health(int baseHealth)
    {
        CurrentHealth = baseHealth;
        BaseHealth = baseHealth;
    }
}

For each component you plan on having in the game, make a new class that contains properties for the variables that you want. Then simply store a collection of these components in a dictionary with the key being the entity ID. Your method has several downsides, including having to remember the names of the attributes, only being able to use one data type etc.

Again, I may be misinterpreting what you are trying to achieve, but in a typical pure ECS architecture, I can’t really see where this ‘EntityAttributes’ concept fits in.

Do say if I have gotten something wrong or you wish for clarification :slight_smile:

Edit: I also noticed that you entity attributes seems to combine what ought to be two distinct components, namely health and speed. I would make health separate and put velocity in a ‘Kinematic Body’ component, which also stores its mass, its acceleration and force being applied to it.

This brilliant series on an ECS I found to be priceless, it also contains a solid implementation (albeit in TypeScript, but converting TypeScript to C# is quite trivial): What is an ECS? - Maxwell Forbes

1 Like

Why not SpeedComponent be its own thing? Like this:

public class SpeedComponent : Component
{
     public int BaseSpeed;
     public int CurrentSpeed;
}

[Edit]: after reading your other comments I see what you are trying to do. By making an EntityAttributes component you are kind of defeating the purpose of components. Health and Speed should be their own separate components. Imagine this scenario, say you have a turn based combat system. Where you have a party of characters. Like Final Fantasy. An enemy casts a spell that does damage to any entity in an area of effect. So you iterate over your entities and figure out which ones are in the area. With your system you would have to do something like this:

for (i = 0; i < entities.Count; i++;)
{
     entities[i].EntityAttributes["CurrentHealth"] -= 
          Enemy.Spell.Damage;
}

Now, that may be fine for you. If so great. But, theres two things.

  1. you’re pulling in more information than you need. Which is fine while you only have four values you need to be concerned with. What if EntityAttributes becomes much bigger? Is Speed and Health going to be the only things ever in there? Probably not. Which can lead to performance issues.

  2. not only do you have to CORRECTLY spell what attribute you want. But you have to type in the string correctly every single time in every single bit of code that deals with any EntityAttribute. Seems like more headache than its worth.

1 Like