Game Dev Archives - ab https://alexandrebruffa.com/category/game-dev/ Sat, 05 Oct 2024 14:40:14 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.5 https://alexandrebruffa.com/wp-content/uploads/2022/04/cropped-cropped-elior-favicon-270x270-1-32x32.png Game Dev Archives - ab https://alexandrebruffa.com/category/game-dev/ 32 32 Unity + Amazon Cognito: My New Course on Udemy! https://alexandrebruffa.com/unity-amazon-cognito-my-new-course-on-udemy/ Wed, 18 Sep 2024 23:30:25 +0000 https://alexandrebruffa.com/?p=1962 My new course is live on Udemy! Discover how Unity and Amazon Cognito can work together!

The post Unity + Amazon Cognito: My New Course on Udemy! appeared first on ab.

]]>
I’m very excited to share with you that I have published my first course on Udemy! 

➡ Check it out: Unity + Amazon Cognito: The ultimate guide 2024!

This course focuses on how Unity and Amazon Cognito can work together and is divided into two main parts: using Cognito as a user directory and as an authorization service for Unity.

In the first part of the course we will see how Amazon Cognito can be used as a user directory. We will learn how to create, retrieve, and delete users from Unity. I will also show you some advanced features of Cognito such as the hosted UI or the federation endpoints and how to log in to a Cognito user with a Google account.

In the second part of the course, we will use Amazon Cognito as an authorization service. We will access Lambda, S3, and DynamoDB from Unity with guest and authenticated users. We will also see the pros and cons of having a direct integration vs. exposing an endpoint and how Cognito can act as an authorizer to secure an endpoint.

I conceived this course as a practice guide; beyond learning Cognito concepts and features, I will show how to write functional C# code in Unity scripts and how to use the AWS console with different Amazon services.

I really hope you will like it and find it useful for your future personal or professional projects. If you have some feedback or suggestions, please reach out to me on my social networks:

🌳 Alexandre Bruffa

The post Unity + Amazon Cognito: My New Course on Udemy! appeared first on ab.

]]>
RealTime Servers & JavaScript SDK: AWS Answered Me! https://alexandrebruffa.com/realtime-servers-javascript-sdk-aws-answered-me/ Fri, 03 May 2024 04:49:09 +0000 https://alexandrebruffa.com/?p=1900 Which version of the JavaScript SDK for your GameLift Realtime server, v2 or v3? Read this article and figure it out!

The post RealTime Servers & JavaScript SDK: AWS Answered Me! appeared first on ab.

]]>
This article was initially published on my Medium Page.

Weeks ago, I showed how a real-time multiplayer game can integrate AI components by connecting a GameLift Realtime server and Bedrock, Amazon’s new generative AI service. I recommend you check out my previous post to know step-by-step how to do it:

Hey! I made a video summarizing this post; check it out!

Context

This is the general architecture I used to integrate AI components into a real-time multiplayer game built with Amazon GameLift:

Let’s focus on the ⚡ part: To connect my Realtime server and Bedrock through a Lambda function, I added code to my Realtime script to assume the service role and invoke the Lambda function, as described in the GameLift documentationRealtime servers use Node.js and JavaScript, so I used the AWS SDK for JavaScript.

🚨 For some reason, I could not use the AWS SDK for JavaScript version 3; it made my game server crash when starting. In the Events section, I figured out that an error was raised indicating that the game server was unhealthy and forcibly terminated:

When I used the AWS SDK for JavaScript version 2, everything worked like a charm. At this point, I wondered why I could not make it with version 3. Did I miss some requirements in the AWS documentation? Let’s delve into it.

JavaScript SDK Version 2 vs. Version 3

Working with version AWS SDK for JavaScript version 3 is convenient, and I will explain why. First, the AWS SDK for JavaScript version 2 is almost deprecated (maintenance mode), and the documentation is sometimes hard to find. As a developer, I prefer to work with up-to-date tools.

Then, remember that the AWS SDK for JavaScript is not installed on Realtime servers, so you have to install it locally, zip it along with your Realtime script, and upload it to GameLift. The main evolution from version 2 to version 3 is the SDK package’s modularity. With version 3, you can install and import only the packages you need instead of installing and importing the whole SDK into your code.

For the previous implementation, wrapping the whole SDK version 2 brought me another issue: the zip file was too large and could not be uploaded directly to GameLift. A workaround was uploading the file to an S3 bucket and creating an additional role, adding more complexity to the implementation.

Working with version 3 would have avoided those issues.

The Solution

The GameLift documentation shows no indications about the compatibility between Realtime servers and the AWS SDK for JavaScript version 3. However, in the AWS SDK for JavaScript v3 documentation, I found this requirement I missed the first time:

