Expanded Blueprint Multiplayer Suggestions

Hey All,

Rather than throw any suggestions for expansion of the Blueprint Multiplayer Tutorial Series into the previous thread, I thought it best to start a new one and keep a bullet pointed list of items to explore so its easier to surface.

Please throw any suggestions into this thread and we will look into incorporating them into a future update.



Just gonna copy my reply from the other thread.


A tutorial on how to implement groups of players that can all travel to a game would be great (ie. having a party of friends who can join games together). I’m assuming using online beacons are the way, but the documentation for it is confusing. Not 100% sure how I’d be able to set up a connection to a beacon from a matchmaking result and be able to reserve space on the host before we all attempt to travel.

We’ve tried some hacky solutions, but knowing the officially supported flow, even in brief, would be great.

Thanks much for the tutorials though! Super psyched to watch through them tonight.

My wishlist:

A server browser like in Multiplayer Shootout, even with the weird system generated server names/IDs.
Managing different game modes, for example: Free For All, Team Deathmatch and TDM without Friendly Fire.
Spectator mode and a way to switch from Player Mode to Spectator and viceversa on the fly.
A voting system to change map, fraglimit, timelimit and other stuff.
Password protected server.
Quick server rejoin if someon gets disconnected.
Leaderboards and/or some kind of MMR management system.

P.S.: Congratulations for the videos they’re effing awesome!

If it’s Steam related only, then:

  • Multiplayer Leaderboards (for individual players, for teams/groups)
  • Multiplayer Achievements (for individual players and achievements that have to be earned as a team, if possible)
  • Players’ stats for developer (demographics, territories, etc.; if that’s something Steamworks provides; I think it would be useful for bizdev)
  • Coop multiplayer
  • Coop multiplayer + local multiplayer (let’s say 2 people on one PC vs 2 people on another PC via Internet)

Just some info so you might be able to skip waiting for new content.

If you watch this tutorial, when he drags off the results from the “Find Sessions” bit, you should be able to use that to populate a server browser UI, and connect to the selected server that way.

If you look at the way he handles chat in these tutorials, you should be able to do a voting system the same way, just passing vote data instead of chat data and modifying the things you need to like he does in the game settings tutorial.

Depending on what you mean by quick, the engine stores your playerstate for a little while after disconnecting. If you reconnect the same way you’d connect normally, anything that was stored in your playerstate should still be around. The functions you want to deal with are UEngine::HandleNetworkFailure and HandleNetworkError on the game instance (the latter is blueprintable, but the former is C++ and can give you access to more useful stuff).

Steamworks provides some of this data (and lets you forward to google analytics I think). Steam has a lot of info/tutorials on the steamworks partner site about this once you set up steam for your app. It would all be at the steamworks partner site (Steamworks).

This should be the same as normal multiplayer. Once your player’s are connected to your server you just do coop-y things with them in your game mode.

