Steps to Reproduce
- Add the following code a C++ project:
`class FTestStructDeltaState : public INetDeltaBaseState
{
public:
bool IsStateEqual(INetDeltaBaseState* Other) override
{
return TestValue == static_cast<FTestStructDeltaState*>(Other)->TestValue;
}
public:
int32 TestValue = 0;
};
USTRUCT()
struct FTestStruct
{
GENERATED_BODY()
public:
UPROPERTY()
int32 TestValue = 0;
bool NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaInfo)
{
if (DeltaInfo.Writer)
{
// Save current state
auto NewState = static_cast<FTestStructDeltaState*>(DeltaInfo.NewState->Get());
if (NewState == nullptr)
{
NewState = new FTestStructDeltaState();
*DeltaInfo.NewState = TSharedPtr(NewState);
}
NewState->TestValue = TestValue;
// Nothing to do if value didn’t change compared to old state
const auto OldState = static_cast<FTestStructDeltaState*>(DeltaInfo.OldState);
if (OldState && OldState->TestValue == TestValue)
{
return false;
}
// Send difference between last sent state and current value
int32 DeltaToWrite = TestValue - (OldState ? OldState->TestValue : 0);
(*DeltaInfo.Writer) << DeltaToWrite;
GEngine->AddOnScreenDebugMessage(INDEX_NONE,
1.0f,
FColor::Blue,
*FString::Printf(TEXT(“Sent delta %i → %i”), DeltaToWrite, TestValue));
}
else if (DeltaInfo.Reader)
{
int32 ReceivedDelta;
(*DeltaInfo.Reader) << ReceivedDelta;
TestValue += ReceivedDelta;
GEngine->AddOnScreenDebugMessage(INDEX_NONE,
1.0f,
FColor::Green,
*FString::Printf(TEXT(“Received delta %i → %i”),
ReceivedDelta,
TestValue));
}
return true;
}
};
template <>
struct TStructOpsTypeTraits : public TStructOpsTypeTraitsBase2
{
public:
enum
{
WithNetDeltaSerializer = true,
};
};
UCLASS()
class AMyTestPawn : public APawn
{
GENERATED_BODY()
public:
AMyTestPawn()
{
bReplicates = true;
}
UPROPERTY(Replicated)
FTestStruct TestStruct;
UFUNCTION(Exec)
void ChangeTestValue()
{
if (HasAuthority())
{
++TestStruct.TestValue;
}
}
void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyTestPawn, TestStruct);
}
};`* Configure AMyTestPawn as your pawn class in your game mode
- Go to Edit -> Editor Preferences -> Play and enable network emulation for everyone with the “Bad” profile
- Start PIE as a listen server with two players
- On the server instance, keep executing the ChangeTestValue function via the console
- Observe that some deltas will not arrive on the client, leading to the values going out of sync over time