v3.201.0 and higher requires Node.js >= 14.
v3.46.0 to v3.200.0 requires Node.js >= 12.
Earlier versions require Node.js >= 10.

Realtime servers use Node.js, but which version of Node.js? No clue about it in the whole GameLift documentation, so let’s find out! In my Realtime script, I added code to print the Node.js version of the Realtime server into the logs:

Then, I read the game session logs, as I described in my previous post. Surprise! The Realtime servers are running an old version of Node.js: 10.15.2.

OK, that could be a problem! The actual version of the AWS SDK for JavaScript (v3.494.0) is not compatible with this version of Node.js. So, in my local environment, I installed the STS and Lambda packages with an old version that matches the Node.js requirements: v3.40.0:

npm install @aws-sdk/client-sts@v3.40.0
npm install @aws-sdk/client-lambda@v3.40.0

Then, re-wrap, re-upload to GameLift (without size issue!), re-create a fleet, and… it works! The game server and game sessions are running correctly.

Me when I found the solution

GameLift Team’s Answer

While I was stuck with this problem, I contacted the GameLift team, and they answered me the following:

Currently, GameLift does not support JavaScript v3 for Realtime Servers. We are happy to take this as an enhancement request and add it to our backlog. However, at this point, we cannot provide any timelines for the availability of this feature.

This makes sense! The AWS SDK for JavaScript version 3 does not offer full support, so the GameLift team recommends not using it.

Conclusion

Although I showed how to make it work with version 3, the GameLift team highly recommends using AWS SDK for JavaScript version 2. So, to access AWS resources from your Realtime server, you can use AWS SDK for JavaScript version 2 (recommended) or version 3 < v3.46.0 (at your own risk).

As an addendum to my previous article, you can find below the Realtime script I used in both versions:

A very big thanks to the GameLift team, who gave me a precise answer to my very technical question, and Chris Blackwell for his help and the guidance he’s always providing me regarding game services.

If you have any feedback or questions, feel free to reach out to me on my social networks:

🎬 YouTube Ⓜ Medium 🌐 Website

See you in the next post!

The post RealTime Servers & JavaScript SDK: AWS Answered Me! appeared first on ab.

]]>
Debug Your GameLift Game Server Like a Pro https://alexandrebruffa.com/debug-your-gamelift-game-server-like-a-pro/ Thu, 01 Feb 2024 02:39:56 +0000 https://alexandrebruffa.com/?p=1886 Based on your feedbacks and comments, I show you how to debug your GameLift game server!

The post Debug Your GameLift Game Server Like a Pro appeared first on ab.

]]>
This article was initially published on my Medium Page.

Lately, I have published a series of articles and videos about creating a real-time multiplayer game with Unity3D and Amazon GameLift. The feedback I received about them had been outstanding: a lot of developers downloaded my source code and made their own projects and games using Amazon services.

I received many messages and e-mails asking me for help as well. Let’s be honest: the architecture of a real-time multiplayer game that I always suggest is simple but contains a lot of distinct elements working together like the cogs in a well-oiled machine. A simple mistake and the whole architecture will fail. Furthermore, GameLift can sometimes be unfriendly; I personally had some hard times when trying to find the cause of an error or bug.

In this post, I will explore the common errors people have experienced and how to debug a GameLift game server.

Do you prefer watching a video instead of reading? Here you have:

5 Common Errors To Avoid

This is the architecture of a real-time multiplayer game I always suggest in my videos and articles:

And those are the 5 common mistakes related to the architecture I could identify:

1. AWS SDK for .NET

Numerous people asking me for help had trouble connecting to the Lambda function from Unity. Remember that Unity uses .NET Standard 2.1, and the Amazon documentation recommends downloading the AWS SDK for .NET here for Unity. If you download the wrong version or download it from elsewhere, some Amazon services won’t work correctly, including the Lambda calls.

Unity project settings

2. Multiple Unity Desktop Clients

In my code, I have included a mechanism to avoid consuming the game server resources if the users minimize the application using the Unity functions OnApplicationFocus and OnApplicationPause. Some of you were trying to launch multiple Unity desktop clients and experienced server disconnections in the out-of-focus clients. In this case, please comment both functions or add a conditional compilation for the Unity editor in the AppController class.

3. Client Proxy / Firewall / VPN

The connection between the Unity client and the game server is established thanks to the TCP and UDP networking. Ensure you don’t have any software or system that could block your TCP and UDP ports, like a proxy, firewall, or VPN.

4. Memory Provisioning for Lambda

I have been told that for the first connection after a long time to the Lambda function, an error is returned, and the player can not join the game. This is totally “normal”: this phenomenon is known as a cold start.

According to the cloud experts PluralSight, “A cold start occurs when an AWS Lambda function is invoked after not being used for an extended period of time, resulting in increased invocation latency.”. A Lambda function has a default timeout of 3 seconds; an error is returned if the execution time exceeds the function timeout.

