What would be the best way for replicating widget component data?

Hi there, I have some network related questions, which I can’t figure out on my own. I hope some of you can help me :slight_smile:

So I would like to update text on UMG TextBlock component on all clients playing game.

I have created the widget under player controller, added it to viewport and saved reference to it.
User can then click on button which calls multicast function on PlayerController, but multicast should only be called on server right? I added Has Authority switch, but then it never executes.

Should client call function which should be replicated on server? From there server can call it’s multicast function which will then contact all the clients?

Do I have to worry about “Owning player” pinof Create Widget node when there are more players connected?

Should I use GameState blueprint? In the docs it states: “The GameState exists on the server and all clients and can replicate freely to keep all machines up to date.”. Isn’t the same thing achievable by replicating variables and thus “keeping all machines up to date” ?

One more thing about GameMode. As I know it exists only on server. Does this mean that if client wants to access some function in gamemode bp, that it’s not available to him?

And one more :slight_smile: The best way to detecting that client has connected is with EventPostLogin node which can be called in GameMode blueprint, right?

Thanks so much!

I’m going home so I just leave this message so I can reply in full later.
In the mean time, check the links in my signature about replication.

Thanks I’ll check those out!

I’ve made some screenshots of my blueprints so you can visualize where I’m at.

First, I create widget in PlayerController blueprint. As you can see, the reference is stored in “ChatWidget” variable.

So this is event which is being called in widget blueprint.

It’s calling “SendChatEvent” which is marked as “Run on server”. It then calls multicast event, which should update the text in the widget.

This is how this widget looks ingame:

But here’s the catch. If I set number of players on 2, run the game and type some text in on the client side, then it sends it to the server and server updates its own widget. So from this direction its’ working.
Then I switch to server window and submit some text and I get this error: PIE:Error:** Error Accessed None** ‘Chat Widget’ from node Set Text in blueprint BP_PlayerController

It looks like the servers instance of playercontroller isn’t storing widget reference on event begin play.

go and check wiki about multiplayer respawn, it has information I wrote before so you don’t have to specify player number.
also check the first link in my signature, PlayerController owns HUD, which in turn owns the Widget BP added to that HUD.

Once you decide to do inputs(ie text change commited), it be bind to a event in HUD where you added the widget, then call the owning player controller to send the multicast event with the text you have.(refer to what I have on respawn wiki)
Or receiving end(all clients), when you have the event issued, you then have to check if the player controller received is a local player, if so, update the chat widget local player’s HUD owns.

So even if I don’t explicitly create widget in BP_HUD but instead in my custom BP_PLayerController, the widget still gets added to the BP_HUD blueprint?

Is this the right way of implementing this checking of local playercontroller? Now it’s only executing on client side, so server doesn’t receive any messages.

Yes, as long as you have the reference to the widget you created, you can add it anywhere, my context menu is added by a blueprint actor that I can place anywhere on my level.

The thing is, you do the multi-cast on server side controller, and do the local check on client side controller(playercontroller have a sync/replicated copy like other replicated objects). hasAuthority works really well on player controller.
Basically, anytime you want to call “NewChatLine”, do if from controller and make sure it’s the server side controller with hasAuthority, once it was called, use hasAuthority to make sure it’s client and then local player check.
If you have a listen server it still works, otherwise my respawn tutorial will fail. As respawn are essentially a player initiated message to the server, while the replication does the rest of job.
(why it is run on server)

But for text you have to multi-cast it back to all clients.

I see, thanks! I’ll try it.

I have another question if you don’t mind. Do you have any idea why would the clients camera positions differ form the server?

Camera is pinned to the root object of my custom pawn blueprint via spring arm. It’s rotated downwards, so basically it’s top-down camera.

So when I start the game it looks ok on server instance, but on all the clients the camera isn’t at predefined height. Rotation is kept intact though, so it’s still looking down.

I don’t think player camera is actively replicated, which means the spring arm and camera control are mostly client side only(which means whatever your player controller is on). Server should really just do important replication and important game play related stuff.
As a client can suddenly die and view a different place, why sync camera position on the server end any way? This way server side don’t even have to do spring arm calculation and collision.
This also explains why clients won’t see camera changes from all other clients, unless you try to sync that part yourself.

It’s the design of the game. All clients including the server are seeing the same scene, therefore I need those cameras to be at the same spot.
The camera is implemented within Pawn blueprint and pinned to the spring arm. No other blueprint (or server code) is modifying it.

This is why I don’t understand why the difference …

