House 7 Inform Tutorial

From IFWiki

In 1998, David Cornelson put together a set of Inform 6 source files that would help beginners with their interactive fiction education. They are recreated here.

Jump to any of the source code examples: Tutorial 1 | Tutorial 2 | Tutorial 3 | Tutorial 4 | Tutorial 5 | Tutorial 6 | Tutorial 7 | Tutorial 8

Return to main article: House Tutorial (Inform)

   ! ------------------------------------------------------------------------------
   ! Inform for New Writers
   !
   ! The House - Version 7
   !
   ! Last Modified: David Cornelson - 01-Feb-1998
   !
   ! This work is freely offered to the Public Domain. - DAC 12-12-2015
   !
   ! ------------------------------------------------------------------------------
   
   Constant Story "The House";
   
   Constant Headline
              "^Inform for New Writers^
                The House - Version 7^
                By New Writer (1998) - Last Compiled: 01-Feb-1998^";
   
   Constant MAX_SCORE 100;
   Serial "980201";
   
   Release 1;
   
   Include "Parser";
   Include "VerbLib";
   
   !-------------------------------------------------------------------------------
   ! Initialise
   !
   !-------------------------------------------------------------------------------
   
   [ Initialise;
   
       location        = Sidewalk;
   
   ];
   
   [ PrintRank;
     print ", earning you the rank of ";
     if (score >= 100) "the greatest.";
     if (score >= 80) "above average.";
     if (score >= 60) "average.";
     if (score >= 40) "below average.";
     if (score >= 20) "the barely living.";
     "the living dead.";
   ];
   
   ! ----------------------------------------------------------------------------
   ! Locations
   !
   ! In this section we will define our locations. These are "Objects" to Inform.
   !
   ! ----------------------------------------------------------------------------
   
   Object Sidewalk "Sidewalk"
       with  description
             "You are standing on the sidewalk in front of a house to the west.",
       w_to  Front_Porch,
       has   light;
   
   Object -> Mailbox "mailbox"
       with    name "mailbox" "box",
   
       before  [;  Open:   if (Snark in Mailbox) {
   
                               StartDaemon(Snark);
                               move Snark to player;
                               give Mailbox open;
   
                               print "~Hey! It's about time! Why are you piddling
                               around out there? Don't you know I need air? Who
                               do you think you are anyway, some big adventurer
                               or something? Pullllease!~, exclaims a small pink
                               thing from the mailbox.^^~Hi. I'm Snark, the 
                               Jarbigruen!~, he cries in a high-pitched voice
                               and then leaps from the mailbox into your
                               arms.^";
                               rtrue;
                           }
               ],
       when_open   "There is an open mailbox here.",
       when_closed "There is a closed mailbox here.",
       has     static container openable;
   
   Object -> -> Snark "small pink Jarbigruen"
       with    name "snark" "jarbigruen" "alien" "monster" "thing",
               description
               "Snark, a little pink Jarbigruen, stands approximately ten
                centimeters tall, has two legs, two arms with tiny little hands,
                a wide-eyed face, and a tuft of yellowish hair on his head.",
   
       before  [; Drop,Insert: if (second == Evil_Couch) {
                                   print "You drop Snark onto the couch and the
                                          cushions begin to smother him slowly,
                                          until he completely disappears. After
                                          a few seconds you hear strange noises
                                          and, ** POP **, a pink ball is spit out
                                          of the couch back into your arms!^^
                                          Snark looks up at you and winks,
                                          ~Jarbigruen's don't go down very easy,
                                          I guess.~^";
                                   rtrue;
                                }
                                print "~Hey! I'm not going anywhere without you!~,
                                       Snark says.^";
                                rtrue;
               ],
       daemon  [;   switch (random(10)) {
                        1: "Snark says, ~Isn't it great to be here!~";
                        3: "Snark looks up at you with a glint in his eye and
                            tickles you.";
                        5: "Snark says, ~You are an excellent adventurer!~";
                        7: "Snark cries, ~Stop it! Your holding me too tight!~";
                        9: "Snark rifles through your pockets and sighs, 
                            ~Got any candy?~";
                    }
               ],
       has     animate;
   
   Attribute legible;
   
   Object -> -> Letter "letter"
       with    name "letter" "paper",
               description
               "The letter is a simple page of notebook paper.",
       before  [; Consult,Read: "The letter contains a vague story about an evil couch,
                                 but you can't make out anymore detail. Interesting
                                 little tidbit though.";
                  Tear: remove Letter;
                        "You rip the letter into tiny pieces that blow away in the wind.";
               ]
       has     legible;
   
   Object Front_Porch "Front Porch"
       with  description
             "This is the front porch of the house. There are two doors
              leading inside. The door on the left leads west and the
              door on the right leads northwest.",
       e_to  Sidewalk,
       w_to  Left_Front_Door,
       in_to Left_Front_Door,
       nw_to Right_Front_Door,
       has   light;
   
   !
   ! VERSION 7 - Using a Class statement to create a group of common objects
   !
   ! There are times when building your game that you begin building the same
   ! types of objects over and over. You end up copying code all over the place
   ! and maintaining this code becomes a search and replace chase scene.
   !
   ! Well, in some instances, there is a better way. We have to discuss a little
   ! bit of methodology first though.
   !
   ! Most games hsouldn't be written like 'The House'. You should write out as much
   ! of your story and physical world as possible. When you have a fairly complete
   ! view of this world, you break down all of aspects into objects.
   !
   ! If we designed the current version of 'The House' this way, it would look
   ! something like this...
   !
   ! ----------------------------
   !
   ! Sidewalk -> Mailbox -> Snark
   !                     -> Letter
   !
   ! Front Porch -> Left Door
   !             -> Right Door
   !
   !   Foyer
   !
   !    Den -> Rock
   !     
   ! Living Room -> Evil Couch
   !
   !   Hallway
   !
   ! Upper Hallway
   !
   ! North Bedroom -> Key
   !
   ! South Bedroom
   !
   ! Kitchen
   !
   ! Backyard -> Pond
   !
   ! ----------------------------
   !
   ! You will likely want to do this BEFORE you begin programming your game. The reason
   ! is that you may be able to reduce some of your coding by locating similar objects.
   !
   ! Q: What two objects in 'The House' are alike?
   !
   ! A: The doors
   !
   ! Correct. We are going to rewrite the two door objects, but first we're going to create
   ! a class for the foundation of their definition.
   !
   
   Class Front_Door
       with    name "front" "door",
       has     static door openable open;
   
   !
   ! And now we'll change the each door object to become a subset of this class.
   ! Notice that we can leave out the names and attributes in the class. These
   ! are 'inherited' by the newly defined objects.
   !
   ! In this example, we didn't reduce our code all that much. But in many cases
   ! you will reduce your code. A good use of this is when you have an NPC or
   ! non-playing character that you want to be seen as learning. You can create
   ! a base class object with rudimentary actions and change to other objects
   ! when the NPC is supposed to be 'smarter'.
   !
   ! Class Base_Snark ...
   !
   ! Base_Snark Snark_1 ...
   ! Base_Snark Snark_2 ...
   ! Base_Snark Snark_3 ...
   !
   ! Anything you define in the class object, is inherited by the continuing
   ! objects. If you redefine something, such as an attribute or property,
   ! then the new definition supercedes the class definition.
   !
   
   Front_Door -> Left_Front_Door "left front door"
       with    name "left",
               description
               "The left front door is made of brass.",
       when_open    "The left front door is open.",
       when_closed  "The left front door is closed.",
       door_to      Foyer,
       door_dir     w_to;
   
   Front_Door -> Right_Front_Door "right front door"
       with    name "right",
               description
               "The right front door is made of wood.",
       when_open     "The right front door is open.",
       when_closed   "The right front door is closed.",
       door_to       [; if (location==Front_Porch) return Den; return Front_Porch; ],
       door_dir      [; if (location==Front_Porch) return nw_to; return se_to; ],
       found_in      Front_Porch Den,
       with_key      right_key,
       has           lockable locked;
   
   Object Den "Den"
       with    description
               "You are in the den of the house. The living room is west of hear
                and the front porch is to the southeast.",
       se_to    Right_Front_Door,
       out_to   Right_Front_Door,
       w_to     Living_Room,
       has      light;
   
   Object -> Rock "rock"
       with    name "rock",
               description
               "It's smooth and flat, perfect for skipping in a pond.",
       before    [;    Insert,PutOn,ThrowAt:
                           if (second==Evil_Couch) rfalse; ! Allow the rock to be eaten by couch
                           if (second==Pond) {
                               print "The rock skips across the water several times and sinks.
                                      Amazingly, after a few moments, the rock washes up at
                                      your feet. Wow, what an undertow!^";
                               move Rock to Backyard;
                               rtrue;
                            } else {
                                print "You can't throw the rock at ",(the) second, ".^";
                               rtrue;
                            }
               ];
   
   Object Living_Room "Living Room"
       with    name "living" "room",
               description
               "This is the living room of the house. The den is to the east.",
       e_to    Den,
       has     light;
   
   Object -> Evil_Couch "couch"
       with    name "couch" "sofa",
       when_open "There is a filthy, worn down couch here.",
       before  [;  Enter: deadflag=1;
                          "You are eaten by the couch. As you flail for your last few
                           seconds, you see Snark beating on the couch trying to save
                           you, to no avail.";
                   Receive: remove noun;
                            "The couch eats ", (the) noun, " and belches.";
               ],
       has     static container open enterable;
   
   Object Foyer "Foyer"
       with  description
             "You are standing in the foyer of the house. It seems as though
              you can go up a staircase, northwest, or back out the front
              door to the east.",
       out_to Front_Porch,
       e_to   Front_Porch,
       nw_to  Hallway,
       u_to   Upper_Hallway,
       has    light;
   
   Object Hallway "Hallway"
       with   description
              "You are in the hallway on the first floor of the house. The
               foyer is southeast and the kitchen is west of here.",
       se_to  Foyer,
       w_to   Kitchen,
       has    light;
   
   Object Kitchen "Kitchen"
       with   description
              "This is the kitchen of the house. A hallway can be seen to the
               east and an open doorway to the west leads out to the backyard.",
       e_to    Hallway,
       w_to    Backyard,
       out_to    Backyard,
       has        light;
   
   Object Backyard "Backyard"
       with    name "yard",
               description
               "This is the backyard behind the house. There is a pond here.",
       e_to    Kitchen,
       in_to    Kitchen,
       has        light;
   
   Object -> Pond "pond"
       with    name "pond" "water",
               description
               "It's a small pond, but wide enough to skip rocks.",
       has        static concealed container open;
   
   Object Upper_Hallway "Upper Hallway"
       with   description
              "This is the second floor hallway. Rooms can be seen north and
               south and a staircase leads down.",
       n_to   North_Bedroom,
       s_to   South_Bedroom,
       d_to   Foyer,
       has    light;
   
   Object North_Bedroom "North Bedroom"
       with   description
              "This is a bedroom on the north side of the house.",
       s_to   Upper_Hallway,
       has    light;
   
   Object -> right_key "right key" with name "right" "key", article "the";
   
   Object South_Bedroom "South Bedroom"
       with   description
              "This is a bedroom on the south side of the house.",
       n_to   Upper_Hallway,
       has    light;
   
   ! ----------------------------------------------------------------------------
   !
   ! Functions
   !
   ! ----------------------------------------------------------------------------
   
   [ ReadSub; <<Examine noun>>; ];
   
   [ TearSub; "You can't tear that"; ];
   
   ! ----------------------------------------------------------------------------
   ! Grammar
   !
   ! The grammar section includes the file "Grammar" and will later include
   ! extensions to the standard grammar library.
   !
   ! ----------------------------------------------------------------------------
   
   Include "Grammar";
   
   Extend "read" first * legible                         -> Read;
   
   Verb "tear" * noun                                    -> Tear;