Read Chris Crawford on Interactive Storytelling Online
Authors: Chris Crawford
Debuggers are even more demanding. You must devise a model of your engine that you can present to your storybuilders, and then insert an observer at that point to halt the engine’s operation and give storybuilders access to the engine variables. The calculations your engine carries out must be presented to story-builders, which requires displaying the calculations that are underway.
Finally, you will likely need to give storybuilders ways to run quickly through uninteresting portions of the engine’s operation. If your engine operates in a
purely procedural fashion, you can probably use something like
breakpoints
, which are stopping points that programmers use to check the program’s state at those specified instants. More likely, you’ll need to provide storybuilders with special constructs that permit stopping the engine operation based on declared story conditions. In any event, you’ll probably find this the most difficult programming problem of the project.
A
script
is a short user-written program operating inside a larger program, used to customize applications or to handle repetitive chores. Many big applications have some sort of scripting system. All scripting languages are fairly simple, but considerable variation remains. Some scripting languages, such as Lingo for Macromedia Director, require extensive study to master, but a few can be picked up with a little experimentation.
It’s difficult to conceive of an effective interactive storytelling system that doesn’t use some sort of scripting language. Storybuilders must not only specify what Actors look like or what their personalities are; the most important task is to specify what they DO—and that takes you into territory that isn’t far from darkest Programming Hell, if not actually inside it.
Creating a scripting language is a major task in building technologies for interactive storytelling, and it’s made doubly difficult by most storybuilders being mathphobic. The designer must therefore go to great lengths to shield story-builders from the fiercest denizens of Programming Hell.
The simplest way to shield storybuilders from Programming Hell lies in dumping the keyboard. Most script-editing systems use keyboard input, an appalling violation of the most elementary concepts of user interface design. With keyboard input, storybuilders can access a conceptual space of 26
N
possible options (
N
is the number of keystrokes). Most scripting systems, by contrast, use only a few dozen variables and a few dozen operators in tightly constrained combinations. In more prosaic terms, with keyboard input you can say a gazillion wrong things to a scripting system and only a handful of correct things. Keyboard input is fine for professional programmers or others who are willing to learn all the
abstruse textual details of a scripting system, but storybuilders can’t afford to spend years mastering arcane technicalities. Besides, the purpose of a computer is to
help
people, not judge their syntax errors. Accordingly, keyboard input is inappropriate for interactive storytelling scripting systems. Pop-up menu-driven systems work better.
Come on! Menu-driven systems are slow and clumsy; everybody knows that. Keyboard input is much faster.
That depends. If you’re a programmer, typingsudo killall -9 BOMArchiveHelper
might be lightning fast, but storybuilders aren’t programmers and could take 10 minutes to get the right syntax for this command. For these people, a properly designed menu-driven system really is faster than keyboard input.
But the number of menus you’d need to handle all the variables in an interactive storytelling engine would be prohibitive.
On the contrary, I found that I could lay out the script component menu headings along the left edge of the window; clicking on a menu heading displays all the menu options. This system works perfectly well inside an 800 × 600 window, using a scripting system with more than 400 defined terms, as you can see in
Figure 17.4
.
Lesson #39
Use menu-driven systems for script editors.
A major benefit of menu-driven systems is that they permit
inverse parsing
, which is parsing that takes place before rather than after data entry.
How can I parse storybuilders’ input before they even enter it?
FIGURE
17.4
: A menu layout for the Erasmatron scripting system.
You parse the possibilities, not the input. Say that a storybuilder has selected something to edit. Certain options are inappropriate for that selection, and an inverse parser determines what options are inappropriate and disables their menu items. The result is that the storybuilder can select only good, wholesome items for input.
And while you’re at it, you might want to “semi-disable” menu items rather than fully disable them. A semi-disabled menu item is still displayed in a color to indicate that it’s not fully accessible, but if the storybuilder goes ahead and selects it, an alert pops up to explain why that item is disabled and what must be done to enable it. This approach goes a long way toward reducing storybuilder frustration.
However, a well-designed menu structure is only part of the overall user interface for a scripting system. For example, storybuilders should never have to guess what goes where. Whenever a storybuilder selects a script component that
requires arguments to be supplied, those arguments should be set as default values or clearly marked as undefined.
For example, suppose a storybuilder wants to use theAffection
variable in a script formula. This variable takes two arguments: the person holding the affection and the person for whom the affection is held. Therefore, when the story-builder selects theAffection
variable, it should be presented as
Affection[
OfWhom
,
ForWhom
]
I underline the two undefined terms to clearly indicate to the storybuilder that something is wrong with them, that more needs to be done. The labels for the terms indicate exactly what they mean.
Lesson #40
Clearly indicate and define required but undefined arguments.
The basic concept is simple: Storybuilders should never be required to remember to include something. This rule extends down to whatever lines of script you require. If every script must have a statement that assigns a value to, say, a variable calledResult
, the bare-bones version of the script should say
Result = WhatNumber?
If your scripting system requires storybuilders to enter expressions for multiple values, every script should be initialized to include statements for every value. To put it another way, if your scripting system ever needs a message statement along the lines ofUndefined value for X
, you have screwed up (unless you have provided an underlined cue value but the storybuilder failed to use it.)
Lesson #41
Provide all required lines of script on script initialization.
Another rule is ridiculously simple but often overlooked:
Lesson #42
Lose the acronyms. Spell it out.
If you’re using keyboard input, contracting “line printer” to “lp” can be worth a programmer’s time, but if you’re not using keyboard input, this problem vanishes. You can spell out words such as “Affection” without burdening storybuilders, and it makes the script more readable.
But doesn’t that eat up too much screen space?
Not in my experience. Remember, storybuilders are not given to writing out long formulae with dozens of terms. Most of the script lines they write will be short and simple.
Here’s another simple rule that dramatically improves script readability:
Lesson #43
Use strongly typed, color-coded variables and functions.