I’ve noticed some unexpected behavior with EntityCommandBufferSystem and wanted to confirm if this is normal?
Here’s a simplified version of my code where two systems are interacting with the same component:
// System 1: Adds component (verified to only run once per entity)
[BurstCompile]
private struct AddHeightDataComponentJob : IJob {
public EntityCommandBuffer CommandBuffer;
public Entity TargetEntity;
public void Execute() {
// Does some stuff with the chunk
CommandBuffer.AddComponent<ChunkNeedsReRender>(TargetEntity);
Debug.Log($"Adding for entity: {TargetEntity.Index} : {TargetEntity.Version}");
}
}
// System 2: Removes component
protected override void OnUpdate() {
var ecb = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>()
.CreateCommandBuffer(World.Unmanaged);
foreach ((RefRO<ChunkCoordinateData> chunkCoordinateData, Entity entity) in
SystemAPI.Query<RefRO<ChunkCoordinateData>>()
.WithAll<HasChunkHeightData, ChunkNeedsReRender>()
.WithEntityAccess())
{
// do some stuff with the entity
ecb.RemoveComponent<ChunkNeedsReRender>(entity);
}
}
Both systems run in InitializationSystemGroup and queue changes to EndSimulationEntityCommandBufferSystem.
System 1 is guaranteed to only add the component once per entity and never again (verified through logs and other safety mechanisms).
Despite this, System 2 sometimes sees and processes the same entity twice across different frames, even though it’s queuing the component removal via ECB.
Expected Behavior: When System 2 queues a component removal via ECB, I expect EndSimulationEntityCommandBufferSystem to execute all commands at the end of the frame, meaning the component should be gone by the next frame.
Actual Behavior: Some entities (different amount every test) get processed twice in system 2. I’ve verified this by tracking processed entities:
if (test.Contains(entity)) {
Debug.Log($"Entity {entity.Index} being processed again");
}
test.Add(entity);
Interestingly, when I switch to using EndInitializationEntityCommandBufferSystem instead (so the same as where the systems are), the issue no longer occurs.
Reproduction of this error is totally unreliable. Some runs it happens other times it doesn’t happen at all for a couple of runs.
I know i should be using Enableable components to avoid structural changes all together but still, I find this behaviour weird?
Is this expected?