ab https://alexandrebruffa.com/ Tue, 05 Nov 2024 14:21:38 +0000 en-US hourly 1 https://wordpress.org/?v=6.7.1 https://alexandrebruffa.com/wp-content/uploads/2022/04/cropped-cropped-elior-favicon-270x270-1-32x32.png ab https://alexandrebruffa.com/ 32 32 Reading JWTs in Unity https://alexandrebruffa.com/reading-jwts-in-unity/ Tue, 05 Nov 2024 12:19:55 +0000 https://alexandrebruffa.com/?p=1975 In this post, we will learn how to perform base64 decoding on Cognito tokens in Unity.

The post Reading JWTs in Unity appeared first on ab.

]]>
Performing Base64 Decoding on Cognito Tokens in Unity.

You may prefer watching a video instead of reading, here it is!

Weeks ago, I published a course on Udemy explaining how Unity and Amazon Cognito can work together. In one of the lectures of the course, I mentioned that reading Cognito tokens in Unity brings some advantages: since important information is contained in those tokens, we can get rid of a Cognito API call to retrieve user information. The counterpart would be that it could be somehow challenging to decode JWTs in Unity. But we love challenges so let’s do it!

If you want to know how to use Amazon Cognito as a user directory or if you want to connect Unity with Amazon services such as Lambda, S3, or DynamoDB, I recommend you check my new course on Udemy:

My new course on Udemy

That said, let’s start!

Cognito works with JSON web tokens (or JWTs). After logging in with a Cognito user, Cognito sends 3 JSON web tokens to the Unity client: access, ID and refresh tokens. Those tokens contain important information that can be extracted and used by the Unity client. In this post, we will focus on the ID token, since it contains interesting information about the user.

Cognito tokens

In order to create those tokens, Cognito first converts the original JSON data into binary data and then into text data thanks to the base64 algorithm. Just a side comment about a common mistake: JSON web tokens are NOT encrypted; they are encoded, meaning that they can be easily decoded on the client side. Plenty of online tools such as jwt.io offer JWT decoding.

JWT encoding process

To decode JSON web tokens in Unity, we are going to do the reverse process: convert the text data into binary data and then into a string thanks to UTF-8. We could also use ASCII but I recommend using UTF-8 to handle a large range of characters: Russian, Chinese, etc.

JWT decoding process

Now, let’s talk about the padding characters. When it comes to base64 decoding, the length of the data text must be a multiple of four. I won’t enter into details because that’s something complex with octets and sextets but anyway! If the length of the data text is not a multiple of four, we must add the necessary padding characters at the end. The padding character in base64 is always the equals sign (=). 

Base64 padding characters

And here is the code:

Notes:

  • JWTs consist of three parts separated by dots: header, payload, and signature. So, we will split the ID token thanks to the Split function (9) and we ensure that it contains three parts (11). Otherwise, this is not a valid token. 
  • The information we need is contained in the payload, so we isolate it (13).
  • We calculate how many padding characters we will add at the end of the payload. So first, we calculate the remainder of the division by four using the modulo operator (14).
  • If the remainder is equal to zero, we can decode the text. Otherwise, we calculate how many characters are missing (18) and we add the padding characters at the end of the payload (19). 
  • We convert the data into binary (22) thanks to the FromBase64String function and into string thanks to the GetString function (23).
  • The resulting string is a JSON string, so we convert it into an object (25) and we show it on screen (26).

That’s it! This post was a bit more technical than other posts of mine but you can now decode Cognito tokens and more generally JSON web tokens in Unity. 

Thanks for reading until the end! If you have any feedback or suggestions, please reach out to me on my social networks:

🌳 Alexandre Bruffa

The post Reading JWTs in Unity appeared first on ab.

]]>
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.

]]>
Generative AI With Amazon Bedrock and Unity3D https://alexandrebruffa.com/generative-ai-with-amazon-bedrock-and-unity3d/ Thu, 19 Oct 2023 16:08:19 +0000 https://alexandrebruffa.com/?p=1855 Have you heard about Bedrock, the new generative AI service from Amazon? Let's build a cool AI chat with Unity3D and Amazon Bedrock!

The post Generative AI With Amazon Bedrock and Unity3D appeared first on ab.

]]>
A few days ago, Amazon made a big announcement: the service Bedrock was finally released.

If you missed the news, here it is: Amazon decided to enter massively into the generative AI field and invested in the company Anthropic for $4 billion in order to compete with popular AI services like ChatGPT, Dall-E, MidJourney, etc. The first proposal of Amazon is Bedrock, a fully managed AI service that offers multiple foundational models such as Claude, Jurassic, and Stable Diffusion XL, among others.