Forgive me as I’m deep in a deep dive design exploration process at the moment AND my connection speeds require I download the videos off of YouTube at 720P which takes 4 hours each… SO these might actually be covered. But these are things I had issues with with my current multiplayer setup!

  1. How do I know which player is which when it comes to map changes? IE: Main Menu > Character Select (Still Main Menu; Players join here and select their characters and settings) > Level 1 (All clients disconnected and reconnect with nothing the same) > Level 2 (Things carry over between levels; all clients disconnect and reconnect). The issue is that I don’t want to blindly accept that a player is who he says he is. Or has what he says he has. Best case scenario is that I can use Steam Username to confirm who the player is and then reassign that player his things but even that can be hacked on the client side of things I’m sure.

  2. How to handle disconnects and rejoining. In my game a player can’t just be left standing. It would effectively end the game. They have to be removed from the game. I could deactivate and reactivate them probably but I haven’t gotten that far yet. That’s not the whole problem though. How do I properly check if they were actually a part of this match? Again, assuming I don’t use Steam Usernames (other services exist I’m sure) to make sure that Usernames are unique or whatever - What other metrics do I have to work off of? I could generate a random UID on the Server and give that to the Client as a “Reconnect Stamp” and encrypt it + Save to a temporary file maybe? Goal isn’t to make the game hack-proof. Realistically the Server can do whatever, people are determined, ect. My concerns are with easy hacks that would be upsetting to players. Things like being kicked so that another player can switch places with you to have your score or current match status probably wouldn’t actually happen but a bug where someone with your same username just happens to join the server right as you’ve been kicked and takes your place? Probably bad design.

  3. Non-Character (Player?) movement. I’m wanting to make flying enemies and allies but haven’t figured out if that’s going to work well over the internet yet. At the very least I’m not sure how I could do it for a player controlled thing (ie a toy airplane that you throw out into the world and control temporarily).

  4. Random Streams. I can’t for the life of me get these to work. Maybe it’s just because it’s in editor but the values are always the same and syncing them up isn’t working. Replicating the end-results works but isn’t the best in the areas I want to use it for.

  5. A better explanation of the differences between Run on Server, Multicast, Run on Client, Non-Replicated. I’ve had to discover these myself, I believe there are more out there, and they’re important to understand them well. Specifically, “Switch Has Authority” is actually “Switch Has Ownership” ; This means that the Client has authority over HUD (100%) and Game Instance (I think). And if the Server ever spawns something and it’s set the Client as the owner (or a Client Owned Actor as the owner) this node will return “Has Ownership” for the Client and “Not Authority” for the Server. And Run on Client actually reads (On the Node thankfully) Run on Owning Client. Which means the same thing. But then how do you tell a Player to, only on their client, do something? For the player this isn’t too hard. MultiCast Function -> Player Controller 0 == Player Character’s Player Controller -> Stuff. BUT! Here it goes:

  6. Split Screen Multiplayer. COMBINED with Network Multiplayer. This makes the “Every Client has themselves registered as Player 0” rule that seemingly everything is built upon null. How is this to be overcome? If each is viewed as a client can this be adjusted to reduce bandwidth? (I don’t need all 3 players to be told where player 1 is). What can I do with the viewport placement (Say everyone is dead and it’s going to be 2 minutes before they’re alive again and, if the player wants it, I give them a larger screen and use some of the real-estate on the side for spectator-actionable/entertaining data/facts. Things like “Player 1 just missed a barn while using a sniper rifle. This is worse than 99% of all players but still better than Player 2.” “12 Seconds ago Player 1 ran past an enemy to grab a mushroom. That enemy just stuck him with a grenade.” Or something far less plain). What if a player needs to leave but the others want to stay? What if that person is Player 1? Can a split-screened player be disconnected while the others remain? Ect. ; The obvious questions that I know to be false are there just in case the solution to this problem isn’t the one that I’m thinking of (ie each split screen player has a PlayerController and is on the same client).

I just checked the series real quick.

As the author of the series about multiplayer tutorial, I’m really glad you finally managed to pull that one out! Not only will I learn a lot from it but it is also cleaner and more comprehensive than my own series of tutorial. So great job and thank you very much for this!

EDIT: I also understand why it took so long to post that one and I know how much time it costs to record one series, and you had to do it twice! Really GG and thank you again.

One morer Cool Tutorial,


What I like to see done is “have an option for use of multiple Users or multiple profiles”. with an option to save/load user settings and stats based on Users name and Profiles names in a single local PC, soo that you have meny users without using the same profile on single local PC, soo you can have for exemple each user with unique personal saves…

Thank you for the tutorials! Have been real usefull!!! :slight_smile:

Steam usernames actually aren’t unique. What you want to use is the unique net id on the playerstate/playercontroller.

This kind of depends. When you disconnect for any reason your playerstate will get put in an inactive player array in the game mode. If you reconnect you will have that playerstate reassigned to you. For detecting when disconnects and stuff happen in gameplay, the game session (also on the game mode) has NotifyLogout and UnregisterPlayer functions that can be overridden, but that’s in C++ otherwise you could use the possession events on the pawns themselves.

This is actually really easy. This is the video tutorial they made about networking in gameplay.

What are you trying to do with this? How you go about it will probably depend on what you’re trying to do.

Authority is the server for any networked actors, and the owning player for any non-networked actors. If you’re in single player/not connected to anyone, you’ll have authority. If you’re connected you’ll be simulated proxy. The video tutorial above goes over it more, but you can check out this too because there’s some weird things that happen when you call different rpc functions in different places. If you want something to run only on the local player’s stuff, you can check against IsLocalController on the PlayerController.

im just new at networking in ue4 and i dont know where to ask.hope ull help me here or guide to right thread.
so, i did everything step by step and now i added to 0_base character varialbes EG for health hirst\hunger, so now how i should apply decay\restoring (pickups) and damage(projectiles) \ healing(pickups) effects to players?
and sorry for my english=)

Great series, and it works as intended at first attempt (couple of little niggles that I need to check out).

