Prom Week Authoring: Crafting Procedurally-Driven Narratives

Cassandra uses a mismatch between her and Gunter's feelings about cultural knowledge base items to shoot down his attempt to ask her out.
Hello! I’m Aaron A. Reed, lead writer on Prom Week, and I wanted to talk a bit about the challenges the writing team faced bringing eighteen characters to life during the most exciting week of their lives. (So far, at least… I’m pretty sure Lil is going to go on to do great things.) I’ve previously worked on large-scale interactive stories before, like my 2009 project Blue Lacuna, but Prom Week presented authoring challenges on a whole different level.

One of the key differences between Prom Week and past AI-driven social simulation games (not that there are a lot of those to begin with!) is that our characters use fully realized scenes to perform social changes. That means coherent English-language dialogue, not emotion icons or vague babble. This design decision meant that each “move” the player makes– mapping to an attempt to change the social state between two characters– needs to be instantiated as a little dramatic scene, usually with something like 4-6 lines of dialogue and attached plumbing (animation choreography and other stuff). Prom Week has twelve major kinds of social exchanges (things like buddy up, romance down, or start enemy), and each can be either accepted or rejected by the responding character, so at a bare minimum, we’d need twenty-four scenes to allow the system to perform each type of social change. A (very boring) stop dating accept scene might look like this:

A: Hey, B, I don’t think we should go out any more.
B: No, probably not.
(result: A no longer dating B)

First of all, why would we write a boring scene like this in the first place? The difficulty from a writer’s perspective is that you know almost nothing about the context this scene might appear in. Which characters are speaking? Why is their relationship ending? We can’t know, and thus it’s pretty hard to make the scene more interesting without saying something that might conflict with the story as it’s happened so far.

But a boring scene like this is going to cause players to disengage pretty quickly, especially if they see it over and over again. We could author a bunch of different versions, or introduce random variation within individual lines (and in fact we do a lot of both) but this doesn’t solve the underlying problem. Furthermore, it’s not very realistic to have eighteen different characters all speaking identical dialogue.

Could we just make a unique version for each character? Well, that would be 18 characters times 24 social results, or over 400 scenes, just to have a baseline of boring scenes to choose from; that’s not viable, either. (Well, maybe for BioWare, but not us.)

A better idea is to restrict scene variants with preconditions, allowing the system to select more specific scenes when the social state allows for them. Imagine we wrote a stop dating scene when the responder has cheated on the initiator:

(precondition: A dating B, A dating C)
A: B, you jerk! I can’t believe you cheated on me with C!
B: It’s not what it looks like, A! C means NOTHING to me! I love *you*!
A: Tell it to the hand. We’re SO OVER!
(result: A no longer dating B, A angry at C)

This has certainly ramped up the drama (if not the maturity level). Not only will this scene seem more on-topic when it appears, it also can change the state in additional ways: we can note that A is now angry at C, for example. Prom Week has a lot of different social state information that can be used to restrict scenes and change the social dynamics: characters have permanent traits, like being witty or shy; temporary statuses like confused or angry at someone; relationships with and feelings about each other; even relationships to items in a cultural knowledge base, allowing for things like the fact that Doug and Chloe both think skateboards are cool to be the basis for a friendship between them.

With preconditions in place, we can create all kinds of more interesting scenes. Imagine this start enemy scene between C and A, which the “angry” change in the scene above could set up:

(precondition: A is friends with C, A is angry at C)
A: I’m so mad at you right now, C, I could kill you!
C: What are you talking about, A? We’re friends. I’d never hurt you.
A: You already did. Never speak to me again.
(result: A enemies with C, A likes C less, C is sad)

This is not bad, but the writer is pretty constrained in coming up with this scene since he or she doesn’t know why A is angry. We could write more specific variants with actual reasons for being angry, like the cheating scenario earlier, but the more specific we get with our preconditions, the less likely any individual scene is to be selected. There are millions of possible combinations of preconditions, and we can’t write scenes to cover them all. What can we do instead?

One way we address this is to remember every event that happens, and allow scenes to both use past events as preconditions and refer to them in dialogue. We can tag the cheater’s stop dating scene above with a new result:

(result: remember that C did something mean to A: “C stole A’s boyfriend.”)

“Something mean” is one of about a dozen categories of action types the system can keep track of, and the quoted text indicates we also store the specifics of this particular mean action. We could now rewrite the start enemy scene like this:

(precondition: C did something mean to A in the last 5 turns)
A: I can’t believe you’d betray me like this, C.
C: What are you talking about?
A: You know damn well what I’m talking about. (the mean thing)!
C: I… I did. I’m so sorry, A …

When this scene is performed, the system can take the reference to the mean event and replace it with an appropriate realization based on who’s speaking and other particulars (so this line might be realized here as “You stole my girlfriend!”) This brings us up to a new level of dynamism: suddenly there are actions and reactions, reintroduction of past plot material, grudges and reminiscences and embarrassing moments that can’t be lived down. It goes a long way to glue a bunch of individually authored moments into something that’s starting to approach a story, without creating the combinatorial explosion you’d get from a branching conversation tree.

The custom design tool for Prom Week authoring, showing the line in the earlier screenshot.
We have a lot of other little authoring tricks to increase variation in Prom Week’s scenes. Each character has a small library of vocabulary, for example, so we can put a generic insult tag in a line of dialogue and trust that jock boy Buzz will use the word “crapface” while goth queen Mave might pull out “emo” instead. Inline randomness and logic let us swap out any number of bad puns within a single line, or change a reference to someone from a “friend” to a “nobody” based on various parameters (tell us how you really feel, Nicholas). All this allows the same scene to be substantially different from one playthrough to the next, often to the point that players don’t even realize they’re watching a scene they’ve seen before.

At the end of the day, though, Prom Week still required authoring a lot of content. It was a very open question as we went into the writing phase just how many individual scenes we’d need to allow the system to really leverage its expressive power: 200? 500? 1000? 10,000?! We just didn’t know until we could see the whole thing in action. All told the authoring team ended up generating something approaching a thousand individual scenes that made it into the final game, each with pre- and post- hooks that allow them to intelligently interface with an ever-changing social simulation. When I see the system make use of our scenes to perform Prom Week’s characters correctly– choosing exactly the right way for shy Kate to ask someone out, or snob Nicholas dredging up the perfect bit of embarrassing past to insult a rival– I get really excited about the future of emergent storytelling and playable social systems.