In my previous articles, I created Unity3D applications communicating with ChatGPT and Dall-E. Let’s do the same with Bedrock!

Do you prefer something more interactive instead of reading? Check my video!

General Architecture

Here is the general architecture of our application:

We use 3 Amazon services:

  • API Gateway to create, expose, and consume endpoints.
  • Lambda to receive the client’s requests and communicate with Bedrock.
  • Bedrock to generate answers based on the client’s prompts.

If you want to get further adding a login mechanism with Cognito, please refer to my previous article:

Bedrock

First, we have to enable the foundational models we want to use. By default, all the models are disabled. Go to the Bedrock console and enable the models you will use in the model access section. If you have an updated payment method, activating the models only takes a few minutes.

Model access section in the Bedrock console

If you don’t enable the models in the Bedrock console, you will receive this error in Lambda:

An error occurred (AccessDeniedException) when calling the InvokeModel operation: Your account is not authorized to invoke this API operation.

Lambda, Boto3 and Bedrock

If you follow my work, you know I’m a Python guy, so I will use the Python SDK for AWS, Boto3. Good news: Bedrock is available on Boto3; bad news: Lambda runs an old version of Boto3 in which Bedrock does not exist yet.

💡 Here is a workaround: creating a new Lambda layer with an up-to-date version of Boto3. This is how to do it:

  1. In PyCharm, create a new project and install boto3 in a new virtual environment. Boto3 and all the dependencies will be installed.
PyCharm project

2. Go to the venv folder of your project and copy the lib folder into a new folder called python. Then, zip it.

venv folder

3. Go to the Layers section of the Lambda console and create a new layer. Upload the zip file we have created before and choose the same Python version as your local Python virtual environment for the runtime.

Creating a new Layer

The Lambda Functions

We create 2 Lambda functions, one for text generation and the other one for image generation, both with the same version as previously for the runtime (In my case, Python 3.9), and we add the layer we have created before.

Adding a new layer to the Lambda function

The text generation function

For the text generation, I use the Claude model and implement it as described in the Amazon documentation.

The image generation function

For the image generation, I use the Stable Diffusion XL model and implement it, as described in the Amazon documentation.

Note that the model IDs can be found in the Bedrock documentation.

The Lambda Policy

In order to allow Lambda to invoke a Bedrock model, we create a new managed policy and add it to the Lambda functions roles:

API Gateway

In the API Gateway console, we create a new REST API with 2 resources: image and text. Each resource has a post method integrating with the Lambda functions we have created before.

API resources

When deploying the API, you will be asked to create a new stage. After the creation of the stage, the final endpoint will be shown. You will have to use this URL in the Unity client to perform the request.

API stages

The Unity Client

the Unity client allows the user to send a message to generate a text or an image as an answer:

Handling the request

First, we need to create serializable classes to embed the sending and receiving data:

Sending a request in Unity is an asynchronous process. Therefore, we create a coroutine that sends the request to the server:

Dealing with the generated image

If we ask for an image generation, the result sent by Bedrock is a base64 image. To show it on the Unity UI, we must convert it into bytes and create a Texture2D. Then, we assign the texture to the RawImage component of the UI.

Result

Here is the result with text and image generations:

Costs

Let’s check with the AWS Calculator and the Bedrock pricing sheet what our system cost would be for a very pessimistic scenario: you love the app, and you perform 2,000 requests a month. 1,000 for text generation with the Claude model and 1,000 for image generation with Stable Diffusion XL.

  • API Gateway: With 2,000 requests to our REST API, the monthly cost is 0,01 USD
  • Lambda: With 2,000 requests with an average time of 5 seconds and 512 MB of memory allocation, the monthly cost is 0.08 USD.
  • Bedrock: 1,000 text generations by month with a maximum of 300 output tokens and 20 input tokens per request would result, in the worst case, in $0.2204 + $9.804. 1,000 image generations would give us a bill of $18.

Total: The total bill for our system would be approximately 28 USD monthly. It’s quite affordable!

Final Thoughts

Using Bedrock is very intuitive, and integrating it with other Amazon services is absolutely straightforward. The fact that Bedrock is an in-house product makes the integration easier: there is no need for API keys or external requests to make it work, resulting in greater performance and security.

Every code of this article has been tested using Unity 2021.3.3 and Visual Studio Community 2022 for Mac. The mobile device I used to run the Unity app is a Galaxy Tab A7 Lite with Android 11.

Thanks for reading until the end!

Resources

