Temporal Blog 09月30日 19:15
Temporal Trivia Game Hackathon
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

Temporal held its second annual Hackathon, where a team built a multiplayer trivia game using Temporal and ChatGPT. The game features player creation, configurable categories, and dynamic question generation. Two workflows, GameWorkflow and AddPlayerWorkflow, manage the game state and player interactions. The backend leverages Temporal for scalability and durability, while the frontend offers SMS and web support. Key learnings include keeping logic centralized, using multiple workflows for better design, and the importance of moderation. The project demonstrates Temporal's capabilities in building scalable and resilient applications.

💡 The project was developed during Temporal's second annual Hackathon, where a team aimed to build 'cool stuff' leveraging Temporal and ChatGPT. The trivia game was designed to scale to millions of users, support multiplayer functionality, and maintain game state durability.

🔄 The game architecture consists of two primary workflows: GameWorkflow and AddPlayerWorkflow. GameWorkflow manages the game loop, question generation via ChatGPT, and player scoring, while AddPlayerWorkflow handles player addition and validation.

🗣️ Players interact with the game through signals for submitting answers and queries for viewing game state. Signals are used to order player responses, awarding extra points for correct answers submitted first, enhancing game engagement.

🛠️ The backend is built using Temporal, enabling centralized game logic and decoupled UI design. This allows team members to choose their preferred language (e.g., Go for backend, TypeScript for frontend) while ensuring seamless workflow interactions.

📱 The frontend evolved from SMS-based interactions in version 1 to a web interface in version 2, enabling broader browser support. This progression highlights the importance of iterative development in achieving a functional MVP.

🔍 The team learned the value of moderation, initially using ChatGPT for name validation but switching to a specialized profanity filter service for better results. This underscores the need for tailored solutions in real-world applications.

⏱️ Efficient workflow management was a key focus, with timers controlling game progression and timeouts. The project also identified areas for improvement, such as optimizing regex parsing and exploring synchronous Workflow Updates for enhanced performance.

This project and post was a true team effort and was written by a handful of people from the Solution Architect Team: Ci-Ci Thomson, Anthony Wong and Keith Tenzer

Introduction#

In Spring of 2023, Temporal held its second annual Hackathon. Leadership challenged us to build “cool stuff” and maybe leverage ChatGPT. As Solution Architects at Temporal, we sadly don’t get to code as much as we would like, in other words this was a perfect opportunity!

We gathered together a team, including Ci-Ci Thomson, Anthony Wong and Keith Tenzer and came up with the idea to build a game using Temporal. In the end, a game is really just some state and logic which can be expressed as a workflow, right? So, we decided to make a Trivia Game and incorporate ChatGPT for question generation.

Our design goals:

    Scale to millions of users Support multiplayer and unlimited number of games Build using polyglot Maintain game state and durability when things break Timeout mechanism for questions Single source of truth for game logic Do it all in a few hundred lines of code!

How the Game Works#

Getting into the thick of it, let’s walk through everything. Players can create or join a game. Category, number of players, number of questions and even a challenge mode are all configurable. Once the game starts, players are presented with questions and multiple choice answers. They submit their answers and results are shown including a final score once the game completes.

Backend Infrastructure#

Temporal Trivia implemented the game as two workflows: GameWorkflow and AddPlayerWorkflow.

The GameWorkflow is launched when a player creates a game. It waits for players to join and starts the game. When a player creates or joins a game, that player is added to the game by the AddPlayerWorkflow.

Once the game is started, trivia questions and answers are gathered using ChatGPT. The GameWorkflow then proceeds through the game loop, gathering player submissions and keeping track of scoring. Once the game is completed, the final scores are displayed.

Activity

Trivia questions and answers are gathered using an activity which executes an API call to ChatGPT. Player moderation executes an activity to validate player names before adding them to the game via the AddPlayerWorkflow. Final scores are calculated using an activity.

Queries

Game state is exposed externally via queries by the GameWorkflow. The GameWorkflow provides three queries: getPlayers, getProgress and getQuestions. Queries are used by the AddPlayerWorkflow and the UI.

Signals

Players are added to the GameWorkflow and submit their answers via signals. Since signals are ordered, we give an extra point to the player who answers the question correctly first. This makes game play more interesting.

Timers

The GameWorkflow progresses between its phases and questions using configurable timers. In addition, a timer is also used to start the game if enough players don’t join.

Backend Diagram#

Frontend Version 1

In Version 1, we had players join the game via SMS and make one player host the game on their computer to show off the Lobby, Questions, Answers, and Results. The main driver for this is because of the time constraints. Not only that, but we were also learning how to use the Svelte. The front end was straightforward — keep querying against the Temporal Workflow to see what the front-end should display. Both the SMS and SvelteKit are connected to the same NodeJS Express Server. The NodeJS Express Server kept track of what game was going on and which player was in which game.

Frontend Version 2

In Version 2, we added browser support. This allowed both desktop and mobile users to join in the game. Each player can see the Lobby, Questions, Answers, and Results in their own devices. We had to use a new framework for this because we wanted to show this off at a conference. Due to time constraints, we have built this out using Python and Flask. The V2 Frontend offers the following features:

    Player name Join in an open game Create a new game and specify the parameters How many questions, players, etc.

Key Learnings#

As mentioned earlier, this was a part of an internal hackathon so many of the concepts we wanted to implement we had never done before, and learning is the main point of a hackathon! The three of us all learned a great deal relating to the parts we coded as well as the best way to work as a team by agreeing on an overall design purposefully upfront to allow for ease of collaboration.

Keeping Logic in One Place#

In general, Temporal allowed us to keep all of the game logic in one place (workflows) and allowed for clean and decoupled UI design. This also allowed us to each choose our language of choice to implement our respective pieces of the project. We found that even though the backend workflows are written in Go and the frontend is written in Typescript, the workflow interactions between languages are seamless (and there were no issues with data serialization/deserialization).

Two Workflows are Better than One#

The initial design of the application had a single workflow that handled both the game and players. After further analysis, we decided to break this into two workflows, one for the GameWorkflow and one for AddPlayerWorkflow. Interactions were then handled via a single gameId. This decision allowed for simplified logic and interactions as well as allowing different team members to work more independently. One of the main learnings we had was that we initially did not cancel the timers properly at first and this caused the timers to unexpectedly fire later and break the game loop.

Moderation is Key#

We also had intended to implement name moderation using the ChatGPT moderation functionality. It turns out that moderation is intended for longer strings of text and intent instead of filtering out profanity words. We then found a service specifically meant for profanity filters (https://www.purgomalum.com/) and were able to replace ChatGPT by only changing the call to the moderation service.

Iteration and Small Pieces make an MVP at each stage#

Version 1 of the trivia game had all players using their phone to join a game and answer questions by texting a specific phone number. Version 2 of the game has been upgraded to have a web interface for users to join games and answer questions. We already have a few upgrades in mind for Version 3 of the game. For instance, instead of having a player lobby where a player joins a game, we plan to use matchmaking to have players automatically assigned to a game.

Each iteration has the potential to be more efficient#

Currently, we use regex parsing to process the ChatGPT chat stream of questions and answers. We plan on simplifying this functionality by having ChatGPT return JSON instead of plain text to get rid of the overhead of regex. The biggest upgrade we plan on for Version 3 is one that has been waiting on new Temporal functionality that has just been released. There is quite a bit of querying and signaling into the Workflow and this is not efficient. We can enhance the performance of the entire game by changing these to a synchronous Workflow Update (link to doc)

In the front end, there has been multiple discussions about the trade-off between polling and websocket. We used the polling method because of the ease of use and limited time. It is still worthwhile exploring websocket as we are looking to build Version 3 of this, which includes Matchmaking.

Not only that but a different front-end stack. In Version 1, we used SvelteKit. It was our first time using it, and after using another front-end framework like React, it is a lot easier to use. The routing was super easy, and building components.

Conclusion#

If you like what you have seen and read and are interested in either trying it out or implementing something similar, here are the Github links:

If you want to dig into the code...

The team is happy to join a Zoom call for a more in-depth discussion of how this was designed and implemented, or if you just have specific questions, feel free to reach out in any of the following methods!

💬 Temporal Community Slack

    Keith Tenzer

    Anthony Wong

    Ci-Ci Thomson

Replay Hackathon#

More importantly, did you hear? We are doing ANOTHER hackathon, and this time, we are inviting you, our community, to participate in it, along with Replay. You can check out some details here on another blog post, or if you want to go ahead and try it, feel free to sign up under the tickets section of our Replay site—use HACK20 for 20% off!

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Temporal ChatGPT Hackathon Trivia Game Workflows Scalability Backend Development Frontend Development Multiplayer Game
相关文章