“Campfire Tales” is my upcoming project that utilizes procedural generation, room-scale environmental effects, and performance elements to make a unique storytelling experience that can’t be found anywhere else. This week: I discuss the origins of the project and my research into tools for procedural text generation.
When I was growing up, I learned the alphabet by playing a storytelling game with my dad we called the “Alphabet Game.” He would tell me a story at bedtime where he would periodically pause because the main character encountered a “blank,” where the blank would start with the next letter of the alphabet. This led to lots of stories with alligators or apples going on boating adventures with cobras. I adapted this storytelling game later in life with friends on camping trips, where you would go around in a circle and each time a new blank occurs, the next person would then become the storyteller. It’s the kind of experience that in either case is impossible without some kind of improvisation, and dialogue between audience and orator. Because it has been such a formative and integral part of my growth as a storyteller, my hope for “Campfire Tales” was to be able to replicate this experience for others, and to find out how I could enhance the experience using computational wizardry.
To make this hope a reality, I set out to develop three major components of the experience: a central program that utilizes procedurally generated content to tell stories with audience interaction, optional room-scale environmental effects driven by the central program to facilitate new types of generative expressions, and introducing performers to direct the player experience in a public performance. To reach as wide an audience as possible, I planned to release “Campfire Tales” on the web so that people could interact with, save, and share their own stories while being encouraged to act them out live with their friends in a similar way to the version being publicly exhibited. Through repeated play, we create our own digital oral traditions as players, performers, and storytellers.
Why Procedural Generation?
Because the player interaction that I want to provide generally consists of a single word during transitions between story beats, and that kind of input can be replicated in code by saving player text input as a variable, I need a way to tell stories that include the possibility for improvisation as a result of that user interaction in order for it to feel meaningful. The solution was to utilize Procedural Narrative Generation, defined as “any automatic process that creates a narrative over time, where that narrative is not determined before the process begins” by Chris Martens and Rogelio Cardona-Rivera in their essential 2017 Game Developers Conference talk on the subject [source]. To do so, I would need to find the right tool that would allow me to generate text that could exist as a part of a larger narrative, respond to user interaction in a meaningful way, allow me to use the content generated to drive a microcontroller or other external electronic hardware component.
What sets Improv apart from other solutions is the ability to create a model, or “object that holds data about the text,” through the reincorporation of tags that can be filtered to ensure more predictable or authored generation[source]. In his PROCJAM tutorial, Bruno provides an example that would allow developers to generate types of ships that are named specifically because they are either military or civilian [source].
At first glance, Rant appears to have quite a lot of the functionality for text generation that I’m looking for, as well as documentation specifically for writers in established projects. At the time of this writing, I had issues integrating Rant into the latest version of Unity, and the .NET platform doesn’t have the same kind of flexibility with external components that I’m looking for.
From the Tracery website: “Tracery is a super-simple tool and language to generate text, by GalaxyKate. It’s been used by middle school students, humanities professors, indie game developers, professional bot makers, and lots of regular people, too. Give it a try today!”
Tracery, like Improv, uses a recursive function to generate text from an authored set of possibilities. While it lacks native support for data modeling and filtering, it is extremely well documented and has been used in a number of projects that served as an inspiration for this game. It has also been ported to other languages (such as ruby and python) and there is even an integration into Twine [source][source]!
At first glance, RitaJS appears to have all the functionality that I need to get things up and running, with the added bonus of having feature analysis to allow me to parse and modify generated text based on english grammar structures. I used RitaJS during my research to create a basic MadLibs Generator that replaces specific particles of speech with words selected from its built in lexicon. Code for this Prototype can be found here [source].
Deciding on Which Platform(s) to Use
Ultimately, I settled on using Tracery as the library for grammar generation based on the simplified nature of its grammar structure. Whereas Improv has the ability to filter text so that I would be less likely to create impossible scenarios, the fact that objects within its grammar generation require tagging meant that it would be a nightmare for users to interact with the program. I didn’t want people to have to type more than one thing per interaction, and it would be especially disruptive to live performances if people had to wait while someone typed in “animal” and “extinct” every time that they wanted to enter the word “dinosaur.” Tracery was powerful enough for my purposes, and allowed me to use a JSON data structure to create and save modified grammars as people played.
Next week, I’ll be detailing my process for developing early technical prototypes for the game and fire effects. Stay tuned!