Hack67.Write Text Adventures with INFORM

Hack 67. Write Text Adventures with INFORM

Create your own journey through a land of words .

Text adventures (also known as interactive fiction ) have been around for decades. While these are broad terms, they usually conjure thoughts of a large array of sectioned-off areas, each with its own unique description, items, and traversable paths. Without a vivid imagination and a keen eye for detail, forays into text-based worlds are brief, painful experiences.

Although it's certainly possible to build a text adventure from scratch, there's no need to reinvent the wheel if you're looking to make a traditional "go north, look, get key"-style game. If that sounds good, then you have your pick of several tools. One of the best is INFORM, a powerful and highly customizable design system that consists of code libraries with prewritten commands and a game-writing language. To write games with INFORM, you'll need to download the libraries and a compiler, available for all platforms at the INFORM homepage: http://www.inform-fiction.org/. You should also download the manual, since it will come in handy when you want to move beyond basic rooms and items.

To actually play your creations, you'll need to download the INFORM interpreter [Hack #64] .

6.6.1. Remember the Rules

Whether you're a first-timer or a veteran author with dozens of games under your belt, it's good to keep a few basic rules of text-adventure writing in mind when you start a new project.

Be detailed, not wordy. Short, custom descriptions for items and clever sentences for nonstandard actions are more than enough to satisfy a player and draw them into the game.

Remember the role of imagination. Your descriptions are going to paint a different picture for everyone no matter how detailed they are, so don't let them run on for pages. Unless her looks are important to the story, describe that princess as having "the most beautiful body you have ever laid eyes on," rather than going on for several sentences about the mole on her cheek.

Make sure the game is always winnable ! If the player picks up a carrot and eats it, only to realize later that they needed it to catch a rabbit, make sure they can either get another carrot or find another way to trap the rabbit. Leaving them no recourse but to restore a saved game is poor design; the player is punished not by the elements of the world, but by a lack of vision on the author's part. In other words, every possible action should kill the player, win the game, or move them somewhere along the path to victory (even if it's back a few steps).

6.6.2. Plan Out Your World

Planning is always essential to developing a game. This is especially true with INFORM; each room allows for movement in the eight cardinal directions, up/down, and in/out. Carefully mapping out your game, as shown in Figure 6-1, before you start coding will give you a valuable reference and minimize dead-ends. Your game will undoubtedly evolve throughout the process, so keep the map current and ensure your digital and paper versions match up.

You'll be focusing on how to code, not write, so the first game will be a painfully boring example program containing the basics elements of a text adventure: a few rooms, a puzzle that requires an item to be solved , a key, and a locked door.

6.6.3. Create the Game

Everything in an INFORM game, from the most detailed room to the humblest item, is called an object. The INFORM libraries define a myriad of properties that can be assigned to objects, and depending on which ones you set, it can become a room, an item, an NPC, or something you create yourself.

Figure 6-1. Map of the example game

This game will place the player in a small city alley; the player must find some money, give it to a bum in exchange for a crowbar, and pry open a manhole to enter the sewers.

6.6.3.1. The INFORM skeleton.

Here is the skeletal source code for this game:

 !% -D !Define constants Constant Story "City Adventure"; Include "Parser"; Include "VerbLib"; !Game code goes here [ Initialise; ]; Include "Grammar"; 

The first line is a special case; letters following the !% are read in as compiler switches ( -D is debug mode). All other lines starting with ! are treated as comments.

In the next section, you define any constant values you wish to use throughout the game. Some of these are built into INFORM, such as Story (the name of your game). Others include Headline (a brief description shown at the start of the game) and MAX_SCORE (the maximum amount of points a player can earn).

The next two lines are critical; they load in INFORM's text parser and command library. You can't do much in a text game if the game can't understand your input!

Next comes the actual game, followed by the Initialise routine (be careful, the spelling has to be British). Initialise is run at the start of the game and can be used for giving the player items, setting their initial location, and generally whatever your game requires.

Finally, the grammar library is included. Due to dependency issues, the Parser, VerbLib, and Grammar libraries must always be included in that order, with Parser and VerbLib coming before the game code, and Grammar at the end.

6.6.3.2. Make some objects.

Fire up your favorite text editor and type in the code from the previous section, then save it as an INF file (such as city.inf ). You're free to compile it at this point, but it'll only result in the player standing around in the dark. So head to the ! Game code goes here line, delete the comment (if you even bothered to type it), and create the game's rooms like so:

 Object the_alley "An alley" with description "This is a small back alley.", has light; 

