A few questions about archetypes

What exactly is an archetype?

I assume the layout of it is [A, A, A, B, B, B, C, C ,C]?

PlayerArchetype = entityManager.CreateArchetype(
   typeof(Position2D), typeof(Heading2D), typeof(PlayerInput),
   typeof(Faction), typeof(Health), typeof(TransformMatrix));

What happens if some components aren’t set? For example you create an entity with the PlayerArchetype but only set a Position2D? Aren’t there holes in the array?

Also what happens when you add a component to an entity where the component is not contained in the archetype? Will this crash? Or will the entity be moved into a different archetype? For example

FooArchetype = entityManager.CreateArchetype(
   typeof(Position2D), typeof(Heading2D));
BarArchetype = entityManager.CreateArchetype(
   typeof(Position2D), typeof(Heading2D), typeof(Bar));
EntityManager.AddComponent(fooEntity, new Bar());

Will the fooEntity be moved into the BarArchetype? And what happens when an entity is created without an archetype? Will Unity just create a new archetype under the hood?

Also is the source code for the entity component system public?

1 Like
        public Entity CreateEntity(params ComponentType[] types)
        {
            return CreateEntity(CreateArchetype(types));
        }

CreateEntity will initialize all components to zero.

AddComponent moves the entire entity data to a different chunk with a different archetype. Archetype creation happens transparently. Archetypes are cached so requesting the same ComponentType[ ] multiple times, returns the same Archetype

1 Like

And yes, the source is public. It’s located in the package folder

1 Like

Pakages folder in my progect contain only fanifest.json file
same on Github only manifest file in Pakages folder https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/Samples/Packages

all I see is dll in Project\Library\ScriptAssemblies\Unity.Entities.dll

where is a source?

I am travelling and using a windows machine at the moment, so on windows it is:
C:\ProgramData\Unity\cache\packages\staging-packages.unity.com\com.unity.entities@0.0.11

The easiest way to get there, is to use one of the built-in components like gameobject entity or position. Then, open the script and it should take you to the source. You can then check the directory it is in…

1 Like

Thanks that basically answers all my questions.

Ah I was only looking in the git repository. Out of curiosity, is the ECS beta build planned for the linux client?

How is the data layed out if you have something like this:

public struct A : IComponentData
{
    public int value;
}

public struct B : IComponentData
{
    public int value;
}

entityManager.CreateArchetype(typeof(A), typeof(B));
entityManager.CreateArchetype(typeof(B));

And how does the system then resolve this:

public struct Group
{
    public ComponentDataArray<B> allBs;
}

[Inject] Group group;

Is some of the data duplicated in the chunks for specific types? Or does the ComponentDataArray contain data from multiple chunks?

There will be two chunks.
One with
a a a a
b b b b

another with just
b b b b

64kb fits approximately 8000 entities, so if you have 5000 entities of each you would have exactly one pointer jump and otherwise completely linear access to both a and b components.

I might sound stupid now but does that mean.

AAAA
BBBB

BBBBBBBB

or

AAAA
BBBB

BBBB

if we have four AB entities and four B entities?

I’d say the latter, that’s where the pointer jump happens.

I have a question with:

public Type[] myComponentArray;

//This works:
entityManager.CreateArchetype(myComponentArray[0], myComponentArray[1]);

//But why can't I pass whole array?
entityManager.CreateArchetype(myComponentArray);

trying to understand the above posts, could I to a foreach loop with AddComponent to get the same effect as passing a whole array to CreateArchetype?

Yes you could, but it would be a bit more unefficient since each time you add a new component the entity has to be moved to a new chunk that is specific for its new archetype.

I wrote an editor window that lets me pick and choose from class/structs in the project that implement IComponentData, and save them to a ScriptableObject’s dictionary of “archetypes” (string, Type[ ]). I was hoping I could load those archetypes defined in edit mode on Awake() but since I can’t pass a whole array to CreateArchetype, the only option is hard code it with the array indexes which is pointless if I could just use typeof(MyType).

The add component method really wouldn’t scale well, I hope a variant of CreateArchetype is added that supports passing a whole type array. Because unless I don’t know about some trick to iterate through an array inside the parameters of a method there really needs to be an option other than hard coding.

The reason why it doesn’t work is because CreateArchetype actually doesn’t take Type as arguments, but ComponentType. When you pass Type it implicitly converts it to a ComponentType with readwrite access. Pass an array of ComponentType instead (which you can create in a loop before based on your Type array) and you should be good.

1 Like

In code:

var componentTypes = new ComponentType[myComponentArray.Length];
for (int i = 0; i < myComponentArray.Length; ++i)
    componentTypes[i] = myComponentArray[i];
var archetype = EntityManager.CreateArchetype(componentTypes);

But you might aswell use ComponentType directly in your editor thingie, and also allow setting the accessmode.

What are the benefits of manually defining archetypes vs letting Unity do it implicitly in the background? Is it just so that when creating an entity, I can pass in an archetype and Unity can more easily assign the components to the correct chunks?

In that case, in situations where you are adding/removing components from an entity (which will automatically change its archetype), rather than creating new entities (based on an archetype), is there any advantage to explicitly defining the entity archetypes beforehand?

I assume yes, you should so that the chunk arrays can be pre-allocated? Thanks!

EntityArchetype has to be used explicitly, exclusively as an argument with EntityManager/EntityCommandBuffer.CreateEntity(archetype) command. The EntityArchetype variable only helps speeding up entity creation from scratch. I believe just creating the archetype does nothing to the internal ECS system. The archetype does not get “defined” in the system after running EntityManager.CreateArchetype, “create” is in the sense of creating the template for your own use later.

I’ve also noticed I can hand archetypes off to a burst enabled job that works with EntityCommandBuffer, at least only using non-SharedComponentData types. Then again the entities involved were simple (an int and a tag basically). This may only work in the latest preview package.

I take it then that we should avoid including Shared Components in an archetype? I have a shared sprite component in my archetype and upon entity creation, I am using SetSharedComponent to set the shared sprite to one I have set in the inspector. It seems to be working fine, but should I be leaving the Shared component out of my archetype and using AddSharedComponent instead?

One other thing, kind of on the same topic. Does Unity create a default shared component so it can add it to entities that have a shared component on their archetype? I ask because I only have a single shared sprite in my scene, and am only assigning it to entities, but when I use GetAllUniqueSharedComponentDatas, the cache contains two unique instances. Where is the extra one coming from?

Thanks!

Yep, as far I understood, and what I read here and there, archetypes are just for user convenience, when organizing types. Technically they can be completely avoided, as they are not required for anything else than during entity creation.

I don’t see reason why would you like, to exclude it from archetype. Unless indeed Burst don’t like them.

What if you try having two different ShaderComponents? Will result with 3, or 4 unique instances?

1 Like