Component Registration

Dive even deeper? You're almost at the earth's core, my dear! Let me show you how to insert components manually!

You've experienced a lot along the way, but you never stop learning... right? So you've reached a point where you want to register and modify components yourself. Then let's take a look!

All components are recorded and stored in the ComponentRegistry. It primarily stores meta data such as the size and types of the components, which are then queried at runtime as a compile-time static or manually to access the underlying arrays of Archetypes and Chunks and more.

These metadata are expressed as ComponentType, a struct that you may have seen here and there before. It combines the component with its most important metadata and is used precisely for this purpose.

Changing the (life) building blocks

There are some cases where you might prefer to register your components yourself because YOU simply know more than Arch and C# at that moment. For example, C# has problems with managed structs or even classes here and there. This feature is also useful for AOT.

// Problematic managed struct
public record struct Inventory(List<Item> Items);

// Register, 8 = Size in bytes of the managed struct.
var componentType = new ComponentType(ComponentRegistry.Size-1, 8);
ComponentRegistry.Add(typeof(Inventory), componentType);

This registers the components manually, so you can also specify a different size when registering.

Alternatively, you can also call up the generic variants such as...

ComponentRegistry.Add<Inventory>();
ArrayRegistry.Add<Inventory>();

These two things do exactly the same thing, but are slightly less boilerplate code and automatically determine the code size.

Acessing the (life) building blocks

You can not only register components but also receive, replace and remove.

// Checks whether the component is registered
var hasInventoryRegistered = ComponentRegistry.Has<Inventory>();

// Try-Get
if(hasInventoryRegistered)
{
    ComponentRegistry.TryGet<Inventory>(out var componentType);
    Console.WriteLine(componentType);
}

// Replaces the component with a new variant e.g. hot Hot-Loading
ComponentRegistry.Replace<Inventory, NewInventory>();

// Removes the Component from registration
ComponentRegistry.Remove<Inventory>();

Of course, there is also a non-generic variant for all generic methods!

Compile-Time static

So now you've registered all these wonderful components... but how does Arch get to it under the hood? And how can you do it yourself? Of course this works by accessing the ComponentRegistry, but this is always associated with a lookup. There has to be an more efficient way!

var componentType = Component<Inventory>.ComponentType;

Using the Component<T0...T25>is one way. This is a compile-time static class that provides all meta-data for the passed Component directly, without any lookups! And the best, it comes with up to 25 generic overloads!

var signature = Component<Dwarf, Axe, Inventory>.Signature;

When passing multiple generics, it returns a Signature. A struct which contains multiple ComponentTypes from the different passed types.

Cool, right? Now you got the tools to build almost everything you want on your own! E.g. custom librarys and extensions!

Last updated