Introduction
Are you smarter than AI? is fun a web-based multiplayer game application. One of the players among you is an AI, incognito. Can you discern who the AI is?
Each round, a prompt is generated and every player has to submit an answer to the prompt, including the AI. Then everyone gets a chance to vote one which answer they think was generated by the AI. If they can get guess the correct response that was generated by the AI, the humans will win. However, if they guess wrong, then a human will be eliminated from the game, and the next round will proceed.
This is our project submission for the AWS Amplify hackathon hosted by Hashnode: https://hashnode.com/hackathons/aws-amplify-2023
Background Story
Many people are finding it challenging to resist the allure of rapidly advancing AI in the present day. They seek assistance from ChatGPT when coding or effortlessly generating artwork using various AI programs. Jokingly, there's a sense that AI might actually conquer the world, but this notion is becoming more of a reality. Hence, it led us to wonder: "To what extent do we currently possess the ability to distinguish between AI and humans?"
Our game style was inspired by a collection of web-based games like Kahoot, Gartic Phone, and Scribble.
Video
Tech Stack
React + Redux + Vite
- Typescript
OpenAI GPT
Amplify Studio + CLI
Authentication
- Cognito
Frontend components + Figma
Amplify data
DynamoDB
AppSync GraphQL
How it was built
Figma design + Game logic
You can either start the game as a "Host" or join a game as a "Player." The following table describes the game's logic for both the host and the player in order of the game sequence.
Database + GraphQL
All the in-game session and user session data is stored in Amplify. The relational database was modeled in Amplify Studio.
Behind the scenes, Amplify created the DynamoDB tables to store the data as well as an AppSync GraphQL server to query the data from the frontend client.
Here is a snippet of our GraphQL schema.
We wrote all of our GraphQL queries using Amplify Datastore on the React frontend. Here's a snippet of a subscription we used to update the player count in real-time each time it is updated lobby page.
When testing out all the game logic and each individual page, we used AppSync to manipulate the data via GraphQL queries/mutations.
Authentication
Authentication is used to persist user session data stats such as total score, games played, wins, and losses. A user can log in / sign up via email and password authentication.
This is the interface for how an user would log in and the stats page they'd see when signed in. It is optional to log in, and anyone can play as a guest if they choose to instead. However, their stats wouldn't be persisted beyond the user session.
To associate the user with UserPersistedData table, we had to update the GraphQL schema auth directive to include the Cognito userPools. As a default strategy, the API key is still used to make authenticated GraphQL requests.
ChatGPT Integration
We used OpenAI’s GPT API to generate prompts and AI responses. We created a Node.js microservice in Javascript with WebSockets to manage multiple connections with clients. This microservice has two endpoints: the first generates questions or prompts, and the second generates answers or responses to those questions. This microservice enables unique prompts to be generated and an AI to play this game alongside real users. Obtaining appropriate responses from GPT required a degree of experimentation with how prompts were structured. We found that we could generate interesting prompts and compelling responses for this game by experimenting with additional context, temperature, and the presence penalty.
Frontend
We chose Vite over Create React App for its superior performance, and to enhance code reliability and readability, we adopted TypeScript.
It can be both fun and tedious to create UI components. To make tasks like these easier, many CSS frameworks have already emerged. However, during this hackathon, we've decided to take this opportunity to create reusable React components with Amplify UI.
npm i @aws-amplify/ui-react aws-amplify
We used Amplify UI's components as the basic framework and customized the finer details to match the overall design of the project. Below is the code snippet that was used to create a login form.
<Card
backgroundColor="#FCFAFD"
borderRadius="12px"
color="black"
padding="5vh"
boxShadow="rgba(13, 26, 38, 0.25) 0px 4px 4px 0px"
style={style}
>
<Flex justifyContent="center" marginBottom="5vh">
<LoginCard />
</Flex>
<Card
backgroundColor="ffffff"
borderRadius="12px"
color="black"
padding="1em"
boxShadow="rgba(13, 26, 38, 0.25) 0px 4px 4px 0px"
paddingLeft="5vw"
paddingRight="5vw"
paddingTop="5vh"
paddingBottom="5vh"
>
<Flex as="form" direction="column" gap="1.5">
<TextField
placeholder="Enter your email"
label="Email"
fontWeight="500"
isRequired={true}
inputStyles={{ color: 'black' }}
onChange={handleEmailChange}
/>
<PasswordField
autoComplete="current-password"
isRequired={true}
label="Password"
name="password"
fontWeight="500"
placeholder="Enter your password"
inputStyles={{ color: 'black' }}
onChange={handlePasswordChange}
/>
<SubmitButton color="#FF6DDF" onClick={submit}>
Sign In
</SubmitButton>
</Flex>
</Card>
</Card>
Code
You can find all of our open-sourced code in our GitHub Repository
Conclusion
This project was a lot of fun, and we learned a lot about AWS Amplify. Our project involved a log of game logic and therefore required numerous queries/mutations on the database to keep track of the game session and each player's session data. To keep things in real-time, we used Amplify Datastore subscriptions to listen for data updates so that the players could progress to the next round as soon as the host had set the next round, as well as subscribing to the number of players that had currently responded. As a result, we've better understood how to use AppSync, Amplify Datastore, and GraphQL.
We also learned how to utilize Amplify UI to create our custom design. It feels similar to ChakraUI, which can be more approachable to some developers coming from a mobile background who used languages like XML, Compose, or SwiftUI to design by code. The great thing about Amplify UI is that you can also create custom components with no code inside of the Amplify Studio, and it'll automatically generate the Amplify UI components for you! For many of us, this was also a chance to improve our React skills as we developed both the UI and the UI logic.
It was also interesting to integrate ChatGPT into our project and see how its responses would be similar to humans. In our testing, some of the answers it provided were very human-like and were hard to discern, making it a more fun game to play.
Overall, we had a great deal of fun working on this project, spending ~30-40 hours on the project. We learned a lot, and we can say that using Amplify is an excellent tool for both beginners and advanced developers who want to build a full-stack application in one place. We thank both AWS Amplify and Hasnode for hosting this hackathon!