So basically I have a running character in my multiplayer game. The player has the ability to adjust how much “effort” they put into running.
At maximum effort, they run at maximum speed, but drain a “stamina” value.
This stamina value as it drains, affects the max running speed the player can move at… down to a point where the player essentially just jogs along and the stamina drain is held steady.
To make the player’s speed drop, I adjust the CharacterMovement component value for “MaxWalkSpeed”. But when I do this over multiplayer, since I’m adjusting the value often, the server and client dont agree on how fast the player should have been going, thus the client’s position is reset multiple times causing choppy movement. (which you can image is made far worse with higher latency)
HELP I’M AFTER
Advice on what is a good approach to adjusting a character’s Max Walk Speed (or something that can give the same effect) frequently over the network which would reduce the position corrections?
I have considered over-riding the Scale value for Add Movement Input, but it seems like thats not the ideal approach especially to stop possible cheating.
WHAT I’M USING
Child class of “Character”
which in turn has the default CharacterMovement Component
Have NOT mad any adjustments to the Replication values for MovementComponent
APPROACHES I HAVE TAKEN
***UPDATE ON TICK ***
Originally I was adjusting this value on the player’s character first, and then replicating the change to the server. When outputting a PrintScreen of each tick’s value of MaxSpeed I could see where the server and client became de-synced.
I’m guessing that the server and client’s aren’t ever guaranteed to be in sync due to framerate speeds and workloads, etc.
EVENT TRIGGERED BY “OnCharacterMovementUpdated” EVENT DISPATCHER
So I came across this event dispatcher and there does not seem to be many discussions on good ways to use this thing, so I had to fumble through it a bit.
I can see that this event seems to be triggered at different rates on the server and client. Eg, there would be times when using a PrintScreen each time it’s triggered, and I could see it triggering 5 times on the client for every 1 time on the server. Yet during periods of movement sometimes it could be either 2 client for each 1 of the server.
At first I thought it was because I was using Set -> MaxWalkSpeed multiple times per tick, but after digging through my code I found that it was not the case. I only ever called Set Max Walk Speed once in a function that handled the state of the character (and the function was only triggered once per update).
I even removed Set -> MaxWalkSpeed (or any other values relating to the CharacterMovement component), yet this OnCharacterMovementUpdated was being triggering. Even when standing still.
So I’m guessing when this event triggers is not based on movements, or changes to movement parameters, but is some rate relating to how movement is handled per tick or something? And I guess at different rates depending if its a client or server? shrug
Anywho, so I bind and event to OnCharacterMovementUpdated, which then adjusts my Max Walk Speed, and I replicate this change to the server.
This approach is essentially worse than using tick. Due to all sorts of weird de-syncing.
So I change the event to fire only on the server, and then THIS then in turns fires a Multicast event back to the client.
From that Multicast event, I then pass along updated movement parameters to the movement controller (which get replicated to the server) and then process player input and set the requested movement parameters to used in the next Tick/Frame/Thingy.
This approach while fiddly, so far has yielded the best results for adjusting changes of Max Walk Speed between the Client and Server with minimal de-sync. BUT as the player strafes from side to side or turns sharply, this causes their speed to drop suddenly which really throws off the calculations between the server and client thus I suddenly get lots of position corrections.