Development
Rethinking interactive fiction games with Curveship
Interactive fiction (IF) is one of the longest continuing computer game traditions — it dates back to the mid-1970s and Will Crowther's "Adventure." Over the years that followed, text-based games became popular because the lack of graphics made them playable on almost any computer system, from minicomputer to PC to mainframe. Just because graphical games have taken over the bulk of the commercial game market doesn't mean text-based games aren't evolving, however: the worlds within them grow ever larger and more complex, and the interpreters can parse increasingly complicated sentence structure. Still, Nick Montfort's recently-released Curveship IF system adds an entirely new wrinkle, the ability to re-flow the narration itself, changing the order in which events are retold, who the principal actor is, and other fundamental characteristics of the story.
Curveship versus existing IF
Traditionally, IF games are written to target a "virtual machine" that maintains the state of the game world, characters, and objects, and implements some base-level logic to simplify the writing process (e.g., defining global rules like "you cannot place any object inside itself" or "you cannot pick up an object that you are already holding"). The most famous is probably the Z-machine specified by Infocom and named after its early hit "Zork" series (which was based on "Adventure").
An actual game is distributed as "story code" files, which are run on a Z-machine interpreter, but game authors would create the game by writing in a higher-level language like Inform. Up through version 6, Inform used a syntax that resembled a structured programming language, complete with includes, object declarations, and conditional expressions. It might be easy to read Inform 6 code and understand what it describes, but it is hardly convenient to write.
In 2006, Inform 7 switched over to a natural-language-like syntax, so that the author could describe the game world in simple English statements like "The Billiards Room is a room. The Billiards Room is north of the Dining Room. Colonel Mustard is a man in the Dining Room." This new syntax makes it easier to design and write a game, but the gameplay is still limited to second-person, present tense narration of the player's actions and how the world responds to them.
Curveship throws out those limitations. The easiest change to understand is that author can create a world and then "play" it from the perspective of any character by starting the game with a different set of options, which Curveship calls a "spin." A Curveship game can also change the tense and tenor of the narration, without requiring the author to re-work the game.
For example, an action the player takes could shift the style of the narration from "You wake up in the Conservatory. A candlestick is lying on the floor." to "You recall seeing a candlestick lying on the floor. You remember waking up in the Conservatory." Presumably this marks a pivotal moment in the plot, not just a random change in style. The advantage for the author is that it takes place automatically, triggered by some change in state of an in-world object, a choice the player makes, or some other event. Changing the narration style on-the-fly, Montfort says, allows authors to tell "the same underlying events in different ways
".
Exploring Curveship
Curveship has its own game-writing syntax and its own interpreter (written in Python). The code is hosted at Github, where you can download a tar archive of the initial release, time-stamped February 1st. The download includes a brief README, the interpreter and supporting Python libraries, six sample games in the "fiction" directory, and seven sample spins in the "spins" directory. The package is released under the BSD-like ISC License.
As distributed, the Curveship example games can only be played from the command line using the python interpreter. Four of the example games are simple demonstrations of Curveship's special functionality: Artmaking, Cloak of Darkness, Lost One, and Robbery. Lost One, for instance, involves a player character waiting for friend in an outdoor plaza. If the player simply stands and waits, looking around at the environment, the friend eventually arrives. But if the player wanders around too much, Curveship slowly begins shifting the narrative structure, making it third-person, past-tense, and increasingly vague.
Robbery is a non-interactive story; it describes a sequence of events
involving a bank holdup. The fun comes from replaying the story with
different spins. To launch the game as-is, run
python curveship.py fiction/robbery.py
. Appending
one or more of the spin files to the end of the command runs the story
with a different narrative structure:
python curveship.py fiction/robbery.py spin/prophecy.py
tells it in future-tense.python curveship.py fiction/robbery.py spin/prophecy.py spin/hesitant.py
tells it in future tense and sprinkles the narration with interjections.python curveship.py fiction/robbery.py spin/told_and_focalized_by_guard.py
tells it in first-person from the bank guard's point of view.
The last example shows off another of Curveship's features: the world model keeps track of what each character in the story knows. The plain-and-straightforward account of the bank robbery starts with the bank robber putting on a "Dora The Explorer" mask, then entering the bank. The guard's account begins only when the teller laughs at the robber's mask, an event that wakes the guard up from his nap.
It is interesting enough that the game engine can do this in a non-interactive story, but imagine the possibilities when applied to a full-blown IF game. The author only needs to create the world once, but the player could experience very different gameplay, including starting at different points in the same story, just by specifying a different spin at run-time.
The last two sample games are Curveship adaptations of other IF games: Cloak of Darkness Plus (which expands the oft-repeated Cloak of Darkness IF demo), and Adventure In Style (a remake of Crowther's original "Adventure").
World structure and syntax
The price for Curveship's mutable narration is that you cannot author a game in the near-English natural language of Inform 7. Montfort describes Curveship's syntax as "strings-with-slots
". It follows basic English sentence structure, but replaces subjects, objects, and verbs with templates that include the base word plus clues for the text generator to adapt when changing tense or style.
The principle (or player) subject is represented as [*/s]; other subjects replace the asterisk with a noun, such as [butler/s] or [hobbit/s]. Objects are likewise enclosed in brackets, but end with the /o closing tag, such as [pantry/o] or [shuttlecraft/o]. Basic variations to specify elements like possessive form are provided, so the construction:
[*/s] notice the [cobra/o] in [*'s] [shoe/o]
Would be rendered as "You notice the cobra in your shoe" in generic first-person, present-tense. Running a spin from some other character's perspective would replace "your shoe" with "the detective's shoe" or whatever the appropriate designation for the principal character happens to be.
Verbs are a bit more complex. In a real game, the verb "notice" in the previous example would be written as [notice/1/v] — the "v" marks the word as a verb, the "1" indicates that the subject is singular. Verbs are generally written in present tense, so that the text generator can adapt them as necessary (e.g., "You noticed the cobra ... "), but if the circumstances of the story demand it, you can force the past tense or present participle by adding qualifiers like /ed — [notice/ed/1/v] would be rendered as "you noticed the cobra," for example.
Combining these techniques, you can construct sentences that work when rendered from any perspective, such as:
[elf/s] [smack/1/v] [dwarf/o] because [elf/s] [notice/ed/1/v] [cobra/o]
The result could be generated as "The elf smacks the dwarf because the elf noticed the cobra," or "The dwarf is smacked by the elf because the elf noticed the cobra." In the latter case, you'll notice, the perspective of the sentence is turned around, but the structure of the action it describes stays the same — the same creature receives the smack each time.
Sadly, Curveship does not have a full syntax description or writer's manual at this time, but it does have a decent introduction to the game world's theoretical model and a general glossary of terms, which illuminate some of the assumptions that make it powerful.
For example, each "actor" (either a player or non-player character) is a top-level item in the world, as is each physical object or room in the environment. That's typical for an IF model. But each actor also has a concept, which tracks what portion of the world the character is aware of. That feature is what enables Curveship to re-orient the narrative around a different actor and come up with a different sequence of events. If an actor does not see an object or other actor at a particular point in the story, it is not in his or her concept.
If that seems nebulous, a good way to get more familiar with concepts is
to print them out while running one of the example games. At the python
prompt while in-game, typing "world tree
" will list the
entire item tree of the game, starting with "cosmos" at the top, followed
by each room, actor, and all of the objects, nested by their locations.
You can view an individual's concept by typing
"concept @actor_name tree
".
If you do that with the Robbery example game, you'll discover something
interesting. The robber and the guard both know that the teller in the
vestibule is holding a black bag. Running
"concept @robber tree
" displays the following:
@cosmos: nature [] @street: street outside the bank [of] @lobby: lobby [of] @robber: twitchy man [in] @fake_gun: gun-shaped object [of] @mask: Dora the Explorer mask [on] @guard: burly guard [in] @pistol: pistol [of] @vestibule: vestibule [of] @slips: deposit slips [in] @bag: black bag [in] @teller: bank teller [in]
But running "concept @teller tree
" reveals that
the black bag doesn't contain what the robber is hoping for:
@cosmos: nature [] @vestibule: vestibule [of] @slips: deposit slips [in] @bag: black bag [in] @fake_money: fake money [in] @teller: bank teller [in] @lobby: lobby [of] @robber: twitchy man [in] @fake_gun: gun-shaped object [of] @mask: Dora the Explorer mask [on] @guard: burly guard [in] @pistol: pistol [of]
It is a small touch, but one that gives authors an interesting tool with which to craft stories.
At the moment, the dearth of documentation — particularly on compiling Curveship source into executable Python code, and on the syntax for writing spins — limits what you can do with Curveship. For Curveship to take off as a full-fledged IF tool, it will need to build up its documentation, and possibly find support from other open source IF engines. Although Python is widespread and cross-platform, installing games currently requires unpacking them into multiple subdirectories of the Curveship distribution.
But then again, this public release is just three weeks old. Montfort has evidently been working on it as a graduate student for around five years, and the publication history indicates that a lot of IF theorists think it is interesting work. So far the development community is small; there is just one outside contribution — a spin called "mopey" that makes all of a game's narration downcast and negative. Montfort recommends interested users visit the intfiction.org IF forum to learn more, where it looks as if Curveship has its share of fans. IF has been going strong for 35 years so far; with the new POV and narrative techniques Curveship brings to the table, it will be interesting to see what the die-hard IF authors manage to come up with next.
Brief items
Quotes of the week
GNOME Shell 2.91.90 released
The GNOME Shell 2.91.90 release is out; this release, it is said, "just about concludes user interface changes anticipated before GNOME 3.0". Those changes include reworked workspace handling, a new PolicyKit authentication agent, the removal of the "minimize" and "maximize" buttons from window title bars (explanation here), and a lot more. This release represents the experience the GNOME developers are expecting to have for 3.0; see the announcement (click below) for details.
libchamplain 0.9.0 released
libchamplain is a clutter-based mapping library; the 0.9.0 release is now available. "We're a bit late as usual but I believe we'll be in time for the Gnome 3.0 release. In this release there have been many changes of layers, markers and polygons (now paths) which means that if your application uses one of these, it will most probably need an update." See the announcement for a list of changes.
Mixxx 1.9.0
Version 1.9.0 of the "Mixxx" DJ system has been released. "Mixxx 1.9.0 adds several major new features including Shoutcast support, direct deck outputs for external mixers, and ReplayGain normalization. We've also added many enhancements to the library, a revamped default skin, and more."
WordPress 3.1 released
The WordPress 3.1 release is out. "This release features a lightning fast redesigned linking workflow which makes it easy to link to your existing posts and pages, an admin bar so you're never more than a click away from your most-used dashboard pages, a streamlined writing interface that hides many of the seldom-used panels by default to create a simpler and less intimidating writing experience for new bloggers (visit Screen Options in the top right to get old panels back), and a refreshed blue admin scheme available for selection under your personal options." Strangely, the code name for this release is "Django". (Update: the code name has since been changed to "Reinhardt".)
Newsletters and articles
Development newsletters from the last week
- Caml Weekly News (February 22)
- PostgreSQL Weekly News (February 20)
Tom's Definitive Linux Software Roundup: Audio Apps (Tom's Hardware)
Tom's Hardware has an extensive guide to Linux audio applications. The article has mini-reviews of a number of different kinds of audio applications, including music managers, audio players, CD players, CD rippers, tag editors, and so on. "Originally, we intended to create a single article on Linux-based audio applications. However, it soon became apparent that the sheer number of audio production apps would not permit this. So that we don't bore casual users with audio production jabber, this article is split in two: content consumption and content creation. Most end-users will be more interested in this article, while musicians and audio professionals should look to the next one for their Linux audio needs."
Page editor: Jonathan Corbet
Next page:
Announcements>>