Difference between Property Replication and RPC technically

Property Replication and RPC both replicate data between server and clients.

And I have some questions about them.

  1. When they replicated? Is it end of tick or something?

  2. Is there bandwidth difference between two?

  1. I do not know though if you find out let me know.
  2. replicated variables use diffs to use less memory. Let’s say you want send continuous changing data.
    For example a score that you increment every time the player hits a target. The player may fire thousands of rounds. Sending the entire number with an rpc will require 4 bytes. However if it only changes by one. It’s really cheap to send a 1 as a single byte instead.

One key difference between RPCs and replicated vars that you may have a misconception on. Is that there are different types of RPCs that allow for sending data from the client to the server, from the server to a client, and from the server to all clients including the server. Replicated vars only replicate changes that occur on the server and send the new value to the clients, never the other way.

RPCs are sent when you run the node. (Or at least queued – sending may be on a separate timer/schedule, based on network tick rate.)
If the network is full, and your RPC is lossy (“fire and forget”) then it may or may not use network bandwidth, and may or may not be lost. If it’s reliable, then it will be re-tried until the other end acknowledges its receipt. (The other end will de-bounce so it only executes once.)

Replicated variables are occasionally sent if they are dirty, but not on any well-controlled schedule. If you change a variable three times in a row, the other end may see between one and three separate changes – e g, it may snap from the first value to the last value, missing the values in-between.

The amount of network bandwidth used by replicated variables depends both on how important the object in question is to the viewer, and your overall net rate. There exists a priority system in the network system that determines which actors and variables to replicate, when, on a prioritized schedule.

BTW: I haven’t actually read the code for this system; this is what I’ve gathered from how it behaves when I use it. I’m reasonably confident this description works, but if some detail is wrong, I’d love to hear about it from someone who knows for sure about that!

There is some quite misleading information in this thread already, so to clear it up - let’s start with the golden rule:

- Use Properties for persistent state.
- Use RPC’s for one-off events or requests.

This is the ONLY metric you need to use when deciding which is more suitable. You can in some cases, also use property replication for lossy events. See my article on Burst Counters. You can NEVER use RPC’s to safely send state-change information.


As for how it works, in a nutshell:

All properties and RPC’s are sent at the END of the frame. Reliable and Unreliable RPC’s are gathered into separate buffers. If you overflow the reliable buffer, you will be kicked from the game. If you overflow the unreliable buffer, subsequent RPC’s will be ignored.

  1. At the end of the frame, the server decides which actors are relevant to which clients.
  2. The server prioritises every actor for every connection based on the update frequency, priority, starvation etc.
  3. Any un-acked property changes are sent, and any pending RPC’s are sent.
  4. Sometime later, the client will notify the server which packets it received, and the server will resend packets it thinks they dropped.

RPC’s and Properties can arrive at the client at different times, there is no defined order. The new IRIS system claims to change this, but we’ll see whether that truly works out. I still don’t think it’ll be reliable enough to actually use in the real world.

RPC’s will always execute in the order they were called (within the same Actor context). Since Unreliables can be dropped however, you’re not garaunteed to get them all any anything that relies on events occuring in order (while inherently risky in MP), should be done using reliables.

If a client drops too any reliable packets, they are kicked.

You are not garaunteed to receive all changes to a property, only it’s eventual state.

This is not true - while smaller actual values can be compressed, delta replication does not work by sending “add 5 to current value” etc. It can’t work this way because it’s inherently lossy. The system may compress small values into smaller packets, but a very big integer will always send as at least 4 bytes, sometimes it may even use more.

All propertires and RPC’s also incur a minimum 2-byte property “header” which identify which property/RPC it is. Properties embedded in structs and subobjects will have larger headers. This is usually not something significant enough to change the design of the code however, apart from in very extreme circumstances.

Replicated variables actually use MORE memory, the Server and Client store shadow states about every variable to know when changes occur - but it doesn’t really matter - they have a different purpose to RPC’s and this is not something you should factor in. Only follow the golden rule.

6 Likes

My example is of course an oversimplification, but property replication does leverage deltas to send more compact info.
Check out NetDeltaSerialize for more info.