Hello! I believe I have found an unhandled edge case when using the push model replication in UNetworkPhysicsComponent that makes the validation fails.
In UNetworkPhysicsComponent::NetworkMarshaledData, when using legacy data, the following piece of code doesn’t take into account a newly emptied data history array, which then leads to an ensure being triggered in CompareParentProperties (“Push Model Property changed value, but was not marked dirty!”).
// Only replicate data to owning client if bDataAltered is true i.e. the input has been altered by the server
ReplicatedInputs.History->ResizeDataHistory(AsyncOutput->InputData->CountAlteredData(/*bIncludeUnimportant*/ true, /*bIncludeImportant*/ bEnableReliableFlow == false), EAllowShrinking::Yes);
ReplicatedInputs.History->SetRecordDataIncremental(true); // Only record data that is newer than already cached data
// Server sends inputs through property replication to owning client
if (AsyncOutput->InputData->CopyAlteredData(*ReplicatedInputs.History, /*bIncludeUnimportant*/ true, /*bIncludeImportant*/ bEnableReliableFlow == false)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UNetworkPhysicsComponent, ReplicatedInputs, this);
}
If the data history array contained any data and was then resized with an “altered data count” of 0, TNetRewindHistory::CopyAlteredData won’t copy anything and will return false by default which will fail to dirty the property and trigger the push model validation ensure.
I fixed the issue locally by making sure a newly emptied data history array is dirtied:
const int32 OldHistorySize = ReplicatedInputs.History->GetHistorySize();
// Only replicate data to owning client if bDataAltered is true i.e. the input has been altered by the server
ReplicatedInputs.History->ResizeDataHistory(AsyncOutput->InputData->CountAlteredData(/*bIncludeUnimportant*/ true, /*bIncludeImportant*/ bEnableReliableFlow == false), EAllowShrinking::Yes);
ReplicatedInputs.History->SetRecordDataIncremental(true); // Only record data that is newer than already cached data
// Server sends inputs through property replication to owning client
if (AsyncOutput->InputData->CopyAlteredData(*ReplicatedInputs.History, /*bIncludeUnimportant*/ true, /*bIncludeImportant*/ bEnableReliableFlow == false)
|| (OldHistorySize != 0 && ReplicatedInputs.History->GetHistorySize() == 0))
{
MARK_PROPERTY_DIRTY_FROM_NAME(UNetworkPhysicsComponent, ReplicatedInputs, this);
}
Thanks!
[Attachment Removed]