Adjusting the MaxWalkSpeed many times on a multiplayer game, stuttering.

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)


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.


Child class of “Character”
which in turn has the default CharacterMovement Component

Have NOT mad any adjustments to the Replication values for MovementComponent



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.


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.


Reading this post I was eager to see the comments and experiences of others; I was surprised to see no comments. Since posting, have you come up with another reliable approach to solve your problem?

better of using a constructed timer then use the tick I think.
Like this dude

Lag Compensation…

Say you have a 100ms latency. That’s 50ms delay to the server. The server’s version of your acceleration/deceleration functionality needs to account for this, otherwise it’s calculations aren’t going to match the client. Thus a prediction error.

Basically you need to speed up the servers timer to account for the delays. This needs to be done on a per player basis.

You can get Ping from APlayerState … APlayerState | Unreal Engine Documentation