To solve this slow invocation issue, Amazon recommends over-provisioning your Lambda function memory instead of the timeout to avoid unexpected costs.

Lambda function configuration

5. GameLift Launch Path

Before creating your GameLift fleet, you need first to upload to GameLift a compressed archive (zip file) containing your Realtime script and dependencies. During the fleet creation, you will be asked for the launch path, in other words, the path of your Javascript code file within the zip file. For example, if you have no dependencies and have compressed the Javascript file directly, the path will be file.js. If you have compressed a folder containing your Javascript file and dependencies, the path will be folder/file.js.

Launch path during fleet creation

if you want more insights about the Realtime script, please check my post about it:

Debugging a GameLift Game Server

Suppose that your Unity client runs great, and your Lambda function is called correctly, but a new game session can not be created, probably due to an error in GameLift. The first thing you must check is whether your game server is running correctly, thanks to the GameLift events and metrics.

Events & Metrics

In the GameLift console, click on your fleet and go to the Events section. This section collects all the log entries describing an event that involves GameLift resources. The GameLift documentation says the following: “In addition to tracking activity, event codes and messages can provide additional information for troubleshooting and debugging problems.”

Events section

If your fleet is running correctly, you should see the following main events showing up in this specific order: FLEET_CREATED, FLEET_STATE_VALIDATING, FLEET_STATE_ACTIVATING, FLEET_STATE_ACTIVE, FLEET_SCALING_EVENT.

Fleet creation events flow

If you see critical messages like SERVER_PROCESS_TERMINATED_UNHEALTHY during the fleet creation, something may be wrong with either the launch path (see previous section) or your Realtime script (wrong syntax or broken dependencies).

The last message of the successful fleet creation is a scaling message, meaning that your fleet has automatically scaled up, launching a new EC2 instance. If you go to the Metrics section, you can visualize it:

Your game server is running correctly!

Game Session Logs

Now, suppose that your game server is running correctly: your fleet has scaled up, and no critical messages have shown up during the fleet creation. You are able to execute multiple Unity clients at the same time, and the multiplayer feature works great. However, in some cases, you notice that for some actions you perform in the Unity client, your game server does not have the expected behavior and can even crash. Something is failing in your Realtime script, and you want to check the value of certain variables at a precise moment in time.

There is a simple workaround: you can write into the game session logs and then access them to see what happened.

Writing into the game session logs

Do you remember my previous article about talking with NPCs?

I will add a few lines of code in the Realtime script: when a player starts to talk with an NPC, I will write information into the game session logs. According to the GameLift documentation, there are 6 levels of server log messages; let’s try with 3 of them: info, warning, and error.

We have written into the game session logs; now, let’s access them!

Accessing the game session logs

This part is a little bit tricky. As described in the GameLift documentation, when a game session finishes, the related logs are stored in an S3 bucket. There is no simple way to access those logs; the only way to achieve it is by using the GetGameSessionLogUrl API call to get the location of the logs. I will implement the API call in a Lambda function. I’m a Python guy so I will do it with Python, but it’s up to you to use your favorite language!

Remember that Lambda includes boto3, the official AWS SDK for Python, perfect! Checking the documentation of the boto3 function get_game_session_log_url, we can figure out that the function requires a parameter called GameSessionId, described as “A unique identifier for the game session to get logs for.”. There is a slight confusion with the boto3 documentation and, more generally, with the whole Amazon documentation: we need the game session ARN, not the game session ID.

Game session ID and ARN

Building the Lambda function

Now we can write the function:

Before executing the function, we need to give the Lambda function the necessary permissions to access the game session logs. Go to the Lambda function role and add the following policy:

Reading the logs

Now, let’s execute the function! The answer will return a pre-signed URL of the location of the logs for the specific game session:

Note that a pre-signed URL is temporary: in this particular case, the URL is valid for 15 minutes after the request. Visit the URL with your favorite internet browser and download the logs. Our messages can be visualized!

game session log file

Final Thoughts

Thanks for reading this post until the end! I really hope it helped you troubleshoot your real-time multiplayer game and understand more deeply how the game session logs work.

If you have any feedback or questions, feel free to reach out to me on my social networks:

🎬 YouTube Ⓜ Medium 🌐 Website

See you in the next post!

The post Debug Your GameLift Game Server Like a Pro appeared first on ab.

]]>
Enhance Your Real-time Multiplayer Game with Generative AI (Bedrock)! https://alexandrebruffa.com/enhance-your-real-time-multiplayer-game-with-generative-ai-bedrock/ Fri, 12 Jan 2024 03:25:07 +0000 https://alexandrebruffa.com/?p=1864 Can an NPC be smart? In this post, I show how to enhance a real-time multiplayer game with AI.

