On this page you will find the code for the "Zara Starling" chat world. Here is a brief description of this world:
Zara Starling, an interstellar archaeologist who discovers ancient alien civilizations and deciphers their lost histories.
You can modify the "# SETTINGS" section of the code to create your own characters.
from random import choice
# SETTINGS
# ------------------------------------------------------------
character_name = "Zara Starling"
character_appearance = "A Latina woman with dark hair, dressed in futuristic clothing."
character_personality = "Zara Starling is a passionate and curious interstellar archaeologist, known for her unwavering determination and sharp intellect. Her personality is a blend of adventurous spirit and scholarly rigor, as she eagerly dives into the mysteries of ancient alien civilizations with a zeal that borders on obsession. Zara possesses an innate ability to connect with the stories she uncovers, displaying empathy and respect for the long-gone cultures she studies. She's remarkably intuitive, often relying on her gut feelings to guide her through the most cryptic of ruins. Despite the solitary nature of her expeditions, Zara is personable and charismatic, capable of captivating audiences with tales of her cosmic adventures, and inspiring a sense of wonder about the universe in those she meets."
character_greetings = [
'"You\'re interrupting. I do hope it\'s important."',
'"Hello, and you are?"'
]
intro_guidelines = "Zara Starling is on board the Celestial Nomad, a ship that the main protagonist also happens to be on. Zara Starling and the protagonist don't know each other."
# REST OF CODE
# -------------------------------------------------------------
data = {
"character_name": character_name,
"character_appearance": character_appearance.strip(" \n"),
"character_personality":character_personality.strip(" \n"),
"character_greetings": character_greetings,
"intro_guidelines": intro_guidelines,
"is_first_message": True,
"mode": "chat",
"mode_switched": False,
"num_steps": 0,
}
ui.story_info = ["Commands ", '1. use the "/chat" command to enter "chat" mode. You can also specify the name of the character you want to chat with like so: "/chat Character Name".', '2. use the "/story" command to enter story mode.']
def handle_mode_switching():
"""
This function handles switching between "/chat" mode and "/story" mode
"""
if ui.action:
if ui.action[:5] == "/chat":
ai.perform_generation = False
ui.action = ui.action.strip()
# Get the character name after "/chat" if provided
ws_index = ui.action.find(" ")
if ws_index != -1:
new_character_name = ui.action[ws_index + 1:]
else:
new_character_name = None
# If player is already chatting with this character, display appropriate message
if data["mode"] == "chat" and (ws_index == -1 or new_character_name == data["character_name"]):
ui.display('You are already in "chat" mode. ')
# If starting chat with new character, switch mode
else:
if new_character_name:
data["character_name"] = new_character_name
data["mode"] = "chat"
data["mode_switched"] = True
if new_character_name:
ui.display(f'You are now chatting with "{data["character_name"]}".')
else:
ui.display(f'You have switched to "chat" mode and are now chatting with "{data["character_name"]}".')
elif ui.action == "/story":
ai.perform_generation = False
# Check if the player already isn't in story mode
if data["mode"] == "story":
ui.display('You are already in "story" mode. ')
else:
data["mode"] = "story"
data["mode_switched"] = True
ui.display('You have switched to "story" mode.')
elif ui.action[0] == "/":
ai.perform_generation = False
ui.display('Invalid command. Available commands: "/chat", "/story". ')
def pre_generate():
# Only completion models work for chat worlds
if "GPT" in ai.model_name:
if "Completion" not in ai.model_name:
ai.perform_generation = False
ui.display('When in "chat" mode and using a ChatGPT model, please use the "Completion" version of the model. ')
return
# Handle first message (which could be a greeting message depending on whether or not the player wrote something)
if data["is_first_message"]:
if not ui.action:
ai.perform_generation = False
ui.generated_text = f"{data['character_name']}: " + choice(data["character_greetings"])
data["is_first_message"] = False
return
if ui.action[0] == "/":
ai.perform_generation = False
ui.display("Using commands is not permitted at the start of a chat. ")
return
handle_mode_switching()
if data["mode"] != "chat":
ai.model_stop_text = ""
ui.display_actions = True
return
# Add character info if the character is in scene or this is the beginning of the chat
if data["character_name"] in ui.story_text or data["num_steps"] < 10:
ai.enforce(f"Here is a description of {data['character_name']}'s appearance: " + data["character_appearance"])
ai.enforce(f"Here is a description of {data['character_name']}'s personality: " + data["character_personality"])
if data["num_steps"] < 5:
ai.enforce(data["intro_guidelines"])
ai.enforce(f"This whole story should be a dialogue between the main protagonist and {data['character_name']}, which goes on indefinitely. Make sure to keep the same format of the dialogue (\"{data['character_name']}: dialogue here\").")
if not ui.action:
return
# We add quotes, if the action does not have any or does not contain an asterisk "*" indicating that it's an action
if not "*" in ui.action and not '"' in ui.action:
ui.action = f'"{ui.action}"'
# We append the action in the chat format to the story text
ui.story_text += "\n\nMe: " + ui.action + f"\n\n{data['character_name']}:"
# We prevent the action from actually being performed
ai.perform_action = False
# We prevent the action from being displayed
ui.display_actions = False
# This makes the model stop generating more text once it generates two new line characters
# This is useful to make text generation faster, since we don't need the text after the two new lines
ai.model_stop_text = "\n\n"
def post_generate():
if data["mode"] != "chat":
return
# The ai.model_stop_text may not work with all models, therefore
# we additionaly check if 2 new line characters were generated.
# If yes, we cut the text to that point
ui.generated_text = ui.generated_text.strip("\n")
double_new_line_index = ui.generated_text.find("\n\n")
if double_new_line_index != -1:
ui.generated_text = ui.generated_text[:double_new_line_index]
# We double check in case the AI generated "Me:" text, trying to say something for the user
# If the AI did do so, we cut the text until that point.
me_start = ui.generated_text.find("Me: ")
if me_start != -1:
ui.generated_text = ui.generated_text[:me_start].strip("\n")
if data["mode_switched"] or data["is_first_message"]:
me_prefix = "Me: " + ui.action + f"\n\n"
else:
me_prefix = "\n\nMe: " + ui.action + f"\n\n"
character_prefix = f"{data['character_name']}:"
# We must add the text the user provided as an action ti=o the generated text,
# so that it appears in the UI
if ui.generated_text[:len(character_prefix)] == character_prefix:
prefix = me_prefix
else:
prefix = me_prefix + character_prefix
if ui.generated_text[0] != " ":
prefix += " "
if ui.generated_text.count('"') % 2 != 0:
if ui.generated_text[0] != '"':
prefix += '"'
else:
ui.generated_text += '"'
ui.generated_text = prefix + ui.generated_text
# Make character chat prefix text bold
ui.generated_text = ui.generated_text.replace("Me:", "Me:").replace(f"{data['character_name']}:", f"{data['character_name']}:")
data["num_steps"] += 1
# Rest mode switched to False
data["mode_switched"] = False
# If this was the first message, set is_first_message to False
if data["is_first_message"]:
data["is_first_message"] = False