Customized Multiplayer With Only Blueprints

Hi everyone and welcome! We have created a blueprint plugin available on the unreal marketplace that allow you to scale your multiplayer game without any previous c++ coding knowledge! Everything is accesible through Blueprints!

In this documentation I will be showing you how to set up skill/latency based matchmaking, a party system to invite and join your friends, a secure login system with user profiles, a no sql database storing game data as well as much more!

What Powerful Services We Use?

Amazon GameLift is a fully managed service for deploying, operating, and scaling your session-based multiplayer game servers in the cloud. Amazon GameLift replaces the work required to host your own game servers, including buying and setting up hardware, and managing ongoing activity, security, storage, and performance tracking. Auto-scaling capabilities provide additional protection from having to pay for more resources than you need, while making sure you always have games available for new players to join with minimal waiting. Through Amazon GameLift we will be able to deploy and manage dedicated game servers with custom rule sets for skill/latency based matchmaking.


Amazon Cognito lets you add user sign-up, sign-in, and access control to your web and mobile apps quickly and easily. Amazon Cognito scales to millions of users and supports sign-in with social identity providers, such as Facebook, Google, Amazon, and enterprise identity providers via SAML 2.0. We will be able to store information about users inside of cognito to use within our matchmaking configurations.


Amazon Lambda allows you to run code for virtually any type of application or backend service - all with zero administration. Just upload your code and Lambda takes care of everything required to run and scale your code with high availability. You can set up your code to automatically trigger from other AWS services or call it directly from any web or mobile app. The possibilities are endless on what that block of code will specifically do but a few examples could be allowing invite and accept functions to have friends join your lobby, writing matchmaking configurations, etc...(essentially the idea would be writing any specific block of code that needs to be triggered at a specific time, so if you have any ideas let me know!)


Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale. It's a fully managed, multiregion, multimaster, durable database with built-in security, backup and restore, and in-memory caching for internet-scale applications. DynamoDB can handle more than 10 trillion requests per day and can support peaks of more than 20 million requests per second.

Completed Example Project

Plugin Installation/AWS Account Setup

Plugin Installation

Step One

Since we will be using dedicated server hosting you will need to a version of the engine installed from source which you can find how to install here. Once installed, follow this straightforward 10 min tutorial Here.

Step Two

InstallToEngine

Now go into your epic games library and install the plugin to any engine that is available through epic games. It does not matter which engine you install it to because we’re going to be moving the plugins over to our source engine, but we need to install them to an engine within our epic games library so that we will be able to find the folders for them on our computer.

Next, go find access to the root of where that plugin is located and copy the plugin folder. For example this is where mine is located, yours could be different on your computer but everything after UE_4.X should be the same.

EpicPath

Now paste the plugin folder that you just copied into your source build of the engine inside of the exact same folder structure that we fold it in.

SourcePath

Step Three

Alright! Now we need to rebuild that engine after we have pasted the plugin folder inside of it, so go back to the root folder of your engine.

Run the setup.bat file as administrator, next run the generateprojectfiles.bat, and then open up the UE4.sln and build your visual studio file making sure you have development editor and Win64 selected at the top.



Step Four

Awesome! Now we should be able to open up the unreal editor for this engine and enable the plugin inside of our project. So go to engine->binaries->win64 and open up the ue4editor.

ue4editor

Now go ahead and create a new blank blueprint project. When the project opens up you should see a manage plugins window in the bottom right corner. If not go to edit->plugins. Click the box that says enabled and restart your project. You should now have access to whichever grouping of plugins you chose to purchase!

pluginenable

Step Five

A few final things we want to make sure and do before we move on any further with our project!

Once your projects restarts we need to go ahead and make it a c++ project. Click on add new-> new c++ class. Choose character as parent class and create class.
c++class parentclass

We need to do this in order to create a source folder inside the root of the our project so that we can create a server target file for our dedicated server. If we do not create a c++ class we will not have this source folder and will have to recreate a server target file everytime we want to launch a new server.


So let's go ahead and add in that server.target into the source folder of your project if there is not already one there.

Go into the source folder of the project you just created and look at the files. If you do not have c# source file called {name of your project}Server.Target.cs we are going to need to create one. To do this copy and paste the editor file and change the name from editor to server. Then inside of the file change all the spots circled from Editor to Server.
sourcefolder editor

Awesome! Now let's move over to AWS and go ahead and get our account set up!

AWS Account Setup

Now let's head over to AWS and create an account if you have not already done so. This should be pretty straight forward as you will just be entering in a lot of your personal information. Next we need to set up a few things inside of our IAM (Identity and Access Management) which will contain important information that we need to place inside of UE4 project as we go through these docs. Inside of IAM you will have full control of choosing what each user and service can or can not do.

I am going to start by creating a group and a user, but the only user inside of it will be myself, so I will be giving both this user/group full administrative access. So for my group I chose the full administrative access policy for the group and then created the group. Then for my user, I made sure and selected programmatic access and added the user inside of my group. Since you have chosen programmatic access, you will be give an access key and secret key, make sure to keep these keys stored somewhere safe, because we will need to use them inside of ur unreal project and it is very important that no one else obtains these keys.

Now we are ready to start building a matchmaking example project! We should have all the necessary setup in place to get started!

Matchmaking Example Setup (GameLift/Cognito)


Necessary Starter Variables

Game Instance

Inside of our game instance we want to store any data we need to be carried between levels. Our game instance will remain the same even from one level to another so this is a good place to keep this type of data.

eventshutdown

if you don't have one already created, you can do it now. You can see on the right side the variable we need. Match player session is a struct that hold "AWS player session" the other are defined by their respective color (pink == string, green == integer) and the object type (blue circle) are litteraly an object of the same name.

We will get in depth of what all of these do as we go along, but for now just recognize them as variables inside of our game instance because we want to be able to access their values while we are at different levels within our game. We also need to be sure and have this event shutdown inside of our gameinstance. So that we can destroy our game lift server if our game instance is shut down.

eventshutdown

Process Parameters

Used for cross process call. It will be called by GameLift service to pass some value to unreal proactively or tell unreal what GameLift service want it to do. For example, if GameLift service want to close a process without game session to scale down, process terminate will be called. And you should override process terminate event to save something or disconnect from something and call parent(I call quit server in parent. so, if you call parent, server process will be quit).

