About Me Game - Development Writeup
Background
My Church has a Koinonia (opens in a new tab) fellowship after every Sunday service. It’s supposed to be an opportunity for the members to have a talk and to get to know each other better. However, we’re facing a situation where people tend to gather with the people they already know and close with and therefore the goal of this fellowship ended up not being achieved. I was tasked to try to find a solution to this situation and like every normal human being, my solution is to create a web-based game.
Game Concept
The concept of the game is simple:
-
Every participant submits their name and a unique and fun description about themselves
-
After everyone submit their description, each of them will be given several descriptions of random members
-
They have to guess the name of the people that are described by the descriptions that they got
-
If they manage to guess all names correctly, they’ve completed the challenge! The fastest to complete the challenge wins
The idea is that the participants will interact with each other during the period of figuring out the descriptions’ owners and the description will act as a conversational starter between them. “About Me” is just a name that I came up with because I have the creativity of a table.
Tech Stack
I didn’t put too much thought into the tech stack of this project. I just used what I’m familiar with and what makes sense for the mission. The stack is as follows:
- NextJS: I built the game on top of my personal website, which was developed with NextJS so its usage is natural. Moreover, the API server feature of NextJS made it convenient to develop a full stack application in a single project and I could implement the API endpoints to connect to the database in a single instance
- Redis: The structure of the database that I had in mind does not require that many relation and quite make sense to be developed as a Key-Value Store database instead. Therefore, I picked Redis because I used it before and wanted to refresh my memory of it, and it also has a hosted version with Free Plan that is enough for my purpose.
Both of them are deployed in free services, which are:
- Vercel: For the deployment of NextJS
- Redis Lab (opens in a new tab): They have a Free Plan that allows up to 30 simultaneous connections. Considering the size of my Church members, this is a sufficient spec for the database so it was an easy decision to go with Redis Lab
Implementation Detail
Database
Some scope limitation and critical assumptions:
- Not taking care of authentication
- Name of the people in a game are assumed to be unique
- Event Code is manually generated and assumed to be unique too
The database is structured as follows:
Hash [$EVENT_CODE:$NAME] = $DESCRIPTION # string
Its a hash map of string to string, where they key is a concatenation of Event Code & the name of the user. Event Code is a unique code to distinguish a game from another. Currently the code is generated manually and is provided as a url query like: https://yogi.sh/about-me-game?**eventCode=code-here
.** The value is just the string of the description that is provided by the user.
API Endpoints
The system has two API endpoints:
/submit
: APOST
request to create a record to the database. It’s just a simple write operation/roll
: APOST
request to retrieve a random set of descriptions from the database. The logic to retrieve that random data is as follows:
targetQuestionLength = # target question length
descriptions = redis query of KEYS($EVENT_CODE:*)
questions = array of string
while questions.length < targetQuestionLength:
randomIdx = randomInt() % targetQuestionLength
if descriptions[randomIdx] != userName && randomIdx doesnt exist in questions:
append descriptions[idx] to the questions
This approach is okay due to the expected low amount of data for each unique event code. But I do think that retrieving all keys and retrieve the value of each key one by one is not the most optimal method. I wonder if there’s a better way to retrieve the random records from a Redis database.
Answer Validation Method
There’s no API endpoint to do the answer validation because currently the answers are returned together with the questions to the client and the validation is done by the client. It does pose a security risk as a user with some technical knowledge would be able to go through the client data and retrieve the answer. But I assumed the people which I made this game for are all honest and kind people who won’t do such thing.
Issue of Frontend Data Persistence
One quite critical issue that I realized and couldn’t solve properly before the usage time of this app is the lack of persistence for the data of the app. The questions and the state of the game is stored as a local state (useState
) of the game page component and therefore will be gone for every refresh of the page. This is an issue because users will lose all of their progress and will get a new set of questions should they accidentally refreshed the page. This couldn’t been solved by using a more persistent store like session or local storage, but I didn’t have time to implement it.
Closing
It was a fun project to make because I could refresh my knowledge of Redis during the process. Also, the usage of the system was immediate and I could directly see it being used by a lot of people (relatively) and could bring an impact that was according to its intention.
There are some things that I’d like to do to this project to make it more production-ready and I might deploy it as a separate service to allow people to use it to host their game. Hopefully I can use it for my church’s Koinonia activity again in the future and bring the people closer and closer with each other.