MovementComponent Server performance issue with RootMotionSources

Hello!

We have a server side performance issue with the CharacterMovementComponent when clients with a high tickrate executes movements with RootmotionSources or Montage.

In this case the client floods the server with moves because move combination isn’t supported for RootMotionsSources/Montages, so ClientNetSendMoveDeltaTime doesn’t help.

We’re looking for any advice or recommandation to handle this issue. For now we’ll limit the client FPS to 120fps, but there’s maybe a better solution.

Any help would be greatly appreciated!

Steps to Reproduce
Execute some client movement with RootMotionSource or Montage with a very high tickrate

Hey Thomas,

Unfortunately, not being able to combine RootMotionSources is a limitation that we don’t have a good solution for it at the moment. Limiting the client’s max framerate will limit sending so it should solve the issue but there are some other things we can give a shot related to limiting the moves the server is processing:

  • Turn on client authoritative movement with higher allowed error margins (for corrections) during root motion and then have the server drop a certain number of moves to limit it on the server end. This should still look good on the sending client, but the actual movement on server will be weird so proxies may get weird/incorrect movement. You could also improve this by delaying processing a root motion move and “combining” it on the server to run a longer delta time every other frame.
  • A similar approach on the client side (that could save bandwidth and server RPCs) would be to have to client not send every move. This would also rely on client authoritative movement and high error tolerance so it would feel snappy locally, and so we don’t get too many corrections. Again, proxies won’t get the full picture in this case so their movement may look weird/incorrect.

Let me know if you have any other questions! I’ll be sure to update this if I think of anything else.

Thanks,

Nate

Hello Nate, thanks for your answer!

I’m afraid of the quality loss with these solutions, but we’ll give it a try after release.

For now we’ll stick to the FPS limit, afterward we might try to combine our RootMotionsSources/Montages.

On paper it doesn’t seem impossible for our usage, but I might not have the big picture.

Do you have any warning or recommendation before we proceed? Could you tell us what prevented the combination?

Thanks again!

Sounds good, let me know if you have any more questions or findings!

In regards to enabling combining on Root Motion Sources, I can think of a couple reasons we haven’t done so from looking at various comments around uses of bForceNoCombine:

  • Combining root motion may sacrifice some of the exact movement from root motion (like if they were moving along a nice curve, combining them might take shortcuts on it), You’ll also get some additional latency on these moves as you wait to send it. But this is all fairly standard with combining moves in general.
  • One issue with Root Motion Montages is that resetting pawn location and resimulating forward doesn’t work since we don’t want to tick a montage twice and fire off events multiple times.
    • One potential solution could be just not combining the move when an event is fired from the montage, but I’m not sure how hard it is to get this info (I can follow up on this after some discussion with some coworkers).
  • Another issue with Root Motion Sources in general is when a move without root motion sources combine with a move that does have movement from a root motion source. It will cause the DeltaTime for that next move to be larger than intended (effectively the root motion would apply to movement that happened prior to its activation - over the entire combined movement).
    • This one will be a bit more tough to work out, but if you have a lot of root motion sources maybe this won’t an issue as both moves to combine will be root motion sources so the DeltaTime is just entirely root motion source. You still might have to separate moves that had different root motion sources though.

I’ll be sure to update this post if I think of other reasons. Feel free to follow up with any questions or clarifications!