eventshutdown

eventshutdown


















Cognito User Pool

User Login will be the first level the client will enter upon entry into your game. We will use a cognito user pool to sign up new users with a username and password. I'm going to provide an overview of how our blueprints should look for you to reference as we go through this documentation and break everything down piece by piece.

Overview on full login using BlueprintUE.com

Let’s first begin by setting up a new empty level. Go to file->newlevel->emptylevel and save the level as user login. Then create a new game mode and player controller for this new level and set them inside of the level’s world settings.

cognitoworldsettings

Create a "login UI" and add this widget to your viewport from any places, I recommend you the player controller.

widgetaddtoviewport

Now we are going to set up the widget blueprint. The first thing we need to do is to be sure we have a reference to our game instance, because as I mentioned earlier we are going to store variable inside of game instance that we are going to need access to at different levels.

eventconstruct1

We then need to create a cognito idp object after we ensure we have a reference to our game instance off of our event construct node. By doing this the client will be able to see the user pools and identity pools inside of the region specified inside of your aws account.

cogidp

Now that our event construct is complete, inside of the designer portion of our widget blueprint, we are going to split our hierarchy up into five separate panels.

panelselect

Sign Up Panel is a panel where a client of your game will create an account that we will store within our Cognito User Pool(we'll get to this in a minute). We will have the client enter profile related information here. In my example the client will create a username and password as well as provide us with their email. panel1
Confirm Sign Up Panel is a panel where we will have our client confirm the account they just created. We will do this by sending a code to the email they provided and then having them enter that code to confirm their account. panel2
Forgot Password Panel is a panel where we will have the client enter their username. We will retrieve the email associated with the account from our cognito userpool and send a code to that email to allow the client to reset their password. panel3
Confirm Forgot Password Panel is a panel where we will allow the client to enter a new password and change to that new password as long as the code they entered is correct. panel4
Login Panel The user will enter their login and password that is associated with the account they signed up with. If the username and password correlates with a user inside of our cognito userpool, we will open the next level to our game! panel5


Now we can set up our panel switchers, so that we can move between different panels. For example, if a user is inside of the login panel, but still needs to sign up for an account, there needs to be a button so that they can switch to your signup panel.

panelswitch panelswitchex

Cognito User Pool creation

Let’s get into the interaction between Cognito and our project. Now we need get our Cognito User pool set up and go over the different options you have within it! First let's go inside of your AWS account (or go Here to create one right now) and then search for the Cognito tab.

From there, we are going to create a new user pool. Enter a pool name and you can go ahead and click review defaults. Go to attributes and under username make sure you check all the options that you would like your users to be able to verify their identity.

Then select all the attributes you would like to store inside of the users cognito profile. You can store custom attributes that you want to keep track of. For example, you may want to store a users steam id and could write a function in your blueprints to get access to a users steam id if they were logged in with steam. For this project I created a custom attribute called level which I will use for matchmaking players.

cognitoattributes levelpic

After you have set up the attributes section how you want, the next spot we need to go is down to app clients and create an app client. This app client enables us to have a reference to this specific user pool inside of our Unreal Engine project.

appclient

That's all for Cognito Service, now we'll go ahead and start integrating the required Blueprint for sign up, log in, forgot password and confirm password (with email).

First, before we forget let's create a variable inside of our unreal project to store that client id variable from Cognito. Inside of the game instance we created earlier, create a new string variable called clientid and set the value of the variable to the app client id value from cognito.

clientIDadd

Before we go through each of those events, I'm going to give you the common point for all of them. They have two input, the target and the request. The target is always the same (Our Cognito Idp Client from our Game Instance), but the request will change according to the event itself. Every request have intuitive name and a client ID input for his event. By example, signUp event will have the request "make signUp request".

Sign Up

This request is the most complex because you can add your custom attribute, beside that it's simple as getting the form and sending it!

signup

Confirm Sign Up

Fill the request with the form following the same rule.

confirmsignup

Forgot Password

Same process again.

forgotpassword

Confirm Forgot Password

*No shit sherlock* Here we go again :D !

confirmforgotpassword

Login

The first step with the login is the same as any other request made by our client. The following will be unique to this process.

login1

From there, we need to make sure the Authentication result had no challenges during the Authentication flow. As long as challenge name is "not set" we will provide the user with the access token, refresh token, id token, and device key generated from that authentication result and store these variables in our Game Instance for later.

login2

If the challenge name was set to anything other than "not set" we will need to respond to the authorization challenge and then check again to see if challenge name is "not set". For more information about the Authentication Result, Challenge Name, and Responding to authorization challenges you can read more here

login3

Now we should be able to sign up new users, allow them to reset their passwords, and authenticate them when they login! You should also be able to see new users inside of your cognito user pool inside of the users tab by running a standalone game in your ue4 project and completing the sign in process!


For Android Users Only You will need to enter this information into your Ca Path every time you Make AWSclientconfiguration throughout this project. For example, when we created the cognito idp object. For a more clear tutorial of what to do please follow this video.



Verify Identity & Link AWS Resources

Now that we have completed the process of setting up a cognito user pool, we need to setup a cognito identity pool. To begin, let's get a better idea of what each a user pool and identity pool do.

User Pool
Say you were creating a new web or mobile app and you were thinking about how to handle user registration, authentication, and account recovery. This is where Cognito User Pools would come in. Cognito User Pool handles all of this and as a developer you just need to use the SDK to retrieve user related information.

Identity Pool
Cognito Identity Pool (or Cognito Federated Identities) on the other hand is a way to authorize your users to use the various AWS services. Say you wanted to allow a user to have access to your GameLift service to start a matchmaking; you could specify that while creating an Identity Pool. And to create these levels of access, the Identity Pool has its own concept of an identity (or user). The source of these identities (or users) could be a Cognito User Pool or even Facebook or Google.

So this is where we are going to connect our identity pool to the rest of the aws services we are using. For now, this will only be the GameLift but later on when we start working with lambda and dynamodb as well, we will set them up in the same spot that we grant access to GameLift through our identity pool. Before we start getting into the blueprints inside, let us go set up the identity pool in question.

Go to "create a new identity pool" and choose a name for it. Then go down to authentication providers and under the cognito tab, put in the user pool id and client id for the userpool you created.

identitypool

Later on in this documentation, we will work with connecting accounts to facebook, Amazon, as well as othe rauthentication providers, but for now all we need is our cognito user pool as an authentication provider.

Next, while we're already inside of AWS let's go ahead and set up our permissions within the IAM (Identity and Access Management) tab to give specific permissions for our cognito identity pool to be able to read/write specific GameLift tasks. So go over to the IAM tab on AWS and click on roles. From there search the name of your identity pool and choose the auth role.

authrole

Then add an inline role and choose GameLift as the service. From there I am going to allow all GameLift actions (for better security practices you can pick to only check the specific functions that are being run in your project, but for now just allow all).

authrole2

And if you are going to be setting up Lambda and DynamoDB functionality in the future go ahead and give full access to both of those services so that we do not have to remember to do it when we are further along in our project.

authrole2

Now that all of that is set up let's head back over into our level blueprint (the empty level we created previously).

Entry Level Map Overview

The first thing I'm going to do before we dive into setting up the blueprints for this level is give you all a top down overview of the entire blueprint setup as a whole. This should provide you all with a solid reference in case you get confused as to where one specific node is coming from as you go from one picture to another inside of this documentation.

We need to first make sure we have a reference to our game instance and then we need to create a cognito identity object. Just like how we had to create a cognito idp object for our user pool, we need to create a cognito identity object for our identity pool.

gameentrybegin

From there we need to get credentials for identity. Any logins provided will be validated for the authentication provider which is our user pool. We will do this by generating an id that can be used to return our credentials. We will use the id token variable generated from our authentication result in the previous section as a reference to the specific user who logged in. Now that our identity pool is set up and our authentication provider is working we can move on to setting up GameLift!

identitycreds

Start GameLift Setup & Get Player Into Lobby Level

Next, we will create a GameLift object for each of our fleet destinations. We will get more into fleets later on, but basically they will be used to host all of our game sessions. For example you may want a couple fleets located inside of North America and a few located inside of Europe and then we could write matchmaking rule sets to try and match players in fleets that are located closer to them. The lobby fleet/alias id variable will be store in a map keyed with a region by us after we upload our Server to GameLift. The GameLift client variable will also be a map but automatically based on our fleet/alias variable.

gameliftobj

After that, I set up a test to see which fleet is a best match for the player based on latency. It will loop through each of the fleets and do a latency check by checking how long it takes to search through the game sessions inside of that lobby fleet/alias id map we just created. It will store the values inside of a latency game instance variable so that we will be able to reference later.

latencyloop1

Image continuation.

latencyloop2

And then finally, we will get the user and create a game session for them inside of a fleet located in their current region. This new level that we open will function as the lobby map for our game.

makelobbysession1

Image continuation.

makelobbysession2

Image continuation.

makelobbysession3

Now players of our game are into our lobby map and we are ready to setup matchmaking for our game!! So let's get started with it!!

Setup Matchmaking UI

We are going to put in place all the required blueprint events. That include start matchmaking, cancel matchmaking, select region and a little bonus to set the player level attribute.

Matchamking UI Overview

Just like in the previous section with the entry level map, I'm going to give you all a top down overview of the entire blueprint setup as a whole. This should provide you a solid reference in case you get confused as to where one specific node is coming from as you go from one picture to another inside of this documentation.

Pre-construct

So let's begin in the event pre-construct making sure we have a reference to the our game instance as we have done multiple times previously. After that we are going to create a region selector. Once we have done this we will set up our region selector option box setting the default value to the players current region and adding a value for every possible region that we have a GameLift client inside of.

regionselect

From there we will set up the rest of our default values and run a couple functions inside of our event pre-construct. The main ideas of what we are doing here is checking if the player is the creator of the lobby level they came from and update the UI according to those data. We will also run a refresh token function inside of our game instance to get new references for our tokens to avoid our old references from timing out.

preconstruct1

Image continuation.

preconstruct2

Image continuation.

refreshtoken

Image continuation.

preconstruct3

Image continuation.

preconstruct4

Region selector

Alright now that our event pre-construct is all set up, let's set up the blueprint code for our Region Selector. To do this the first thing we are going to do is make sure the new region that the player selected is not the same as the region they previously had selected. If they are selecting a new one, we refresh the tokens and continue.

regionselector1

We can now confirm this user by getting our Access tokens. If the user is valid, we hit the next function.

regionselector2

Now it's time to create a session and based on that result, join the lobby level (this level had not beign created yet, don't worry).