ahh…okay. If that’s the case, try avoid spring arm so you have better control. If it’s top down and not gonna hit anything a construct variable to set height should be good enough. Also, if everyone is seeing through the same camera, does any one actually controlling it? (ie, say for some top/down twin stick with coop, it might be an average between player positions and slightly zoomed out if they are further apart from each other.)

If no one is controlling it, then server can update a camera actor and during pawn construction or begin play, you can set view target to any camera you have access to in player controller. So if you have game mode that spawn the camera/or fetch from level, then pass it to all clients with post login, you should be able to set this up.

If one player have control over camera, obviously it’s gonna be more tricker, but similar principle can apply, just that instead of camera calculate it’s own position, controlling camera will send run on server call to the camera actor instead.(and you have to handle if that player disconnected, who would then take control of said camera)

Thanks! I’ve managed to fix most of my problems. Now I also understand replication much better :slight_smile:

Camera position wasn’t actually the problem. The problem was that the scale of the actor wasn’t replicated through network. So the camera was spawned for every player on the same place, only the scale of the actors was messed up for all the players except the server.
And since the game is happening in space, there was no reference point, until I added plane :slight_smile:

But now I have another problem. Reliable Multicast function isn’t working.

Imagine this scenario: at any given time in game, there are multiple actors alive. I’m talking in the scale from 30-100. Those actors are visible to all the players. Transform of those actors has to be replicated to all the players. (Actors are marked as replicated)
I found out that this is too much for the network. So I changed my logic from spawning on server, to spawning on all the players connected. The best function for this would be Multicast (reliable). So server should multicast transform and other info needed to clients, which would then spawn its own actors. But here is a catch: Reliable Multicast isn)t working as described here: https://answers.unrealengine.com/questions/97569/client-cant-join-a-server-if-server-is-running-rel.html

Whenever server calls this method, clients crash (well, sometimes the game restarts, but usually I can detect this fail, when the camera changes back to default position - just like you would open new project).

I should mention that I can’t use “Add movement input” (which should replicate movement better), because all my actor are moving around based on this logic (imagine two flocks of birds - two teams, and they are hunting each other). Replace birds with space ships :smiley: So you could said that they’re controlled by it’s own AI. Everything the user (PlayerController) has to to, is spawn them.

So my question is; what would be the best way of replacing multicast method. All I want to do is this: when one of the players initiates spawn command, it should spawn the same type of actor on all the clients.

I’m thinking of rewriting everything in c++, since it looks like I’ll have to modify the engine code anyways.

Thanks!

edit: Is it possible to change the title of this topic to “Network related questions and stuff”? :slight_smile:

edit2: How do the big games (Supreme commander - Forged Alliance multiplayer for example) handle all those units and projectiles. Number of units can go to 1000 for one player, and there are up to 12 players. All those transforms have to be calculated on client …

basically, anything that could be replicated by itself, like actor or variable of a actor, or movement component of a actor, let them manage that part themselves. (if you check the respawn wiki, I don’t need to spawn an actor on client side, replication takes cares of it if you spawn something that already replicate on its own.) For say particle systems that are not part of a actor(say rocket impact explosion, play sound, etc), then you need a multicast RPC so every one sees the explosion properly.

From what I’ve experimented so far, about 80% of things can be taken care of just by RunOnServer RPC, and about 20% needs multicast, and in special cases needed to run on owning clients.
Also, aside from really critical things, using reliable check box is not recommended. The more frequent your events getting called, the more likely it wouldn’t require reliable turned on.

Well, reliable checkbox isn’t even working in 4.6.1 so the only way of fixing this is to edit the engine code.

As I said, I tried with spawning only on server and let the engine replicate, but I noticed lag on client side (while playing both server and client window on one machine). That’s the reason why I want to spawn actors on all players, and this is the only reason why I need to use multicast.

And since my actors don’t have movement component and I’m setting position based on delta time and some other parameters, I assume the lag is even bigger (since movement component should be optimized for replication)

it is weird as I just convert my network test project and spawning projectiles are fine for me.(I even did on another prototype that have friend test with me cross pacific ocean on 4.4).
If you have lags, definitely check if you try to do too many things on construction script or begin play event.

In content examples project, under Network map/scene, there is an example of function replication. One of the nodes is marked as multicast, but not reliable. If I change this to reliable, it crashes the example.

So, in my project, if I choose multicast it doesn’t even reach client. Like nothing has happened. If I mark it to reliable, then it chrashes the game.

Spawning an actor as replicated on the server is working and this is when I experience lag. Movement is jerky (like non interpolated movement). I assume it’s because my actors don’t use movement component.

Actually there is a really old thread discuss about this from UE4 launch, I was there so I know.

Hopefully going through this old thread will help you, not everything needs to be reliable.