Hi all, I’m trying to create 2 prediction keys - 1 client side and 1 server side with the same ID. The reason for this is somewhat specific, and I can provide a full explanation of my use case, but for now it’s about a sword slash that happens over time. Essentially the issue comes down to the client trying to predictively apply a gameplay effect, but the server trying to apply one as well before the client tells it to. Since they don’t have the same prediction key beforehand, the effect replication from the server leads to effects stacking.
For example, the client starts a sword slash. This “slash” is really just a hitbox rotating around their camera, applying an effect to whatever it hits. As it starts, it also RPCs to the server to start as well. Because of these simultaneous slashes being on different running games, there could be a number of ways that the server’s hitbox hits something (applying the gameplay effect) before the client is able to give it a prediction key for the effect, for example a ping spike, just desync, server movement updates not reaching client as fast etc. This means the client isn’t really able to give the server a prediction key, as the hit happened on the server before the client’s hit did, meaning the server’s effect is replicated down to the client and instead of removing the client’s effect and applying, it just stacks on top of the client’s effect. This is where the need for “deterministic” prediction key ID creation on both client and server comes from, so that the same prediction key ID can be assigned to both effects and when the server’s effect is replicated it can remove the client’s version of it, by finding it using the prediction key ID.
Right now this is essentially what I’m doing to create prediction keys on both client and server:
FPredictionKey Key = FPredictionKey();
Key.Current = ID;
And I’m passing that in to a ApplyGameplayEffectSpecToTarget
call to apply the effect. I’ve already done the ID generation, and am (mostly) accounting for “ID collisions” between gameplay effects, and I just now need to set the prediction key’s ID to the generated ID. I thought that all that I needed to do I’d done in the block of code above, yet when the server’s effect replicates down the client’s predicted one is not being removed.
Unless I’m misunderstanding how exactly predicted effects are rolled back, I can’t really spot any mistakes, and I’ve tried to look through the source of GAS many times and not found too much apart from ability rollbacks, so I’m posting here since it could easily take me weeks to understand the source of it. Can anyone help?
Side Note: On the FPredictionKey docs page, it says that “we will have 2 of the ‘same’ GameplayEffects in our ActiveGameplayEffects container, temporarily”, which makes me think my understanding of how effects are rolled back is wrong, and that they are rolled back through a reliable RPC. This is because property replication is unreliable yet could be faster, but RPCs are reliable but could be slower, meaning there could be an initial replication of the properties and then an RPC to remove the predicted version. The docs don’t specify exactly what “temporarily” means, but if anyone knows more about it, I’d be happy to hear.
Thanks all.