Home


Search

Back issues

Guestbook

Community

Related links

Subscribe

FAQ

XYZZYnews

Tales From the Code Front:
The Hardest Part is
Making It Look Easy, or,
Five Simple Steps to Coding a Stetson

by Phil Darnowsky

This vacation, I decided to amuse myself (and, hopefully, others) by writing my own text adventure. The hardest part, I found, was not thinking up a plot line, or writing puzzles. The hardest part was making my objects, the player, and the game world interact in a natural-seeming manner -- in other words, making it look easy.

As it turned out, one of the most difficult objects to implement (as of this stage of coding, anyway) was a simple gray hat. Simple? Sure. Read on and see just how simple a hat can be to implement...

  1. I get an idea for a puzzle: The player needs to cross a certain obstacle with their hands free, and yet transport a pack of cigarettes across it. The solution that occurs to me? Allow the player to put the cigarettes in their hat! Humming contentedly, I begin coding.
  2. I give the hat the "container" attribute (Note: I program in Inform, but I'm sure TADS programmers have had similar experiences). I re-compile and check my inventory. Unfortunately, I had forgotten that the hat had sub-objects (a hat-band, specifically), and now that the hat was a container, the hat-band was described as being in the hat, rather than part of it. No sweat: this is why I keep the Inform Designers' Manual handy. After flipping through it for a minute, I find the property add_to_scope, which allows me (among a host of other uses) to define sub-objects of a container, without actually putting the things in the container. I fix that, and re-compile.
  3. Upon testing it yet again, I realize my new dilemma. Due to the way that Inform treats containers and scope rules, my choices are two: either have the contents of the hat visible to the player all the time, or only when the hat is "open." Since neither an invisible hat nor an "openable" one appeal to me, I come up with a clever little routine that "opens" the hat whenever it is removed, and "closes" it (and thus hides any objects inside) whenever it is put on. Re-compile and smoke break.
  4. That now works, but ever the perfectionist, I decide that when the hat is "open" (i.e. unworn) EXAMINING the hat should provide a list of whatever is inside it. That's easy enough to implement, but I realize, upon re-compiling yet again, that the description of the hat describes the hat as "empty" when there is nothing in it -- which is right in itself, but gives the puzzle away. Another quick consultation of the Designers' Manual provides me with the answer, and I type the command to compile with a deep sense of pessimism.
  5. One which is well-founded: although the description of the hat doesn't give away the fact that things can be put inside it, I realize that ANYTHING can be put in this hat, including such unwieldy things as a mandolin case. A quick slash and burn through the code later, having marked as "small" everything small enough to fit in the hat, and a re-compile, the hat finally works, more or less.
This whole process took me more than an hour, from conception of the puzzle to the final testing. What do I get for my hour of work? A hat that interacts properly with its environment.

Some people would feel that spending that long on such a seemingly unimportant object is foolish. They are overlooking the importance of suspension of disbelief, the magic ingredient that makes fiction work. Suspension of disbelief is a funny thing: people will believe in dragons, fairies, and the honesty of the government, but give them a hat that they can look through while it's on their head and you've lost them. Making it look easy may be the hardest trick, but it's also the most important.

[Author's Note: After writing this, I discovered one or two more small bugs in the code for the hat, which I squelched rapidly. If you like, think of this as "Seven Easy Steps to Coding a Stetson."]


Source code example: Defining the Stetson

This is all of the code associated with the Stetson that gave me merry hell, with the backslashes omitted for clarity. -- P.D.
Attribute small;                               ! Will fit in the hat

Object arthur "Arthur, King of the Hats"
  with name "arthur" "king" "hat" "stetson" "fedora" "gray" "heirloom" 
            "classic",
       description [; print "This gray Stetson fedora is a classic, 
first 
                            worn by your grandfather.  It's an old 
family
                            heirloom, and you're proud to have it.";
                      if (feather in hatband) print " There's a pigeon
                            feather jauntily stuck in the hatband.";
                      if ((children(self) ~= 0) && self has open)
                        <>;
                      " ";
                   ],
       before [; Receive: if (noun == feather) <>;
                          if (self hasnt open)
                            "You'd have to take the hat off first.";
                          if (noun hasnt small)
                            "That won't fit in your hat.";
                 Wear: give self ~open;
                 Disrobe: give self open;
              ],
       invent [; if (inventory_stage == 2)
                   if (self hasnt open || children(self) == 0) rtrue;
                 rfalse;
              ],
       add_to_scope hatband,
       capacity 3
has clothing worn proper container ~openable;

Note that this chunk of code is still not bug-free. Back to the text editor...


Go to the next page in this issue
Flip back to the previous page
Go to the XYZZYnews home page
This site is maintained by Eileen Mullin
Legal information