The post Enhance Your Real-time Multiplayer Game with Generative AI (Bedrock)! appeared first on ab.

]]>
This article was initially published on my Medium Page.

Can an NPC be smart? What about having a real conversation with an NPC? You may have watched those incredible videos of gamers talking with AI NPCs. Can it be done with Unity3D and Amazon services? Let’s see!

Check my video to learn how to do it:

Preamble

Lately, I have published a series of articles and videos about building a real-time multiplayer game with Unity3D and Amazon GameLift.

I also entered the AI field and produced content about integrating Unity3D and AI services: ChatGPT, Dall-E, and Amazon Bedrock.

On my video about Amazon Bedrock, a clever follower left this comment:

What an outstanding idea! Technically, it would be a perfect mix between my work about Amazon GameLift and the one about Bedrock. Thanks for the idea, bro; let’s do it!

About NPCs

A non-player character (NPC), as its name indicates, is a character that is not controlled by a player but can eventually interact with the real players of a game. Therefore, every action or decision taken by the NPC is server-managed. The flow is the following:

  1. A player interacts with an NPC; the player notifies the game server.
  2. The game server processes the information and eventually connects to other services (Database, AI, etc. )
  3. The game server sends an answer to all the players, and Unity clients are updated.

General Architecture

The architecture of this project contains 3 main parts:

  1. A simple architecture of a real-time multiplayer game implicating the services Cognito, Lambda, and GameLift.
  2. A Lambda function that calls the generative AI service Amazon Bedrock.
  3. A connection between the GameLift’s game server and the Lambda function.

For the first two parts, please refer to the following articles and videos: Building a Real-Time Multiplayer Game With Unity3D and Amazon GameLift and Generative AI With Amazon Bedrock and Unity3D. This article will focus on how to invoke a Lambda function from a GameLift’s game server.

Accessing AWS Resources From GameLift

We want the game server to access another AWS resource here, Lambda. The classical way to do it would be to create a role with associated policies to allow GameLift to invoke a specific Lambda function. But this is an uncommon case and requires an extra step. The GameLift documentation says you can achieve doing the following:

  1. Set up an IAM service role for Amazon GameLift.
  2. Associate the service role with an Amazon GameLift fleet.
  3. Add code to your game server to assume the service role.

So, why this extra step? Remember that GameLift game servers are actually composed of one or various EC2 instances (fleet); therefore, we must associate a role to the fleet and also to the EC2 instance where the game session is running. After that, we can invoke our Lambda function from the game server.

It’s not so straightforward, so fasten your seatbelt, and let’s start!

The IAM role

The new role we are creating will allow GameLift to access other resources. To do so, we select GameLift as a trusted entity when creating the role.

By default, an AWS-managed policy called GameLiftGameServerGroupPolicy is attached to the role. We create a new policy to allow access to the Lambda function and attach it to the role.

Okay, so we have the role ready; we can attach it to a new GameLift fleet. But don’t create the fleet yet! We need to work on the Realtime script and dependencies first.

The Realtime Script

This is the spicy part. The role we have created is assumed by the GameLift fleet, but as mentioned before, we also need to assume the role from the Realtime script. Realtime servers use Node.js and JavaScript, so we will use the AWS SDK for JavaScript.

For some reason, I could not use the AWS SDK for Javascript version 3; it made my game server crash. I used the AWS SDK for Javascript version 2 instead, and everything worked like a charm. If you could achieve it with version 3, please reach out to me!

First, we need the game server to assume the role we have created. In the init function of the Realtime Script, we call the STS service and assume the role:

Notes:

  • We call the function assumeRole as specified in the STS documentation

As indicated in the STS documentation, the response has the following structure containing credentials:

Thanks to the credentials, we can now call our lambda function:

Notes:

  • We call the Lambda constructor thanks to the credentials returned by STS, as specified in the documentation.
  • We invoke the Lambda function (in my case npcFunction), as specified in the documentation.

To get more details about how the Realtime script works, please refer to this previous article:

The Dependencies

In the previous section, we worked with the AWS SDK for JavaScript in the Realtime script. Small but very important detail: the AWS SDK for JavaScript is not installed on the game server! Good news: we can upload the dependencies along with the Realtime script. Therefore, we will follow those steps:

Install Node.js in your local environment.

First, go to the Node.js from the official website. Select the operating system running on your local machine and install Node. Once installed, open a new terminal (or command prompt) and type “node”. You should be able to enter the Node console:

Install the AWS SDK for Javascript

In a new terminal, go to the folder containing your Realtime script and install the AWS SDK for Javascript version 2 thanks to Node’s package manager, NPM:npm install aws-sdk

Once installed, 3 new items have been created: the package.json and package-lock.json files and the node_modules folder.

Wrap the script and the dependencies

