Announcement

Collapse
No announcement yet.

OnRep vs multicast

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    OnRep vs multicast

    Hi all!
    I see that most tutorials use OnRep events and stay away from multicasts.
    What is the real difference between doing an OnRep (with no COND and a call directly for listen server), and doing a multicast (called from server)?
    Also, one thing that has been bothering me: I assume that functions that are neither client or server, are run by "whoever calls it". Is this assumption true? (My debugging indicates so...)

    Also: Is there some "golden rule" as to what need to be reliable and not? How often will an unreliable RPC be skipped? Can we set stuff like mesh visibility with an unreliable RPC, without visibility bugs becoming a recurring annoyance?

    Also, is there any delay with replicated vars? If I change a DoRep var on the server, will the OnRep be called instantly (so that further methods in the initial function can rely on change made by the said OnRep), or does this happen "when it happens"? In other words: If you check a replicated var; do you check a local copy of this var, or do you actually check the var directly on the server?


    Hoping Rama, or someone, can come along and share of their voodoo






    An intro to replication exists, I know, but it would be nice to have like a primer or something, that just goes over roles and the various things that happens when you call the different kinds of RPCs from the different levels of auth. Maybe I could write one myself, when I get these questions answered...
    Last edited by oasf; 12-16-2014, 07:40 PM.

    #2
    Alright, let's say you have a replicated Actor but it's not network relevant to a client.

    If the server wants the Actor to explode, it could trigger a multicasted event which plays an explosion effect. Clients where the Actor isn't network relevant don't need to see the explosion and they won't.

    Though let's say the server wants to change the colour of the Actor and have the change replicated to clients. If the server triggers a multicast event to change the colour, that will fire on all the clients where the actor is network relevant.

    That means (generally) that clients close to the Actor will see the updated colour, but clients far away won't get the event to update the colour so they'll still see the old one indefinitely.

    If you have a replicated variable to control the colour state with an OnRep instead, even if the Actor isn't relevant the OnRep will fire when the Actor becomes network relevant again and the colour will update correctly.

    So basically: Use OnRep when you need to replicate a change in persistant state and multicast events for temporary things that won't matter in the future.

    Also, my golden rule with reliable is to use it when an event or variable change must get to the client, and not reliable when it's something that updates a lot (like every frame) and it doesn't matter if an update gets lost.
    [Game] Hyper Jam - Neon-soaked arena brawler
    [Plugin] Auto Settings - Game options and input binding toolkit
    [Plugin] [Free] Inline Styling Decorator - Allow inline styling on RichTextBlock

    Comment


      #3
      @Acren
      Thanks for the reply. This actually cleared stuff up...

      Comment


        #4
        The main difference is, that OnRep will happen sometimes (literally), when replicated variable arrive to clients (which happens sometimes).

        Multicast will happen right now, after it's called on server. It will happen even before any replicated variables, replicate. Which might or might not be desired behaviour.
        https://github.com/iniside/ActionRPGGame - Action RPG Starter kit. Work in Progress. You can use it in whatever way you wish.

        Comment


          #5
          Originally posted by iniside View Post
          The main difference is, that OnRep will happen sometimes (literally), when replicated variable arrive to clients (which happens sometimes).

          Multicast will happen right now, after it's called on server. It will happen even before any replicated variables, replicate. Which might or might not be desired behaviour.
          Ok. Then I think I have RPCs covered.
          Out of curiosity: Is there a set time between replication updates? Is it arbitrary, or does it happen every tick, or...?
          How long should I "wait" until I can trust a replicated var to be "correct"?

          Comment


            #6
            All variables are replicaated at end of tick. They are check for changes several time in one tick tough.
            https://github.com/iniside/ActionRPGGame - Action RPG Starter kit. Work in Progress. You can use it in whatever way you wish.

            Comment


              #7
              Originally posted by Sam Bonifacio View Post
              Alright, let's say you have a replicated Actor but it's not network relevant to a client.

              If the server wants the Actor to explode, it could trigger a multicasted event which plays an explosion effect. Clients where the Actor isn't network relevant don't need to see the explosion and they won't.

              Though let's say the server wants to change the colour of the Actor and have the change replicated to clients. If the server triggers a multicast event to change the colour, that will fire on all the clients where the actor is network relevant.

              That means (generally) that clients close to the Actor will see the updated colour, but clients far away won't get the event to update the colour so they'll still see the old one indefinitely.

              If you have a replicated variable to control the colour state with an OnRep instead, even if the Actor isn't relevant the OnRep will fire when the Actor becomes network relevant again and the colour will update correctly.

              So basically: Use OnRep when you need to replicate a change in persistant state and multicast events for temporary things that won't matter in the future.

              Also, my golden rule with reliable is to use it when an event or variable change must get to the client, and not reliable when it's something that updates a lot (like every frame) and it doesn't matter if an update gets lost.


              so should we be doing both?

              multicast and onrep so when the actor becomes relevant it works vs it being just multicast?

              I heard people saying dont use multicast because it will cause lag

              Comment


                #8
                Originally posted by PRESSURE2000 View Post

                so should we be doing both?

                multicast and onrep so when the actor becomes relevant it works vs it being just multicast?

                I heard people saying dont use multicast because it will cause lag
                Use one or the other depending on if you're replicating state or not.
                Multicast is fine if it's being used properly, but if they're being called so many times it lags maybe it's time to optimize.
                [Game] Hyper Jam - Neon-soaked arena brawler
                [Plugin] Auto Settings - Game options and input binding toolkit
                [Plugin] [Free] Inline Styling Decorator - Allow inline styling on RichTextBlock

                Comment


                  #9
                  Senior Multiplayer programmer here - here is a good rule of thumb:
                  • If you are changing the State of an actor, use a replicated variable. Use an OnRep callback if you want to respond to changes.
                  • If you need a one-time Event, use a multicast.
                  This design eliminates any interference from Network Relevancy and handles Join-In-Progress etc seamlessly. Personally, I don't often find much use for Multicasts in gameplay code - they're more useful for say, broadcasting a server message to players etc.

                  However - sometimes it can make sense to use replicated variables for events which occur very often. A good example is ShooterGame's 'BurstCounter' - which in that case is just simple integer value on the weapon class, which increments and uses an OnRep to trigger firing effects on clients.

                  You don't want to be clogging up your RPC buffer with unreliable multicasts for simple cosmetic events like this, especially as they occur so often. Leave the RPC buffer free for other more important things. Variable replication is also considerably more efficient here, because you can benefit from network prioritisation and update rate optimisations - you get no such benefit with RPC's.

                  ---

                  There is a myth that OnRep callbacks are not reliable, but they absolutely are. If you receive a value from the Server and it differs from the Clients' current value, the OnRep WILL be called. I have worked on several games that rely on this behaviour, and they simply wouldn't work if it didn't.

                  In addition, OnRep's have some other useful tools you can use. You can force the OnRep to be called even if the Clients' current state matches the received state by adding the following flags in GetLifetimeReplicatedProps:

                  Code:
                  DOREPLIFETIME_CONDITION_NOTIFY(AMyActor, MyReplicatedProperty, COND_Custom, REPNOTIFY_Always);
                  You can also optionally add a "Previous Value" argument to the OnRep callback, and Unreal will pass the variables previous client value to it. This is now used by Epic quite extensively as part of the Gameplay Abilities system, but it has always been a feature, and you can use it in regular gamecode too. Here's an example from one of my projects:

                  .h
                  Code:
                  /* Used to drive firing simulation effects (muzzle flashes, audio etc.) */
                  UPROPERTY(Transient, DuplicateTransient, ReplicatedUsing = "OnRep_BurstCounter")
                  FHT_RepBurstInfo BurstCounter;
                  
                  /* Replication function. */
                  UFUNCTION() void OnRep_BurstCounter(const FHT_RepBurstInfo& PreviousValue);
                  The Server will *ONLY* send values to clients if it thinks that the client has a different value currently (the server maintains a list of "acked" property states for every property).

                  I think this is where people get confused and assume it to not be working properly. You will not receive all updates made to a variable, you are only garaunteed to receive the eventual state. It's up to you to make the code resilient to this.
                  Last edited by TheJamsh; 06-20-2020, 07:17 AM.

                  Comment


                    #10
                    Hello everyone,

                    I just started playing with UE4 and wanted to implement a "shift to run" feature. I wanted it to work in multiplayer, offline as a client and on the server. My first realization was that the Max Walk Speed is not a replicated value. I came up with two solutions to solve this, which actually this post boils down to RepNotify vs Multicast.

                    My first solution was to set the value on the server and then have the server do a multicast to inform everyone of the change to Max Walk Speed.

                    I then had the idea that I could replicate the "IsRunning" variable on the character by using RepNotify. So I call the server to update the IsRunning variable, and then in OnRep_IsRunning I update the Max Walk Speed.

                    Reading what you wrote above, out of my two solutions, the RepNotify is the recommended one? Maybe there's a better way of doing a "shift to run" feature?

                    Comment


                      #11
                      • If you need a one-time Event, use a multicast.
                      So multicast would be good for starting up your weather event?

                      Comment


                        #12
                        Originally posted by Cybrosys View Post
                        Hello everyone,

                        I just started playing with UE4 and wanted to implement a "shift to run" feature. I wanted it to work in multiplayer, offline as a client and on the server. My first realization was that the Max Walk Speed is not a replicated value. I came up with two solutions to solve this, which actually this post boils down to RepNotify vs Multicast.

                        My first solution was to set the value on the server and then have the server do a multicast to inform everyone of the change to Max Walk Speed.

                        I then had the idea that I could replicate the "IsRunning" variable on the character by using RepNotify. So I call the server to update the IsRunning variable, and then in OnRep_IsRunning I update the Max Walk Speed.

                        Reading what you wrote above, out of my two solutions, the RepNotify is the recommended one? Maybe there's a better way of doing a "shift to run" feature?
                        i would use RepNotify on IsRunning" then you can use that to do it all. From get him to run, but also use it in your anim tree to get animations to fire the run animation.

                        Comment

                        Working...
                        X