AWS Logo
Menu
Blessings come from curses. Bear this in mind. Be with your creed.

Blessings come from curses. Bear this in mind. Be with your creed.

Web-base Multi-player Real-time Game Application with Amazon Q Developer

Published Jan 14, 2025
Last Modified Jan 15, 2025

Introduction

Blessings come from curses. Bear this in mind. Be with your creed.
One day, a grand mansion appeared out of nowhere—the residence of the enigmatic Lady Lobelia. In this place, you must fight off enemies, survive, and unravel its mysteries. With the blessings of four guardian flowers by your side, endure the intoxicating scent of roses and the lingering smell of blood as you strive to survive in this eerie mansion. Remember. Be with your creed.
The mansion of lobellia logo page
logo

Background

Do you enjoy Dungeons & Dragons? Personally, I’ve never had the chance to play it myself, but I’ve spent plenty of time enjoying Table-Top Role Playing Games (TTRPGs) using systems like Call of Cthulhu. For people like me, who love creating original characters, it’s not uncommon to dream of designing a custom set of rules to run their own unique games, beyond established systems like Dungeons & Dragons or Call of Cthulhu. I’ve always been one of those dreamers.
Everyone has different schedules and skill levels when it comes to playing games. However, simply creating and role-playing original characters together doesn’t have to be complicated. Instead of arranging a full-on game session, players can role-play casually through a Mastodon server by creating accounts for their characters. Then, when time permits, the actual gameplay—like battling monsters—can take place through a dedicated website. This concept merges a social media platform with a web-based game, creating an online game community that blends both worlds seamlessly.
The Mansion of Lobellia is an idea that I’ve been mulling over for quite some time, thinking about both its story and system. This is the first time I’ve had the chance to build a prototype, and it feels surreal. If I had discovered this hackathon in November instead of December 20th, our team could’ve delivered a project of even higher quality. It’s a bit of a bittersweet feeling 🥲.

Contributors

Imgyeong Lee: Lead the overall game development. Almost everything. (Except for OpenAI Integration)
Hla Htun: OpenAI Integration with Lambda function + AWS API Gateway, Battle System Mechanism

Game Concept and Mechanics

Story

The head of the house, Lobellia, abandoned her humanity and became a monster for the revival of her family. She is waiting for the characters on the 5th floor. Your goal is to clear the monsters starting from the 1st floor, defeat the "Guardians" who protect each floor, and eventually reach the 5th floor to defeat Lobellia. The reason the characters share this common goal of defeating Lobellia is that rumors say if she is defeated, the mysterious mansion will grant one wish. What that wish will be is up to you.

Character Creation

The game genre is a turn-based RPG. Players can create one character and choose one of the four flower blessings to shape their character. The blessing chosen will affect the number of available skills and slightly alter the character's stat modifications. The details are as follows.

Seven Stats

  • Attack: Represents the character's attack power. A higher stat means greater damage dealt to opponents.
  • Defense: Represents the character's defense (%). A higher stat reduces the damage received.
  • HP: Represents the character's health points. A higher stat increases the maximum HP.
  • Cost: Represents the character's resource for using skills.
  • Crit: Represents the critical hit chance. A higher stat increases the probability of landing a critical hit.
  • Dodge: Represents the dodge chance. A higher stat increases the likelihood of evading enemy attacks.
  • Speed: Represents the character’s speed. A higher stat ensures the character takes their action first.

Blessings

Blessing of Gladiolus
Strength and Pride.
Those blessed by Gladiolus possess great physical strength and a distinct sense of self-esteem. They tend to pursue enjoyment above all else. Characters with this blessing receive additional bonuses to HP and Defense but incur penalties to Attack and Dodge.
Blessing of Saintpaulia
Knowledge and Loyalty.
Those blessed by Saintpaulia love to acquire knowledge and are highly curious. They tend to pursue order in the end. Characters with this blessing receive additional bonuses to HP and Cost but incur penalties to Attack and Crit.
Blessing of Cypress
Death and Sorrow.
Those blessed by Cypress are deeply empathetic and composed. They tend to pursue destruction in the end. Characters with this blessing receive additional bonuses to Crit and Attack but incur penalties to HP and Cost.
Blessing of Blackthorn
Freedom and Adventure.
Those blessed by Blackthorn are capricious yet highly adaptable to their environment. They tend to pursue freedom above all else. Characters with this blessing receive additional bonuses to Dodge and Cost but incur penalties to Defense and Crit.

