Hi Iris / GameplayAbilitySystem friends!
I’ve noticed a confusing change now that we’ve upgraded to 5.6.
bImmediateDispatchEndReplicationForSubObjects got added to ReplicationReader and it’s currently set to true by default, so that EndReplication is triggered for subobjects _before_ any RepNotifies for the accompanying state data. This is causing us troubles when a GameplayTask on the server completes and is removed from the GameplayTaskComponent::SimulatedTasks array. The server happily replicates two things:
1) the task should be removed from SimulatedTasks
2) the task should be destroyed because replication is being ended
the client gets all this information, and as expected with the new code, the order of processing is
1) SimualtedTasks is updated to remove the Task. the PreviousState is cached with the Task still in there, as expected.
2) now the task is told replication has stopped and it begins to destroy itself. UGameplayTask::OnDestroy is called, which marks the task as garbage
3) finally OnReps are called and UGameplayTaskComponent::OnRep_SimulatedTasks is called. because the Previous state was cached, the PreviousSimulatedTasks param passed into OnRep_SimulatedTasks actually still contains that MarkedAsGarbage task. When the code iterates PreviousSimulatedTasks, it ends up trying to call RemoveReplicatedSubobject(OldSimulatedTask) on that task marked as gabage. We have some custom logic in here that ends up checking IsValid on the task, and that is returning false because it is marked as garbage. This worked fine in 5.5 because of the different ordering
what is the proper solve here? Should we just set bImmediateDispatchEndReplicationForSubObjects to false and assume that CVar will always exist and is ok to use? Or should we not be using InValid inside an OnRep, expecting some previous state’s objects to be garbage even when we need to do things with them?
Or all that said, are OnReps going to be replaced with something else? Will we be expected to have custom iris serializers for everything so that we can run callbacks _before_ the property is overwritten and the EndReplication calls are handled?
thanks!
Josh