Trivial empowers users to engage in continuous learning through an immersive trivia experience fueled by Google's AI. By seamlessly blending the vast knowledge of Wikipedia with real-time competitive gameplay, Trivial creates a dynamic environment where players can explore their interests, discover new passions, and challenge themselves intellectually. Whether playing solo or competing against friends, users are encouraged to expand their horizons and test their trivia prowess. Leveraging the Gemini API, Trivial generates a vast supply of engaging and informative trivia content, from intriguing category titles to thought-provoking clues and accurate answers. Wikipedia serves as a rich foundation, providing context and depth to the generated questions, ensuring that players not only have fun but also learn something new with every game.
For more information, check out our demo video!
The backend for Trivial is a Python-based system built on the FastAPI framework, leveraging SocketIO for real-time communication, asyncio for asynchronous task management, and Firestore for flexible data storage. The FastAPI high-performance web framework handles RESTful API endpoints for various room-setup related operations, such as creating rooms and player sessions. SocketIO enables real-time bidirectional communication between the server and clients, ensuring seamless updates on game progress, timers, and player scores.
To generate a Trivial board, a dedicated process is spawned for each room to efficiently manage Gemini API interactions. Upon successful generation, the board data is persisted to the Firestore database for subsequent retrieval as the game unfolds. To maintain game pace and urgency, the backend continuously creates timers to give players a limited amount of time to answer questions and buzz-in. Leveraging the asyncio library, these timers operate asynchronously, preventing blocking behavior and ensuring smooth gameplay. Timer start and end times are recorded in the Firestore database for pausing functionality. By judiciously utilizing asyncio.sleep, the system accommodates other critical asynchronous tasks within the game loop.
The frontend for Trivial, is made with Angular. Leveraging Angular's component-based architecture, the UI is structured into reusable components for efficient development and maintenance. The frontend establishes a WebSocket connection using SocketIO to facilitate real-time interactions with the backend, ensuring seamless updates to the game state, timers, and player scores. Angular's reactive programming capabilities, powered by RxJS, are utilized to manage asynchronous data streams and handle user interactions effectively.
- Python 3.12 + FastAPI API development.
- Firestore for storing user data, game data and room specific data.
- Wikipedia for fetching data from Wikipedia and adding context to clue generation to ensure factually correct clues.
- Gemini via VertexAI for generating categories, category titles, clues and answers.
- Angular for frontend developement
Trivia categories are difficult to generate for a couple reasons. First, Gemini does not handle returning random answers very well. Secondly, it is hard to ensure the categories are not too specific but also not too general. To create categories for Trivial a novel method was used involving something we call a Category Tree. A Category is a tree data structure composed of nodes. Each node in the tree holds a trivia topics for example "math" or "literature". Each node can have any number of children, with the only stipulation being that each child node is considered a "subcategory" of the parent node. What constitutes a "subcategory" is not well defined, but this tree structure allows us to use the Gemini API to generate various categories.
To increase the variety and variability of the trivia answers, Gemini is prompted to respond with more answers than needed to generate the board. Once this happens enough answers are randomly selected to fufill the requirements for the number of clues per category.
To enhance the accuracy of generated trivia, the backend incorporates the Retrieval-Augmented Generation (RAG) method. By leveraging factual data from Wikipedia as context, the system mitigates the risk of the model producing incorrect or misleading information. This approach significantly improves the overall quality and reliability of the generated trivia clues, ensuring that players are challenged with accurate and informative questions.
Nativate to the server directory
cd server
Install the python packages
pip install -r requirements.txt
Create firestore credentials and place the file in the server directory.
Then set the environment variable FIREBASE_PATH to the name of the file with the credentials:
In Windows:
set FIREBASE_PATH=<CREDENTIALS_FILE_NAME>.json
In Linux:
export FIREBASE_PATH=<credentials file name>.json
Create a Gemini API Key and set the environment variable.
In Windows:
set API_KEY=<YOUR_API_KEY>
In Linux:
export API_KEY=<YOUR_API_KEY>
(Optional): Choose the port by setting the PORT
environment variable.
Run the server directly or with uvicorn (hosts on port 8000 by default)
python main.py
or
uvicorn main:app --host <localhost> --port <YOUR_CHOSEN_PORT>
Install node.js and navigate to the client directory.
cd client
To install dependencies run:
npm install
Host the server with:
ng serve
(Note: build the frontend in developement mode when running locally to avoid errors)