regionselector3

Image continuation.

regionselector4

Level selector

Next, let's set up the blueprint code for when the player enters text to enter their level. First, we are going to make sure the level value the player entered was numeric and as long as it was we are going to run an update player level function in our lobby character in order to multicast that update so that every player within your lobby is made aware of your level change. From there we are then going to update the level attribute so that it is changed inside of our cognito user pool. And this will be the process for changing any user attribute and could be applied a much better way for calculating a players level, rather than just having them enter it.

level1

level2

level3

Ready event

Okay so the first thing we are going to do is check if you are the creator of the lobby, if yes we are going to get all the other players lobby character in your party and get all the user attributes for the players in your lobby, this includes each persons level variable as well as their region latency map which we created previously. Once we have gathered all of that information we will open up a gate to start matchmaking which will only be closed if the cancel button is clicked making us not ready.

readybutton1

readybutton2

Now inside of our gate handling the matchmaking, the first thing we are going to do is start matchmaking and connect that to our matchmaking configuration name located inside of GameLift. I will break down how to set up a matchmaking configuration name in just a second so for now don't worry too much about it.

We are going to be sure and sync our matchmaking ticket with all of the players within our lobby by multicasting the event for each player to ensure all players have the same ticket id. We are going to check/update our matchmaking status every 5 seconds trying to see if the matchmaking ticket is either cancelled or completed.

matchmake1

If it is cancelled all we need to do is set the ready play button back to enabled and each of the cancel and accept matchmaking buttons back to not enabled.If our matchmaking ticket is completed we need to set the accept matchmaking button to enabled so that the players can accept the match, set a match result variable of type AWS game session connection info to game session connection info from our matchmaking ticket and sync the matchmaking ticket for all the players again.

matchmake2

Image continuation.

matchmake3

Image continuation and sync ticket in our player controller.

