Search Unity

EntityManager.EntityManager.CopyAndReplaceEntitiesFrom has a few bugs

Discussion in 'Data Oriented Technology Stack' started by Ashkan_gc, Sep 3, 2019.

  1. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    917
    EntityManager.CopyAndReplaceEntitiesFrom mostly works perfectly but has a few problems.
    1- the entity debugger shows blinking entities after I rollback main world to one of previous states.
    2- when I rollback to initial state before running any frames and then try to run the game and move forward, this exception is thrown.


    ArgumentException: All entities passed to EntityManager must exist. One of the entities has already been destroyed or was never created.
    Unity.Entities.EntityComponentStore.AssertEntitiesExist (Unity.Entities.Entity* entities, System.Int32 count) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/EntityComponentStoreDebug.cs:183)
    Unity.Entities.EntityManager.InstantiateInternal (Unity.Entities.Entity srcEntity, Unity.Entities.Entity* outputEntities, System.Int32 count) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/EntityManagerCreateDestroyEntities.cs:226)
    Unity.Entities.EntityManager.Instantiate (Unity.Entities.Entity srcEntity) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/EntityManagerCreateDestroyEntities.cs:161)
    FixedRateSpawnerSystem.CustomInstnatiate (Unity.Entities.EntityManager entityManager, System.Single spawnTime, UnityEngine.GameObject ecsView, Unity.Entities.Entity entityPrefab, System.Int32 owner) (at Assets/ECS/FixedTimestepWorkaround/FixedRateSpawnerSystem.cs:50)
    FixedRateSpawnerSystem.OnUpdate () (at Assets/ECS/FixedTimestepWorkaround/FixedRateSpawnerSystem.cs:38)
    Unity.Entities.ComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:800)
    Unity.Entities.ComponentSystemBase.Update () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
    FixedTimestepUpdater.Tick () (at Assets/ECS/FixedTimestepWorkaround/FixedTimestepUpdater.cs:86)
    FixedTimestepUpdater.OnGUI () (at Assets/ECS/FixedTimestepWorkaround/FixedTimestepUpdater.cs:60)

     
  2. Creepgin

    Creepgin

    Joined:
    Dec 14, 2010
    Posts:
    270
    Not sure if this is it, but I was tripped by it due to the copying of SystemStateComponents. See the caveats in the source comments:

    Code (CSharp):
    1. /// <summary>
    2. /// Copies all entities from srcEntityManager and replaces all entities in this EntityManager
    3. /// </summary>
    4. /// <remarks>
    5. /// Gurantees that the chunk layout & order of the entities will match exactly, thus this method can be used for deterministic rollback.
    6. /// This feature is not complete and only supports a subset of the EntityManager features at the moment:
    7. /// * Currently it copies all SystemStateComponents (They should not be copied)
    8. /// * Currently does not support class based components
    9. /// </remarks>
    10. public void CopyAndReplaceEntitiesFrom(EntityManager srcEntityManager)
    11. {
    12. #if ENABLE_UNITY_COLLECTIONS_CHECKS
    13.     if (srcEntityManager == null || !srcEntityManager.IsCreated)
    14.         throw new ArgumentNullException(nameof(srcEntityManager));
    15.     if (!IsCreated)
    16.         throw new ArgumentException("This EntityManager has been destroyed");
    17. #endif
    18.  
    19.     srcEntityManager.CompleteAllJobs();
    20.     CompleteAllJobs();
    21.  
    22.     using (var srcChunks = srcEntityManager.m_UniversalQueryWithChunks.CreateArchetypeChunkArray(Allocator.TempJob))
    23.     using (var dstChunks = m_UniversalQueryWithChunks.CreateArchetypeChunkArray(Allocator.TempJob))
    24.     {
    25.         using (var archetypeChunkChanges = ArchetypeChunkChangeUtility.GetArchetypeChunkChanges(srcChunks, dstChunks, Allocator.TempJob))
    26.         {
    27.             EntityManagerDifferUtility.CopyAndReplaceChunks(srcEntityManager, this, m_UniversalQueryWithChunks, archetypeChunkChanges);
    28.             Unity.Entities.EntityComponentStore.AssertSameEntities(srcEntityManager.EntityComponentStore, EntityComponentStore);
    29.         }
    30.     }
    31. }
     
  3. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    917
    @Creepgin well might be / might not. I'm not explicitly using any SystemStatecomponents but i'm not as sure about internal systems.

    However assertion of chunks being equal also throw and the rollback breaks. I'm going to submit a bug and hopefully @Joachim_Ante and other unity guys will fix it soon. I know that the method is not complete yet but maybe some of the things i'm seeing here are unknowns. am going to send the case number here as well.
     
    mkracik likes this.
  4. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    917
    1182319 is the case number
     
  5. mkracik

    mkracik

    Joined:
    Aug 5, 2018
    Posts:
    9
    I am getting assertion error as soon as I destroy an entity created earlier:

    Code (CSharp):
    1. using NUnit.Framework;
    2. using Unity.Entities;
    3.  
    4. namespace SystemsTests
    5. {
    6.     [TestFixture]
    7.     class SaveGameTests2 : ECSTestsFixture
    8.     {
    9.         [Test]
    10.         public void CopyAndReplaceEntitiesFromFailsAfterDestroyEntity()
    11.         {
    12.             Entity entity1 = World.EntityManager.CreateEntity(typeof(Unity.Transforms.Translation));
    13.          
    14.             using (World savingWorld = new World("saving"))
    15.             {
    16.                 savingWorld.EntityManager.CopyAndReplaceEntitiesFrom(World.Active.EntityManager);
    17.             }
    18.          
    19.             Entity entity2 = World.EntityManager.CreateEntity(typeof(Unity.Transforms.Translation));
    20.          
    21.             World.EntityManager.DestroyEntity(entity1);
    22.          
    23.             using (World savingWorld = new World("saving"))
    24.             {
    25.                 // fails with UnityEngine.Assertions.AssertionException : Assertion failure. Values are not equal.
    26.                 // Expected: 2 == 1
    27.                 savingWorld.EntityManager.CopyAndReplaceEntitiesFrom(World.Active.EntityManager);
    28.             }
    29.         }
    30.     }
    31. }
    32.  
    CopyAndReplaceEntitiesFromFailsAfterDestroyEntity (0.401s)
    ---
    UnityEngine.Assertions.AssertionException : Assertion failure. Values are not equal.
    Expected: 2 == 1
    ---
    at UnityEngine.Assertions.Assert.Fail (System.String message, System.String userMessage) [0x0003c] in C:\buildslave\unity\build\Runtime\Export\Assertions\Assert\AssertBase.cs:29
    at UnityEngine.Assertions.Assert.AreEqual[T] (T expected, T actual, System.String message, System.Collections.Generic.IEqualityComparer`1[T] comparer) [0x00061] in C:\buildslave\unity\build\Runtime\Export\Assertions\Assert\AssertGeneric.cs:31
    at UnityEngine.Assertions.Assert.AreEqual[T] (T expected, T actual, System.String message) [0x00009] in C:\buildslave\unity\build\Runtime\Export\Assertions\Assert\AssertGeneric.cs:19
    at UnityEngine.Assertions.Assert.AreEqual (System.Int32 expected, System.Int32 actual) [0x0000b] in C:\buildslave\unity\build\Runtime\Export\Assertions\Assert\AssertPrimitiveTypes.cs:176
    at Unity.Assertions.Assert.AreEqual (System.Int32 expected, System.Int32 actual) [0x0000b] in E:\LastGuardian\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities\Stubs\Unity.Assertions\Assert.cs:81
    at Unity.Entities.EntityComponentStore.AssertSameEntities (Unity.Entities.EntityComponentStore* rhs, Unity.Entities.EntityComponentStore* lhs) [0x00058] in E:\LastGuardian\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities\EntityComponentStoreDebug.cs:135
    at Unity.Entities.EntityManager.CopyAndReplaceEntitiesFrom (Unity.Entities.EntityManager srcEntityManager) [0x0007b] in E:\LastGuardian\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities\EntityManagerCopyEntitiesFrom.cs:36
    at SystemsTests.SaveGameTests2.CopyAndReplaceEntitiesFromFailsAfterDestroyEntity () [0x000a9] in E:\LastGuardian\Assets\Editor\Tests\NonEditModeTests\SystemsTests\SaveGameTests2.cs:27
    at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
    at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <a8ed250850854b439cedc18931a314fe>:0
     
  6. Creepgin

    Creepgin

    Joined:
    Dec 14, 2010
    Posts:
    270
    Can confirm. It seems the entities
    IndexInChunk
    will be mismatched after
    EntityManagerDifferUtility.CopyAndReplaceChunks()
    if
    DestroyEntity()
    was used on the source EntityManager.

    Code (CSharp):
    1. [Test]
    2. public void CopyAndReplaceEntitiesFromFailsAfterDestroyEntity() {
    3.     Entity entity1 = World.EntityManager.CreateEntity(typeof(EcsTestData));
    4.     Entity entity2 = World.EntityManager.CreateEntity(typeof(EcsTestData));
    5.     World.EntityManager.DestroyEntity(entity1);
    6.  
    7.     using (World savingWorld = new World("saving")) {
    8.         // fails with UnityEngine.Assertions.AssertionException : Assertion failure. Values are not equal.
    9.         // Expected: 2 == 1
    10.         savingWorld.EntityManager.CopyAndReplaceEntitiesFrom(World.EntityManager);
    11.     }
    12. }
     
  7. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,671
    We have a fix in master of dots.
    It is a bug in AssertSameEntities. You could embed the package and remove that specific line for the time being.
     
    mkracik and Creepgin like this.
  8. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    917
    @Joachim_Ante what about the bug I found? case number 1182319 it is not just a matter of assertions, or you fixed that as well?