Your First Component - NocturnalWisp/Tynted-Engine GitHub Wiki

Getting Started

You may think that components should go before systems, but not so much. Despite Systems using components, components are just data. You don't need them until you need new raw variables to "attribute" to an entity. Creating a component shell is just about as easy as creating a game or system. For the sake of this example we will be creating a "Health Component." So here we go.

Creating the Component class

Starting of yet again with a simple shell is probably the best way of doing this. Make sure you set it to a class!

public class Health : IComponent
{
    public bool Enabled { get; set; }
    public IComponent Clone { get; }
}

Populating It

Components often contain different pieces of data to be utilized in systems. It is highly recommended to have a constructor, but no methods. Properties are fine, but try to steer clear of methods as that is the main intention of systems. I've just added 2 variables to be accessed else where, and a constructor.

public class Health : IComponent
{
    public bool Enabled { get; set; }
    public IComponent Clone { get => new Health(health, resistance); }

    public Health(float health, float resistance)
    {
        Enabled = true;

        this.health = health;
        this.resistance = resistance;
    }

    public float health;
    public float resistance;
}

Applying It

Now that the health component is created, we need to register it with the game.

using Tynted;
using Tynted.Components;
using Tynted.SFML.Graphics;
using Box2DNet.Common;

public class YourGameName : Game
{
    public YourGameName(GameOptions options) : base(options) { }

    public override void Initialize()
    {
        base.Initialize();

        ECSManager.AddSystem(typeof(MovingObjectSystem));
        //IMPORTANT!!!! ADD Component HERE.
        ECSManager.AddComponent(typeof(Health));
        
        //Create the entity.
        ECSManager.CreateEntity("Test1");
        
        //Make sure you have a texture in your /Res/ folder
        var texture = new Texture("Res/img.png");
        
        //Add Components to the entity "Test1".
        ECSManager.RegisterEntityComponents(new List<EntityComponentIdentifier>()
        {
            new EntityComponentIdentifier("Test1", new Transform(new Vec2(200, 200))),
            new EntityComponentIdentifier("Test1", new SpriteRenderee(texture))
        });
    }
}

Using It

Now you can update the game script again to add the component to the test object, and in update I am just going to print the value of health to the console.

using Tynted;
using Tynted.Components;
using Tynted.SFML.Graphics;
using Box2DNet.Common;

public class YourGameName : Game
{
    public YourGameName(GameOptions options) : base(options) { }

    public override void Initialize()
    {
        base.Intitialize();

        ECSManager.AddSystem(typeof(MovingObjectSystem));
        ECSManager.AddComponent(typeof(Health));
        
        //Create the entity.
        ECSManager.CreateEntity("Test1");
        
        //Make sure you have a texture in your /Res/ folder
        var texture = new Texture("Res/img.png");
        
        //Add Components to the entity "Test1".
        ECSManager.RegisterEntityComponents(new List<EntityComponentIdentifier>()
        {
            new EntityComponentIdentifier("Test1", new Transform(new Vec2(200, 200))),
            new EntityComponentIdentifier("Test1", new SpriteRenderee(texture)),
            //Update here!
            new EntityComponentIdentifier("Test1", new Health(20, 5))
        });
    }

    //Print the test health to the console every frame.
    protected override void Update(GameTime gameTime)
    {
        base.Update(gameTime);

        Health testHealth = (Health)ECSManager.GetEntityComponent("Test1", typeof(Health));
        Console.WriteLine(testHealth.health);
    }
}

Congratulations

You've just created your first component! You should be able to run the game and see in the console that it is printing the health of the test entity. You can now use this component with a system to do whatever you like, in this case, maybe a collision system. You can now move on with this and create a scene.