PART 1 - 강의 3/3

네트워크 예측 기초

Prediction Key 시스템과 롤백 메커니즘

01

Prediction Key 개념

클라이언트 예측의 핵심 식별자

FPredictionKey 구조 // FPredictionKey는 클라이언트에서 생성되는 고유 ID struct FPredictionKey { int16 Current; // 현재 예측 키 int16 Base; // 기본 예측 키 (체인용) bool bIsServerInitiated; // 서버에서 시작된 것인지 // 예측 키는 클라이언트->서버로 복제되지만, // 서버->클라이언트로는 원본 클라이언트에게만 복제됨 }; // 예측 키의 역할: // 1. 클라이언트가 수행한 예측 작업 식별 // 2. 서버가 승인/거부 판단 후 해당 작업 찾기 // 3. 거부 시 연관된 모든 변경사항 롤백
예측 키 복제 방향

예측 키는 클라이언트 -> 서버로만 복제됩니다. 서버에서 클라이언트로는 원래 보낸 클라이언트에게만 결과가 전달되어 다른 클라이언트에게는 노출되지 않습니다.

02

예측 가능/불가능 항목

GAS에서 예측이 지원되는 범위

예측 가능 예측 불가능
어빌리티 활성화 GameplayEffect 제거
트리거된 이벤트 Periodic Effect (DoT)
GameplayEffect 적용 Execution Calculation
어트리뷰트 수정 체인된 어빌리티 롤백
GameplayTag 수정 서버 전용 로직
GameplayCue 이벤트 -
몽타주 재생 -
Execution Calculation 주의

Execution Calculation은 예측 불가능합니다. 복잡한 데미지 계산은 서버 권위로 처리하고, 클라이언트는 결과만 받아서 표시하는 것이 권장됩니다.

03

예측 윈도우와 스코프

예측 작업의 범위 관리

FScopedPredictionWindow 사용 void UMyAbility::ActivateAbility(...) { // 어빌리티 활성화 시 자동으로 예측 윈도우 생성 // 이 스코프 내에서 발생하는 부작용은 예측됨 // 마나 감소, 쿨다운 적용 등은 명시적으로 묻지 않음 // 어빌리티 활성화와 논리적으로 원자적(atomic)으로 처리 } // 새로운 예측 윈도우 생성 (예: 입력 이벤트 대기 후) void UMyAbilityTask::OnInputReceived() { FScopedPredictionWindow ScopedPrediction( AbilitySystemComponent, IsPredictingClient() ); // 새 예측 키로 추가 작업 수행 if (ScopedPrediction.IsValid()) { // 이 스코프 내 작업은 새 예측 키와 연관됨 ApplyGameplayEffectToSelf(...); } }
예측 윈도우 생성 시점
  • 어빌리티 활성화 - 자동으로 윈도우 생성
  • 입력 이벤트 - 사용자 액션에 반응할 때
  • AbilityTask 완료 - 비동기 작업 완료 시
  • 명시적 생성 - FScopedPredictionWindow 직접 사용
04

롤백 메커니즘

서버 거부 시 변경사항 취소

롤백 처리 흐름 // 서버가 어빌리티를 거부하면 롤백 발생 // FPredictionKeyDelegates를 통해 처리 void UAbilitySystemComponent::ClientActivateAbilityFailed_Implementation( FGameplayAbilitySpecHandle Handle, int16 PredictionKey) { // 예측 키와 연관된 모든 부작용 롤백: // - 예측된 GameplayEffect 제거 // - 예측된 태그 변경 취소 // - 예측된 어트리뷰트 변경 취소 FPredictionKeyDelegates::BroadcastRejectedDelegate(PredictionKey); } // 롤백 대상 등록 예제 void RegisterForRollback(FPredictionKey PredictionKey) { if (PredictionKey.IsValidForMorePrediction()) { // 이 키가 거부되면 콜백 호출 FPredictionKeyDelegates::AddDependentDelegate( PredictionKey, FPredictionKeyEvent::CreateUObject(this, &ThisClass::OnRejected)); } }
롤백 시 주의사항

롤백은 예측 키와 연관된 변경만 취소합니다. GameplayCue와 같은 시청각 효과는 별도로 처리해야 할 수 있습니다. 게임 로직에서 직접 변경한 상태는 자동 롤백되지 않습니다.

05

Net Execution Policy

어빌리티의 네트워크 실행 정책

EGameplayAbilityNetExecutionPolicy UENUM() enum class EGameplayAbilityNetExecutionPolicy : uint8 { // 로컬 클라이언트에서만 실행 (UI, 코스메틱) LocalOnly, // 클라이언트 예측 + 서버 검증 (권장) LocalPredicted, // 서버에서만 실행 (패시브, AI) ServerOnly, // 서버가 먼저 실행, 클라이언트에게 통지 ServerInitiated }; // 사용 예시 UMyAbility::UMyAbility() { // 플레이어 공격 - 클라이언트 예측 NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::LocalPredicted; }
정책 사용 사례 특징
LocalOnly UI 토글, 로컬 이펙트 네트워크 트래픽 없음
LocalPredicted 플레이어 스킬, 공격 즉각 반응, 서버 검증
ServerOnly 패시브, AI, 환경 트랩 서버 권위, 치트 방지
ServerInitiated 강제 상태 변경 서버 시작, 클라 통지
SUMMARY

핵심 요약

  • Prediction Key는 클라이언트 예측 작업의 고유 식별자
  • 예측 가능: 어빌리티 활성화, GE 적용, 태그/어트리뷰트 수정, Cue
  • 예측 불가: GE 제거, Periodic Effect, Execution Calculation
  • FScopedPredictionWindow로 새 예측 윈도우 생성
  • 서버 거부 시 FPredictionKeyDelegates로 롤백
  • 플레이어 스킬은 LocalPredicted, AI/패시브는 ServerOnly 권장
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: 예측 어빌리티 활성화

NetExecutionPolicy를 LocalPredicted로 설정한 어빌리티를 만들고, 200ms 지연 환경에서 클라이언트 즉시 실행과 서버 검증 과정을 관찰하세요.

실습 2: 예측 실패 롤백 관찰

의도적으로 서버에서 CanActivateAbility를 false로 반환하게 하여 예측 실패를 유발하세요. GameplayEffect가 롤백되고 GameplayCue가 제거되는 과정을 확인하세요.

심화 과제

undefined