matchmake4 matchmake5


So now let's go all the way back to the beginning of this function and handle if you were not the creator of the lobby. Basically all we need to do here is stop matchmaking if the ticket id length is greater than zero because this mean that one of the players who is not the leader of the lobby click unready.

notcreator1

notcreator2

Cancel event

Now let's move on to the cancel button. When the cancel button is pressed we are going to stop matchmaking and then make the ready button enabled and disable the cancel button and accept matchmaknig result button.

cancel1

cancel2

Accept event

Some of you will probably not want to force your players to accept the match, in this case you can run this code on complete, the only requirement will be in GameLift service to check a box (mention in the matchmaking configuration section). But this is the way I set it up for this example.

The first thing that happen is a loop through all the other matched ids of players in the proposed match and then accept the match.

accept1

From there, we are going to prepare the game sessions and each player sessions so that all of our matched players can join.

accept2

Image continuation.

accept3

Image continuation.

accept4

Then we are going to loop through every current player in your lobby and sync all of the game session and player session information on each owning client so that they can open up the correct level inside of that game session and have their player session accounted for.

accept5

Here you can see the prerequisites before we join the level.

accept6

This completes the setup for the matchamking UI in this example project.

Setup Lobby Character

The first thing we will do is make sure the player is not the server and that they're controller is equal to their player controller.

playerchar1

From there we are going to replicate our event player latencies to every other player inside of a lobby, this way each player will have access to each others player latencies which will help us with finding a match for this group of players. We will also go ahead and make sure we have a reference of our game instance.

playerchar2

Latency event that update map.

playerchar3

Next, we are going to get access to our cognito attributes in order to set our default level attribute as well as our player id. We will then multicast these values so that every other players in our lobby can also have access to these values for matchmaking.

attribute1

Every attribute equal to level and sub. You could replicate any player attributes from this place.

attribute2

Event replicate for those attribute.

attribute3

After replicating players attribute we need create a player session and sync thosee data with the server.

playersesh1

Set player session on Server, the first step is to describe the player.

playersesh2

Now we can accept the player in this session.

playersesh3

End play event

Then for on event end play, we need to remove our player session and open up the user login map if the reason for the end play was because the server was destroyed.

endplay1

Setup Lobby Game Mode

There is only one function we need to run inside of our game mode and that is done on event begin play node to setup our GameLift server. The first thing we need to do is initialize the GameLift SDK because we can not perform any GameLift functionality until this has been done. From there we can construct our process parameters which we went over in the very beginning. Then finally, we can set our port, log paths, and run process ready in order to notify GameLift that we are ready to recieve GameLift sessions. We will have to run this function inside of every game mode that a fleet is located because it sets up our GameLift functionality for use.

lobbygamemode

Now we have finished all the code setup for our lobby level, so let's move over into the GameLift interface and get a breakdown of what we are going to need to do inside of there!

Interacting With The GameLift Interface

Okay, so if you have not worked with aws GameLift extensively, some of the blueprint nodes/matchmaking configurations we set up inside of our lobby may not fully make sense in terms of why I set things up that way. So in this section I'd like to give a quick rundown of how builds, fleets, aliases, matchmamking configurations, matchmaking rule sets, and queues all interact with each another. In order to fully be able to maximize the use of these plugins to tailor them for the setup of your game, you will need to have an understanding of how all things interact with one another.

Builds

This is the package version of your game upload to AWS, in this example project we need two build. One for the lobby and one for the game. Those build are use to generate fleets. Whitout a build you can't create a fleet! They are setup to work either on Windows or Linux operating system when you upload them, you'll have to choose it based on what operating system you choose when you package.

Fleets

Fleets are going to function as our hosting resources in the form of EC2 instances. These instances have varying combinations of CPU, memory, storage, networking capacity, and cost and give you the flexibility to choose the appropriate mix of resources that is the best fit for your game. Inside of our fleet is where we will be able to track all of our game sessions and player sessions. The size of a fleet depends on the number of instances you give it, and you can adjust fleet size to meet player demand either manually or by auto-scaling. You need multiple fleets if, for example, you want to host players in more than one region, or if you have two or more versions of your game server build or script.

Aliases

An Amazon GameLift alias is used to abstract a fleet designation. Fleet designations tell Amazon GameLift where to search for available resources when creating new game sessions for players. By using aliases instead of specific fleet IDs, you can more easily and seamlessly switch player traffic from one fleet to another by changing the alias's target location.

buildfleetalias

Queues

Amazon GameLift uses queues to process requests for game session placements and find hosting resources for new game sessions. The way you design your queue determines where Amazon GameLift looks for available resources, and how Amazon GameLift evaluates available resources to find the optimal choice for each new game session. We need a queue in order to setup matchmaking configurations and to create spot fleets, a cheaper form of ec2 instances that can be utilized effectively through a queue.

Matchmaking Rule Sets

The rule set determines the two key elements of a match: your game's team structure and size, and how to group players together for the best possible match. For example let's take a look at the rule set I created for this example project:

ruleset

In this example I try to match players closely skilled based on the value of the level attribute that we defined inside of our matchmaking UI. As time goes on without finding a match I relax the strictness of how closely related players level attribute needs to be in order to be matched together. For more information about building rule sets along with a couple different examples go here.

Matchmaking Configurations

Once you have set up a queue and a matchmaking rule set, we can begin setting up matchmaking configurations. In our matchmaking configuration, we are going to essentially tie our rule set and queue together and use this configuration as our top level matchmaking tool. Then fill in the rest of the matchmaking configuration details specific to how you want your game to run.

matchmakeconfig

And now that we have a better idea of how all of the aws GameLift features work, let's go ahead and finish adding in the blueprint code and then get this game all set up!

Finializing Blueprints

Alright, now back inside of our unreal project we are going to use the level map that your actual game is going to take place! For this example I am just going to open up a thirdperson example map with no real game play functionality implemented, but if you already already have a game mode constructed or a map designed you should still be able to use that game mode/map just adding in the code that I add in which will be the exact same code we added in for the lobby game mode.

lobbygamemode

Then our final blueprint we need to set up is thirdperson character blueprint. Again, just like the game mode, you should be able to have all of your game functionality for your character inside of this blueprint and have zero impact on our GameLift services, just add in the code I add in as well. The code we are going to add in here is very similar to the code for our lobby character but there will be a few differences because we will be creating a player session inside of a different game session inside of a different fleet.