Zip the folder containing the Realtime script and the dependencies (4 files in total), and go to the GameLift console. In the script section, create a new script and select the zip file.

🚨 Houston, we have a problem: our zip file is too big! The reason is the following: AWS SDK for Javascript version 2 is not modular, so we had no choice: we have installed and zipped the whole SDK (12 MB). With the AWS SDK for Javascript version 3, we could have installed only the services we need (STS and Lambda), and this would have resulted in a lightweight zip file (2–3 MB).

Hopefully, another option is available: hosting our zip file in an Amazon S3 bucket. This is our updated architecture:

Create an S3 bucket and a related role

Create a new S3 private bucket and upload the zip file.

In the IAM console, create a new role with GameLift as a trusted entity and attach a policy that allows the private bucket and its content to be read:

Upload the script and the dependencies to GameLift

Come back to the GameLift console! In the script section, create a new script, but this time, select the zip file from S3 and the role we have just created:

GameLift can now access your Realtime script and dependencies during fleet creation through an S3 bucket.

Creating a new Fleet

When creating a new fleet, in the additional details section, indicate the role we have created at the beginning.

You will be asked for the Realtime script. Select the script you have created before, and in the Runtime configuration section, indicate the script’s path. Remember that we have zipped a folder containing the script; therefore, the path will be folder/script, in my case, GameLift/Multiplayer.js.

The Unity Client

The NPC

As I mentioned in other posts, I’m not a modeler or a 3D artist; therefore, I always look for free assets for my projects. The characters I’m using for this project, like the previous ones, are from the website Mixamo. This time, I looked for something different for the NPC and found this great Moai model on free3D.com. OBJ format is compatible with Unity, perfect!

Moai on free3D.com

The events

For this project, I added 4 new events related to the NPC:

  • PLAYER_MEETS_NPC: A player notifies the game server that he wants to interact with the NPC. If the game server allows it, the same event is sent back to all players.
  • PLAYER_TO_NPC: The player can now interact with the NPC; he can send this event along with a message.
  • NPC_TO_PLAYER: The game server sends a message back to the player.
  • PLAYER_LEAVES_NPC: The interaction ends, and all players are notified.

Final Result

This is the final result of one of the characters interacting with Moai; it looks pretty cool!

Closing Thoughts

Weeks ago, I had the opportunity to share my knowledge as a speaker at the AWS UG Peru Conference 2023. One of the attendees asked me: “What is the advantage of using GameLift over another similar service like Photon?”. My answer was the following: using GameLift, YOU build the cloud architecture of your game, and therefore, you can do absolutely what you want. You could, for example, connect your game to an AI service, a database, a notification system, etc.

And that is totally what I meant with this article: accessing AWS Resources from a GameLift game server opens the door to infinite possibilities! The implementation was a little bit complex, but hey, it is totally worth it!

Resources

Here are the resources mentioned in the article:

I also used free Mixamo characters and a model from free3D.com.

The post Enhance Your Real-time Multiplayer Game with Generative AI (Bedrock)! appeared first on ab.

]]>
My First Experience as a Speaker in an AWS Conference https://alexandrebruffa.com/my-first-experience-as-a-speaker-in-an-aws-conference/ Thu, 19 Oct 2023 16:30:28 +0000 https://alexandrebruffa.com/?p=1859 I had the incredible opportunity to participate in the AWS UG Peru 2023 Conference as the speaker. I share my experience in this post!

The post My First Experience as a Speaker in an AWS Conference appeared first on ab.

]]>
This article was initially published on my Medium Page.

Last Saturday, I had the opportunity to share my knowledge as a speaker at the AWS UG Peru Conference 2023. It was a wonderful experience; I will share it in this post.

Promotional banner for my talk

An Event Huger Than Expected

When I postulated to be a speaker at this conference, I totally underestimated the event’s magnitude. 4500 registered persons, 2300 attendees, and more than 100 speakers in just one day making it one of the biggest AWS events in Latin America. It was impressive!

4 floors of the PUCP Cultural Center in Lima were full of AWS enthusiasts attending highly diverse talks and participating in activities, workshops, and contests; an El Dorado for any cloud lover!

Speakers from all over the Americas shared their knowledge in various languages. I chose to speak Spanish to feel more comfortable and answer the audience’s questions easily.

My name and picture on the banner of the Nazca conference room
My name and picture on the banner of the Nazca conference room

A Risky Talk

For my talk, I chose to make a live demo of a real-time multiplayer game created with Unity3D and Amazon GameLift. Undoubtedly a bold bet since this live demo required multiple fully operational Unity clients, some Amazon services running on the cloud, and an excellent internet connection. If one of those components did not respond as expected, it would have been a total failure!

Following my fellow AWS CB Diana Alfaro’s wise advice, I recorded the whole demo the day before the conference. In the worst case, I would have shown a video to the audience. Maybe not the ideal scenario, but it would have saved the day.

Hopefully, the internet of the PUCP Cultural Center could handle thousands of simultaneous connections with a high bandwidth; perfect! I could make my demo without experiment any inconvenience.

3 Unity clients running on 2 devices

A Great Audience

I will be honest; for this talk, I was expecting a cloud veterans audience, but the title of my talk attracted the curiosity of young people interested in video game creation, and the result was awesome! I’m aware that the content I’m producing through my posts and videos may be uncommon, and I was so thrilled that so many people came to see my talk!

The spectators paid a lot of attention and asked me questions about GameLift, Unity, and game development in general. A lucky guy in the first row could even participate in the demo: I let him play with one of the Unity clients running on a mobile device while everybody could see it on the projector screen.

Overview of the audience
My family also came to see me ❤

Final Thoughts

It was an incredible experience, and I hope to be part of the AWS UG Peru Conference next year as a speaker and as a member of the organization’s staff.

My talk was not recorded, but I created a video summarizing the Q&A section.

The post My First Experience as a Speaker in an AWS Conference appeared first on ab.

]]>
Unity3D + Amazon GameLift: Focus on the Realtime Script https://alexandrebruffa.com/unity3d-amazon-gamelift-focus-on-the-realtime-script/ Mon, 18 Sep 2023 18:28:38 +0000 https://alexandrebruffa.com/?p=1772 In this article, I explain in detail how the Realtime Script works providing an example of implementation.

The post Unity3D + Amazon GameLift: Focus on the Realtime Script appeared first on ab.

]]>
This article was initially published on my Medium Page.

In a previous article, I showed how to build an entire real-time multiplayer game with Amazon GameLift and Unity3D. The process implicates creating game sessions and player sessions with Lambda, guest access to the services with Cognito, and a game server with GameLift.

We could also find out that the game server’s behavior is defined by a script written in Javascript: the Realtime Script. This article will detail how this script works and how to create game server events.

You can also check out the video version of this blog post:

Overview of The Realtime Script

The Realtime Script is a collection of callback functions the game server calls during its lifetime. In other words, we can implement custom behavior for each of these functions. All the callback functions are described in the GameLift documentation; here are the main ones:

  • onStartGameSession(): Called when a new game session is started. In the callback function, we can store relevant information as the game server start time.
  • onPlayerAccepted(): Called when a player is accepted into the game. In the callback function, we can notify the other players that a new player has just joined the game.
  • onPlayerDisconnect(): Called when a player has left or been forcibly terminated. In the same way, we can notify the other players that the player disconnected in the callback function.
  • onMessage(): Called when a player sends a message to the server (i.e., action performed, position, etc.). In the callback function, we can send the new data to the other players.

Furthermore, the game session provides interesting functions such as:

  • getPlayers(): Retrieves a list of players currently connected to the game session.
  • newTextGameMessage(): Creates a new message containing text.
  • sendReliableMessage(): Sends a message to a player.
  • processEnding(): Terminates the game server.

All the game session functions are available in the GameLift documentation.

Creating a Game Server Event

In my previous article, I provided a very basic script making the game server act as a simple “dispatcher”. The game server notifies the players if someone joins or disconnects and resends a message sent by a player to the other players (i.e., action, life update, etc. ).

This time, we will create a non-related player event: a meteorite will fall on the map from time to time. No matter how many players are on the map or what they are doing, this event is 100% managed by the game server.

Our script contains a loop function used to check if the game session should be ended. We will integrate our new server event in the loop function:

We modify the script, adding the new feature in the loop function:

Notes:

You can find the entire code in the resources section of this article ⬇

The Unity Client

In the Unity client, we implement the new event sent by the game server with a countdown and cool VFXs:

It looks awesome! For the meteorite and the explosion, I used assets from the Voxel Arsenal assets. I managed the explosion force field with a Sphere Collider in trigger mode:

Explosion force field

I used the OnTriggerEnter and the CompareTag functions to detect this force on the player. Then, I normalized the differential vector and applied a ratio to it. I found that a ratio of 200 creates a cool visual effect. Finally, I applied the AddForce function to the player’s Rigidbody:

Final Thoughts

At first glance, the Realtime Script can be complex and challenging to understand, but once you master it, you have total control over the game server’s behavior and can do absolutely what you want! Meteorites, snow, rain, sunshine, real-time updating environment, non-player characters, etc. The only limit is your imagination!

In the resources section, I provide a Unity package of the game I showed in the demo. The meteorite and explosion assets are not included because of the license type.

You are free to use all the resources I provided in this article. Please ping me if you use them to build your game; I would be delighted to see the result!

Resources

Here are all the resources mentioned in the article:

For the demo, I’m using the Voxel Arsenal assets.

