VR Multiplayer failing to do a RPC to Server from PlayerController or Pawn

I have a single player VR game (search for “Marble Mechanics”) which I’m trying to make multiplayer.

The Server (listenServer) is responsible for creating the track segments in the world and replicating them to clients. Each track segment has a unique integer ID that is property Replicated with Initial Only condition.

A key aspect in this game is for the player to grab track segments. When grabbed, they can be deleted, duplicated or edited (longer, straighter, etc.). My understanding is that the client tells the Server to grab the corresponding track and so all of the work while grabbed would be done on the Server.

Since these are not inexpensive operations, I would prefer that the local clients do this work locally. Then once the local client drops a track segment, that client should push back to the Server what happened. The Server than accepts or rejects it and if accepted, updates the affected track segments in the world.

It seemed an easy way to do this is to extend the GrabComponent in VRPawn (from VRTemplate). I added three Event Dispatchers to GrabComponent. In VRPawn just before a track element is grabbed, we call a function CallBacks to set up bindings to the new Event Dispatchers.

Then in the track segment blueprint when its GrabComponent fires OnGrabbed or OnDropped, we fire of a corresponding message via the GrabComponent with information we need.


(we also have a OnDeletedIDs, but we won’t show it…)

Function CallBacks is in MyPawn (which is the parent of VRPawn) and simply sets up the bindings. When any newly binded Event is triggered, we unbind and try to call a RPC that should run on the Server.

And finally the Server functions are also in MyPawn.

(ignore all lines going off to the left, they are going to PrintStrings…). Already have a Server function in my player controller (CreateTracks) for creating track elements in the world, so that is reused in AddGroup.

Everything works fine if the client is on the ListenServer. None of the RPC on the Server (last image) get called if we’re on a different client. To be clear, the S_ArrayOfInts is just a structure that holds an array of unique integer IDs of the track segments. Usually that array is just one element, but the user can group track segments and so grabbing one, grabs all in the group. Also the ID2Tracks mapping maps the unique integer ID into a parameter structure which contains all the information required to reconstruct the track segment and place it correctly in the world.

How can I get the RPC Server functions to fire on the Server when triggered on a client that’s is not on ListenServer. I’m doing this all from the pawn (owned by PlayerController). I also tried to place the RPC Server functions into my PlayerController, but still it only works when the client is on the ListenServer.

Thanks for help. Or a better way of doing this?

UPDATE

Title is misleading. Turns out that most of the RPC running on the Server was executed from a client pawn. One was not. It was using a map as a parameter in the RPC function call. Runtime logs flagged an error. Splitting the map into two parallel arrays into a structure could be passed without trouble. There were no warnings/errors during Blueprint compiling or building the project.

The log has something like “No owning connection for actor…”?

Yes, for a client on the listenServer, the Log is littered with stuff like:

LogNet: Warning: UNetDriver::ProcessRemoteFunction: No owning connection for actor VRPawn_C_214748228. Function UpdateController_Server will not be processed.

No such log entries on the client on the listenServer.

Considering that the client always (almost) owns his pawn, this means that you are trying to call a server event in another player’s (lister server, in this case) pawn (for some reason).

You are here:

Link

You are correct, the VRPawn referred to in the log on the error is NOT the same VRPawn that the game reports when it starts up in the client not on the listenServer.

This does explain why the RPC to the Server isn’t working.

Confused what this VRPawn in the log is, actually. I mean, you see what I did, and it’s all mostly in VRPawn (other than issuing the new Event Dispatchers in GrabComponent in the track segment blueprints).

Feel like I’m missing some mental picture.

You need to add Print String wherever you do anything with delegates.

Are you using a pawn reference somewhere? GetPlayerPawn(1)?
On the client - it will be a server pawn…

Yeah, now I’m putting in a bunch (more) of PrintStrings to see what is going on…

Meanwhile, GetPlayerPawn(0) is used (was originally used in the VRTemplate for teleport). It’s also used to store after it’s casted to MyPawn (parent of VRPawn) but never use GetPlayerPawn(1).

ok, when listenServer is started, there is just one MyPawn that exists.

Connecting with a client, that client now says there are two MyPawns which seems right: the clients pawn and the other user’s pawn that is on the listenServer.

Regardless, on the non-listenServer client, I see the correct Pawn is being called back from the GrabComponent and when it tries to call the RPC on the server I actually have the following error:

LogProperty: Error: Replicated TMaps are not supported.

Any clue what that means.

(btw the non owning stuff appears to be garbage… concerning the listenServer pawn…)

Turns out that AddGroup, GrabGroup and DeleteGroup are called and executed on the Server as expected. It is the DropGroup that doesn’t work. Apparently it doesn’t like the map I’m sending it. Even if I wrap the map into a blueprint structure it still complains. I’ll make a structure of two arrays and use that as parameters to the Server RPC DropGroup.

Is this true, you can not send a map parameter to a RPC that will run on the Server?

Yes, this was the problem, you can not send a map as a parameter to a RPC to be executed on the Server (i.e. DropGroup in the last picture- had to change it into a structure that held two arrays). You only get an error in the log. No warnings or errors when compiling the blueprints even though it should realize there is a problem (i.e. it has all the information it needs to determine there will be a problem).

Thank you @PREDALIEN for listening and getting me on track. Pun not intended.

1 Like