I particually liked the consistency of the series, after a couple of the vids I had got a feel of your style and could predict where you were going to stop laying stuff down and explain the section, whilst keeping the relevant work in screenshot.
This then gives the student time to hit pause, and complete that section… typically after you comment out something.
A slight slowing when setting options in variables would help, or keep the variable options on screen for a couple of seconds longer just to let the students catch up.
But the best series I have worked through… take a bow :slight_smile:

For additions,
I would like to see an IP option added… so LAN -IP - STEAM.
given the BP limitations on extracting the STEAM name etc, I think it is important that you can directly connect with a “Friend”.

The server name to be saved ?.. probably just a direct copy of the player name set up?

Display Character Name alongside/under the thumb in “The Players” list? Eg Barbarous

Display Ping values in “The Players” list?

Find game would be better presenting a list of servers even if it is the STEAM ID with associated Pings that could be selected from (possibly a seperate addon on series) ?

Given the interest of Multiplayer in UE4 please give consideration to including a fully featured MP/STEAM Lobby+Chat System (editable) with the engine.
Devs can then get on with the creative side, please remember that not all games are shooters and coop play is important.

Thanks again for a great series


Mrooney, just wanted to let you know that your replies were appreciated. Thank you very much, most of it, despite having spent a ton of time learning and using the networking features of the Unreal Engine, was completely unknown to me. <Exposition> **I took notes on all of it for use later (ease of indexing). I’ve had the LOVELY experience of back to back food poisoning and am still sick so when I got the Email Notification of a response I quickly realized it was super useful and decided to check on it later when I wasn’t dying. Got tired of waiting. Decided to look at this thread and start the video tutorials. ** </Exposition>

Random Streams: My use case for this was: 1. Server Only (not hidden just… not used by clients): Determining what the damage will be for Crits, Min-Max damage ranges, ect. and being able to reliably generate completely random™ variables for them. 2. Semi-large level generation. The original idea being that I’d be able to generate about 400 cubes as walls, a giant plane as a floor, and use that data to also spawn in items at specific locations. But instead of replicating the cubes I wanted to replicate the Stream Seed and save a ton of bandwidth and time (and not mess about with replicating non-moving structures, something I now realize wouldn’t have been a problem as things are only replicated if they change) while generating the level. THREE things went wrong:
Static Seed, Draw Calls, Pop-in.

Static Seed: For whatever reason I couldn’t get the seed to change. My changes in the value never stuck (manual or generated) so I always got the same results each game. Exact same numbers. In fact, iirc my walls were all placed in a diagonal line because the randomly generated numbers Output by a Stream Int InRange (or whatever) was ALWAYS the same exact number. This wasn’t a problem when not using the Stream versions of those nodes.

Draw Calls: When not using Instanced Static Mesh Hierarchies this was an unplayable game. And an indevelop-able game. My Editor FPS would start off at 160, drop to 5 when hitting play, and never recover past 15FPS when the game ended. Just… awful. Draw calls were over 4000. With ISTMH’s it went down a bit and became playable (at 14MS per frame on a much better rig than I’m developing for) but it caused the Pop-In problem.

Pop-in: Seemingly without reason (only the) cubes would “become hidden and then become unhidden” for brief periods of time. Flickering, “pulsing”, ect. This simply killed the game as it made it an utter displeasure to play/view and, in addition, forced players attention away from where it should have been toward the flickering. In a game where lots of stuff is happening and I’m pushing Player Bandwidth and designing around keeping it from being overloaded with information… having the relatively irrelevant walls working against the player’s ability to play the game meant, well, the game couldn’t be played.

From there I tried modular level design but even that had too many draw calls. So I had to move to prototyping with BSP’s and then turning those into full meshes ect. (the Content Examples’ “Level Design” method). Thus creating 1 map. Of about 10. And then adding in some randomization here and there to kind of achieve what I was going for. By that point I shelved the prototype, deeming it a timesink, and moved on to the next prototype with everything that I’d learned in mind. I’ve seen the Level Generation tutorials out there (for UE4) but none of them do what I was trying to do in a way that solved my problem. Epic’s YouTube video (and downloadable example) were actually the first thing I turned to when my Draw Calls were crazy high. They, however, didn’t suffer from my popping problem. Or weird seed issue. I plan to revisit the prototype once DX12 and Vulkan are properly implemented, rendering my Draw Calls issue a non-issue as, if I recall correctly, both APIs heavily reduce drawcalls… or basically remove them. Can’t recall which; I’m not positive.