thirdpersonchar1

thirdpersonchar2

thirdpersonchar3

thirdpersonchar4

thirdpersonchar5

thirdpersonchar6

All of our blueprints should be completely set up now! So let's move on to building the game and uploading it onto GameLift!

Prepare Server Upload For Windows or Linux

We need to be able to upload our server builds to Amazon GameLift. We can do this through either a linux server or windows server, I will first show you how to setup each of them so that they will be able to interact with AWS.

The first thing we are going to need to do is install the AWS Command Line Interface, which can be found here.
Now run aws Configure in your command line and fill in your aws account details.

$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]: json
                                

Windows

The steps needed to upload our Game Server through Windows are very simple. All we need to do to be able to upload through Windows is follow these simple steps.

  • We need to download/save the GameLift SDK from the developer resources which can be found here.
  • Run these commands inside of cmd or windows powershell:
    $ cd Downloads
    $ ls
    $ unzip GameLift_12_14_2018.zip              
  • Then once that finishes unzipping, we can run our next set of commands:
    $ ls
    $ cd Gamelift_12_14_2018
    $ ls
    $ cd GameLiftLocal-Release-1.0.4/
    $ ls
    $ java -jar GameLiftLocal.jar

Now we should be able to build a Game Server through Windows and upload it to Amazon GameLift. The only real advantage I see to using Windows to upload your server builds to AWS over Linux is that you are most likely more familiar with Windows because the majority of us have worked with a Windows operating system before more than Linux/Unix. So it may not be a bad idea to start out uploading builds using Windows while learning more about GameLift and AWS, but in the long term I recommend switching to Linux, especially if you planning to release a game using GameLift.

Linux

Set up Linux from beginning video


I am going to show you how to get a linux operating system installed to your windows system also through documentation (I recommend watching the video if you are setting up Linux for the first time).

General Things
  • The first thing we need to do is make sure that your Engine and your project are at different drive discs, (C/ and D/ for example)
  • Then we are going to download two applications inside of windows, Fedora-30 and Oracle VirtualBox.
  • Next, follow this youtube tutorial to get Fedora-30 and Oracle VirtualBox installed onto your machine.
  • If fedora Doesn’t appear at virtual box for X64 version, follow these steps:
    • Go to Bios
    • usually go to CPU settings inside bios
    • ENABLE Virtual Machine, sometimes it is off
Fedora Setup
  • We are going to set a few of our default settings. To do this, go to your fedora system, go to settings and then:
    • Give 50Gb for virtual machine disc space
    • Set 8gb Memory of ram to avoid troubles at AWS installation at Linux
    • Set cpu: 2/4 threads for Fedora
  • Go to Network settings at fedora, you should have Nat Network at adaptor 1. If you do not, you need to assign a name at Oracle VM VirtualBox: Go to Manager -> Files -> Preferences -> Add a new Nat Network.
  • Then go back to your Fedora settings and select that name.
  • Finally, at adapter 2 set Host only adapter.