The post Unity3D + Amazon GameLift: Focus on the Realtime Script appeared first on ab.

]]>
Building a Real-Time Multiplayer Game With Unity3D and GameLift https://alexandrebruffa.com/building-a-real-time-multiplayer-game-with-unity3d-and-gamelift/ Tue, 18 Jul 2023 19:28:27 +0000 https://alexandrebruffa.com/?p=1757 In this article, I explain step by step how to build a real-time multiplayer game with Unity3D and Amazon GameLift.

The post Building a Real-Time Multiplayer Game With Unity3D and GameLift appeared first on ab.

]]>
This article was initially published on my Medium Page.

You are talented with Unity and game creation in general, and it’s time for you to move up a gear by creating a real-time multiplayer game, but you have no idea how to do it, and you know very little about cloud computing. Don’t worry, we will see how to do it step by step.

This article is based on the excellent tutorial by Chris Blackwell. Please take a look at it!

Disclaimer: This is not an article about game design. I will focus on the technical aspect of creating a real-time multiplayer game.

Here is the final result:

Preamble

When one starts to work on a real-time multiplayer game, a lot of questions come to mind:

How can I match the players in one or multiple rooms (game sessions)? How can my players communicate together? How can I achieve to have a very low latency for my game?

Representation of a game server

Short answer: Amazon GameLift.

Amazon GameLift is a managed service for multiplayer games with the following characteristics:

  • It deploys a set of EC2 instances (fleet) for you, so you won’t have to worry about mounting EC2 instances, securing them, etc.
  • It operates the EC2 instances for you: you will never connect to the instances nor install anything. A game server is automatically set up when you run a new GameLift fleet.
  • It scales the service for you. No matter how many users your game is played by, GameLift automatically scales up or down according to the demand.
  • It connects the players through the game server, creating game and player sessions.

The Architecture

We can achieve building a real-time multiplayer game with few components. Here is our architecture:

This is how it works:

  • The client (Unity application on a mobile device) joins the game by calling a Lambda function.
  • The Lambda function indicates GameLift to create a new game session if no game session is available and to create a new player session. The function returns the necessary information to connect to the game server (IP, port, credentials, etc.).
  • The client establishes a new connection with the game server, and the user is ready to play.

Lambda

The Lambda function (Python 3.10) will work directly with GameLift and will have the following behavior:

The origin tutorial exposed a Node.js function, but since I’m a Python guy, I rewrote the function in Python. You can find the whole function in the last section of this article.

Also, the Lambda function needs the following permissions to access the GameLift service: CreateGameSessionDescribeGameSessionDetailsCreatePlayerSession, and SearchGameSessions. You can create a new manage IAM policy with those permissions and add it to the Lambda function role.

You can find the policy at the end of this article.

Cognito

In previous articles of mine, I performed user authentication through IAM users or Cognito User Pools. We don’t need user authentication this time: we will use guest access to avoid any restrictions; everyone who downloads our game can play immediately.

In this opportunity, the Unity client invokes a Lambda function, and the best way to give access to AWS resources without credentials (guest access) is through a Cognito Identity Pool. A Cognito Identity Pool allows both authenticated and guest users, so if you want to enable some authentication feature in the future (for example, linking users’ Facebook or Twitter accounts to save game progress), you could do it easily.

Creating a Cognito Identity Pool with guest access

We must attach the necessary permissions (Lambda Invoke) to the Identity Pool we created. You can edit the guest role associated with the Identity Pool and create a new policy to achieve it. You can find the policy at the end of this article.

GameLift

Before running a new GameLift fleet, we need to elaborate a script that will be attached to the fleet. The first step is defining the behavior of the game server. This is how a game session will be managed:

Based on the above flow, we can write and upload a JavaScript script to GameLift. Then, we can create a new fleet and include our script during the fleet creation. Check the end of this article for the script.

GameLift Script
GameLift Fleet using the script

Before configuring the auto-scaling of your fleet, you need first set limits for it. Imagine that your game has an unexpected success; you don’t want to run out of budget in a few days! In the scaling capacity section, you can set a minimum and a maximum of instances for your fleet:

Scaling options in Amazon GameLift

Now, let’s create an auto-scaling policy. An EC2 instance usually takes one or two minutes to start and can inconvenience the players joining the game. Furthermore, it’s better to start an instance preventively before reaching the player limit:

Auto-scaling policy in Amazon GameLift

You can see how many available instances you have for your fleet here and request a limit increase here if necessary. In my case, I had only one available instance for my fleet (c4.large); the support team gently increased the limit to 15.

Unity

The plugins

We will integrate the Unity client directly with a Lambda function, so we need some AWS classes and functions. In the original tutorial, Chris Blackwell recommends using the AWS Mobile SDK for Unity to achieve it. Unfortunately, the AWS Mobile SDK for Unity has been deprecated, and Amazon recommends now using the AWS SDK for .NET. Let’s see.

