Skip to content

Multiplayer Trivia Game - Part 1 - Design

Posted on:September 3, 2024 at 03:22 PM

Table of contents

Open Table of contents

Introduction

Trivia Murder Party is a great game to play with friends and family. During one of these sessions, a thought occurred to me

why can’t we play trivia games based on topics we create ourselves?

And thus, this project was born with a relatively simple premise:

to create AI-generated trivia games from any given topic

Basic Requirements

At a high level, we need the following elements to get a bare-bones version of this project out into the ether:

A fairly small and straightforward set of requirements, right?

Overall Structure

Trivia Generation

Let’s start with the fun part: generating the trivia questions. We need to ask ourselves, is this going to be a complex workflow? Probably not, so we should be fine with a bare-bones SDK (in lieu of something like LangChain) from a popular LLM provider like OpenAI. Anthropic is an option, but OpenAI is more mature. As of this writing, they officially support two languages: Python and Node.js. My preference is Typescript, as its fully-typed. Let’s flesh out some more details before deciding.

Data Modeling

The primary model, based on our requirements, will be the “Game Room.” The overall project has an ephemeral and short-lived nature. Generally speaking, our models will be active for a short time, involving a lot of interactions such as players submitting answers, cycling through questions, and status updates. Eventually, after a few hours, the game room will need to be destroyed, preferably automatically. In other words, we need something that can handle high transaction volumes and supports models with a TTL (Time to Live) or a similar mechanism for managing a lifecycle. We have a few options, but popular ones that come to mind are Redis and DynamoDB. Both support sub-second queries and writes, and both offer TTL. For now, we’ll go with Redis because it’s cost-effective, supports our use cases, and has clients for both Python and Node.js.

Services

In general, our services need to do the following:

Thus, our stack will require the following technologies:

Making Decisions

When designing a system, I prefer to use the same language whenever possible. Our first decision: Python or TypeScript?

We prefer TypeScript, but remember everything we need to support: a robust API framework, WebSockets, OpenAI SDK support, and strong event-sourcing libraries. These days, finding a well-written API framework that is TypeScript-first is challenging. NestJS is the de-facto standard in this space, but many developers, including myself, have concerns about its paradigms and overall design. Another advantage of Python is its excellent support for data validation through libraries like Pydantic. Given these factors, we’ll use Python for the API but stick with TypeScript for the web portal.

Now that we’ve made that decision, let’s refine our choices further:

Design Summary

Our services will have these characteristics:

Given the need to support WebSockets, serverless offerings aren’t really an option here, so we’re opting for a microservice architecture.

Backing Services

Frontend Components


In summary, we will have four services plus workers and a web portal for the end users. Next, we’ll flesh out the backing services needed to support this undertaking.