I’ve been messing around with networking for several days and there are stuff that confuses me a lot.
I can’t find any information on that one and it’s been a hell to understand what’s going on there.
Whether I use a “OnClicked” event in an actor or any widget buttons, print function would tell me it didn’t belong to client 1, 2, 3… etc. nor to Server, but Client -2. (client minus 2).
If i look at all of instances of widget, i notice that (unlike any actor) it doesn’t exist on server, and strange things happens when trying to trigger some gameplay event using replication.
For instance this case
I try to make a multiplayer chessgame to learn how to use RPC.
For debug purpose I use a Widget to trigger some kind of rebuild function to clean board and replace pieces.
And so far it’s been a nightmare to make it to work in MP. I get weird CLIENT -2 which makes replication hazardous. I try to sent event from Widget to its owning Controller and from there to Board actor. But engine believes owner is CLIENT -2 half way through (notice print text saying -2 -2 -2 and all of sudden Client 1… oO), and thus no replication.
Am I doing my widget replication totally wrong or is there something quite messy here?
I’ve assigned someone from our team who’s more specifically familiar with UMG to look into this issue on Monday, and they’ll post here if they have more questions for you.
In meantime, I’d encourage you to read our documentation on Networking and Blueprints, found here. Widgets in a Multiplayer scenario can be tricky to understand because of where they live (Client vs Server) and who owns them. Unfortunately I don’t think there’s anything in there specifically about widgets in networking, but general communication principles will still apply.
If you can create a small test project for us that demonstrates specific issue you’re running into, that would be super helpful. Otherwise, a specific set of repro steps to follow would also be great. Thanks!
It’s already some kind of clean project (as I created it to get familiar with RPC), but i’ll make a new one to isolate issue and send it to you.
In meantime, OnClicked Event is easy to repro :
Create a new blueprint Actor
Add a Static Mesh Component
Add an Event OnClicked using StaticMesh
Add a Custom Event and set its replication to Run on Server
Add a Custom Event and set its replication to Multicast
Add a node AddActorWorldRotation and set whatever rotation you want except 0,0,0
Link this chain that way : OnClicked>Run on Server / Run on Server>MultiCast / Multicast>AddActorWorlRotation
Compile, Save and play in editor with multiple clients
Notice issue, replication didn’t occur.
Any print placed during this chain of node will either show “Client -2” or don’t appear as they are not replicated since, that’s my guess, Client -2 is not owning actor, and non owning clients can’t talk to server.
And to be sure i replaced OnClicked with a OnBeginOverlap, just to be sure. And that one worked.
Might be, but it depends on whether you had any default settings for project (from Config folder) and what type of project it was (Blank, Third Person, etc). I can give it a try if you let me know what project type it started as.
It looks like your Run On Server event in your BP_Controller wasn’t actually set to replicate. If you select that Event node, in Details panel you’ll see a drop-down for Replicates that’s set to Not Replicated. Set that to Run on Server and your logic should work like you expect.
What was happening was Client was trying to run an event on Board, but nothing was communicating this to Server. Custom Event will only act as an RPC if you specify that in its details. Hope that helps!
I’m not sure why it’s saying Client -2 when running this from Client without that set properly. It looks like a weird logging error. I’m going to check with network devs to see if this is some sort of intentional debugging tool, and I’ll let you know if we enter a bug report for it.
Ah crap, that means I wasn’t able to repro original issue. Unless something else wasn’t set properly on my side, but I was really thorough (or I think I was) in original project before starting from scratch.
Anyway, without any real example, let’s close that topic.
Although, OnClick event is still there. Here is another project content with issue, and that one i’m sure is real
Ah, okay, I see what you’re saying now. problem you’re running into is one of ownership. If an event is invoked from Client and target is not owned by Client, event will be dropped. only way to communicate from Client up to Server is through Run on Server RPC, as you’re trying to do here, but if owning Actor (in this case, BP_ActorClick) is not owned by Client, even that communication won’t occur.
This limits most of this communication to Client’s PlayerController (which presents its own limitations, given where each controller exists on network and its own RPC limitations) and that controller’s Pawn. You can also use Client PlayerState.
So you might say, “why does it work with Overlap scenario, then?” Well, ActorClick BP exists on both Server and Client, and its overlap is looking for anything. If anything overlaps it, it’s going to fire Run on Server event. In this case, Server instance of Actor is being overlapped by Server instance of Character, so Server (which can run Run on Server RPC without any problems) is what’s actually firing. This won’t work with OnClicked event, because that’s only being touched by Client’s PlayerController.
Hope that makes sense. short answer is that way to handle this is to instead do communication inside Pawn (or PlayerState), or inside PlayerController itself. When OnClicked event fires, it should communicate with owned controller or pawn, which should ask Server to perform operation. If you need help setting that up, lemme know and I’ll throw a small project up somewhere.
As an aside, issue with board not being set on Client 100% of time in your initial project is likely an order of instantiation issue, but I’ll have to look into that a bit later on. I’ll let you know what to do with that (most likely using GameMode’s Client Post Login node to ensure certain things have been created before performing rest of operations). That’s just a first guess, though =)
Yeah okay that’s what I was suspecting and also fearing
I solved issue as you explained. I did a bit of script in controller to manage a click system and communicate,through Blueprint Interface, with any actor Player clicked on.
While it’s working pretty good, I’m still wondering why OnClick event wasn’t looking for “anything that clicked on it” like overlap does.
Ps : Shouldn’t this event have tiny screen icon that ‘cosmetic’ events usually have? Or at least a small note so it won’t confuse newcomers.
events won’t have those icons because an event isn’t, by itself, either client or server only. I think icon system is just part of how nodes look, and nodes don’t change based on property changes (like Replication setting) beyond text. I can ask developers to add a more full tooltip for Run on Server option, though, because it could definitely be clearer.
OnClicked event responds to Controller input only, which can only occur on Server or Client that owns it. So while Server instance of Actor could see that it was overlapped by Server instance of character when Client overlaps it (it’s occurring on both Server and Client), when Client controller clicks on it, only Client instance is getting any input, because PlayerControllers only exist on their respective machines. Server instance, which is only instance that could run Run on Server RPC, never saw that Client controller interacted with it (because again, Client controller isn’t replicated and therefore only interacted with Client instance) and thus couldn’t run Server-side event.