Features

Once you create a character, you can choose a dungeon to create a party, purchase items from the shop, or modify your character's information.

Battle Mechanism

Once a dungeon party is created, an invitation code can be shared to allow others to join the battle. Upon entering the lobby, enemies are randomly generated. The turn order is determined based on the speed attributes of the characters and enemies. The game ends only when all enemies or all characters are defeated. The overall game flow is depicted in the image below.
The game mechanism
mechanism

Tech Stack

💻 Web Framework: Next.js (React) for server-side rendered applications with fast development
⭐️ State Management: Zustand for simple state management
🔒 Authentication: AWS Cognito to verify the user with email
🗳️ Data Fetching: Combination of React Query and Next.js API Routes for efficient data fetching
🗄️ Database: Supabase (PostgreSQL) with Prisma ORM for real-time data subscription
Styling: Tailwind CSS and shadcn/ui components for reusable components to empower the user experience
🤖 AI Integration: OpenAI and AWS Lambda function with AWS API Gateway to get the AI response appropriately
🌃 Image Store: AWS S3 Bucket to store the image on the cloud with no limitation
🔨 Coding AI Assistant Tool: AWS Q Developer

Overall Application Mechanism

tech diagram

Development Journey

First Try

In fact, I have created a similar project before. It's a web-based game called Litania, which I developed mostly on my own over about six months. You can see the screenshots below:
Litania: Battle page
When I did the Litania project, I only used Firebase and Next.js, which are two technologies.
However, I believe that hackathons are all about challenging yourself with new things and aiming for rapid growth, so for this project, I decided to use only technologies I had never used before. Additionally, I made a few changes to the gameplay that was used in Litania. In Litania, the user-controlled the character while the admin controlled the enemies. Also, in Litania, during the user's turn, all users acted at once, and after processing all user actions, the admin's turn would follow. Influenced by other turn-based games, I changed the system so that the turn order is determined based on the character's speed attribute and automated the enemy control by using AI instead of an admin.
At first, I wanted to use AWS Amplify Studio to build the web application and combine it with DynamoDB. However, I couldn’t create custom data structure arrays with them. So, I ended up scrapping everything I had built over two days and starting from scratch.

Setting up the database schema

(I cannot even have all the data schema on one screen)
For this project, I used Supabase as the database instead of Firebase. It was my first time working with Supabase. However, one thing I realized during this project is that when building a real-time web game with a complex mechanism, an SQL-based database may not be the most efficient choice for development. In my personal opinion, using a NoSQL database can significantly accelerate the development of such web applications.
Throughout the process, an AWS Q Developer helped me resolve some of the small mistakes I made related to SQL. Typically, when I explained the issues I was facing (e.g., RLS Policy-related problems), the AWS Q Developer was more than willing to assist me.

Authentication/Authorization

Using AWS Cognito for the first time, I implemented features for user registration, authentication, and management. Since I was working with Next.js, I utilized the AWS Amplify SDK for this implementation. However, I encountered significant challenges while trying to use the getCurrentUser function to implement protected routes. An unexplained error consumed a lot of my time, but I eventually managed to find an edge case related to Next.js in the Amplify Docs, which helped me resolve the issue.
Unlike the times when I used third-party services like Clerk or built simple registration APIs, I was particularly proud of adding a verification process via authentication emails to confirm the validity of users' email addresses.
Below is a code snippet for anyone looking to combine AWS Cognito with Next.js to implement protected routes in the future:
(For setting up your server context)
(For protected routes)

Image Upload API

In the past, I typically spent time building image upload APIs directly through a backend implemented with Node.js. This approach was inefficient since it involved continuously storing images on the server. For this project, I implemented an image upload API using S3 Bucket for the first time.
I had previously attempted to use S3 Bucket to create an image upload API for a personal project but failed. However, with the help of the AWS Q Developer, I was able to implement this functionality very easily this time. Below is the code provided by the AWS Q Developer.
(Setting up your AWS S3 Client)
(/api/image/upload/route.ts)

