ArgumentException: The EntityArchetype was not created by this EntityManager

Hi all!

I’ve just upgraded to Entities 0.5.0-preview.17, and now I am running into a ArgumentException: The EntityArchetype was not created by this EntityManager.

Full error:

ArgumentException: The EntityArchetype was not created by this EntityManager
EntityCommandBuffer was recorded in FiringJobSystem and played back in Unity.Entities.EndSimulationEntityCommandBufferSystem.

In the below FiringJobSystem, I am getting a projectileRequestArchetype, which is just an entity archetype that I have cached and am trying to reuse that signals my SpawnSystem to create a projectile.

In the OnUpdate, I am then trying to use commandBuffer.CreateEntity with the archetype to generate a ProjectileRequest entity from the archetype.

I do not understand the error – yes, the archetype was not generated by the commandBuffer, since I cache it in another system. How can I cache the archetype, then? Do I have a fundamental misunderstanding of how archetypes or EntityManagers should be used or do I just have a silly error in the code below?

public class FiringJobSystem : JobComponentSystem
{
    // EndFrameBarrier provides the CommandBuffer
    EntityCommandBufferSystem barrier;
 
    protected override void OnCreate()
    {
        base.OnCreate();

        // Cache the EndFrameBarrier in a field, so we don't have to get it every frame.
        barrier = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
    }

    [BurstCompile]
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        var dt = Time.DeltaTime;
        var projectileRequestArchetype = Archetypes.Spawn(EntityManager, typeof(ProjectileRequest));
        var commandBuffer = barrier.CreateCommandBuffer().ToConcurrent();
        var handle = Entities
            .ForEach(
                (Entity entity,
                    int entityInQueryIndex,
                    ref Weapon weapon,
                    ref WeaponCooldown weaponCooldown,
                    ref LocalToWorld ltw) =>
                {
                    if (weaponCooldown.seconds <= 0) {
                        // Creates a projectile in the SpawnSystem.
                        var projectileRequestEntity = commandBuffer.CreateEntity(entityInQueryIndex, projectileRequestArchetype);
                        var translation = ltw.Position + ltw.Forward * 2f;
                        var target      = translation + ltw.Forward;
                        commandBuffer.SetComponent(entityInQueryIndex, projectileRequestEntity, new ProjectileRequest {
                            translation = new Translation { Value = translation },
                            target = new Translation { Value = target },
                            speed = 500f,
                        });
                    }

                    // Reset the cooldown timer.
                    weaponCooldown.seconds = weapon.secondsCooldown;
                }).Schedule(inputDeps);
        barrier.AddJobHandleForProducer(handle);
        return handle;
    }
}

Many thanks in advance for any help!

Show your Archetypes.Spawn implementation

I think most likely you are caching an Archetype from another world (Maybe as a static variable?) and this new check found a bug in your code.

Thanks for your answers!

The Archetypes.Spawn implementation is rather old, and part of the issue is indeed as @Joachim_Ante_1 guesses that I use a static instead of a per-spawn system cache (better: have an Archetypes instance on the SpawnSystem).

        static private Dictionary<ComponentType, EntityArchetype> spawnArchetypes = new Dictionary<ComponentType, EntityArchetype>();

        internal static EntityArchetype Spawn(EntityManager manager, ComponentType type)
        {
            EntityArchetype entityArchetype;
            spawnArchetypes.TryGetValue(type, out entityArchetype);

            Debug.Log("Entity Manager: " + manager.World);

            if (entityArchetype.Valid) {
                return entityArchetype;
            } else {
                var entityArchetypeToInsert = manager.CreateArchetype(typeof(Spawn), type);
                spawnArchetypes.Add(type, entityArchetypeToInsert);
                return entityArchetypeToInsert;
            }
        }

The second half of the issue is that I am running NetCode (which I forgot to mention, I’m afraid). For some reason I assumed that the Server would run in a separate process, but for ease of development, it does not in play mode, so in combination with the static dictionary this turns out to be an issue, as the dict is shared by Client and Server world.

The output of Debug.Log("Entity Manager: " + manager.World); by the way is:
5387394--546255--Screenshot 2020-01-19 19.08.15.png
So the ClientWorld0 is first in storing the value, and further down:

So, thanks again.

A feedback: I would have immediately noticed the issue if the error message would have contained the entity manager’s World, such as The EntityArchetype was not created by this EntityManager (ServerWorld). So that maybe helps avoid future posts.