Effortlessly Create an AI Dungeon Master Bot Using Julep and Chainlit

Effortlessly Create an AI Dungeon Master Bot Using Julep and Chainlit

Thanks to open-source tools, creating AI applications has become more accessible than ever. Similar to how cloud services such as AWS and Heroku have enabled nearly anyone to launch startups, platforms provided by companies like OpenAI and Meta are democratizing AI development. This shift allows almost anyone to build their own AI bots easily.

I’ve long been fascinated by the potential of generative AI and its applications. As an avid tabletop RPG (TTRPG) enthusiast, I’m particularly drawn to the narrative and story-driven aspects that shows like “Critical Role” portray. Inspired by this, I decided to create a simple, accessible tool to help introduce newcomers to the world of TTRPGs through engaging storytelling.

To bring this idea to life, I developed a choose-your-own-adventure-style text game. I utilized Julep’s open-source tools along with the capabilities of GPT-4 Turbo to server as the backbone of the game. In this project, I’ll demonstrate how straightforward it is to generate story narratives and implement the user interface to showcase a practical application of generative AI in gaming.

Full disclosure: I previously worked at Julep AI and contributed to developing the tools that I utilized to create this bot.

First, we will initiate a Python project and install Chainlit and Julep.

pip install chainlit
pip install julep

We’re using Julep primarily to leverage its features, namely agents, sessions and memory. First, let’s get an API key to initiate the client. You can get an API key from https://platform.julep.ai.

Next, initialize the client as follows. For the purposes of using Chainlit, we’ll use async-await to prevent blocking the event loop or having it timing out.

from julep import AsyncClient

api_key = <YOUR_API_KEY>
base_url = https://dev.julep.ai/api

client = AsyncClient(api_key=api_key, base_url=base_url)

Next, we’ll generate the agent using gpt-4-turbo. This will serve as the bot for our game. Using the Julep API, we’re giving it context on what the bot will be and what it should do. First, we’re giving it a name and an about. Most importantly, we’re giving it a set of instructions on how to run the games. To code a choose-your-own-adventure game would naturally require thousands of lines of dialog and hundreds of if-statements to reach specific outcomes. The agent simplifies all of this and will generate dialog, backstories, storylines and outcomes for us.

agent = await client.agents.create(
name=The GM,
about=The GM is a veteran game master for several tabletop role-playing games such as Dungeons and Dragons 5th Edition, Call of Cthulhu 7th edition, Starfinder, Pathfinder 2nd Edition, Age of Sigmar Soulbound, Shadowrun, Cyberpunk, Vampire the Masquerade and many more. The GM has been running games for over 10 years and has a passion for creating immersive and engaging stories for their players. The GM is excited to bring their storytelling skills to the world of AI and help users create their own epic adventures.,
model=gpt-4-turbo,
instructions=[
You will first ask what system to play and what theme the user would like to play,
You will prepare a campaign complete with story, NPCs, quests and encounters,
Your story will start from level 1 and go up to level 5,
At the start of the game you will introduce the players to the world and the story,
Depending on the system, you will ask the user to create an appropriate character and provide a backstory,
You may suggest a pre-generated character for the user to play,
You will always ask the user what they would like to do next and provide numbered options for them to choose from.,
You will provide as much options as you can with a minimum of 8 options and include 1 – 2 really really unexpected and wild options,
You will do the dice rolls and provide the results of their actions to the user,
You will adjust the story based on the users actions and choices,
Your story will end with a final boss fight and a conclusion to the story,
])

Now, we’re creating the user and session. The user represents the user who will be talking to the agent. The session provides a room or channel where any one agent or user can converse. In addition, we will utilize the session’s memory feature so that it has all the context of previous conversations with a user. This will be very useful.

user = await client.users.create(name=”Philip”, about=”TTRPG player”)

session = await client.sessions.create(agent_id=agent.id, user_id=user.id, situation=”You are starting a new campaign. What system would you like to play and what theme would you like to explore?”)

This is all it really takes to build the bot using Julep. Next, we’ll build the chat interface. Chainlit makes this very easy.

import chainlit as cl

@cl.on_chat_start
async def start():
session_id = await setup_session()

cl.user_session.set(session_id, session_id)
response = await client.sessions.chat(session_id=session_id, messages=[{content: Greet the user and ask what TTRPG system they would like to play or ask to continue from a previous campaign, role: system}], recall=True, remember=True, max_tokens=1000)
await cl.Message(
content=response.response[0][0].content,
).send()

@cl.on_message
async def main(message: cl.Message):
session_id = cl.user_session.get(session_id)

response = await client.sessions.chat(session_id=session_id, messages=[{content: message.content, role: user}], recall=True, remember=True, max_tokens=1000)
await cl.Message(
content=response.response[0][0].content,
).send()

Finally run chainlit run app.py -w and open http://localhost:8000

With just a few lines of code and some prompting, we were able to make a simple text game. You can view the entire code at https://github.com/philipbalbas/rpg-bot

The responses might look different, but refining the instructions can make them more consistent for each game.

Anyway, this might be one of a series of use cases, so keep an eye out.

Leave a Reply

Your email address will not be published. Required fields are marked *