Unreal Engine Networking and Multiplayer Games part 3

While going further in this tutorial, it is important to understand, that this is a very simple example. Usually a commercial game is much more complex, it has more elaborate and complex user interfaces, more game features and so on. This will focus on bare basics that show the core components and processes in a multiplayer game. Also, this is not necessarily the best way to implement some features. As said before, developing a multiplayer game is a learning experience and you have to start somewhere, and then gradually deepen the understanding of each mechanism.

Gameplay State

Usually a game follows a loop of some kind. Game starts, then it progresses through various stages, and eventually it will end one way or another. This has nothing to do with level progression that is entirely different thing. Instead of that we are interested about the current status of game, and to keep things organized, we will express it as an enum. So we will create an enum blueprint named GameplayState, and give it following enumerators

No alt text provided for this image
  • Startup happens immediately when game is launched, and the game will proceed to MainMenu
  • MainMenu is the state where player may either start and host a new game, or look for games to join. There are also some configuration options.
  • ServerList If player wants to join other games, he will go to ServerList state, where he is shown a list of servers.
  • LoadingScreen This is a transition state that happens before the actual game starts.
  • ErrorDialog Whenever something goes wrong, player will be put to ErrorDialog state and shown an error popup window.
  • GameInProgress When actual game play begins, the player will be in this state, until he somehow exits, e.g. by quitting the game, returning to MainMenu.
  • Indeterminate This is for cases that are none of the above.

It is important to understand, that each player may have different GameplayState value during the game. That is the main reason why this kind of state variable is necessary. Otherwise it would be really difficult and cumbersome to determine the state of one player. With several players it would be impractical.

There are many situations where server should be able to see quickly what is the state of each player, and with this one variable it is easy to achieve. This is just a simplistic example, and there are only couple of states, but in more complex game there could be many more, even some substates, and then this variable is invaluable.

Input Settings

You cannot really play unless player can give controller input. In this project I will use Action and Axis Events named according to the picture below. You can define and bind them to any key you like, in the same manner as in any single player game, there is no difference. But keep the names like they are in the picture.

No alt text provided for this image

User Interfaces

We need several user interface windows to start the game, to show what servers are available and so on. GameplayState definitions reveal that most of them are tied into a certain state. Making user interfaces for multiplayer game is quite the same as making user interfaces for single player games. In the first part of this tutorial series you already saw that user interfaces are isolated to each client. They are never replicated between different clients.

But you still have to take care, that any data that you want to show in the user interface is available, and you have the right reference to it. In such case it matters whether some variable e.g. in a pawn is properly replicated or otherwise synchronized.

I will show the basic graphical layout of the user interfaces, but I will not give any detailed description how to do it. I assume that you know already how to make a simple graphical UI widgets in Unreal Engine editor, how to make buttons and how to bind functions to UI elements. How it looks like is not really important in this context. How it functions is the focus here, and there will be detailed event graphs, but otherwise you should be able to make a simple UI.

Additions to MPGameInstance

Before we can make our main user interface, we have to add some variables and custom event stubs to MPGameInstance, so we can make references to them. Add following variables (CurrentState, EnableLAN, TeamNumber) and create two custom action stubs (HostGame and ShowServers), as shown in the picture below. CurrentState variable is of GameplayState enum type described above. Just save and compile the blueprint, it will be elaborated later.

No alt text provided for this image

UI_Main

When player starts the game, this will be the first visual entry point to the game. From here player can choose to start and host a game, or search for available games. When he wants to quit playing, he can press Quit button. There are two configuration buttons. One for networking type - either LAN or internet. Second button is used to choose the team, since this game will support two teams.

No alt text provided for this image

My own UI looks like one above. It uses elements not available in the marketplace, so you have to substitute your own graphics. But there does not have to be any graphics at all, you can make simple one color buttons with UI design elements.

After that we will add all functionalities to the UI. Just add the 5 events shown in the pictures below, and then create bindings to the text shown in LANtoggle and Teamtoggle buttons. Then save and compile UI_Main.

No alt text provided for this image
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image

Add New Events to MPGameInstance

Before we can proceed with an user interface that will search and list servers, we have to add two new events to MPGameInstance - ShowMainMenu and JoinGame. Leave them as unfinished stubs, they will be finished later. JoinGame has one input, and its type is BlueprintSessionResult.

No alt text provided for this image
No alt text provided for this image

UI_ServerList and UI_ServerRow

This is not a full blown lobby system, but a simple system that shows the core mechanics to host a game, find and list available game sessions, and then join one of those sessions. But this is all that is necessary to learn how it happens. It consists of of two widgets, the main widget UI_ServerList, which will show all available servers, each represented as UI_ServerRow widget. Pictures show their components, event graph and functions.

UI_ServerRow

No alt text provided for this image
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image

UI_ServerList

No alt text provided for this image
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image

We do not have nothing functional yet, but we are getting closer. Already it is easy to see the importance of GameInstance class, since there are lots of references to it. This is not a coincidence, since each client has its own unique GameInstance which is not replicated, and even server has no direct access to it. As such, there is also a clear connection between UI widgets and GameInstance, since both exist only on owning client.

But the most important fact is that GameInstance is destroyed only when player exits the application. Otherwise it persists over all transitions in game. That is why we store the team number (that player chooses in Main Menu) in MPGameInstance, because it will stay there until we need it. If there were other player preferences we could store them in GameInstance as well.

Next installment in this series will continue to flesh out MPGameInstance and various other core classes, and we will make short level scripts for MainMenu and our gameplay level.

To view or add a comment, sign in

Insights from the community

Others also viewed

Explore topics