What is the best way to replicate a value that changes often?

Basically I want to replicate the location and rotation of a Pawn, that does not affect gameplay. It’s just so that the players can see each other. So I need to replicate the value from the client controlling the Pawn to the server. From there I also need to replicate the value to the clients.


So what would be the best way to replicate the value from client to server?

  1. Reliable Function every tick (definitely not)
  2. Reliable Function when the value changes (probably not, because location in my case changes quite often, but rotation shouldn’t change as often)
  3. Unreliable Function every tick (less network load and completely reliable)
  4. Unreliable Function when the value changes (not as reliable, because the latest update might not arrive on the server)
  5. Reliable Function every 0.1 seconds if the value changed (reliable, slim network load, looks ok if I interpolate the location on the clients, but adds an extra delay of about 0.1 seconds)
  6. Unreliable Function every 0.1 seconds (reliable, slimmest network load, extra .1 second delay)

Secondly, what would be the best way to replicate the value from server to clients?

The possibilities are pretty much the same, with the exception, that I could also use a replicated variable.

I guess the question really boils down to how do reliable functions compare to unreliable functions?
And how do replicated functions compare to replicated variables in terms of network load? Maybe some of you have a rule of thumb, that they would like to share.

Also, is it possible to use the normal replicate movement flag for this? Maybe it is possible to override a function, that handles the movement replication? Then I could override that function and stop it from executing on the client, that controls the Pawn.

Edit: I could override AActor::PostNetReceiveLocationAndRotation() to achieve just that. So I am pretty sure the best way to Replicate from Server to Clients is to use the standard Movement Replication.

I am pretty certain what the best solution for my case would be and what I am going to do. But keep in mind that this solution is not the best solution for every case, so try to consider all the different options in your case.

So for the server to clients replication, I will override PostNetReceiveLocationAndRotation() on my Pawn, so that the Client does not do anything, when he receives an update, since the Client acts authoritative in my case, because the Pawn has no direct Gameplay impact, like the observing Pawn in a strategy game. So that method would look something like this:

void AMyPawn::PostNetReceiveLocationAndRotation()
{
    if (!IsLocallyControlled)
    {
        Super::PostNetReceiveLocationAndRotation();
    }
}

For the replication from the client controlling the Pawn to the server, I will use an Unreliable Function every tick. But I will also keep track of how often the function was with the same Location value. Kinda like this:

pseudo code:

uint8 LocationUpdateRepititions;

if (LocationChanged())
{
    SentUpdateToServer();
    LocationUpdateRepititions = 0;
}
else if (LocationUpdateRepititions < 10)
{
    SentUpdateToServer();
    ++LocationUpdateRepititions;
}

Of course I would have to change the Threshold based on how well this works.