Monday, August 9, 2010

Best Practices in IF

Whenever we code, there are both formal rules we must follow and informal habits we adopt to make things easier on ourselves. These "best practices" are common in mainstream programming textbooks, but have received less attention in the IF world than perhaps they deserve.

One of the most common, nearly genre-defining parser errors is the dreaded "You can't see any such thing," which all too often appears in reference to something the story just narrated your character seeing. In Chapter 4 of my upcoming Inform 7 book, I introduce an IF best practice called BENT designed to help minimize this problem. Those who want to get BENT should Bracket Every Notable Thing in descriptive text: make every object that could sensibly be interacted with by the player a text substitution.

The description of Base of the Tower is "Behind [the building] [a steel girder] rises from [the sand], one of three legs of [the huge electrical tower] looming like some gargantuan spider into blackness above you. [A tumbleweed] drifts lazily against the rusted metal among [scrawny weeds] and [bits of trash]. The desert stretches in all directions except back south towards the building."

Why would you do this? To mangle a metaphor, it keeps you from writing nouns your parser can't cash. Now, it's not just a game-level problem that "EXAMINE GIRDER" is not a recognized command: you've made it a compiler-level problem, too. Having told Inform that something called "the steel girder" exists in your story world, it won't let you compile your story until you've created that object, instead giving you a problem message explaining that it doesn't yet exist.

More importantly, BENT forces you to think about the gameplay implications of the words you type. If you're describing the piles of trash, and you write something like this:

The description of trash is "Aluminum pop cans, newspaper pages, plastic bags, and other junk rest in precarious piles underneath the steel girder."

...bracketing all that stuff may cause you to realize that you're just creating a lot of red herrings and frustration for both yourself and the player. Instead, you might refine your description to this:

The description of bits of trash is "Worthless and forgotten, drifting against snags like non-biodegradable snow."

...which requires nothing to be bracketed, and correctly signals to your player that this item is not important to the story.

What counts as notable is subjective, of course. In this example I've left out "gargantuan spider" since it's part of a metaphor (the player really can't see any such thing) and "blackness" since it's an abstract concept. Synonym words like "legs" must be dealt with differently, too (through Understand rules). But the hope is that adopting BENT will get you in the habit of looking for ways to keep the parser's mental model of the story world in line with the player's.


Andrew Plotkin said...

This model seems to short-circuit a tool I use heavily, which is to route a lot of (player-typable) objects together into one. I would happily throw your "Aluminum pop cans, newspaper pages, ..." description into a game, but all of those words would refer back to the trash object -- examining them would just give the same message again. This is a strong player hint to stop messing with them.

(It would have to be backed up by more explicit "unimportant" responses on more active verbs.)

Even in your primary description, I would want to make "girder" and "tower" the same object. Any salient action (climb, hit, examine) that applies to one could reasonably be phrased in terms of the other.

I guess you could say "a steel girder is a thing that varies. A steel girder is the huge electrical tower." But this seems painful. But, contrariwise, maybe it's worth it for the sort of implementation discipline you suggest.

Sarah said...

This sounds kind of like something people do in journalism, where before a story goes to print (obviously this is a lot less doable online!) the writer underlines everything that can be construed as a fact (i.e. that can be wrong) to check it. It's time-consuming, but in my admittedly limited experience it does help catch what would otherwise turn into corrections.

I'm less sold on writing descriptions to avoid mentioning other objects; really, it depends on the PC. (As most things do.) Does he look at a forest and think "Hey, cool forest," or does he think "Hey, cool trees?" Those two examples you gave sound like they came out of the mouth of two entirely different people. The question, I guess, is whether it's a red herring or a characterization bit. (Redirecting synonyms like Zarf said could do a lot to mitigate that, too.)

Pacian said...

I find it a bit jarring in IF games when what I thought was an interesting detail turns out to merely be a synonym.

If different objects aren't important enough to at least warrant their own descriptions (even if they're not to be messed with) why mention them in the first place?

Sarah said...

Because it's hard not to without a purposeful exercise in avoiding nouns.

Matt Wigdahl said...

I agree with Pacian. For some reason, compound scenery objects really bug me as a player, although I can see the strong temptation to code them this way -- it's a lot less work.

Aaron A. Reed said...

I should have cleaned this up from the original context: the reason the girder and tower were separate objects is because the tower itself was a backdrop visible from multiple locations, and the girder an in-room object that could be interacted with, which I forgot to mention in the write-up. The solution this led you to is interesting, though. I guess in general, BENT is meant to be combined with copious understand rules, so assuming the tower were just a single room object you'd add something like:

Understand "steel/girder" as the huge electrical tower.

...but then you're back to the problem of trying to remember to add such a line for all the synonym words you use in your description. I've long wished there were some elegant way to introduce new synonym words in the midst of descriptive text, without having to separately update both the prose and a vocab list. In imaginary-Inform-8 code, it would be cool if you could do something like this:

The description is "Behind [the building] ['a steel girder' (huge tower)] rises from [the sand], one of ['three legs' (huge tower)] of [the huge electrical tower] looming above."

...which would both print the text in single quotes and understand those words as referring to the parenthetical object.