Hello everyone! I’m learning Mass Entity through a project I’m working on in my free time. So far, it’s been going pretty well. I upgraded to 5.8 because I saw that there were a lot of positive changes to the Mass Entity system, and I found a couple of issues that you may already be aware of, so I wanted to share them here.
First, I think this one is already known: I have to disable UseProcessingQueue to avoid a MassReplication check assertion caused by FQueryInfo checking the query by pointer instead of using an ID.
However, I found another issue related to removing replicated entities. The code that removes the entity from the array is located in a child class of UMassReplicatorBase that I created, following the same logic as the Crowd replication implementation:
auto RemoveEntityCallback = [&RepSharedFrag](FMassExecutionContext& Context, const FMassReplicatedAgentHandle Handle, const FMassClientHandle ClientHandle)
{
ADAMassZombieClientBubbleInfo& UnitBubbleInfo = RepSharedFrag->GetTypedClientBubbleInfoChecked<ADAMassZombieClientBubbleInfo>(ClientHandle);
UnitBubbleInfo.GetUnitSerializer().Bubble.RemoveAgentChecked(Handle);
};
CalculateClientReplication<FDAMassZombieFastArrayItem>(Context, ReplicationContext, CacheViewsCallback, AddEntityCallback, ModifyEntityCallback, RemoveEntityCallback);
The ReplicationProcessor also calls ProcessClientReplication by iterating over shared fragments.
QUICK_SCOPE_CYCLE_COUNTER(UMassReplicationProcessor_ProcessClientReplication);
FMassReplicationContext ReplicationContext(*World, LODSubsystem, *ReplicationSubsystem);
EntityManager.ForEachSharedFragment<FMassReplicationSharedFragment>([&EntityManager, &Context, &ReplicationContext, &ClientHandle](FMassReplicationSharedFragment& RepSharedFragment)
{
RepSharedFragment.CurrentClientHandle = ClientHandle;
RepSharedFragment.EntityQuery.ForEachEntityChunk(Context, [&ReplicationContext, &RepSharedFragment](FMassExecutionContext& Context)
{
RepSharedFragment.CachedReplicator->ProcessClientReplication(Context, ReplicationContext);
});
});
The issue is that when you remove the last entity, that query no longer returns anything. Since there are no entities, there is no shared fragment to process, so ProcessClientReplication never gets called. This eventually causes the final check in the MassProcessor to fail.
for (FMassReplicationAgentDataMap::TIterator It = ClientReplicationInfo.AgentsData.CreateIterator(); It; ++It)
{
FMassReplicatedAgentData& AgentData = It.Value();
if (AgentData.bPendingDestruction || AgentData.LOD == EMassLOD::Off)
{
checkf(!AgentData.Handle.IsValid(), TEXT("This replicated agent should have been removed from this client and was not"));
It.RemoveCurrent();
}
}
For now, I can work around this by keeping a dummy entity isolated somewhere in the world, but I wanted to let you know that this is happening as well.
On another note, I also wanted to take this opportunity to say that so far I think the framework is pretty cool. It may still have some bugs and need a bit more time to mature, but so far I’ve found it quite straightforward to use.
[Attachment Removed]