Ok, here’s a basic explanation of UE4’s networking.
Client and Server code exist in the same place. For simplicity’s sake, let’s use a scenario with 1 client and a dedicated server. If you have an “Event Tick” leading to a “Print” node (with “Hello”) on the character’s blueprint, you should see
Client 1: Hello
Client 1: Hello
This is because the event is being executed on both the (dedicated) server and the client. In multiplayer games, you generally want the server to have authority over game data. That is to say: All the important stuff should be done on the server. Don’t trust the client to do any calculations. The exception would be running visual effects, playing sounds, maybe calculating the position of a ragdoll corpse where it doesn’t matter if all the players see it end up in the same place.
Ok, so let’s pretend that the “Event Tick” is doing something important. Maybe it’s moving a wall that is slowly pushing the player closer and closer to a spike pit. This is a game-changing important process going on and NEEDS to be done on the server not only because we want to make sure there’s a single authority for controlling it but also to ensure that all clients see the same thing.
So right after “Event Tick”, add a “Has Authority” switch. It will split the execution into a “Authority” and “Remote”. If this code is executing on the server, it will continue down the Authority execution pin. If it’s executing on a client, it will continue down the Remote execution pin. This switch is one of the biggest things you’ll need when dealing with multiplayer. Connect the “Print” to the Authority execution and re-run it. You’ll see
So since the client is “Remote”, it is no longer executing the print. Don’t be confused by the fact that this printed line is showing up on your client when it is executing on the server. There’s some back-end code in place that has this string replicate to your client, possibly only when it’s executing in the editor. I’m not sure. But don’t worry about that.
Now, let’s pretend we have the code all set up that would move a wall to slowly push a player off a cliff. We would want to execute this from the “Authority” pin to ensure that the server is controlling the wall movement. But if we ran it, the client would not see the wall move. The client WOULD get pushed off the cliff and into the pit but the client would never actually see the wall that pushed them. This is because the server moved the wall, determined that the character was colliding with it and adjusted the character’s position accordingly. The client saw their own character moving because the character has “Replicate Movement” ticked off in the class defaults of the character blueprint (which is something you should check, if it’s not checked already).
A quick note on “Replicate Movement” for your character. Checking this will handle a lot of the networking for you. If you use any movement input for the character on the client, it will properly handle telling the Server you have moved and your movements will be replicated to all other connected clients as well. It’s super handy. But this will only work for stuff that has a movement component… not for custom stuff like the wall we have (you could theoretically add a movement component to the wall and replicate its movement with the checkbox but that kinda defeats my whole explanation).
Ok, so with the Move Wall code attached to Authority, the player is pushed into the pit but we don’t see it. If you had the Move Wall code attached to the “Remote” pin, you would see the wall moving towards you and maybe see yourself get pushed a bit, but you would be corrected back to where you were repeatedly until finally the wall was beyond you and you were left back where you started. You see yourself move a bit due to client side prediction. Rather than wait for the server to tell you you’re being pushed, your client GUESSES at what should happen and does it. It’s a way to make multiplayer feel less laggy. But then the server says “No no, that wall isn’t actually moving, you shouldn’t have been pushed” and corrects your position.
So moving the wall on the server alone didn’t work and moving the wall on the client alone didn’t work. So you might think: Ok, well lets get rid of the “Has Authority” switch entirely so it runs on both the client and server! And if you did that, it would LOOK correct … to Client 1. But if you connect Client 2, Client 2 would never see the wall move.
The solution to this is that the server needs to replicate this movement to all connected clients. So if you have a custom event called “Move Wall” that we are calling from the Event Tick (through the “Authority” pin), you can set the property on it to “Multicast”. Then that event can update the walls position and everyone can see it.
The above works pretty well because of one thing: Player Characters exist on both the Client and Server. They both have a “copy” of the same player character. Think of it literally like it exists in two places. If you move it in one place, it needs to move in the other too to keep them in sync. But if you wanted to do something like… the player presses a button in a HUD and it moves the wall, that gets more complex. HUD elements exist on the client ONLY. So the Client needs to make a call to the server to say “I pushed the button!”. Then the server needs to broadcast to everyone “Hey, client 1 pushed the button!”. To do that first part, you need to execute an event that is set as “Run on server” but it needs to be done in a place where the server has a copy of that element. Since HUD elements don’t exist on the server, it can’t be done there. Often the game mode is used, or game instance… or player controller. There’s lots of places this can be done. But I think I’m rambling on too much in this paragraph and I’m out of time so I gotta wrap it up.
But I’ll subscribe here and if you wanna post a specific blueprint you need help with I can take a look.