Non-Character Movement: Saw that video a bunch actually :slight_smile: And looked at the Content Examples. Lots of notes. So maybe I’m missing something but here’s what I’m trying to solve:
Case 1) Flying Ai. Not sure if I could make them characters. Point is, I want enemies which, for all accounts and purposes, are large mosquitos that attempt to evade player attacks, fly about in all coordinates, land on things including the ceiling, and attack the player. My confusion is mainly about how to do this as Behavior Trees seem to require Ai Controllers which seem to require Characters. I’m more than well aware that I’m on my own in figuring out exactly how to make them land (select a suitable place, move to simple, “stick to”) and plenty else. Main concern is how to actually make these characters fly. If I can do that then replication is easier. I’ve noticed that non-Character-movement replication is a bit less smooth. More jittery. Things like moving platforms on a Timeline.

Non-Character-Player-Movement: This seems far simpler. Player Controllers can possess Pawns. Temporary camera swap (with a clean transition), do the thing, repossess character. Maybe my concern was actually about the jitters? Honestly I’m thinking I threw this in here just because I thought of a related problem and didn’t give it any thought before adding it in as a “I’d like to see how this would be done” sort of thing. Next best thing would be my concern with how to solve for input changes but even that’s simple enough. When possible (almost always) use the PlayerController ONLY to pass inputs to the Possessed which then uses that information uniquely. When dealing with unique Pawns/Characters use Interfaces (“How do I have the door tell me I can open it when I’m nearby?”), and, in the worst case scenario, use States to determine whether or not you should do something (ie “But I don’t want pressing E to open up the door if I’m an Airplane”) if, for whatever (cough I did it dammit) dumb reason you decided to put Interaction logic in the Player Controller. >-> It would be simpler to migrate / rewrite that rather than sorting out where to put States, remembering to use them properly, ect. though.

For random streams. How are you seeding the random stream? What are you using to send the seed from the server to the clients?

For draw calls, what size are your cubes for your map, what size is your map, and what are you using as your cube meshes? Try again and use “stat quick” and “stat slow” to pin down which functions are taking so long.

For Flying movement, the character movement component already has a flying mode that you could use, but it might be easier to make a new movement component. It’s a decent amount of work, but it’ll probably function more like how you want if you do it that way.

This sounds like something is implemented incorrectly. It sounds like you are moving the platforms on both the server and the client, but still trying to use the network to decide where the objects are. If you want movement handled by the network you should only be moving the thing on the server. If it’s something that can be handled locally then it should only be on the client.

This sounds like ping to me, which is usual thing for just “replicate movement” for actor.

I can’t tell, is this a feature request thread for tutorials or for engine support for features? I ask because looking at the list of stuff people are writing here, I haven’t yet seen anything that isn’t already possible.

Seed Syncronisation requires a syncronished time stamp between server and client. Character Movement does this with FNetworkPredictionData_Client and FNetworkPredictionData_Server. Look at UCharacterMovementComponent::GetNetworkSafeRandomAngleDegrees(), which does the best it can.

Unfortunately, the code to sync those timestamps is very difficult - and it will ]bnever** be perfect. It is actually impossible to perfectly syncronise two clocks on two different machines.

The non-character movement replication is a latency thing. When you replicate movement, all you’re doing is sending position data from the Server to Clients, and when clients recieve it they set those values on the object. This means that as soon as any latency is introduced, those updates are ‘late’ when the client gets them. It also means the client is constantly being updated with old values.

This is the nature of the internet, and the only way to work around it is to build a prediction & reconciliation system. This is extremely advanced however, and takes some serious skill level to implement. The Character Movement Component does all of this for you under the hood, but it’s very difficult to provide an implementation that will work for any style of movement. I’m afraid this is something left up to the end developer. Even seasoned developers cack themselves when they have to mess around with CMC, if that’s any consolation…

It is for tutorials, specifically the recently released video series by Wes.

They shouldn’t be jittery if it’s just ping, the movements would just be weird. There’s a decent amount of smoothing unless the ping is huge, which it wouldn’t be if he’s just playing locally. It sounds more like he’s trying to move something on the client that has replicated movement already so the actor is constantly fighting over which position it should be using, the client set location or the location the network is telling it to move to.

Stats and Leader board…

…Besides that it be nice to have a statistics board with some player and game stats, like “player personal played time and scoores” and “top overall best times and scoores”…

Thanks!!! :smiley: