Saturday, February 2, 2013

Narrative systems workflow; using Fourier analysis and level design metaphors to systemize stories.

This assumes familiarity with Shakespeare, a procedurally-branching narrative system that I'm designing. For an overview / introduction, read "More talk, more rock."

I started by arguing that interactive fiction's narrative systems expose too much complexity and detail to its authors and players, or at least more than most people need or want. With Shakespeare, I hope to achieve just a fraction of that functionality, and I think that fraction is enough to be very compelling while facilitating a writer's work.

In engineering Shakespeare, I think of the system in four parts:
a) The real-time system that runs algorithms, interfaces with the game as the player plays.
b) The data / format of narrative itself, how it's structured.
c) The Unity editor interface for generating, editing, or creating the narrative data.
d) The suggested workflow / instructions for using that interface.

Now that I have enough of a base implemented, I'm starting to think more about that last part, the operations design. Roughly, I think the tool could work like this:

1) Write a short scene or play.
2) Analyze your play and find the "system" in the story.
3) Create the narrative system, iterate, test, etc.
4) Go back to step 2 frequently.

The only way to see if that process works is to try doing it. Here's a (not great but good enough) drama I've written, a short 1 scene domestic comedy based on some real-life events...

GUERRERO, a short 1 act.

JUSTIN, a web coder
ROBIN, a designer or PR person or something
ALLISON, Jackson's GF, a corporate accountant or something
JACKSON, Allison's BF, don't know what the hell he does?
DAVE, the guy who needs to leave

[SCENE: an apartment on Guerrero St.]

[JACKSON enters with box and drops it.]
JACKSON: You really have too much fucking stuff. Phew!

[ALLISON enters behind him with much bigger box.]
ALLISON: Uh, Jack, these are all *your* shoes.
[ALLISON drops box and embraces JACKSON.]
ALLISON: ... You do like wearing my bras, though.
JACKSON: Shhh! Okay okay: *we* really have too much stuff.

[They share a moment.]

DAVE: ... Hey guys. [was there all along]
DAVE: Ahh!

