Multicast Invalidates Blueprint References (or something, it's weird)

Before anything else. PLEASE HELP ME, I HAVE TRIED EVERYTHING AND NOTHING WORKS. I AM TOO INCOMPETENT TO FIGURE IT OUT :sob:.
Now, without further ado:

Hello, I’ve been trying and failing to fix a very simple but confusing bug that has to do with RPCs. A reference in a blueprint exists on all clients, but can’t be accessed when a multicast is called.

What I am trying to do is rather simple: The character controller, upon pressing V, sends out a Server RPC to then send out a Multicast RPC to get the HUD and show/hide an icon. That’s all!

Now, since the issue is with getting the HUD variable in the multicast, I will spare you how the UI blueprint works and solely focus on the part that is failing.

First, we handle input, as you can see, pressing V calls our “SV” Server RPC function, which just calls a Multicast RPC telling each client to, in their own Character Controller (since we fetch “Player HUD” inside the Multicast RPC), to execute a function in the “Player HUD” (client-side).

Next, in our “Player HUD”, we print out “Show me VC!” if the button was pressed, and a list of players in the server if released, controlled by the boolean we passed.

So, what happens if we press “V” during tests?
If the server host presses the key:

  • Prints out both “Show me VC!” and the player list
  • Clients do not react whatsoever, nothing prints

If the a client presses the key:

  • Noting prints
  • Server host prints out “player hud does not exist”

It is a fact that the player HUD exists on all clients. I’ve tested this very thoroughly, I even have a debug function inside the player controller that prints out data from the player HUD every second after a button press. It works on all clients.

Today, I’ve worked on this bug for 11 hours straight without even stopping to eat. When I went to make this post, I realized that I was no longer capable of writing coherently (and I was unable to read text either, it stopped making sense), so I was forced to take a short break to rest before I could write this.

I have been humiliated by this bug and have become obsessed with fixing it. I won’t be sleeping well tonight knowing that such a simple error has gone unresolved.

1 Like

As you can see here

SpectatorPawn and HUD exist only on owning client.

The HUD is not something you want to check on the server since it doesn’t exist there!
You probably want to create an event dispatcher in the Game State and call it from the server function (if you want things to happen in every client).
You can subscribe to it from where you need it (the HUD for example) and bind an event to toggle things.


Steps:

  • Create a custom game state and assign it in the game mode
  • Create an event dispatcher in the game state with a boolean parameter (so you can call on and off with the same event)
  • Create an event in the game state (with a bool too) and call the event dispatcher from there

In the player controller:

  • Get the game state and cast it to your custom child class (save it to a variable if you want to avoid other gets and casts in future)
  • Call the event when you need it in a server function.

In the HUD:

  • In BeginPlay Get the game state and cast it to your custom child class (save it to a variable if you want to avoid other gets and casts in future), assign the event dispatcher to a custom function to toggle the widget
2 Likes

also keep in mind that while the PlayerState itself is replicated, your ‘ControllerPlayerState’ variable is not set to replicates therefore it will be Null on the ServerRPC.

3 Likes

Actually, I’d like some further clarification on this, since I’m having a little bit of trouble understanding the issue…

The HUD is not something you want to check on the server since it doesn’t exist there!

I thought I wasn’t checking it on the server, that since I am running it via a multicast RPC, it would instead run in the context of every client.

Did I misunderstand how multicasting works?




Similarly, for this reply:

also keep in mind that while the PlayerState itself is replicated, your ‘ControllerPlayerState’ variable is not set to replicates therefore it will be Null on the ServerRPC.

Since I am passing the data to the function, I thought it didn’t need to be replicated. Is that not the case?

I tested and indeed it by adding a print and indeed, it only works in one direction (client → host).


I find this quite shocking since I have a lot of blueprints with similar setups where data is just passed to over to the multicast via the server without explicit replication, and they do work in all cases…

I apologize for how stupid my questions are, I’m having a bit of trouble wrapping my head around this stuff.

in the case of Objects you’re not passing data, you’re passing a reference to that data and since that’s not replicated that reference doesn’t exist on the server.

consider your bool, you’re not copying the bool reference you’re copying the bool value so it doesnt need to be replicated, however with an Object you dont want to copy the entire player state over the network so it just sends a reference to that Object and the server checks its own version, which doesnt exist because its neither replicated nor set on server

1 Like

I see, that makes sense. Thank you for explaining it to me!

(post deleted by author)

(post deleted by author)