House 5 Inform Tutorial

From IFWiki
Jump to: navigation, search

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 5
   !
   ! Last Modified: David Cornelson - 22-Jan-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 5^
                By New Writer (1998) - Last Compiled: 22-Jan-1998^";
   
   Constant MAX_SCORE 100;
   Serial "980122";
   
   Release 2;
   
   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.
   !
   ! ----------------------------------------------------------------------------
   
   !
   ! VERSION 5 - Adding a container to your game, functions, verbs, and death.
   !
   ! In many cases you will want an object to be able to contain other objects.
   ! This may be as simple as creating a 'backpack' that will contain your school
   ! papers, apple, and pencil sharpener. In a more complex definition, a container
   ! could be a chasm, a bottomless pit, refrigerator, or a television.
   !
   ! We're going to create a simple container and a complex container.
   !
   ! The simple container is probably very familiar to you. It's a mailbox amd it's
   ! right here in front of the house. It contains a letter that can be read as well.
   !
   
   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;
   
   !
   ! Add the mailbox with open and closed descriptions.
   !
   Object -> Mailbox "mailbox"
       with    name "mailbox" "box",
       when_open   "There is an open mailbox here.",
       when_closed "There is a closed mailbox here.",
       has     static container openable;
   
   !
   ! Add 'legible' attribute to distinguish something that can be 'read'.
   ! This is determined in the verb extension located in the grammar
   ! section at the end of this file.
   !
   Attribute legible;
   
   !
   ! And here is the letter, which can be consulted, read, or torn up. If it's
   ! torn up, the letter is removed from the game, never to be seen again.
   !
   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;
   
   Object -> Left_Front_Door "left front door"
       with    name "left" "front" "door",
               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,
       has          static door openable;
   
   Object Right_Front_Door "right front door"
       with    name "right" "front" "door",
               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            static door openable 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;
                               !
                               ! Replace rock so that player can try it again....
                               !
                            } 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;
   
   !
   ! And here is our evil couch. Anything put on or in the couch will be
   ! 'eaten', including you. In fact, by setting the 'deadflag' to 1,
   ! Inform is informed to 'end' the game because you have died.
   !
   ! Notice we used the 'before' property and the 'Enter' and 'Receive'
   ! verbs to handle the action.
   !
   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.";
                   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
   !
   ! ----------------------------------------------------------------------------
   
   !
   ! Added function ReadSub so that the property 'before' can use it. The default,
   ! if there is no 'before read', is to examine the object.
   !
   [ 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";
   
   !
   ! We also have to extend the read grammar to call ReadSub
   ! by default.
   !
   ! We're using the 'Extend' statment because the word "read" is already defined
   ! in the grammar file included above. This adds our usage.
   !
   ! The 'first' tag is used to indicate to Inform that this usage of the word
   ! "read" should be the first one checked. Without 'first', the "read" word
   ! will not work the way we want it to because the default usage will get
   ! called and will not handle our code properly.
   !
   ! 'legible' is the attribute we created and by placing it here, we're telling
   ! Inform that this attribute must be present in the object to call this usage
   ! of the word "read".
   !
   Extend "read" first * legible                       -> Read;
   
   !
   ! We've also added the ability to 'tear' an object. Notice
   ! we had to specify 'noun' and then direct the default to
   ! TearSub.
   !
   ! By the way, the 'Sub' is added on automatically by Inform.
   !
   ! The word 'noun' tells Inform that the word "tear" must be followed by a
   ! noun, otherwise Inform will reply, "What do you want to tear?".
   !
   Verb "tear" * noun                                    -> Tear;
   !
   ! Q: I'm really confused! Inform uses the words "first", "second", and "noun".
   !    Can you explain the difference again?
   !
   ! A: Sure.
   !
   !    'first' is a flag used in the grammar statement "Extend" so that the
   !    new usage is called before previously defined usages. Without this
   !    flag, an older usage might get called and your code may not work.
   !
   !    'second' is a variable that Inform sets if there is a second noun in
   !    the player's statement.
   !
   !    'noun' is a variable that Inform sets if there are any nouns in the
   !    player's statement. It gets set to the first noun found.
   !
   !    > THROW ROCK AT POND
   !
   !              ^       ^
   !            noun    second
   !