InfiniteScribe - The Next Page

Once we figure out the odds, I kick off a number of simultaneous processes to generate the next chapter of the story the user is experiencing. Here’s a breakdown of the various prompt techniques and other approaches I use to make the experience as immersive as possible!

The Roll

As with most tabletop RPG systems, there is a randomization element of some sort to add a degree of chance to the story’s progression. I’ve seen systems use all sorts of sizes and number of dice, decks of cards, and various other randomizers to provide this chance. In Infinite Scribe’s case, we use a simple call to Random.NextInt(1, 100). Comparing that to our odds chart from Mythic, we determine if the user’s action is successful or not, and craft the next prompt.

The user attempts to {Analyze the Network} using their {Smartphone} {with great success}.  Continue the story, limiting your response to two paragraphs.  Ensure the story maintains a {lighthearted} tone.

Random Events

In addition to this randomization, one of the cool aspects of the Mythic system is the chance of introducing a random twist to the story. This is generally done within the in-person system by comparing the two 10-sided die that were rolled to determined the result; if the two numbers are the same (i.e. 60 and 6), and the matched number is higher than the current chaos factor, you’re prompted to roll against a random event table to inject a new unexpected element in the story. We reproduce this feature in code in much the same way, by checking the rolled number and then generating a prompt with randomized results.

The user attempts to {Analyze the Network} using their {Smartphone} {with great success}.  However, the story is interrupted by {a new character entering the scene.  This should be caused by an action that is {abandoning} {an advantage}}.  Continue the story, limiting your response to two paragraphs.  Ensure the story maintains a {lighthearted} tone.

You can see how this small change ignites the imagination and changes the story in an interesting way! The random events are one of my favourite parts of the Mythic system.

The rest of these prompts are run after the next two paragraphs of the story are generated, as they perform operations on the result of that generated story. Each of the prompts are run against a separate copy of the conversation, often with only the mostly recently generated story paragraphs included, which allows us to run the inference faster and cheaper. The prompts are also all using Google’s “Gemini Flash” model, as we often just need a one word generation or classification and don’t require Gemma’s creativity.

Character Conditions

One component of most of my favourite tabletop RPG systems have is the concept of “conditions”. As players proceed through their story, their choices and random chance may find them getting sick, tired, hungry, blessed, lucky, or various other temporary effects, modifying the player’s chances in future rolls. This is particularly present in games like Eldritch Horror, where an entire stack of hundreds of cards is dedicated solely to this purpose.

Needless to say I was very interested in replicating this feature in Infinite Scribe. When the player has a “critical success” or “critical failure” as the story progresses, I ask the language model to identify the positive (or negative) condition that the user gains as a result of the next generated paragraphs.

Based on the last response, identify one {positive/negative} condition that the user has gained.  Return the name of the condition as one word without any punctuation.

I eventually added some filters to ensure that no more than one positive and one negative condition is gained in any given scene. I also have the conditions lasting two scenes (including the scene in which the condition was gained). These conditions are used in further odds calculations:

User: The user is a {teen student named Ace}. They are motivated by {Justice} but plagued by {Recklessness}.  They are good at {Athletics and Tech}, but are weak because they are {Impulsive and Naive}.  Their current conditions include {knowledge and injured}  Discuss the odds of the user being able to {Analyze the Network} successfully while using their {Smartphone}.

Stat Modifiers

Remember the health and stamina stats our character has? I use a separate prompt here to decide if the story has caused the user to spend or recover any health or stamina.

You are a roleplaying game master describing the consequences of the user's last action.  Rewrite the last entry with the following modifications:
- After each sentence where the user takes an action that would require a lot of energy, follow the sentence with (-stamina).
- After each sentence where the user is injured or hurt due to a physical conflict, follow the sentence with (-health).
- After each sentence where the user is able to rest and recover their energy, follow the sentence with (+stamina).
- After each sentence where the user is able to care for their wounds, follow the sentence with (+health).

This gives us a new version of the generated story paragraphs which we can then parse for those specific markers. I run it through some string.IndexOf calls, counting up each instance of each tag, and then change the user’s character stats accordingly. I limit the change for each story paragraph to +/- 1, as the language model likes to pile on the hits if it gets a chance to.

These stats culminate in a few changes to our other prompts:

  • If the user is completely out of stamina, I include that in the odds calculation prompt - making any future checks more difficult
  • If the user is completely out of health, the scene ends with the user falling unconscious
  • If the user is close to 0 in either stat, I ensure we generate an option that allows them to try to recover (if they choose it)

Gaining and Losing Items

In a similar approach to the stat modifiers, I ask a language model to detect if the user gained or lost an item in the generated story. I run these two tasks separately and combine their result. If the user gained an item, there’s a bit of follow up prompting to ask the language model to pick an icon from the game-icons.net list that we can use in the UI.

Option Generation

Finally, once all that is complete, we generate three new options for the user to choose from. This allows them to decide what their character does next in the story.

The user is a {teen student named Ace}.  Generate 3 options of potential next actions for the user to choose.  The options shouldn't be longer than a few words each, and they should follow the format '<verb> the <noun>' or 'Ask <character> about <subject>'.

There’s also an option to generate three new options if they don’t like the initial choices - when we regenerate, we keep a list of the previously generated options so that we ensure we don’t just repeat variations of the original three choices.


That’s about it for our scene generation! Next post I’ll talk about our scene bookkeeping - how we decide when we’re done with a scene and what happens between each of them.