Player Controller client RPC not triggered

I am trying to trigger some syncing code from the HandleStartingNewPlayer in my GameMode.

From there I call a server side event on the Player Controller. This again calls a client side event.

Now this works for when the server joins the map, but if a client joins the client RPC never gets triggered (although it gets called).

I had something similar once with an event called from OnPossess, but making it reliable was enough back then.

Is the HandleStartingNewPlayer too early? Which event would I use then? Or is this maybe caused by something else?

Replicated variables with OnRep functions or replicated Exposed on Spawn variables are often more reliable than RPC’s.

Some refer to replicated variables as Network States and RPC’s as Network Events. A state is long-term and Event is short-term and is often unreliable. States/Variables always reflect the latest state as soon as possible and may skip intermediate (old states). Reliable RPC’s should only be used when it is critical that the Event is resent if lost.

As far as I remember it should be okay to make a reliable Server-side RunOnOwner call when the owner variable is valid which should have happened at BeginPlay. Then the RPC is placed in a queue for that particular owner and re-sent until that owner acknowledges it.

I guess I could rework it so it uses variables rather than calls, but could you please elaborate on replicated exposed on spawn variables?

I remember having big trouble trying to get an exposed variable to correctly replicated (see [this thread][1] for example).

Where would you put logic that syncs the client map and should preferably run before the client spawned. In detail it resulted from another question about in-progress joins and interactable foliage. Basically clients that join after the interaction (remove/add instance) don’t know about it, so I have to somehow sync before/at join time.

Is there no place for doing things like that?

[Here is the question][2] if you want to read further.

EDIT: You basically suggest I use a RepNotify just like I would have used the replicated event?

EDIT2: I tested this out and setting the variable like in the screenshot seems to completely destroy all other character replication :S The OnRep function is empty as of now


OnRep functions ONLY gets called when the server predicts that the client variable is out of sync. If your ExposedOnSpawn variable is equal to the default value then the server don’t see any reason to call OnRep as it is wasteful traffic.

Late joining players like you experienced will not know about all the Network Events (RPC’s) that has happened before they joined. This is where Network States (replicated variables) become very important since when a new player joins the Server will begin to update all those out-of-sync variables to there current state.

To make matters worse (multiplayer is difficult) you should not make everything replicated variables (long-term) since if a large explosion etc happens when the variable is updated then this event will get triggered when the new player joined as if it just happened even though it could have happened 30 minutes ago.
This is why RPC’s and Replicated variables go hand in hand and should be used together.
The sound/Visual events gets triggered by the RPC (particle effects etc.) while the network state (the door is open or the tree is burnt down) is saved as a replicated variable.

I don’t quite understand. Do you mean equal to the current value? Why would I want my server to only sync when something differs from the default, and not the current value?

So if I use RepNotify, late joining players trigger all the notifies for variables that were changed?

Jeez, why can’t the RPC just trigger, I’d be done by now…

If you have 5000 or more Actors that has to replicate when someone joins it will affect the other players. if only 200 out of those 5000 have actually changed since the game started then you just saved a ton of traffic.

OnRep should never be used to initialize an Actor… that is handled in the Construction script and BeginPlay.

Note that replicated Variables on a PlayerController can’t be seen by other Players. PlayerController is a private connection between the Server and one Client.

I have 1 foliage actor, 1 server player and 1 player joining. That is all there is to replicate right now. No 5000 actors. No ton of traffic. 1 single OnRep variable in the whole project.

Why does my client freeze and doesn’t get any replicated calls if I use this single OnRep variable? Where should I put “login sync logic” if not in an OnRep and not in an RPC?

I only have the Server player and the client and I only want to trigger one simple client RPC on the joining player controller so he can sync the foliage :’((

Well something is not right if neither of those work. You need to show more of your setup to debug the problem.

There is nothing more to show I fear.

It does not seem to matter when / where I call the server event.

Even if I make rhe event mutlicast and delete all foliage, it only ever gets called on the server.

My efforts of making this variable based only destroyed more.

How shoulf I handle in progress joins? Should the joining player get his controller switched once he joins and have some other controller in the main menu map? Can that be the problem?

Thank you kindly for your help. I reproduced the issue in a seperate project and it seems the HandleStartingNewPlayer is just too early to call any client side logic on the Player Controller.

Using the BeginPlay of the controller works in the seperate project.

I still would recommend replicated variables. It might take a while for all of them to sync but they will sync eventually.

You are probably experiencing a race condition where events during heavy load gets executed in a different order than expected. It can be difficult to debug but you could try to add a longer delay and stagger the heavy load and RPC calls.

So another update. All worked fine in the seperated project, but when I come to my main project with >9k instanced I need to sync. RPCs start getting lost again. When I stay below 1k (transform array), it works fine. Any idea on what I can do to solve this?

Making bulks of information would work but then there’s the limit of 2 RPC calls per frame and also the limit of how much I can send doesn’t seem very reliable.

I might stick with replicated variables for this one… The advantage is this is per client, so once a client joins, only he will have to replicate the state (I guess Player Controller is the place for something like this).

Splitting up into multiple RPC calls might be a bad idea. If a client is let’s say currently syncing 3/10 calls, and the server removes a foliage instance, the client will be out of sync again. Removing foliage instanced might affect the whole array.

So optimally this is all transmitted at once so there can’t be changes in between. Client might still be out of sync but at least as one valid version of the instance array.

Do you have an idea on this? Maybe there isn’t event a clean way to do this… ?

Thanks again for your input tho!
Offtopic: you were mentioned in the 4.24 feature hightlights among the top 10 of karma point earners! :stuck_out_tongue_winking_eye: