Search Unity

Bug [WithChangeFilter] not working for DynamicBuffers

Discussion in 'NetCode for ECS' started by Opeth001, Nov 9, 2023.

  1. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,115
    Hello Everyone,
    I am encountering a problem where a system continues to operate despite the DynamicBuffer Component being marked with `[WithChangeFilter]`. I understand that if even one entity within the chunk has read-write (RW) access to that component, the entire chunk is activated. However, in my case, I have verified that no entities on the server side have RW access to that dynamic buffer. Yet, the system persists in recognizing changes on the client side, even after I've disabled all server-side and client-side systems that might have RW access to that DynamicBuffer.


    Thanks!

    Job Sample:

    Code (CSharp):
    1.  [WithNone(typeof(PredictedGhost))]
    2.         private partial struct GameplayAttributesComponentReplicationForInterpolatedGhostsJob : IJobEntity
    3.         {
    4.             //GameplayAttributes
    5.             [ReadOnly] public NativeBitArray gameplayAttributesReplicatedComponentsMask;
    6.             [ReadOnly] public NativeHashMap<AttributeKey, ComponentType> gameplayAttributesReplicatedComponentTypes;
    7.  
    8.             public EntityCommandBuffer.ParallelWriter ecbParallel;
    9.  
    10.             private unsafe void Execute(Entity actorEntity, [ChunkIndexInQuery] int sortKey,
    11.                 [WithChangeFilter] in DynamicBuffer<ActorGameplayAttributes> actorGameplayAttributes)
    12.             {
    13.                 Debug.Log($"GameplayAttributesComponentReplicationForInterpolatedGhostsJob");
    14.                 //Iterate, Check Replication Requirements and Replicate the Attributes
    15.                 for (int i = 0; i < actorGameplayAttributes.Length; i++)
    16.                 {
    17.                     var attribute = actorGameplayAttributes[i];
    18.  
    19.                     //Check if Attribute Require Replication or Component non generated
    20.                     if (!gameplayAttributesReplicatedComponentsMask.IsSet(attribute.Key.value) ||
    21.                         !gameplayAttributesReplicatedComponentTypes.TryGetValue(attribute.Key, out var componentType))
    22.                         continue;
    23.  
    24.                     //Replicate Attribute Component
    25.                     ParallelWriterExtension.AddComponentDataUnsafe(ref ecbParallel, sortKey, actorEntity,
    26.                         componentType.TypeIndex, 4,
    27.                         UnsafeUtility.AddressOf(ref attribute.Value.Current));
    28.                 }
    29.             }
    30.         }
     
  2. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    894
    It may be we are doing something incorrectly and bumping some version when we restore buffer or apply buffer changes.
    Thanks for reporting. Are you able to repro on smaller project or test?
     
    Opeth001 likes this.
  3. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,115
    Thanks I’ll try to push a repro sample today.
     
  4. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,115
  5. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    894
    Thanks!! We will take a look!
     
    Opeth001 likes this.
  6. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,115
    anything new about this bug ?!
    is there any place i can follow up ?

    Thank you !
     
  7. NikiWalker

    NikiWalker

    Unity Technologies

    Joined:
    May 18, 2021
    Posts:
    314
    I did some digging:
    • I'm unable to repro this myself by making a quick modification to our NetcodeSamples repro.
      Confirmed via the Journaling window that there was no per-update RW access.
    • So I tried to repro in your project, and was able to. I saw the same result that you did.
      But oddly: I also confirmed via the Journaling window that there was no per-update RW access.
    • Which implies [WithChangeFilter] is not working properly, or Netcode GhostUpdateSystem has a bug.
    • So removed the [GhostField] attribute on the PlayerMovementCommands. This didn't help. Thus likely not the GhostUpdateSystem.
    • I replaced the [WithChangeFilter] with an explicit query (see code below). This fixed the issue! I'd recommend using this as a short-term workaround for now.
    I'll CC someone from the entities team.
    Code (CSharp):
    1. using Samples.HelloNetcode;
    2. using Unity.Burst;
    3. using Unity.Collections;
    4. using Unity.Entities;
    5. using Unity.NetCode;
    6. using UnityEngine;
    7.  
    8. [UpdateInGroup(typeof(GhostSimulationSystemGroup))]
    9. [UpdateAfter(typeof(GhostUpdateSystem))]
    10. [WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation | WorldSystemFilterFlags.ThinClientSimulation)]
    11. public partial struct CommandsReactionSystem : ISystem
    12. {
    13.     private EntityQuery _query;
    14.  
    15.     public void OnCreate(ref SystemState state)
    16.     {
    17.         _query = state.GetEntityQuery(ComponentType.ReadOnly<PlayerMovementCommands>());
    18.         _query.AddChangedVersionFilter(ComponentType.ReadOnly<PlayerMovementCommands>());
    19.     }
    20.  
    21.     [BurstCompile]
    22.     public void OnUpdate(ref SystemState state)
    23.     {
    24.      
    25.         new CommandsReactionJob()
    26.         {
    27.             world = state.WorldUnmanaged.Name,
    28.         }.ScheduleParallel(_query);
    29.     }
    30.  
    31.     private partial struct CommandsReactionJob : IJobEntity
    32.     {
    33.         public FixedString128Bytes world;
    34.         private void Execute(Entity playerEntity, [ChunkIndexInQuery] int sortKey,
    35.             //[WithChangeFilter] in DynamicBuffer<PlayerMovementCommands> actorGameplayAttributes)
    36.             in DynamicBuffer<PlayerMovementCommands> actorGameplayAttributes)
    37.         {
    38.             Debug.Log($"{world} GameplayAttributesComponentReplicationForInterpolatedGhostsJob: {playerEntity.ToFixedString()} - actorGameplayAttributes.Length: {actorGameplayAttributes.Length}");
    39.         }
    40.     }
    41. }
     
    Last edited: Dec 14, 2023
    Opeth001 and optimise like this.
  8. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,129
    I guess this issue only happens at IJobEntity? No issue at idiomatic foreach?
     
  9. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,129
    @CMarastoni Can u confirm this and also will it fixed at next 1.2 release?
     
    Opeth001 likes this.
  10. NikiWalker

    NikiWalker

    Unity Technologies

    Joined:
    May 18, 2021
    Posts:
    314
    The issue is isolated to the WithChangeFilter attribute. The fix will take some time (Christmas holidays), but the Entities team are aware. We can only give release timings after the fix lands (and will do so).
     
    Opeth001 and optimise like this.