Need some clarification on NetMulticast Events and actor relevancy

I have a question regarding NetMulticast and Actor relevancy.

Hypothetical situation:
PlayerA is battling PlayerB at some location.
PlayerC is somewhat 100000km away, aka not relevant to PlayerA nor PlayerB.
During the battle, the server executes a NetMulticast on PlayerAs character (for example, to make PlayerAs character play an animation).

Question:
How will that NetMulticast be handled. Is it either

  1. The server is smart enough to realize that PlayerA is not relevant in PlayerCs perspective, thus the server will only send the NetMulticast about PlayerAs character to PlayerA and PlayerB?
  2. The server sends the NetMulticast to PlayerA, PlayerB and PlayerC, but PlayerCs client realizes ā€œthat data packet is not relevant for me, iā€™ll ignore thatā€?

Obviously the first possibility could save alot of bandwidth while the second wastes bandwidth and cpu time on PlayerCs client.

1 Like

The server holds all the cards so it decides if a client needs to receive the event or not. The server makes a relevancy check if the Multicast is unreliable. If the Multicast is reliable it skips the relevancy check though.

The whole point of relevancy checks is to save bandwidth on unimportant actors.

Do you have a source for this? Why would the reliability flag affect relevancy?

I found another user who claims this. Interesting!
https://forums.unrealengine.com/development-discussion/c-gameplay-programming/95610-netmulticast-function-executed-on-unrelevant-clients

ā€œReliableā€ specifier means that the engine will ensure that the RPC is called in the client. That means that it will be called even if the actor is not relevant for the client.

Currently NetMulticast is sent to all clients (even if calling actor is not relevant to them). Iā€™m only tested Reliable NetMulticast but more on that later.
There is bug report which covers some part of this problem so vote for it and maybe Epic will finally fix this issue.

Regarding to Reliable\Unreliable specifiers: https://docs.unrealengine.com/en-US/ā€¦ons/Specifiers
To my knowledge and for what I see in docs: Unreliable RPC (server, client, multicast) may not reach receiver because of network errors (lost\dropped packets) or limited bandwidth (Same as UDP protocol). Reliable RPC is guaranteed to reach receiver (if it can be reached at all), so receiver must confirm that data arrived or sender will resend it again and again. (Same as TCP protocol).

So it should not modify NetMulticast relevance checks behavior in any way. As I see if you for any reason need multicast called on all clients regardless of relevancy you should call it from GameState (always relevant for everyone) or from custom actor which is also set to be always relevant.

I hope Epic will fix this problem because it has a lot of performance, gameplay and bandwidth problems.

  1. Spawning not relevant actor for few seconds, also if calling actor is attached to something (Example: Weapon attached to characters mesh socket) it will spawn on client in world space (0, 0, 0). It seems happen because client receive information about actor that calls NetMulticast but has no info about it parent (because its currently not relevant).
  2. Doing thing that is not relevant for some clients like playing effects that they never see (NetMuticast function body)
  3. Sending not needed data through network

Wow, so right now using reliable multicasts is a huge bandwidth and performance waster if multicast is used on actors that are not relevant to all.

IMO they should make it four categories instead of two for multicasting:
UnreliableToAll - Unreliable multicast to all clients regardless of relevancy
ReliableToAll - Reliable multicast to all clients regardless of relevancy
UnreliableToRelevant - Unreliable multicast only to clients for which the multicasted actor is relevant
ReliableToRelevant - Reliable multicast only to clients for which the multicasted actor is relevant

Have you verified this? If the actor isnt yet relevant on the client, then there would be no way for the rpc to be handled as the actor id would be invalid as far as the client is concerned.

I havenā€™t looked into it, but it could be handled in such a way that if a client client recieves a multicast request for a non-relevant object, it checks via IsValid() or something similar whether the object exists on the client and if not it ignores/discards the multicast request. Again, i havenā€™t checked it myself, but this woujld be the logical thing to do if reliable netmulticasts are truly sent to all clients regardless of an actors relevancy.

Iā€™m going to quickly rez this topic because its still an ongoing issue.
EPIC set the ticket to wonā€™t fix because its more of a design difference in what they believe to be the right answer vsā€¦ well everyone else Iā€™ve talked too. They force create a channel and replicate the actor then process the multicast RPC because they assume anything that is within cull distance, that has an RPC call occur on it, is ā€˜goingā€™ to arrive in the near future, which obviously isnt true if the relevancy is being controlled.

I came up with a work around after reading over the code with how net multicasts work and Iā€™m posting it here for future people to find.

If you set the cull distance of the actor to zero, then manage the relevancy yourself via overriding IsNetRelevantFor within the actor. You can work around this issue because of there assumptions with cull distance.

If your interested in the code that actually does this, check out line 2165 of ReplicationGraph.cpp. this covers how Multicast works, and if you look at the parts that work with ā€˜bShouldOpenChannelā€™ youā€™ll see what I mean about opening the channel just to replicate the RPC.

This isnt a great solution and probably a custom ReplicationGraph would really fix it, but so far Iā€™ve had little success making that work correctly, and for my specific usage case, this solves the problem, so Iā€™m just going with it for now.