This is a lightweight web application engine that allows you to create and host your AI-powered text adventure games. Unlike traditional text adventures, which often limit players to pre-defined options, this engine leverages OpenAI's powerful Davinci 3.5 API to dynamically respond to players' actions, allowing them to co-create a unique and immersive experience with the author each time they play.
The engine reads JSON format screenplays. You have the flexibility to specify where to embed AI interactions and what prompts and API parameters to use. This means you can craft rich and complex narratives that evolve and adapt to the player's decisions, while still maintaining control over the generated stories.
It is built on Python web framework Flask, so you can easily host it on your personal computer or server, inviting players to your world. The default visual style is minimalistic, featuring interactive animations that guide players through the game. You have the option to replace these elements with your own tailored designs.
To get started with this project, follow the steps below:
- Download the code
- Install dependencies: Navigate to the project directory and run
pip install -r requirements.txt
. - Get your OpenAI API key: Go to OpenAI Account API Keys and obtain your API key.
- Set the API key: Set the value of your API key as an environment variable called
openai_api_key
. Alternatively, you can store it in a.env
file. - Run the application: Navigate to the code folder and execute
python run.py
. - Access the application: Open your preferred web browser and enter the URL
http://localhost:8367
To get started with writing your own screenplay, follow the steps below:
- Copy the screenplay template: Go to the project's
/static/screenplays folder
and make a copy of thedemo.json
file. Rename the copied file with your desired screenplay name. - Edit your screenplay: Open the newly copied screenplay file and customize it according to your creative vision. Detailed explanations for the editing process will be provided in a later section.
- Rerun the application: After you have finished editing your screenplay, save the file and rerun the application. Access your screenplay by visiting the URL
http://localhost:8367/read/[your_screenplay_name]
. Remember to replace[your_screenplay_name]
in the URL with the actual name of your screenplay.
The screenplay template consists of 4 major parts in the JSON format. /static/screenplays/demo.json
is a complete example.
{
"language_code":"en",
"opening": [
{
"display":"You find yourself stuck in a dimly lit room, with no memory of how you got there. But you know you have to escape before something bad happens."
}
],
"steps": [
{
"intro": [
{
"display":"Looking around, you see a small rug and a bookshelf with a few books on it."
}
],
"interaction": {
"hint_0":"You decide to...",
"max_input":"100",
"hint_1":"describe your action within 100 characters",
"prompt":"{{all}} You {{input}}.",
"suffix": ", where you discover a hidden item.",
"max_tokens":257,
"temperature":1.3,
"n":3,
"display":"{{reply}}, where you discover a hidden item."
},
"outro": [
{
"prompt":"{{all}} It is",
"max_tokens":257,
"temperature":1.7,
"stop":".",
"best_of":3,
"display":"It is{{reply}}."
}
]
}
],
"ending": [
{
"display":"You now have a good feeling about this."
},
{
"display":"However, the demo ends here, leaving the rest of your escape to your imagination."
}
]
}
There are 4 parts in the structure:
-
Language Code: Set the two-letter language code of the major language used in your screenplay. For example,
"language_code": "en"
for English or"language_code": "zh"
for Chinese. The language code is not fully utilized in this version. If you are unsure, you can simply set"language_code": "en"
. -
Opening: This section consists of a list of Display Blocks to provide context and introduce your adventure. Although there is no player interaction, you can leverage AI writing to add uncertainty and surprise for each gameplay.
-
Steps: This section comprises a list of Step Blocks. Each step block represents a step in the adventure and includes interactions with the player. You can guide players and utilize AI writing to dynamically change the plot.
-
Ending: This section is similar to the opening section but to provide the ending of your adventure.
Display Block
The is the main component of your adventure story. The only required field is "display"
. Here's an example from demo.json
:
{
"display":"You find yourself stuck in a dimly lit room, with no memory of how you got there. But you know you have to escape before something bad happens."
}
If you need AI-generated writing, the "prompt"
field is also required. The following parameters are optional: "suffix"
, "max_tokens"
, "temperature"
, "n"
, "stop"
, and "best_of"
. You can refer to the OpenAI API documentation for detailed explanations of these optional parameters.
In our implementation, "n"
is tweaked such that only one of the "n"
choices will be selected during gameplay. The selection criterion is based on the shortest reply with "finish_reason" == "stop"
. This approach ensures a clean and smooth story flow. On the other hand, "best_of"
is selected by the API using the criterion of the highest log probability
. It is strongly recommended to use a suffix to guide the plot.
In the "prompt"
field, you have two options for providing context to the AI model:
- Use
{{all}}
to represent the entire story up to the current point. - Use
{{n}}
: Ifn >= 0
, it represents the recent n display blocks. Ifn < 0
, it represents all contents except for the recent n display blocks.
In the "display"
field, you can use {{reply}}
to represent the AI-generated writing within the "display"
field.
Here's an example from demo.json
:
{
"prompt":"{{all}} It is",
"max_tokens":257,
"temperature":1.7,
"stop":".",
"best_of":3,
"display":"It is{{reply}}."
}
Step Block The Step Block is used to define player interactions in your adventure. Its structure is as follows: There are 3 parts in the structure:
- Intro: This is a list of display blocks that provide an introduction to the step. You can leave it as a blank list if there's no specific introduction needed.
- Interaction: This block represents a player interaction within the step. It contains the following required fields:
"hint_0"
(hint displayed above the input box),"max_input"
(maximum number of characters allowed for input),"hint_1"
(hint displayed below the input box),"prompt"
and"display"
. The other optional parameters are the same as the display block parameters used for AI interaction. Here's an example from demo.json:
"interaction": {
"hint_0":"You decide to...",
"max_input":"100",
"hint_1":"describe your action within 100 characters",
"prompt":"{{all}} You {{input}}.",
"suffix": ", where you discover a hidden item.",
"max_tokens":257,
"temperature":1.3,
"n":3,
"display":"{{reply}}, where you discover a hidden item."
}
- Outro: This is a list of display blocks that provide an outro or conclusion to the step. You can leave it as a blank list if there's no specific outro needed.
Happy screenwriting!
-
Edit the
main.css
file located in the/static/style
directory. You can modify the CSS rules to match your desired design. -
Add your animations in the
/static/animations
directory. You can use$("#current_state").val()
to control the animation based on the current state of the story. The possible values are as follows: An empty string represents the story proceeding. "I" indicates that player input is needed. "L" means the system is waiting for the OpenAI API response. "E" signifies that the story is complete. Editmain.css
in/static/style
-
Load your animations in the
/static/animations/main.html
file. Replace the following line with the appropriate code that loads your animations:
<script src="/static/p5/my_rug.js" type="text/javascript"></script>
This is my first open-source tool, and there are many items on my to-do list. Please stay tuned for updates!