Client에서 Predict 된다는 의미는 Server에서 Gameplay Ability 활성화나 Gameplay Effect 등록에 대한 허가를 기다릴 필요가 없다는 것을 의미한다.
이는 작업을 수행할 권한을 부여해준 Server와 Gameplay Effect가 적용 될 Target을 Predict 하는 것이다.
Server는 Client가 활동하고 나서 네트워크 지연 시간이 지난 후 GameplayAbility를 실행한 후, Client에 Predict로 시행한 동작이 맞는지 틀린지 답해준다.
만약 Client가 틀렸다면, Client에서 잘못 Predict 한 것을 Server의 결과로 복구한다.
GAS에서의 Predict 관련된 코드들은 GameplayPrediction.h 파일에 있다.
Epic의 Predict에 대한 철학은 "해도 될 것 같은 것"에 사용하는 것이다.
예를 들어 Paragon이나 Fortnite는 Damage를 Predict 하지 않는다.
대부분 ExecutionCalculations를 통해 Predict 할 수 없는 Damage를 처리한다.
... we are also not all in on a "predict everything: seamlessly and automatically" solution. We still feel player prediction is best kept to a minimum (meaning: predict the minimum amount of stuff you can get away with).
Dave Ratti from Epic's comment from the new Network Prediction Plugin
Predict 가능한 것
Ability Activation
Triggered Events
GameplayEffect Application
Attribute Modification(Not Executions, only Attribute Modification)
GameplayTag Modification
Gameplay Cue Events
Montages
Movement(in UCharacterMovement)
Predict 불가능한 것
GameplayEffect Removal
GameplayEffect periodic Effect
추가 설명
GameplayEffect 등록은 Predict 할 수 있지만, 제거는 Predict 할 수 없다.
이 제약을 피하는 한가지 방법은 제거 대신 Inverse Effect를 Predict하는 것이다.
GameplayEffect 제거를 Predict 할 수 없기 때문에, 우리는 GameplayEffect Cooldown을 Predict 할 수 없다.
심지어 이건 Inverse도 없다.
Server에서 Replicate 된 Cooldown GE는 Client에 존재 할 것이고 이를 제거하려는 모든 시도는 Server에 의해 거부될 것이다.
이는 지연시간이 긴 유저가 서버로부터 Cooldown을 받는데 걸리는 시간이 길어 더 불리하다는 얘기이다.
Fortnite는 이를 피하기 위해 Cooldown GE 대신 Custom Bookkeeping을 사용하고 있다.
Instant GE를 자신에게 사용할 때에는 문제 없지만, 타인에게 사용할 때에는 값이 잠깐 튈 수 있다.
Instant GE를 Predict 하는 것은 Infinite GE처럼 취급되어 복구가 될 수 있다.
만약 Server의 GE가 적용되면, 아주 잠깐동안 동시에 2개의 GE가 존재하여 Modifier가 2번 적용될 수 있다.
이는 곧 정상화가 되겠지만, 일부 유저들은 이상현상을 감지할 수 있다.
PredictionKey
GA의 Prediction은 Client가 Gameplay Ability를 활성화 할 때 생성되는 Integer Identifier를 기반으로 동작한다.
Gameplay Ability가 활성화 될 때 Prediction Key가 생성된다.
이를 Activation Prediction Key라 지칭한다.
Client는 이 Key를 CallServerTryActivateAbility() 함수를 통해 Server에 전달한다.
Client는 이 Key가 Valid한 동안 등록된 모든 Gameplay Effect에 추가한다.
Client의 Prediction Key가 Scope를 벗어난다.
같은 Gameplay Ability에 Predict 한 Effect는 새 Scoped Prediction Window가 필요하다.
Serverrk Prediction Key를 Client로부터 전달 받는다.
Server가 Prediction Key를 등록된 모든 Gameplay Effect에 전달한다.
Server가 Prediction Key를 Client로 다시 Replicate 한다.
Client는 GE를 등록하는데 사용한 Prediction Key와 함께 GE를 Replicate 받는다.
만약 Client에서 등록한 GE 중 Replicate 받은 GE와 동일한 것이 있다면, Predict가 성공한 것이다.
Client가 Predict한 GE를 제거하기 전까지 한 Target에 대해 일시적으로 2개의 GE가 존재하게 된다.
Client가 Server로부터 Prediction Key를 받는다.
이것은 Replicated Prediction Key라 부른다.
이 Prediction Key는 이제 Stale 상태로 둔다.
Client는 Stale 상태의 Replicated Prediction Key을 이용해 모든 GE를 지운다.
Server로부터 Replicate 받은 GE는 유지가 될 것이다.
Client가 생성했지만 Server로부터 Replicated Prediction Key를 받지 못한 GE는 모두 Predict 실패 처리된다.
Prediction Key는 GameAbility가 Activation Prediction Key로 인해 활성화 되고 나서 Window라는 Atomic Group 명령이 수행되는 동안 Valid를 보장 받는다.
단순하게 한 Frame동안 Valid를 보장 받는다 생각하면 된다.
새로운 Scoped Prediction Window를 생성하는 Synch Point를 가지고 있지 않다면 예정되어 있는 Ability Task의 모든 Callback은 Valid한 Prediction Key를 가질 수 없다.
Creating New Prediction Windows in Ability
Ability Task에서 발생한 Callback에 대해 더 많은 Predict를 하기 위해, 새 Scoped Prediction Key를 이용해 새 Scoped Prediction Window를 만들 필요가 있다.
이는 Client와 Server 사이의 Synch Point로 여겨지기도 한다.
Input과 같은 일부 Ability Task에는 새 Scoped Prediction Window를 생성하는 기능이 내장되어 있다.
이는 Ability Task의 Callback의 단위 코드는 유효한 Scoped Prediction Key를 가지고 있다는 뜻이다.
만약 Ability Task 이후의 행동을 Predict 한다면, WaitDelay와 같이 Scoped Prediction Window를 만드는 코드가 없을 것이다.
때문에 OnlyServerWait 옵션과 함께 AbilityTask관련하여 WaitNetSync을 사용해야만 한다.
Client가 OnlyServerWait 옵션인 채로 WaitNetSync를 호출하면 다음 동작을 시행한다.
Gameplay Ability의 Activation Prediction Key를 기반으로 한 새 Scoped Prediction Key를 생성
새 Scoped Prediction Key를 Server에 RPC로 전달하고
등록된 GE에 새 Scoped Prediction Key 추가
Server가 OnlyServerWait 옵션인채로 WaitNetSync를 호출하면 다음 동작을 시행한다.
작업하기 전 Client로부터 새 Scoped Prediction Key를 받을 때까지 대기
이 Scoped Prediction Key는 GE에 등록된 Activation Prediction Keys와 일치하고, Client에 Stale 한 채로 Replicate 된다.
Scoped Prediction Key는 Scope를 벗어나기 전까지 유효하다.
이는 Scoped Prediction Window는 닫혀 있다는 것이다.
그렇기에 미루어지지 않는 Atomic 연산만이 새 Scoped Prediction Key를 사용할 수 있다.
WaitNetSync를 사용하면, Server의 Gameplay Ability가 Client로부터 패킷을 받을 때까지 대기상태에 빠질 수 있다.
이는 해커에게 취약점을 제공할 수 있다.
Predictively Spawning Actor
Client에서 Actor Spawn을 Predict 하는 것은 좀 더 복잡한 이슈이다.
적어도 GAS는 이러한 기능을 제공하지는 않는다.
중요한건 Replicate 되는 Actor을 Client와 Server 양쪽에 모드 Spawn 해야 한다는 것이다.
만약 Actor가 장식이거나 Gameplay 목적이 전혀 없다면, IsNetRelavantFor() 함수를 Override 하여 Server가 소유한 Client에 Replicate하지 않도록 하는 것도 방법이다.
Owner Client는 Local 상으로 Spawn을 하고, Server나 다른 Client는 Spawn을 하지 않는다.