Though a good game would be a bit more descriptive, this room will serve our purposes nicely . The first line tells the compiler that you're about to create a new object, followed by its internal name , "the_alley", and external name , "An alley." The internal name is used to refer to the room within the source file, while the external name is what the player sees. This system makes it possible to have the player see multiple rooms with the same name; a handy feature for mazes, forests, or other areas where unique room names aren't necessary.

The with and has keywords both start lists of various object properties. The first property you need to define is description ; what the player sees when they look at the room, item, etc. We also illuminate the room using the light property.

Add in the remaining rooms:

 Object fire_escape "Fire escape"         with description "You're way up high. The floor wobbles unsteadily.", has light; Object street_corner "6th & Elm"  with description "Cars rush back and forth. Forget about crossing.",  has light; Object bum_town "Pat's cardboard box" with description "A surly bum named Pat lies asleep here.", has light; Object manhole_room "Manhole" with description "There's a manhole at this end of the alley.", has light; Object win_room "You win!" with description "You descend into the sewers, smiling happily.   You win!",         each_turn [; deadflag = 2;], has light; 

each_turn is a loop-like structure that executes every turn the player is in the room. In this case, it sets deadflag , a built-in player property, to 2 , which indicates that the player has won the game. By default, deadflag is set to (the player is alive ). Setting it to 1 kills the player.

Move down to the Initialise routine and change it to:

 [ Initialise; location = the_alley;]; 

Save the game as city.inf . Open a shell/terminal window (or Command Prompt under windows ) and make sure that:

  • The Inform library ( English.h, Grammar.h , and so forth, which are contained in a Zip file that you can get at http://www.inform-fiction.org/), and the city.inf source file are all sitting in your current directory.

  • The Inform compiler is located in your $ PATH (% PATH % on Windows).

Then, compile the game. Here is how the compilation looks on Unix, Linux, or Mac OS X (Windows will be similar):

 $  inform city.inf  Inform 6.30 (27th Feb 2004) $ 

That's itno news is good news.

Now you can run the game ( city.z5 ) with an INFORM interpreter. You'll find yourself stuck in the alley; you can "look" to your heart's content, but that's about it. The next step is to connect the room. Replace the definition of the alley with this (the new lines are shown in bold):

 Object the_alley "An alley"         with description "This is a small back alley. A fire escape is  accessible immediately above you, and exits lead off to the  east, southeast, and northeast.",  u_to fire_escape,   ne_to street_corner,   e_to bum_town,   se_to manhole_room,   w_to "There's nothing but a brick wall that way."  has light; 

If you compile and run the game again, you'll be able to move from the alley to another room, but not vice-versa. Go back to the source file and connect the street corner, bum, and manhole rooms back to the alley. Remember: you have twelve total connections available: the eight cardinal directions (n_ to, s_to, e_to, w_to, nw_to, ne_to, sw_to, se_to), up/down (u_to, d_to), and in/out (in_to, out_to). For example, to complete the manhole room, you'd change the definition to:

 Object manhole_room "Manhole"         with description "There's a manhole at this end of the alley.",  nw_to the_alley,  has light; 

To add more detail to the environment, you can also display a custom message if the player tries to go down a nonexistent path (such as west in the alley).

There's nothing that stops you from making strange and nonsensical connections, like going up to the fire escape from the alley, and then east from the fire escape back to the alley. This is usually a bad idea; it'll be hard for both you and the player to keep an accurate map of the game world. Confuse the player with a cryptic message or difficult puzzle, not random room connections.


At this point, the world is complete; compile the game and you can roam anywhere you likeexcept the win_room .

6.6.3.3. Add in items.

Now that the basics are in place, you can add the items. You can create them anywhere in the source file, but it's best to separate them from the rooms.

INFORM describes items for you; during play, items appear after a room's description as "There is also a/an X here."

You need to create four items: A dollar to give to the bum, the bum himself (whom I've named Pat), a crowbar to pry open the manhole, and the actual manhole, which leads to the final room and ends the game. The dollar and crowbar are just generic items that sit in the player's inventory, while the manhole actually functions as a door, and requires some special properties.

Note that in addition to defining an internal and external name for each item, you can type in a room name on the first line to set its initial location:

 Object dollar "dollar" fire_escape          with description "It looks like it's been in circulation for quite           a while.",         name 'dollar' 'bill' 'buck' 'washington', has;     Object crowbar "crowbar"  with description "It's old and rusty, but it still does everything             it was made to do.",         name 'crowbar' 'bar', has; Object manhole_lid "manhole" manhole_room         with description "The center reads, 'City Sewage'", name 'manhole' 'hole' 'portal', with_key crowbar, door_dir d_to, door_to win_room, has scenery door openable lockable locked; Object bum "Pat" bum_town         with description "He reeks of alcohol and potato chips.", name 'bum' 'pat' 'drunk' 'vagrant', life [;     Give:                 if(noun == dollar)   {                         move dollar to self;     move crowbar to player;     "Pat grunts and rolls over, revealing his crowbar.                        You take it.";    }    else "Pat doesn't want that."; ], has scenery animate proper; 

You will also need to connect the manhole room to its door (the manhole lid). You can do that by adding the line shown in bold to the manhole room's definition:

 Object manhole_room "Manhole"         with description "There's a manhole at this end of the alley.", nw_to the_alley,  d_to manhole_lid,  has light; 

Here's a breakdown of how the items were defined in the preceding code:



name

The name attribute allows the player to refer to an item by more than its in-game name. While you don't need to go crazy, put yourself in the player's shoes and think of at least one easy-to-use shorthand name. Be extremely careful with the syntax: use single quotes, one space in between names, and a comma at the end.



object manhole_lid

The manhole is a lockable door, and as such has several attributes that define it as such. The first is its key (in this case, the crowbar), followed by which direction it's blocking (down), and where it leads (the "You win!" room).

door, openable, lockable , and locked are also door- related properties that should be self-explanatory. Leaving any one of them out will render your door useless.



scenery

scenery takes care of two things: it prevents the player from picking up the object, and it removes the "There is also a manhole/bum here." line. Since both the room name and description allude to the object's existence, it's unnecessary (and awkward ) for the player to see the extra line. You can still look at and interact with them like any other item.



life

The large block of code following Pat's declaration is a routine that allows you to interact with him. life is a built-in INFORM routine; here, you use it to make Pat react to the player. Give indicates the command Pat reacts to, while if(noun==dollar ) checks to see if the player is trying to give him the dollar. If she is, Pat takes the dollar and gives the player the crowbar via INFORM's move function. Otherwise, Pat declines.



animate

animate tells INFORM that Pat is a living creature, which will change the game's default responses when you interact with him, while proper indicates Pat is a proper noun and should be referred to by name, with no articles in front.

The game is now complete; you can wander all over our little world, give poor Pat some money and triumphantly enter the sewer. You can go back and add in more rooms, make Pat react to more commands, or take what you've learned and start bringing your own ideas to life.

Here is a walkthrough of this simple game. Note that this game takes some artistic license with the meaning of the word "unlock":

 City Adventure Release 1 / Serial number 050621 / Inform v6.30 Library 6/11 SD An alley  This is a small back alley. A fire escape is accessible immediately  above you, and exits lead off to the east, southeast, and northeast. >  u  Fire escape You're way up high. The floor wobbles unsteadily. You can see a dollar here. >  take dollar  Taken. >  d  An alley >  e  Pat's cardboard box A surly bum named Pat lies asleep here. >  give pat a dollar  Pat grunts and rolls over, revealing his crowbar. You take it. >  w  An alley >  se  Manhole There's a manhole at this end of the alley. >  unlock manhole  (with the crowbar) You unlock the manhole. >  open it  You open the manhole. >  d  You win! You descend into the sewers, smiling happily. You win!         *** You have won ***      In that game you scored 0 out of a possible 0, in 11 turns. Would you like to RESTART, RESTORE a saved game or QUIT? 

Amazingly enough, we've barely scratched the surface of INFORM's capabilitiesit's possible to kill the player with traps or deadly items, have the game respond to commands with custom messages, award points for getting items or accomplishing tasks , and even add to the code libraries and make your own commands! With INFORM, your imagination is the only limit. To take your game to the next level, be sure to read the Inform Designer's Manual (http://www.inform-fiction.org/manual/).

Matt DelGiudice



Retro Gaming Hacks
Retro Gaming Hacks: Tips & Tools for Playing the Classics
ISBN: 0596009178
EAN: 2147483647
Year: 2003
Pages: 150
Authors: Chris Kohler

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net