I am in the process of creating an ability system with client prediction akin to Unreal Engine 4’s Gameplay Ability System.
I found an edge case where the client’s tags that are applied from effects become out of sync with the server.
The prediction method I use is the same as detailed here.
Here is a scenario that illustrates this:
The player has 2 abilities, an ability to unsheathe their weapon, and an ability to sheathe their weapon. Each ability requires a specific tag to activate. For the unsheathe ability, it is the “Sheathed” tag. For the sheathe ability, it is the “Unsheathed” tag.
There also exist two effects that apply these tags. The UnsheatheEffect applies the “Unsheathed” tag and the SheatheEffect applies the “Sheathed” tag.
The unsheathe ability lasts for 1 second and at the end applies the UnsheatheEffect and removes the SheatheEffect. The sheathe ability does the same thing but applies the SheatheEffect and removes the UnsheatheEffect.
In this scenario, the player has a static ping of 1 second.
0 seconds: The client activates unsheathe ability. Tags {"Sheathed"}
1 second: The server activates unsheathe ability.
1 second: The client finishes unsheathe ability. Tags {"Unsheathed"}
1 second: The client proceeds to activate sheathe ability. Tags {"Unsheathed"}
2 seconds: The server finishes unsheathe ability and starts the sheathe ability.
2 seconds: The client finishes the sheathe ability. Tags {"Sheathed"}
2 seconds: The client activates the unsheathe ability. Tags {"Sheathed"}
3 seconds: The client reconciles with what happened on the server as a result of the unsheathe ability. Tags {"Unsheathed", "Sheathed"}
.
The issue is that the client has already gone through the process of removing tags after abilities, but they are soon added back because of the reconciliation with the server. I am really not sure what to do about this, because the client should be in sync with the server, but it ends up just messing up the whole system.