Status of NetworkPrediction plugin working in tandem with CharacterMovementComponent? Troubles synchronizing walk speed/stamina across client/server.

Hello!

We are currently building a stamina based sprint where the character is able to sprint at different speeds depending on stamina. The hiccup we’re hitting is that the stamina dictates the sprint speed (think of it as sprint having two different modes of operating “run” and “jog” -- when they have stamina the character’s speed is their “run” speed, when they’re out of stamina they use a “jog” speed).

We’ve implemented the sprint as a custom movement mode, with the stamina being updated during the `PhysCustom` update. In there we adjust the stamina and then the speed once the stamina is depleted. As you can imagine the stamina can easily get out of sync on the client/server during the sprint, leading to rubber banding (the client ran out of stamina before the server, or vice versa).

I am trying to figure out the best way to synchronize the stamina during the sprint. This led me to discovering the NetworkPrediction plugin. I’ve come across a number of old threads now mentioning how there’s work in progress to marry NetworkPrediction with the CharacterMovementComponent, but they’re years old at this point and I am unclear on the state of that today.

The NetworkPrediction plugin does seem a little like overkill for this problem though, so I’ve been also considering utilizing the move data time stamps to more accurately predict stamina across the network. However, I’m struggling a bit to make heads or tails of all the different time stamps in `FNetworkPredictionData_Server_Character`, etc. and am unsure which (if any) to use.

Please let me know if you have any suggestions here.

Thank you!

Hi,

To clarify, there are not any plans to integrate the network prediction plugin with the Character Movement Component. The NPP is being used as part of the new, experimental Mover plugin, and you can find more info on that here: https://dev.epicgames.com/documentation/en-us/unreal-engine/mover-in-unreal-engine

In this case, we would recommend just using the CMC and extending the move data to include anything relevant to your sprint movement. You’ll also likely want to extend the CharacterMoveResponseData, so if there’s a correction, the client can receive the server’s state data on the sprint in order to avoid further corrections.

For example, you could include a flag on the saved move and CharacterNetworkMoveData indicating that the client is trying to sprint, and on the saved move and move response data you could include a timestamp of when the client’s latest sprint started and the current amount of stamina the client has. With this information, the server could verify the client’s sprinting state and that stamina is changing at the expected rate (using the client’s delta time), correcting the client if necessary. (This may need to be handled differently depending on the design/needs of your sprint functionality.)

You can find more info here on customizing movement as well as on how the client’s delta time is calculated.

If you have any further questions, please don’t hesitate to reach out, but please note that support will be limited for the next two weeks due to the company break.

Thanks,

Alex

Hi Alex,

Thanks for this.

This was essentially where I was heading.

There is a world where the client’s stamina is out of sync and a correction would need to be issued. Ideally, in some scenarios, I could issue a correction to just the stamina before it has depleted on the client and I wouldn’t have to issue a positional correction. I had hoped there was some scenario where I could utilize the NetworkPrediction system for this, and interleave corrections from that into my character movement. I’ll stick to the tried and true CMC structs for now.

What’s the latest on the status of the Mover plugin? Is there work in flight to port Fortnite to it anytime soon?

Hi,

While I can’t share any info on Fortnite, work on the Mover plugin is still ongoing. I can’t speak to when it may no longer be experimental, but we are working to expand and improve Mover as well as to integrate it with other systems in the engine. I believe some upcoming focus areas are physics-based character movement and handling movement off of the game thread, but please note that all plans are subject to change.

Thanks,

Alex

Hi Alex,

Hope you’re having an enjoyable summer break (I am not expecting a response to this until you folks are all back), but…

In regards to the docs on ‘how the client’s delta time is calculated’, I don’t see any mention of the `NetServerMaxMoveDeltaTimeScalar` CVar (`p.NetServerMaxMoveDeltaTimeScalar`) which looks like it was introduced in 5.5. Would you mind going into more detail regarding this setting and how/when it’ll affect the sim time on server?

From the looks of it, the server’s DT might be greater than the client’s (potentially leading to issues like I was seeing, where accumulating something like stamina drain could get out of sync).

Hi,

That CVar was introduced at CL 33812393 (GitHub commit here) in order to reduce corrections when client updates are lost. This is used in GetBaseServerMoveDeltaTime (called from GetServerMoveDeltaTime) to scale MaxMoveDeltaTime, but if this value is larger than `ClientTimeStamp - CurrentClientTimeStamp`, then the difference of those timestamps will be used for the delta time. You can see where this DeltaTime is retrieved in UCharacterMovementComponent::ServerMove_PerformMovement before it is passed to MoveAutonomous.

You can try setting p.NetServerMaxMoveDeltaTimeScalar to 1 to test if this is causing issues for your project.

Thanks,

Alex