스탯이나 아이템 같이 게임플레이의 핵심 데이터가 서버와 클라이언트에서 각자 따로 처리되면 네트워크 문제 발생 시 서버와 클라이언트의 데이터가 불일치가 발생할 수 있음
언리얼 엔진에서의 클라이언트-서버 모델에서는 클라이언트의 데이터는 기본적으로 신뢰할 수 없다는 것을 가정하고 설계
플레이어의 세부적인 스탯 정보를 모든 클라이언트에 공유할 필요가 있는가?
모든 스탯 정보를 공유하면 네트워크에 전송할 데이터도 많아지고 클라이언트가 해당 정보를 받아 다른 형태로 악용할 수도 있음
클라이언트는 다른 캐릭터를 볼 때 HP바만 표시해도 됨
스탯 정보는 소유자에게만 공유하고 다른 클라이언트(Simulated Proxy)는 체력 정보만 공유

네트워크로 전송할 구조체 데이터를 직접 설계해 보내고 싶은 경우에 유용
데이터 양을 최소화 할 수 있음
데이터가 자주 바뀔 때 유용하게 활용
플래그를 설정해 불필요한 데이터 전송을 건너뛸 수 있음
정수 데이터를 변환해 크기를 줄일 수 있음
프로퍼티 리플리케이션
209비트

NetSerialize
121비트로 압축

값이 변경되었을 경우에만 리플리케이션
bool FRepMovement::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
{
...
// Flags에 bool 값을 한 비트씩 저장하여 압축하여 저장
uint8 Flags = (bSimulatedPhysicSleep << 0) | (bRepPhysics << 1) | ((ServerFrame > 0) << 2) | ((ServerPhysicsHandle != INDEX_NONE) << 3);
Ar.SerializeBits(&Flags, bServerFrameAndHandleSupported ? 4 : 2);
// 불러올땐 SerializeBits()에서 Flags를 세팅하여 가져옴
bSimulatedPhysicSleep = (Flags & (1 << 0)) ? 1 : 0;
bRepPhysics = (Flags & (1 << 1)) ? 1 : 0;
... // 플래그에 따라 원하는 값에 대해서만 인코딩과 디코딩 진행
}
https://github.com/dnjfs/ArenaBattle_Network/commit/28d8ff25473e89f76759a22b4f41f62f5138c476
스탯 동기화
스탯 처리는 서버에서만 진행
BaseStat과 ModifierStat의 리플리케이션 처리하여 클라이언트 동기화 (오너에게만)
HP 정보만 모든 클라이언트에게 보내주어 UI도 처리
구조체 최적화
NetSerialize() 함수 구현
TStructOpsTypeTraits 구조체 정의