In previous articles, I recommended downloading the AWS packages on NuGet.org, the official package manager for .NET. Although it could work, the Amazon documentation recommends doing it here for Unity. Since Unity uses .NET Standard 2.1, download and unzips the .NET Standard 2.0 zip file (it also supports 2.1).

Then, copy the following DLL files to the Plugins folder of your Unity project: AWSSDK.Core, AWSSDK.Lambda, AWSSDK.CognitoIdentity, and AWSSDK.SecurityToken. The Lambda function call is asynchronous, so you also need the Microsoft AsyncInterfaces package.

Unity project settings

Then, we will need an extra plugin to connect to the game server: the GameLift Realtime Client SDK. Go to the GameLift page and download it. Once unzipped, you can figure out this is a whole .NET project. Open the project with Visual Studio and compile it. Five DLL files will be generated: GameLiftRealtimeClientSdkNet45.dllGoogle.Protobuf.dlllog4net.dllSuperSocket.ClientEngine.dll, and WebSocket4Net.dll. Move those DLL files to the Plugins folder of your Unity project.

Plugins folder

Characters and animations

Since I’m not a designer or a 3D modeler, I had to look for a third party who could provide the animations I needed for my Unity project. I found out that Mixamo has a lot of fantastic free characters and animations.

I tried it by downloading the character Remy as an FBX file for Unity and moved it to my Unity project.

Character downloading

It looks good! After that, I downloaded multiple animations to give life to Remy. The animations should be downloaded without skin. We indicate the animation in the editor to use the character’s skin we previously downloaded.

Animation downloading

Then I defined the animations flow inside a new Animator. It looks great!

Animations flow

Building the App

In this section, I will give you some hints about how I built the Unity app. Don’t worry about the code and the project hierarchy! The entire Unity project is available for download at the end of this article.

Character movements

Our character can run, walk back, and rotate. We use the function OnAnimatorMove to have total control over it.

Sending data to the game server

When one starts to build the client, the following question comes to mind:

When should I send data to the game server?

The game server needs to be aware of all actions a player performs to inform the other players, but sending too much information would saturate the game server and burn resources. Remember: don’t send data every frame; otherwise, your game server will die!

I found that data can be sent in those cases: when the player starts and ends any movement (running and walking back), any rotation (turning left and right), and any action (punching, etc.).

If you have played online, you may have experienced the famous “lag,” meaning that what you see is delayed over reality. That can be caused by a slow internet connection or a high-latency game server, but it can also mean the server data must be updated. That is why this is important to “fix” the data occasionally, sending the server updated data. I decided to do it every second in the movement functions.

In red, the player sends updated data to the server.

Player data

For the basic game I made, I used the following data:

Note that the PlayerCoord class has four components: I used this for position or rotation (quaternions).

Costs

Let’s consider the following case: you published a successful FPS game with the following characteristics:

  • Every game session has a limit of 30 players.
  • In the peak hour, your game receives approximately 40 concurrent connections from players located in the United States.
  • Your GameLift fleet uses c4.large Linux Spot instances, and each instance handles a single game server.

Based on the Steam statistics, we can speculate that roughly 35% of the day, a single game server is used versus two games servers in the peak hour:

In red, the number of game servers used

The pricing sheet of Amazon GameLift indicates that a c4.large Linux Spot instance costs $0.07848 per hour, $56.51 per month. We can deduce the following calculation:

Total cost per month = $56.51 x 1.35 ≈ $76.28

GameLift is expensive, but hey, it is worth it! You save time and money instead of implementing your solution and possibly needing help with scaling issues. If you are using GameLift for your game, you should find a way to monetize it (ads, in-app purchases, etc.).

Here are the other costs:

  • Unity: As always, Unity is free. The personal plan is a good fit unless you need specific advanced features for your game.
  • Cognito: There is no charge for Cognito Identity Pools. Awesome!
  • Lambda: The Lambda function is called only once when a new player joins the game. Estimating an exact number of monthly connections is complex, but let’s say 100,000. With 128 MB allocated memory, and each request duration of 500 ms, the cost would be $0.12.

Total: Our real-time multiplayer game bill would be approximately $77 per month.

Final Thoughts

Building a real-time multiplayer game is relatively easy! Amazon GameLift provides all the infrastructure required for this type of application and allows game developers to focus on the visual part.

You are free to use all the resources I provided in this article. Please ping me if you use them to build your game; I would be delighted to see the result!

Resources

Here are all the resources mentioned in the article:

I also used free Mixamo characters and PolyHeaven-free textures.

The post Building a Real-Time Multiplayer Game With Unity3D and GameLift appeared first on ab.

]]>