Implementation of AI for Monster’s Behavior with AWS Lambda Function

One of the most compelling aspects of our project is that the AI directly controls the monsters. To achieve complete automation without requiring an admin to control the enemies, we designed a system where the data of the enemy entities and the participating characters are combined into a BattleState data type. This information is then sent to OpenAI, which determines the actions the enemies should take in the current situation. Based on this response, the web application updates the database accordingly. The task of sending data to OpenAI and receiving responses is handled by an AWS Lambda function integrated with AWS API Gateway.
One of the key challenges during development was determining how to ensure that this Lambda function executes only once.
The Lambda function must trigger exactly once when it becomes the monster's turn. If the data schema is poorly designed, multiple clients subscribing to the same database could result in the situation illustrated in the image below.
wrong version of system design
We wanted to ensure that all clients subscribed to the database would receive updates simultaneously whenever there were changes, while also ensuring that the AWS Lambda function would only trigger once. To address this, we added a separate hostId field to the BattleRoom data schema. This allows the Lambda function to be triggered only by the host client's side when it’s the monster's turn. The updated structure is depicted in the image below.
correct version of system design
Initially, we planned to implement a mechanism where, if the host left the room, another character would randomly become the new host. However, due to time constraints, we had to skip this feature. Instead, we ensured that the room would automatically be deleted if all characters left it.

Comparison Using AWS Q Developer vs Just Coding

The project started on December 20th, but due to unforeseen circumstances, including my graduate school interviews, we only had about three weeks to complete it. This limited timeframe left us unable to conduct more extensive testing, which is something I (Imgyeong Lee) regret. Initially, I was developing alone until the end of December, but realizing that even an MVP seemed unattainable, I reached out to my teammate, Hla Htun, for help. However, since he also had a part-time job, we couldn’t dedicate as much time to the project as we wanted.
To make matters more challenging, aside from Next.js and Prisma, all other technologies used in this project were completely new to us, which slowed down the development process even further.
Despite these challenges, we take immense pride in how much we were able to accomplish with such a tight schedule and new technologies. Below is a timeline of a project called Litania, which has a similar mechanism to ours, for comparison.
The Litania project took approximately five months to complete, even though we used a technology comparable to Firebase. In contrast, the Mansion of Lobellia project was completed in just about three weeks, despite both of us being extremely busy and unable to dedicate much time to it. Remarkably, with just one additional week, we could have further enhanced its quality. This represents an impressive 85% reduction in development time compared to the Litania project.
Although this might be because it was our second time developing a multiplayer real-time web-based game application, it is still impressive considering that neither of us had much experience using AWS features. Excluding Next.js and Prisma, every other stack we used was new to us. Moreover, while using AWS Q Developer, there were some errors in the answers (for instance, when I initially tried to use Amplify Studio for development, I was told that custom data schema types could be arrays, which wasn't the case), when implementing standard features with AWS, we were able to get accurate and fast responses.

Conclusion

Thanks to this hackathon, we gained deeper insights into which tech stacks are most efficient for implementing complex web game mechanisms and how to design data effectively. The experience of using AWS Cognito and AWS Lambda functions was especially valuable.
Even after the hackathon judging ended, we are planning to continue this project. We intend to refine the hastily written code, fix errors, and add new skills and features, with the goal of launching it for real use around June-July.
Since we are using OpenAI, we won’t be deploying the project publicly. However, for those interested in running the project in a local environment, please refer to the README file in our GitHub repository!
Also, if you're interested in similar previous projects, feel free to check out the following link:
Litania (Please note that this website is in Korean. The test user's username is Ezra, and the password is atticoc_0720. I turned off permission to update the data just in case.)

Screenshots

Registration form
Registration form
Resources
Character Creation Form
Character creation form
Character Information
Character Information
Store page
Store page
Lobby
Lobby
Battle
Battle

Resources

Vector Images from Noun Project
Pixel art images from DALL-E AI
Logo Designed by Imgyeong Lee, Edited by Haein Lee
Other images from Imgyeong Lee 🤞

Contacts

Comments