AI is the thing nowadays. Everyone in Cal Hacks has probably vibe coded something for their project. And it’s not just taking over tech; it’s affecting every industry. That means a new highly sought for skill is emerging in our society. That’s right, prompt engineering. So we thought… how can we prepare everyone for the future? Oh yeah, of course. Why not MAKE A GAME?... Introducing Impromptu!
Each game, everyone gets the same topic - something tricky, weird, or creative. Your mission? Prompt the AI to give the best possible response to that topic. Once everyone submits their prompts, we unleash our AI judges, including personalities like AI Gordon Ramsay, who’s never afraid to tell you if you cooked or served up raw garbage. 🍳
What Inspired Us
We were inspired by the sudden, massive rise of large language models like ChatGPT. We noticed that everyone was getting wildly different results, and it became clear that "prompt engineering" is a new, creative skill. We saw a fun opportunity to take this new skill and turn it into a hilarious, competitive party game, much in the spirit of Jackbox Games, but built for the AI generation. We wanted to answer the question: who is really the best at talking to machines?
How We Built It
Impromptu is a full-stack web application using Next.js. For the multiplayer functionality, we used Supabase Realtime to handle our realtime changes to the database. The backend consists of Next.js API Routes. These routes manage the core game logic, but most importantly, they securely handle the calls to two separate LLM APIs: one to generate the player's creative response and a second, specialized "Judge AI" to critically analyze and score all the submissions. We also used Mastra to add a “deep research” feature.
The Challenges We Faced
The challenges we faced were significant, as this project was ambitious on two fronts. First, for most of the team, this meant learning a brand new tech stack from scratch. Second, this was our first time making a multiplayer game, and we quickly learned that managing real-time game state, player turns, and asynchronous events across multiple clients was far more complex than we realized.
We had two possible solutions to add functionality to update state in real time. We could use WebSockets, which would not be compatible with Next.js because when you deploy Next.js to a service like Vercel, they turn your backend into serverless functions. That means that nothing is running on one central server. Alternatively, we could use a realtime database like Supabase that makes it easy to store data and check for updates live. Since the backend is a third party service, it doesn’t matter where it’s hosted. This seemed like the more efficient approach, so we went with Supabase.
However there were downsides to choosing a realtime database service. If we wanted to add any actual server side code, such as watching the database until all players have submitted a response to start AI judging, it wouldn’t be straightforward. The solution to that was to use Supabase Edge Functions which are small server actions that can be run when a certain condition is met. This is caused by a trigger on the Postgres database.
In addition, there are countless race conditions that could happen with doing asynchronous/realtime operations like this (and that we probably have not spotted yet). For example, we encountered a bug where, when someone joined a game, we created a user profile in the database and tried to assign the player to the room at the same time. But you need to have the user profile created first to add them to a room, so if the room add happens first you’d result in an error.
What We Learned
Through this project, we learned a tremendous amount about modern, full-stack web development. We gained practical experience with the entire Next.js ecosystem, from building interactive React components to writing robust, serverless backend logic. We also learned the core principles of real-time application design and the complexities of state management in a multiplayer environment.
Most interestingly, we learned about the nuances of AI prompting itself. It's one thing to prompt an AI for a creative answer, but it's a completely different and fascinating challenge to engineer a prompt that forces an AI to act as an impartial, critical judge and return a consistent, structured score.
Built with
We built the frontend using Next.js and React, the realtime database with Supabase Realtime, and the backend with Next.js API routes. We called the Google Gemini 2.0 Flash Experimental API, Anthropic’s Claude Sonnet 4.5, and OpenAI’s GPT 4o mini in the chat room interface so that users can experiment with different models.
Built With
- next.js
- react

Log in or sign up for Devpost to join the conversation.