Hello, this is a sanity check on myself. Input would be appreciated, no pun intended.
Given that a player character may have different items equipped in their inventory that may influences their movement, does it make sense to handle the equipped item change in the SavedMove system?
The setup would be that when equipment would change (keypress for example), it would trigger the Character to tell the movement component to set an id for that item in the inventory. This gets saved SavedMove_Character, along with the logic to copy it into CharacterNetworkMoveData so that it is replicated to the server. Keep in mind: the point of the system is that the server has authority so this “move” is a request from the player and a prediction that it will be accepted by the server. So the client is predicting that their item gets equipped, which will affect any current or future movement that may occur, and the server will receive the “move” which in this context is both any movement AND the item being equipped.
Thus it will be able to perform the exact same change of equipment and movement logic along with propagating that item equip to any other systems (ie replicating it to other connected players) all within the SAME frame. The replication from the server to other players would simply be a property on the actor that the server sets whiles handling the movement. Any corrections that the server needs to make (eg you cannot equip this item) will simply enforce that the MoveResponse to the client is flagged as a bad “move”. This triggers the RPC handling of it on the client to do a correction of position which will be overridden to also support correcting the equipped item(s) the local player has mispredicted, and subsequent unack’ed moves that get replayed back to also handle this correction via overriding SavedMove_Character::PrepMoveFor.
Is this a sound design for UE4+? This is how I’ve implemented it in other engines in the past, similarly anyway, when it comes to predicting movement and swapping actions. It’s just in Unreal Engine 4 weirdly to me there is a very strict dependency between the CharacterMovementComponent and the SavedMove_Character because the Saved"Move" also is equipped to handle more than just movement prediction.
Another example could be abilities. Even if you’re not moving but want to replicate something that is important to client prediction (maybe it will affect movement in the future or to other players? Maybe not?) - it seems best to put it into SavedMove_Character. Am I not mistaken?
For devil’s advocate, let us say that I decided to put the change of equipment “action” into an RPC instead and eliminate everything in the saved move. I’m not aware of any guarantee for order of operations on the server side when that move gets read in versus when the RPC for change of equipment may occur. There’s also the obvious issue of reliability, which move RPCs are not! For example, if I change equipment (RPC A) and move in the same frame (RPC B) locally, the server may process B before A somehow whether there is packet loss or some kind of actor priority setup going wonky even if RPC A is set to be reliable. That would surely interfere with prediction of movement or abilities for players, which moves are not reliable and the equipment change has to be. So in summary, it seems best (to my understanding) to put everything related to prediction, at least as far as possibly determinism for order of operations and potentially affecting movement, in SavedMove_Character.