ALLISON: Oh, sorry, we didn't...
JACKSON: Dave, was it?
[JACKSON approaches to shake hands. DAVE doesn't understand.]

DAVE: Yeah. I gotta go now. Have fun unpacking.
[DAVE leaves.]

JACKSON: Wait, why is he still here?
ALLISON: Yeah, you're right, Dave's really fucking creepy.
JACKSON: But there's only 3 bedrooms, right?...
ALLISON: I agree. He'd probably stab me in face.
JACKSON: It's us... then Justin... -- that's 2 -- and then Robin...

[JUSTIN enters.]
JUSTIN: Hey, I got some Indian pizza for dinner! Dig in!
JACKSON: What's it say on the box?
ALLISON: "It's so ethnic!" [reading box aloud]

[ROBIN enters.]
ROBIN: Damnit, Justin! I was going to make lasagna tonight.
JUSTIN: Oh. Well, we can have lasagna tomorrow.
JUSTIN: Right now: Pizza! Grab a slice, Allison. It's basil tandoori.

ALLISON: Justin, that creepy guy is still here.
JUSTIN: [eating pizza] C'mon, Allison, Dave's not that...
ROBIN: What? But *I'm* moving in!
ALLISON: He was supposed to move out a week ago!
JUSTIN: [eating pizza]...
ROBIN: If he's here, where am I going to sleep?
JACKSON: ... on the couch?
ALLISON: Shut up, Jack!
ROBIN: Shut up, Jack!

ROBIN: So you told him to leave, and he said no?
JUSTIN: Uh, no, I've been really busy with work, and, you know...
ROBIN: Justin, you told me a week ago --
JUSTIN: ... it's just, you know, really awkward to tell him to...
JACKSON: Yeah, you're throwing him out on the street!
ALLISON: Shut up, Jack!
ROBIN: Shut up, Jack!
JUSTIN: Shut up, Jack!

JUSTIN: Okay, fine. I'll tell him after dinner.
JUSTIN: I just... the right time never came up.
ROBIN: What kind of bullshit is that? "The right time"?
ROBIN: This isn't like losing your virginity on prom night.
[ALLISON / JACKSON look at each other.]
ROBIN: Just make sure you tell Dave tonight.

DAVE: Tell me what tonight? [was there the whole time]
ROBIN: Aahh!
DAVE: Ahh!

ROBIN: Tell him, Justin.
JACKSON: Yeah, tell him, Justin!
[everyone stares at JACKSON]
JACKSON: Oh, uh, mm, is this basil tandoori? It's so ethnic!

JUSTIN: Dave, um, the thing is...
JUSTIN: ... I kinda want to live with my friends...
JUSTIN: ... so I think you should move out.
DAVE: ...
JUSTIN: But you don't have to move out right away!...
[ROBIN and ALLISON glare at Justin.]
JUSTIN: ... uh, but yeah, by next week?...
DAVE: ...
JUSTIN: Sorry.
DAVE: ... Okay.
[DAVE leaves.]

JACKSON: Well that was easy.
ALLISON: He barely even said anything. Creepy.
ROBIN: Whatever. I just want my room.
JUSTIN: I don't know what I was so scared of, haha!

[DAVE returns, holding a knife]
DAVE: I was just wondering...
ROBIN: He's got a knife!
ALLISON: He's going to stab me in the face!
JACKSON: Stab Allison in the face, she said you were creepy!
[They all run out the door.]
DAVE: ... if anyone wanted my cooking knives?
DAVE: Hello?
DAVE: ...
DAVE: Oooh, Indian pizza... it's so ethnic!


Now, it's not important at this stage whether your play is good or not because you're basically going to throw it away, so don't spend too much time making sure it's good as a static linear text -- a static linear text isn't what we're going for. It's more like a sketch or a study, to help you figure out the rough structure of your plot, and get a sense of how to write the characters.

At this point, I imagine a writer performing a sort of "narrative Fourier analysis" / FFT on their story: tease out simpler patterns that make up more complex waveforms, and think about what makes them happen. Which situations / phrases repeat, and under what conditions?

For example, the "it's so ethnic" line is funny (or intended to be funny) because that's exactly the appeal of making something like "Indian pizza" and selling it to middle-class 20 somethings in San Francisco with disposable incomes -- but thinking that is also missing the point of a pizza, which is that pizza is delicious, and eating pizza for the idea of eating pizza is silly. It's also somewhat non-sequitor and pops up in the play only when you've forgotten it. It's also absurd that three different people would independently find that tag-line compelling. Now that I've explained that joke to death, assuming it was ever alive, how do we teach the computer to crack jokes?

Answer: we don't. Instead, a writer tells Shakespeare to try to execute the "PLT_ETHNIC" concept every 2-3 minutes, and with a different speaker each time, but no more than 3 successful times. Some other "waveforms" that we can analyze and distinguish from the play:
  • Dave appearing out of nowhere and scaring everyone.
  • Everyone telling Jack to shut up.
  • Justin stalling his explanation and changing the subject.
  • Allison saying Dave is creepy / mentioning stabbing.
  • Jackson and Allison acting in a way that suggests they're a couple.
  • Robin getting short-changed.
In Shakespeare, (for now), each of these ideas are formatted as a PlotConcept object, and they ping Shakespeare to try to path to their plot targets. For instance, a "PoorRobin" plot thread or a "Jallison" plot thread -- those are recurring motifs that demonstrate and reinforce aspects of those characters -- and maybe you would tell Shakespeare to weigh those events less than a main plot thread about who will verbalize the "TLK_DaveMoveOut" concept to Dave. Or maybe making Dave angry will increase the weight of the "DaveKnife" plot thread and then Shakespeare will try to make happen / remind you / foreshadow that to occur more often?

This system imagines "narrative" as a series of prioritized plot threads. As you test and iterate on the narrative, you'll have to tune different plot thread weights and timing. Maybe in-game it'll turn out to be too hard to get Justin to say "TLK_DaveMoveOut" because it's hard for Shakespeare to narratively path to the "PLT_Confrontation" concept -- so you could add another plot thread about Dave making Justin angry.

Imagine your story is a multiplayer FPS arena. The sniper's balcony is too easily defended, so you have to add an underground tunnel to balance that balcony. You could think of narrative like that: you might need to add narrative situations in order to "balance a plot," or fine-tune some of the joke-timing like you'd fine-tune the distance between a flag and a speed power-up.

Suddenly, it's too easy for the player to make Dave angry, so you have to complicate that plot thread and add some more narrative obstacles -- Dave's been reading a lot of self-help books and can meditate every few minutes to remove an "Anger" concept from his memory.

Notice that there's no "mood" or "personality" simulation going on, whether in the system or in the author's process. Dave's or Justin's or whoever's character traits aren't there because they make them a sympathetic human being of infinite psychological depth -- they are there to make the plot system behave like it should. You don't sympathize with fictional characters. Instead, you sympathize with fictional situations.

If this sounds complicated... yeah, it is. I think this system is too complex to use because -- as I try to explain how it works -- I barely know what I'm talking about. Also, I'm in the middle of coding it, so again, I don't know if the system will work like this or if it "should" work like this... it feels like I'm trying to build a hammer without knowing what a hammer is, or what it should do, or how to use it, or what to use it for.