MfGames' Gallium

Gallium is a simple Entity-Component-System (ECS) written to mimic much of the System.Linq namespace in C#. It is focused on less on performance and volume, and more with following established C# patterns to make it easy to use.

Namespace

The bulk of the library is located in the MfGames.Gallium namespace.

using MfGames.Gallium;

There is only one package, MfGames.Gallium which can be installed from inside Rider, Visual Studio, or via the dotnet command line:

dotnet add package MfGames.Gallium

Entities

The primary object of the ECS is the Entity class, a flyweight class with little more than an integer identifier and a collection of components.

// To create an entity with a specific identifier.
Entity entity1 = new(13);

Assert.Equal(13, entity.Id);

// To create an entity with an automatically incrementing identifier starting
// with zero.
Entity entity2 = new();

// To create a copy of the entity with a new identifiers but a shallow copy
// of the components inside the entity.
Entity entity3 = entity2.Copy();

Assert.NotEqual(entity2.Id, entity3.Id);

// To create a duplicate copy of the entity, including components, and with
// the same identifier.
Entity entity4 = entity2.ExactCopy();

Assert.Equal(entity2.Id, entity4.Id);

📝 Note: The use of int for Entity.Id which based on the intended usage of the library where there will rarely be more than two billion files and objects loaded into memory. However, we have had sites that exceeded the 32k file limit, so the int was considered “good enough” for our purposes.

Components

A component in Gallium is defined by its Type (as in value.GetType()) and generics. This cannot be changed in any method, but the class that the component is registered underneath can be a parent class.

entity.Add("value");

Assert.Equal("value", entity.Get<string>());
Assert.True(entity.Has<string>());
Assert.ThrowsException(() => entity.Add("second value"));

entity.Remove<string>();

Assert.False(entity.Has<string>());
Assert.ThrowsException(() => entity.Get(typeof(string)));

entity.Add("value2");
entity.Set("value3");

Assert.Equal("value3", entity.Get<string>());

entity.Add<object>("value4");