0
\$\begingroup\$

I am implementing a fighting game in Unreal Engine and I want to implement "rollback". The way I envision it so far is that in every frame, the client will send the inputs it received in that frame (30 fps max for now) to the client. Dropping any inputs is unacceptable. To me, it looks like the best way to do this is with RPCs, and if there are inputs in one frame, I will send an RPC to the other client with those inputs. Since inputs can't be dropped, it looks like a good idea to use reliable RPCs. However the documentation explicitly warns against making a reliable RPC every frame.

Warning: Overuse of Reliable functions can result in overflowing the queue for them. This will result in forced disconnections. If you call a replicated function on a frame-by-frame basis, you should make it Unreliable. If you have a Reliable function that is bound to player input, you should limit how often the player can call that function.

Should I really be concerned about hitting this limit if I am making only one RPC per client every frame, and at 30fps max? 60 fps? During a match, theoretically these RPCs will be the only network traffic, as everything gameplay essential will be computed client side from the inputs, and nothing else needs replication. It would be the simplest method by far.

A second question is, even if I don't hit this limit, would reliable RPC introduce noticable latency over, say, using TCP, or some other method I am unaware of? Is sending packets every frame simply too much traffic?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Using Reliable RPCs for Inputs works and can be fine if this is your only usage. I would suggest using Unreliable RPCs and send absolute values instead of deltas. However, that's where the usage of Reliable RPCs should (mostly) end. Use Reliable RPCs judiciously and only when you cannot use replicated variables.

Unreal Engine's networking (and your game) lives and dies by the concept of replicated variables:

  • Replicated Variables are reliable in that it is guaranteed that any change to the value will be received, however there is no guarantee that intermediate changes are also sent (e.g. if you attempt to send 1 and then 2 and then 3, it's possible that you only receive 3 whereas with Reliable RPCs, you are guaranteed to get all 3 in that order)
  • Replicated Variables are throttled and respect the network relevancy tuning
  • Replicated Variables, unlike RPCs, are guaranteed to be received by an Object/Actor that is not yet created on the client (fairly big downside of Reliable RPCs which make no such guarantees).
  • Replicated Variables can only be replicated from Server to Client where as Reliable RPCs can be replicated from Client to Server (and only from Actors that the client owns, which is usually only the player character and player controller).
  • If you want your game to support late-joining, replicated variables is the only answer

Downside of replicated variables is that they will replicate whenever Unreal feels like it can replicate them. Reliable RPCs however get preference and are replicated as fast as possible. However, this comes at a cost where if you overrun a hard-coded limit in the engine, the client(s) will be disconnected. Unreal is very strict when it comes to Reliable RPCs.

For most functionality, replicated variables is the way to go. Trust the architecture of Unreal here and use them for most of your replication. Only use Reliable RPCs when you have to (e.g. GAS uses Reliable RPCs for Ability related events).

Finally, I would highly suggest to not fight against Unreal's Networking architecture/design and fit in your own version. Embrace it, understand it, and help it help you.

\$\endgroup\$
0
\$\begingroup\$

You should try to avoid sending Reliable RPCs whenever you can. Unreliable RPCs however you may send as much as you want. The engine will send them, but they may get dropped due to the nature of underlying network implementation (UDP)

The downside of using Reliable RPCs is that they need to be re-transmitted and they won't go thru the network and arrive the server faster than they can. If it's physically impossible to send a packet over they won't go thru regardless of reliable or unreliable. They simply get re-transmitted.

Reliability basically incurs a cost of having to resend your RPCs, having to order them and also waiting, to make sure they all arrive in order. This can eventually increase latency and may not be what you want for a fast paced game.

What you could do is queue up your input commands and re-send them manually, and order them on your end. Most of the time you only care about the latest input anyways.

I'm want to refer you to the old UDK docs which provides a pattern you could use.

Pleas see Semi-reliable function calls

https://docs.unrealengine.com/udk/Three/FunctionReplication.html

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.