Test Communication
  • Now you are ready to enter on your fedora operating system, press START, you have to remember your username and password for later setup.
  • At fedora go to your terminal (Press Activities):
    terminal

  • From there press: ifconfig. You should see an “enp0s8” section and then remember that IP shown. Ex: 192.168.xxx.xxx
  • Now you should see at conEmu or CMD if you can make your Host operating system (Windows→ Host) to communicate with (linux→ Guest), by typing:
    $ ssh YourUserName@192.168.xxx.xxx
  • Then it asks for your Password (It doesn't show it, but it is writing and you press enter and if it shows a last login, then everything is fine.)
Download AWS into Fedora Operating System
  • We need to download/save the GameLift SDK from the developer resources which can be found here.
  • Go to terminal and write the following:
    $ cd Downloads
    $ ls
    $ unzip GameLift_12_14_2018.zip
  • Then once that finishes unzipping, we can run our next set of commands:
    $ ls
    $ cd Gamelift_12_14_2018
    $ ls
    $ cd GameLiftLocal-Release-1.0.4/
    $ ls
    $ java -jar GameLiftLocal.jar              
  • You should open your project, go to device manager, and add a device. Add the following (Must be exact or your gonna have packaging errors):
    • at Device Identifier: 192.168.xxx.xxx (yours found at enp0s8 in fedora terminal with ifconfig at terminal)
    • at Display Name: Your project name
    • at User: your fedora user
    • at Password: your fedora password

Now you should have setup a linux server that can interact with your GameLift project. Using a Linux operating system to upload our server builds to AWS instead of Windows is cheaper, faster, and more stable. I would recommend spending the time to learning Linux because it is the better solution for interaction between our Unreal project and AWS in the long run.

Upload Lobby/Game Map Server Builds To GameLift

We are now ready to upload our Server builds to Amazon GameLift! In this example project we are going to have two Server builds that we are going to upload to GameLift: One for our lobby and one for our Third Person Example Map. So let's first go verify that a couple variables are set correctly and that our setting defaults are correct.

First thing to do is to make sure all of our maps are link in the picture above. We are going to build the server for the lobby first, that is why the lobby map is the server default map for now.

maps

Make sure you have set the Game Instance!

gameinst

Okay now we are ready to package our server, so let's go to the project launcher inside of our project.

If you are using Linux Server, you will be using the device that we just added and it should be named as your Device Identifier, 192.168.xxx.xxx, set the config to developement and the data build to by the book. If you are not seeing the options that I see, make sure you have toggled to see the advanced options. Also be sure that your linux server is open and running inside of fedora.

linux

If you are using a Windows Server, you will be using your desktop. Make sure your variant is set to Windows Server, and the data build is by the book. If you are not seeing the options that I see, make sure you have toggled to see the advanced options.

windows

Now we wait for that launch to complete, and hopefully everything was successful, if you encountered an error in the build section you most likely have a cache issue either inside of your project or engine. The best way to solve this is make sure the aws plugin inside your engine is up to date and then rebuild your engine, and then rebuild your project, by deleting all of the binary files and then rebuilding the c++ files. If you had a problem during the cooking section, the most likely issue is that there was a problem with the way you named an asset inside of your project, check the log and it should point you to the specific asset that caused a problem.

launch

And now if we go inside of our project folder, go to saved, go to staged builds you should see either a Windows Server or Linux Server folder depending on which one you built. Now I went ahead and changed the name of this folder to LobbyWindowsServer or LobbyLinuxServer so that it does not get overwritten when we build our game server.

Next, if you built a Windows Server you need to add these files inside of your LobbyWindowsServer folder. If you built a Linux Server you are going to need to alter the install.sh file inside of your LobbyLinuxServer folder so that you will be able to to download the log inside of your game sesion console and monitor the health of your server from your own computer. You can follow this video to show you what to do.

Now we are ready to upload to GameLift, follow these templates for uploading with either Windows or Linux, you can run these commands inside of your CMD or windows powershell. The name and build version can be what ever you want to set for it.

upload

Okay now we are going to upload the server for the game map as well. Almost every step will be done the exact same way but there are a few things you need to be sure and change first. The first thing you need to make sure you do is change the server default map to the third person example map or whatever map you are using for your game. Then you can go ahead and begin the launch.

Once that is successful, change the server folder name so that it was GameWindowsServer or GameLinuxServer. Then, if you're using windows make sure you add those required files into the folder or if you used Linux that you adjust that install.sh file. Then make sure you specify the correct name inside of your build root and go ahead and upload that to Amazon GameLift as well.

And now if you go inside of your GameLift Dashboard you should be able to see your build uploads. I have many versions in there but it should look something like this.

builds

Setup Matchmaking Configurations In AWS For Game

In this section we are going to up our fleets, aliases, queue, matchmaking rule set, and matchmaking configurations to interact with our game. We already did a brief rundown of how each of these things works to get a better understanding how Amazon GameLift functions in general but now we're going to set it up for our project!

Fleets

Let us first set up our fleets, for now we are going to set up two fleets, one for each of our builds and they will be located inside of the region you are currently in (top right too see your region). Keep in mind that the number of fleet is higly sujective to your game, the number of people playing and their location in the world. It is also a good idea to use both spot and on demand fleets and allow you're queue to decide whether it will be okay to place players' game session inside of a spot fleet at the time they are matched together. Depending on the type of game you make, you will need to determine which instance type will work best for you.

In this example, both of my fleets were spot fleets and both of them used the c5.large instance type. You may not be able to create two fleets inside of the same region with the same instance type, so you can either make one of your fleets (the game fleet) of type c5.xlarge or make one of the fleets inside of a different region.

Under Server Process Allocation you need to set the launch path, Game represents the folder of your server so either LobbyWindowsServer folder or LobbyLinuxServer folder when building your lobby fleet and same idea for your game fleet. From that folder the path will be (NameOfYouProject Folder)\Binaries\Win64\(NameOfYourProjectServer.exe). Then I went ahead and set 20 concurrent process.

launchpath

Under game session activation, I set the max concurrent game session activation to 20 per instance, and left the new activation timeout at 600 seconds. This will be the same for both of the fleets. At least for on the free tier instance type, I've found 20 to be the most amount of active game sessions you want on each instance.

Next, let's set up the port settings. I am going to set up protocol for both UDP and TCP. For UDP, I used ports 7777-7796 and the address range I just set to 0.0.0.0/0. I setup TCP protocol on port 3389 with the same address range. The reason for setting up TCP protocol is to allow us to actually access the machine that runs the server. This allows us to monitor the server from our own computer. Also under the protection policy I chose full protection. this setup will be the same for both fleets.

Aliases

Now that our fleets are set up, let's go ahead and create two aliases to reference each of those fleets. This should be quite simple as all you are going to need to do is: create an alias, give the alias a name, a description, and then select its associated fleet.

Queue

Next up, let's set up our Queue. We are only going to need one queue because it is only necessary for our game fleet. We will not need a queue for our lobby. So go ahead and give your queue a name and leave the queue timeout at 600 seconds. I am not going to add any player latency policies for this queue currently. I am going to add the alias associated with our game fleet to the list of destinations and then select create queue.

Matchmaking Rule Set

Okay now that our queue is set up, let's go ahead and create a matchmaking rule set. The matchmaking rule set that I used you can copy here. Now to give you a better idea of how this rule set functions so that you'll be able to implement your own rule set in the future, I am going to break down this rule set and how the variables interact with your blueprint code. Inside of our matchmaking UI, remember when we created this player attribute and added a level attribute for each player inside of our lobby when the lobby leader clicked readybeginplay.

rulesetplayer

So now back inside of our rule set, we are able to access this level attributes value in order to matchmake teams so that they have relatively similar levels.

rulesetplayer

Matchmaking Configuration

Then, with our rule set and queue set up, we can set up our matchmaking configuration which will link our queue and rule set together so that we can actually matchmake teams based on the rules that we have defined. So, let's go ahead and give our matchmaking configuration a name and set the request timeout to 60 seconds. I went ahead and set the backfill mode to automatic since I did not set up any way to handle it within my blueprints.

Then I chose the rule set we just set up for my rule set and the queue we just created as my queue for my matchmaking configuration and went ahead and created it. Then picking up from where left off in regards to explanation of how this functions you can see when we run "start matchmaking" inside of our matchmaking UI, the matchmaking configuration is what will trigger our rule set to run, using the information attribute information inside of our players array, and then use our queue to find the best avaiable fleet to create a new game session.

configname

Launching Our Client

Alright! Now on to the final section for creating this matchmaking example project, as we need to prepare to launch our client. We have set up all the blueprints inside of Unreal project as well as now set up our matchmaking configurations, but we now need to link a few GameLift variables inside of our project so that we can be sure that everything will function together.

Let's go into our Game Instance and you'll need to create a variable of type Map that can take in the value of two strings. I named the variable lobby fleet/alias id. Inside of the first string you are going to enter the aws region that you created your fleet inside of, for example: us-east-2. Inside of the second string you are going to put the alias id for the alias that is associated with your lobby fleet, for example alias-1eed2fef-ce37-4ac3-8ed7-fhgjmnhjfg5. Then let' also create one more string varaible called current region and set the value of that to the aws region that you created your fleet inside of as well.

Next, go into your Matchmaking UI and create a string variable called Matchmaking Configuration Name and enter in the name that you gave your matchmaking configuration. Now we should be ready to build the client as all other variables we use values should be generated themselves. Finally, make sure that your game default map is set to UserLogin.

You can now package your client. I recommand you doing it from File->Package project and then choose appropriate platform.

If everything was successful, let's go ahead and see if we can open up our game. Let's go inside of our project folder, go to saved, staged builds, and find our WindowsNoEditor folder. From there, (Name of project folder)\binaries\win64 and then open up that executable. This will be the executable that will allow other people to play your game. Once you open up that executable, you should be at that cognito login screen that we created. Once you login to your cognito user pool, you should be taken to your lobby map, where you can search for match, and then accept that match. If you are unable to find a match when searching by yourself, it is most likely because of the way that your rule set is setup.


Accessing Your Gamelift Instance

Thank you to our friend @trdwll, who has set up many different guides/projects for the Unreal Engine including this guide for accessing your GameLift instance via RDP or ssh for both Linux or Windows builds.

Guide

Party System & Database (Lambda/DynamoDB)


Introduction To What We Are Doing

In this section we are going to set up a Party System so that users of your game can invite and join their friends inside of the lobby level. We will be primarily using features provided by Lambda to set up this party system, with DynamoDB functioning as a way to limit the number of times we invoke a lambda function to help keep our costs down.

I have already written all of the functions that we will be using inside of both Ruby and Nodejs. I will go through all functions and explain what is happening, but I will provide links to download the functions written in both languages. Lambda essentially functions by allwing you to run code snippets of C#, Java, NodeJS, Python, Go, Powershell, and Ruby... which is why I have found Lambda to be an incredible/simplier than ever solution for setting up a party system as well as many other features that we will get to in the future.

For now though, let's go ahead and get started with setting up this Party system as this will be really cool for your game once it is complete!

invitepic

invitepic2

Download Functions & Setup S3 Bucket

First, you need to go ahead and download those functions that I mentioned in the previous section. It does not matter which one you choose as the processes for uploading each type are essentially the exact same so I would just choose whichever language you are more familar with.

NodeJS       Ruby

Now we need to upload these functions to an s3 bucket inside of your aws account. So let's head over to the s3 tab inside of your aws account and go ahead and create a new bucket. Go ahead and give your bucket a name and make the region the region you are in. then click next. Under configure options we are going to select versioning so that we keep all versions of an object inside the bucket and then click next. Under set permissions we are going to be sure and un-check block all public access and then we can create bucket.

And now since our bucket is created let's go ahead and upload that zip you downloaded previously so that it is inside of your bucket. This is all we need to do inside of S3 so now let's go ahead and setup our.

Lambda Service Role

Our next step is to set up our Lambda Service Role. we will do this so that our Lambda service can have access to other aws services, specifically DynamoDB, SES, Cognito, X-Ray, Cloudwatch, and KMS. So go ahead and head over to IAM and create a new role. Then, these are the 6 policies that I attached to my role:

lambdapolicy1

The first two policies are created by AWS so they should already be available to you, but the next 4 policies you will need to create yourself. Fill in the service, action, and resource as shown below.

lambdapolicy2

lambdapolicy3

lambdapolicy4

lambdapolicy5

Set up Verified Email Inside of SES

Go over to your SES (Simple Email Service). Go to email addresses and verify a new email address. We are going to use this to send an email to a user when they have been invited to join a game, which is a feature you may or may not want in your actual game but is already coded to be set up inside of the zip you downloaded earlier so I am going to show you how to do it.

ses

And now that our Lambda Role is set up and we have verified an email, we are ready to move over to Lambda and set up each of the functions we are going to be using in order to set up our party system.

Lambda Functions

We are going to set up five Lambda functions inside of our lambda service. Only two of them are necessary for setting up the party system, but I am going to include the other three functions as well because it will be simple to set them up and you could possibly find good use cases for them inside of your game.

functions

So let's get started by creating a new function. we are going to choose Author from scratch. Go ahead and give the first function you are creating a name whether that be get_invitation, get_latency, etc... Select either NodeJS or Ruby for the runtime depending on which zip you downloaded and then under create/choose an execution role we are going to choose that Lambda role that we created in the previous section.

lambdarole

Then we can go ahead and create the function.

Then under code entry type choose upload a file from amazon s3. Then in a seperate tab go over to the s3 bucket we created earlier and copy over the object url for our zip file. We are going to place this inside of our amazon s3 link url. Then for what code we are going to enter inside of our handler we are going to run whichever of the five functions we are attempting to execute with awsLambda placed in front. For example if we want to run the function get_latence the handler would be awsLambda.get_latence.

getlatence

Now do this process for each of the other four functions that we need to setup. Then we should have everything setup inside of our Lambda service and we can now move over to our blueprint code so that I can show you guys how we are able to invoke a function.

Encrypt Environment Variables

So for each of our functions we're going to want to add these environment variables

encrypt

And we can encrypt these using either the aws default encrytion, which you can find inside of your key management service under AWS managed keys

awskeys

Or you can use a customer master key which can be created inside of your key management service under customer managed keys

ownkeys

Invoke Lambda Functions (Check Player Latency)

In this section, I am going to show you how we can invoke a Lambda function inside of our blueprint code. In order to fully maximize the effectiveness of our party system, we will need to set up a DynamoDB table so that we if a user is spamming the invite button to their friend we don't run our Lambda function over and over again, because we are being charged for each time that lambda function runs and even though each specific invoke of a function is incredibly cheap, our cost can add up quick if players are spamming the invite button. But for now I just want to show how the process works for invoking a function inside of our blueprint code, so I will show that now.

The first thing we need to do is create a lambda object, which will be done in the exact same spot as we created a GameLift object inside of the matchmaking example project section (inside of our game entry map). We do this so that our blueprint code is able to communicate with our aws account and have access to our functions inside of our lambda service.

lambdaobj

Let's use the get timestamp function from lambda in order to figure out which of our lobby fleet locations has the least amount amount of latency and will be the best fit for where the best fleet location would be for the player to open a new game session. In this example, inside of each lambda object, we will set a start timestamp and then run our get_timestamp lambda function.

timestamp1

We will then subtract the values and store this final value in a map of latency values for each lamba object (aka fleet destination). We will use the invoke function to run our lambda function, where we provide the function name for the invoke request, and our target will be each of the lambda objects we created, which will be stored inside of game instance variable lambda client, which will be a map of all of our lambda objects. We will be able to break the invoke request and get the response from the function from the payload.

timestamp2

timestamp3

And now you should have a good idea of how we can invoke lambda functions through our blueprint code. So now let's move on to setting up our dynamoDB table so that we can get to setting up our party system

How to Create a DynamoDB Table

So now head over to the DynamoDB service and we are going to create a table. I named my table Invitation with a partition key of type string called to-user-sub and a sort key of type number called expire-time. Then I created the table. Once I got to the overview of the table I selected manage stream and made the view type both new and old images and then I enabled the stream.

invitationtable

Now our table is set up and we can go ahead and move over to the blueprint code to see how we can interact with our dynamodb table using the blueprints within our project!

Inside of our blueprints let's go ahead and create our DynamoDB Objects as well as our DynamoDB Streams Objects. We will do this the exact same way that we set up our GameLift and lambda objects inside of our gameentry map.

dynamodbobjs

Setup DynamoDB Table (Kill to Death Ratio)

In this section, I am going to Setup a DynamoDB table which you could use as a template for setting up your own table to track a players kill to death ratio. For this example table I am going to allow the user to change and get the value of a players kill to death ratio just by typing in the numbers, but I will be showing you how to update as well as query through your table so that you will understand how the table works and will be able to apply this code I setup to the correct spot to correctly function for your game. You are going to need a json blueprint plugin in order to work with a dynamodb table. I recommend using this one which is free.

The first step is setting up the actual table inside of dynamoDB. for this table I am going to have a primary partiton key of type string called user-sub-id and a primary sort key of type number called kda. I left everything else as default and did not enable stream for this table.

Now let's move over to our blueprints, make sure you have setup your dynamodb objects and your dynamodbstreams objects as I told you how to do in the previous section. From there I am going to go into my matchmakingUI. I created a get and a set button inside of my UI in order to demonstrate how the table works. For an actual game this would obviously not be the way you would want to get and set a kill to death ratio. But it does a fine job demonstrating how to read and write to your dynamodb table.

kdaUI

Then inside of the blueprints there is just 2 functions I am going to write. One for the when a player sets the kda value (writing to the dynamoDB table) and one for when a player gets the kda value (reading from the dynamoDB table).

To set the item we are going to run the update Item function. We will make an update item request, specify the name of our table and use json code in order to identify the correct primary key so that we can update the value of the sort key to what we are trying to set it to.

setKD1

setKD2

Then in order to get the value of the item from the table, we are to run the query function using our primary partition key so that we can get access to the value of items for that specific user inside of our table. We then will get the value of our kda and change the value that appears inside of our matchmakingUI.

getKD1

getKD2

getKD3

So now we have setup an example dynamoDB table and tracking a k/d ratio could be a very important feature of your game. Now let's get back to setting up our party system and start by showing the blueprint setup for that.

Party System Blueprint Nodes

Okay, now in this section let's go ahead and set up the blueprint nodes in order to get our party system effectively functioning. We have already set up each of the lambda functions we are going to use as well as our Invitation DynamooDB table. we have also created our lambda objects, dynamodb objects, and dynamodb streams objects.

I am going to provide an overview of the functions we will be adding inside of our matchmakingUI widget blueprint. You can use this to reference how everything is connected together if you get confused while we are breaking it down piece by piece.

Invite event

The first thing I'm going to set up two seperate widget blueprints. one will be for inviting your friends to your game and the other will be for joining your friends game. Each of these blueprints will then be setup inside of the event pre-construct of our MatchmakingUI widget blueprint.

Let's start with the first user widget which I named user label. This widget will be used to invite our friends to join our lobby.

invitefriend

As usual, a reference of our Game Instance will be required.

userlabel1

When the invite button is pressed next to a specific players name, we are going to get that players user id from cognito and invite them to join our lobby game session.

userlabel2

userlabel3

userlabel4

Now let's move on to the other widget blueprint which I named Invitation. This widget will be used for players to accept their friends invitation and join their lobby game session.

invitation1

Accept & Reject event

Inside of this blueprint, if the player rejects the invitation we will remove the widget from the screen, and if they accept the invitation we will set the value of the game session we want to join inside of our matchmakingUI to the game session id of the player who invited you to their game. Also after 5 seconds, if you do not accept or reject the game session we will remove the widget from your screen.

invitation2

Accept & Reject event

Next, let's move back over to our MatchmakingUI widget blueprint and get these two widget blueprints we just set up effectively functioning inside of our matchamkingUI. Everything we are going to set up will be inside of the event pre-construct function.

For our user label widget, we are going to get all of the users inside of our cognito identity pool and create a user label widget for each user inside of our user pool. When making your actual game, you would probably want the user to have a friend list to only invite specific players, which I will be showing you all how to setup soon. But for now a user label is going to be added for every user inside of a user pool.

UserLabel

UserLabel

For the invitation widget, we will run a timer which will check every 5 seconds if the player was invited to a match. In order for the Invitation widget to appear on the players screen who was invited, we will first make a check with our DynamoDB table to be sure there is not already an invitation from the same pplayer that has not expired yet. Then we will get the information that is necessary for the user to join the other players game session such as region and game session id. We will then have the invitation widget appear and plugin the necessary inputs so that hte invited player will have enough information to successfully join the pther players lobby game session. In order to see all of this code implemented it will be easier to take a look at the overview of this code at the top of this section. It should all be created inside of the event pre-construct function.

Awesome! Now we have set up our party system functionality. I think this is a very interesting feature with lots of different possibilities and options for you to cater to the way you want to set up your game.

FAQ Answers

Recently I finished setting up a discord bot will allow all of you guys to upvote questions asked by other people so that we can answer the most upvoted questions first and slowly move our way down the list. I will store all the questions asked and answered inside of this section of the documentation.

Video Tutorials

GameLift Video Tutorial

Cognito Video Tutorial

Lambda Video Tutorial

DynamoDB Video Tutorial

Loading Screen PDF

Example Projects

Full Multiplayer Example (GameLift, Cognito, Lambda, DynamoDB)

Matchmaking Example (GameLift & Cognito)

GameLift Example

Cognito Example

Find Us

Join Our Discord