Here is the resource mentioned in the article:

The post Generative AI With Amazon Bedrock and Unity3D appeared first on ab.

]]>
AWS UG Perú Conf 2023 https://alexandrebruffa.com/aws-ug-peru-conf-2023/ Mon, 18 Sep 2023 18:44:00 +0000 https://alexandrebruffa.com/?p=1780 I'm very thrilled to announce that I will be speaking at AWS UG Perú Conf 2023; see you there!

The post AWS UG Perú Conf 2023 appeared first on ab.

]]>
I’m very thrilled to announce that I have been selected to speak at AWS UG Perú Conf 2023. I will make a demo of a real-time multiplayer game created with Amazon GameLift and Unity3D. See you there!

The post AWS UG Perú Conf 2023 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.

]]>
Detecting Unsafe Content With Unity3D and Amazon Rekognition https://alexandrebruffa.com/detecting-unsafe-content-with-unity3d-and-amazon-rekognition/ Wed, 19 Jul 2023 17:31:08 +0000 https://alexandrebruffa.com/?p=1769 Is my profile picture suggestive? In this article, I show how to detect unsafe content thanks to AWS Rekognition and Unity3D.

The post Detecting Unsafe Content With Unity3D and Amazon Rekognition appeared first on ab.

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

If you prefer watching a video instead of reading, here you have:

My Brief Journey on TikTok

Weeks ago, I finally decided to download TikTok. I download the app and create a new account. The first thing I always do just after registering on a social network is upload a profile picture. Strangely, TikTok did not let me do it. I tried two more times the same day, but I had no success. After that, I also tried to add friends and change my username, but still no success. I waited for a couple of days, I reopened the app, and I got this message:

Permanently banned message in Spanish.

I have been permanently banned from TikTok, and I don’t know why! Then I started to think. What did I do wrong? I did not post any publications or messages. I used a valid email to register, entered my real name, and tried to upload a real picture of me. I don’t believe my email and my name are a problem. What about my profile picture? Did TikTok detect it as inappropriate? Is it because I have no hair? 👨🏻‍🦲 How to find it out?

The System I built

Then I remembered that Amazon has a service for unsafe content detection: Rekognition; let’s try it! Additionally, you may remember this previous article of mine where I created a chat in Unity showing images from Dall-E. I will reuse the interface for this article.

This is how it works:

  • The Unity client login thanks to Cognito User Pool.
  • The client uploads then a picture to S3.
  • Finally, the client calls a Lambda function that works directly with Rekognition to define if the picture contains unsafe content.

Amazon Services

➡ About Cognito, I created an authenticated access using a User Pool coupled with an Identity Pool. A policy attached to the authenticated role of the Identity Pool allows users to access S3 (PutObject) and Lambda (InvokeFunction). If you want to know in detail how to do it, please check this previous article of mine:

➡ The S3 Bucket is private, so nobody but the authenticated users can access it. I called it censorimagesbucket.

➡ I wrote the Lambda function in Python:

Notes:

  • I used boto3, the AWS SDK for Python, to connect with Rekognition.
  • I used all the Rekognition’s top-level category moderation labels. My face may be offensive in many ways; we never know.
  • I used Rekognition’s DetectModeration API thanks to the detect_moderation_labels function and the S3Object parameter.
  • I used the very cool Pythonic any function.

Don’t forget to attach to the function’s role a policy allowing access to Rekognition and S3:

Unity

The connection between Unity3D and Amazon services is done through the AWS SDK for .NET, as described in my previous article. However, the function invocation is different this time because we have to send the filename to Lambda. We do it thanks to the Payload parameter.

Result

I performed three tests: one with a picture of Bibi, my daughter’s favorite teddy bear, a picture of a girl wearing a bikini, and a picture of myself.

It’s working great! The only unsafe content (the girl in a bikini) has been filtered successfully, and the following moderation labels have been detected:

The result is very accurate, with high confidence rates.

Conclusion

Apparently, my face is not unsafe content! I still don’t know why I have been permanently banned from TikTok, but thanks to this misadventure, I had the opportunity to discover Amazon Rekognition and realize an implementation with Unity3D.

All ids and tokens shown in this article are fake or expired; if you try to use them, you will not be able to establish any connections.

Every code of this article has been tested using Unity 2021.3.3 and Visual Studio Community 2022 for Mac. The mobile device I used to run the Unity app is a Galaxy Tab A7 Lite with Android 11.

Resources

Here are all the resources mentioned in the article:

The post Detecting Unsafe Content With Unity3D and Amazon Rekognition appeared first on ab.

]]>