WelcomeWhat's NewsInform GuideORLibraryDownloadsLinksWebMaster@OnyxRing.com

This site
produced
656719
pageviews since
8/19/2004

Today's date:
12/19/2018


Author: Inform Moderator
Title: Part C1: Miscellaneous ORLibrary Modules

Creation Date: 8/9/2004 6:10:34 PM
Last Updated: 8/9/2004 6:10:34 PM


NOTE: This article has been depreciated along with all of the original ORLib Manual efforts. The newer manual can be found at http://www.onyxring.com/ORLibDocToc.aspx




Part C1 : Miscellaneous ORLibrary Modules (part one)

In this section we will continue the development of our sample game by beginning to review and implement various ORLib modules. Since most of these examples will be added to rooms that are not available from the foyer, let’s change the starting room again:

 
location=library;

1. ORCenter

Center is a flexible routine used to center text on the screen. Its simplest usage is simply:

 
Center("Chapter One");

As could probably be guessed, this will simply center the worlds "Chapter One". A slightly more sophisticated use could involve multiple lines. The first time user might call the center() routine for each line, and though fine, the center() routine will also take into consideration line-breaks and adjust accordingly. For our tutorial example, let's place a bit of morbid poetry at the beginning of our tutorial using a single call to Center():

 
Center("^^How shall the burial rite be read?^The solemn
song be sung?^The requiem for the loveliest dead,
^That ever died so young? ^^-Edgar Allan Poe ~A Paean~");

Additionally, if the Center() routine does not encounter a line-break before reaching the ending of the line, it will word wrap the text and center it anyway. In this manner, unformatted text can also be centered.

As a final note, it should be mentioned that the center() routine relies upon mono-spaced fonts to achieve accurate centering calculations and will temporarily assume that mode when centering text.

2. OREject

The eject() routine takes no parameters and generates a transitional effect. It is most often used to separate passages of stand-alone text, such as chapters, by scrolling any printed text to the top of the screen and forcing the "More" prompt before continuing program output. The following tutorial example, added to the initialize() routine, demonstrates the transition between an introduction and the actual game substance:

 
 Center("^^Prologue^"); 
 print "It had been a game, a murder-mystery party where the 
     players paired off and investigated a mock killing. 
     Fun, I supposed, if something hadn't gone wrong. Or 
     right. One of the players, it seemed, had a problem 
     with another. Ms. Corpus had been murdered for real 
     by her game-partner during the course of the mock 
     investigation. ^^It looked as though the killing had 
     been planned all along, and the game was just a ruse 
     to get the right people together. ",(italics)"But who 
     had been her partner?","^^That was our job, to find 
     out. Both me, and that ",(strong)"creep",", Inspector 
     Snobby, had been assigned to the same case, though we 
     were working independently as we had numerous times 
     before.^^Historically, my track record competing 
     against Snobby wasn't too great.",(italics)" But this 
     time",", I swore with conviction, ",(italics)"I would 
     solve the case first!"; 
 Eject(); 
 Center("^^^^Part the First^^"); 
 print "Snobby and I had arrived at exactly the same moment, as we 
     often did. We were escorted into the Living Room and 
     each given a list of the game's players. The suspects, 
     we were told, were still wandering free in the house. I 
     would have to question everyone and see who Corpus' 
     partner had been. Snobby, I knew, would be doing the 
     same.^^"; 


Note the use of the (italics) and (bold) print rules covered in part B, section 6.2.

3. ORFirstThoughts

One of the considerations that must be made when writing interactive fiction concerns the coalescing of player and character knowledge bases. The character of a story will usually have some knowledge or opinion about something that needs to be communicated to the player. The ORFirstThoughts entry provides one possible mechanism for accomplishing this.

Objects derived from the ORFirstThoughts class make use of descriptions in two logical parts: The character's subjective thoughts when (s)he first examines the object and the actual non-subjective description of the object.

In practice the subjective portion of a description can both precede and follow the actual descriptive text. Think of it as a description sandwich where the meat of a description is wrapped in subjective bread. Each of these three description pieces are placed into one of three properties:

firsttime
descrip
firsttimePost

When an object (or room) is first examined, the text in the Descrip property is output between the text of the two Firsttime properties. Be default, subsequent examinations do not include the Firsttime text.

For players that want to re-read the character's initial first impressions, the verb REEXAMINE has been implemented and variations of EXAMINE and LOOK point to this (e.g. EXAMINE BOOK AGAIN, LOOK AGAIN AT MIRROR).

On a slightly technical note, the ORFirstThoughts class makes use of the description property. Defining this property effectively disables the ORFirstThoughts functionality for any given object.

Let us continue with our tutorial by adding the ORFirstThoughts functionality to our base classes:

 

 class MyObject !the basic object that you can pick up manipulate etc... 
   class ORFirstThoughts 
 ; 
 class MyRoom !a basic room object 
   class ORFirstThoughts 
   has light 
 ; 

Now we can implement some of the thoughts for the character as he sees the object or room in question. For the sake of clarity, we'll eliminate the morphing text enhancements that we made in section 7 and write the text in first-person, past-tense. Notice the use of the descrip property rather than description. Note also that the butler and maid have not been re-implemented. Although their descriptions could have been implemented in the descrip property, their importance to the game is minimal and they will serve as a reminder that the use of the description property is not off limits despite the choice to derive them for ORFirstThoughts (via the MyObject class). As they are, they continue to function as they always have.

 
 MyRoom Study "The Study" 
   with w_to Laboratory 
   , initial "My eyes took a moment to adjust to the dimly 
          illuminated room." 
   , firsttime "The study reminded me of my grandfather. I 
          am not certain why; possibly because of the manner 
          in which it was decorated. " 
   , descrip "It was a cozy room with plush carpeting and walls 
          lined in woodwork. An iron door lay to the west." 
   , firsttimepost "It was just the sort of room that my 
          grandfather would have as his own. He had always 
          loved woodworking. I could almost imagine him sitting 
          here, puffing on his pipe." 
 ; 
 MyRoom Laboratory "The Laboratory" 
   with e_to Study 
   , firsttime "It was a strange room to have in a house, a 
          laboratory. I wondered what sort of experiments were 
          conducted in the room as I looked around sizing it up. " 
   , descrip "Drab and bare, the lab was a cold sterile 
          environment, not at all comfortable but brightly lit. 
          Shards of glass, possibly from broken test tubes littered 
          the floor. The iron door to the study lay to the east." 
 ; 
 MyObject Candlestick "candlestick" study 
   with name 'stick' 
   , descrip "The candlestick was copper, or perhaps brass. The metal 
          had been polished so as to gleam in the room's lighting. It 
          was heavy and hard enough to make a formidable weapon." 
   , firsttimepost "I hefted it, calculating the force it would exert 
          across the back of someone's head. It could definitely serve 
          as a murder weapon." 
 ; 
 MyRoom foyer "Foyer" 
   with descrip "Of striking elegance, the foyer was exquisite in 
          every detail. The front door on the southern wall was
          closed and locked, preventing suspects from leaving, but 
          they wandered freely throughout the rest of the house. To 
          the north I could see a living room; to the east, a long 
          hallway. " 
   , firsttime "I looked around the entrance room and 
          smirked. This house was like something out of a movie. 
          Extravagance was the defining trait of this crime scene. " 
   , firsttimepost "I wandered in amazement why the suspects 
          hadn’t been confined for the duration of the investigation. " 
   , each_turn[; 
        print"^"; 
        ClearPronoun(); 
        if(random(2)==1) print (ig)CIVerb(butler, 
                "coughed","cough"),". "; 
        if(random(2)==1) print (ig)CIVerb(maid, 
                "scratched","scratch","scratches")," ", 
                (my)maid," chin. "; 
        if(random(2)==1) print 
                (ig)CIVerb(butler,"grimaced","grimace"), 
                " at ",(theMe)maid,". "; 
        if(random(2)==1) print (ig)CIVerb(maid, 
                "gave","give")," ",(theMe)butler," a wink."; 
     ] 
 ; 



4. ORDoor

The ORDoor class offers no new functionality over and above the standard door covered in section 13 of the DM4. It does, however, greatly reduce the amount of code needed to create one of these doors. The following is an example of a basic door which we could put between the Laboratory and the Study in our tutorial (Don't do this):


 
 !—A sample door without the ORDoor entry 
 Object SteelDoor "iron door" 
   has openable door static scenery open 
   with name 'metal' 
   , door_dir [; 
      if (parent(actor) == Study) 
           return w_to; 
      else 
           return e_to; 
     ] 
   , door_to [; 
      if (parent(actor) == Study) 
           return Laboratory; 
      else 
           return Study; 
     ] 
   , found_in Study Laboratory 
 ; 
				 



The door_dir and door_to properties implement a fairly straightforward algorithm. Specifically, they use the current location of the actor (or player if the door is not sensitive to NPC actions) to decide which of two possible values to return. The ORDoor entry implements this algorithm automatically so there is no longer a need to write specialized code for these properties.

Using the ORDoor entry, the same door can be created with the following four lines:


 
 !—A sample door WITH the ORDoor entry 
 ORDoor SteelDoor "iron door" 
   has open 
   with name 'metal' 
   , found_in Study Laboratory 
 ; 
				 


For our tutorial we'll go ahead and take this a step further and create a base class from which to derive all our doors:

 
 class MyDoor !a basic door 
   has open !leave doors open by default 
   class ORFirstThoughts 
   class ORDoor 
 ; 



Now we'll actually create the door (with a description to boot):


 
 MyDoor SteelDoor "iron door" 
   has ~open !close this door 
   with name 'metal' 
   , found_in Study Laboratory 
   , descrip "The iron door was thick and solid. Much 
          like I would have expected in a bank vault." 
 ; 
				 



Finally we'll point the appropriate directions to the door:


 
 MyRoom Study "The Study" 
   with w_to SteelDoor 
 . . . 

 MyRoom Laboratory "The Laboratory" 
   with e_to SteelDoor 
 . . . 




5. ORRecogName

The name property is the mechanism by which the Inform parser identifies which objects the player is referring to. The separation between the name and the display name has often been a source of grumbling by those who program in Inform. Many developers are annoyed at having to specify the words that in the display name in the name property as well:


 
 Object DirtyBook "old black leather bound book" 
   with name 'old' 'black' 'leather' 'bound' 'book' 
 ; 
				 


The ORRecogName library entry eliminates the need to specify the name property at all. The words of the display name will be used to identify an object and the name property can be used to specify synonyms alone.

There is no code needed to make the ORRecogName entry to work. Simply include it and it will begin working. In the tutorial thus far, notice that without this entry, the Candlestick can only be reference by the word "stick". Also the Steel Door can only be referenced by the word "metal", as can the cleaning lady with only the word "maid". After adding this entry, these objects can also be addressed by any of the words contained within their display name. That is, commands such as EXAMINE CANDLESTICK or OPEN DOOR or EXAMINE LADY will now work.

For the remainder of the tutorial examples, the ORRecogName entry will be presumed so the name property will not be defined at all for several objects.

6. ORLookRoom

This module adds the functionality of examining a neighboring room. That is, a player presented with the description of a room:

You are in the Dining Room. To the North is the Laboratory.

will have the ability to use any of the following:

look north
look at laboratory
examine laboratory

The description of a neighboring room is determined by the following logic:

1) If the current room has a direction-description property defined, then that is used. The following are direction-description properties:

n_look
s_look
e_look
w_look
nw_look
sw_look
ne_look
se_look
u_look
d_look

2) Failing the above, the room being looked at is searched for the 'remote_description' property. If found, then that is use.

3) Finally, if the all of the above fails, then the room being looked at is checked for the attribute 'describe_as_if_present'. If present, then the normal room descriptions are called as though the character were actually present in the room.

Note that the printing of a room description from a remote location is slightly more complex and an effort is made to determine if the room can actually be seen. That is, if the room is directly adjacent to the current location, or connected via a door that is either open or transparent.

Additionally, for completeness, the commands "examine room" and "look around" have been implemented along with minor variations.

To exemplify this entry, let us create another set of rooms that lead off from the Study with a couple of doors introduced as well:


 
 MyDoor darkdoor "dark door" 
   with descrip "This was a dark, dreary door." 
   , found_in library beach; 
 MyDoor glassdoor "glass door" 
   has transparent 
   with descrip "This was a clean, glass door." 
   , found_in SunRoom Beach; 
 MyRoom library "Library" 
   with w_to study 
   , n_to darkdoor 
   , remote_description "The library was dark and it was 
          difficult to make out details, but from this distance 
          it looked to be in a state of disarray. There 
          appeared to books piled sporadically with little or 
          no order. " 
   , descrip [; print "Somewhere, it seemed, a light was 
          burned out. The library was dark, but lit well enough 
          to see by. There were several shelves lined with 
          numerous books. In the corner sat a large storage 
          chest. Dim light strewn in from the south and west. "; 
          if(darkdoor has open) print"A brighter light 
          shown through the open door to the north. ";] 
   , firsttimepost "I shook my head at the disarray of 
          this room." 
 ; 
 MyRoom SunRoom "Sun Room" 
   with s_to study 
   , e_to glassdoor 
   , n_look "Through the windows was a breath-taking 
          view. A lush, green landscape extended as far as the 
          eye could see. The foliage to the west was 
          interrupted only by a winding, lazy river which feed 
          into the blue ocean to the east. The colors were so 
          vivid I felt that I could stare out the window for 
          hours." 
   , descrip "This sitting room was adequately furnished 
          with a small table and a couple of chairs being 
          centered in the room. On its own merit, it would 
          not have been a room that people frequented having 
          little that was especially inviting. By the windowed 
          wall to the north added an ambiance that was beyond 
          measure. The view it provided gave a feeling of 
          warmth and comfort making this a place that put its 
          occupants at ease and encouraged quiet conversation. 
          A large glass door led eastward to the beach. Almost 
          unnoticeable relative to the view in the other 
          directions lay doorways to the south and west. " 
 ; 
 MyRoom Beach "Beach" 
   with s_to darkdoor 
   , w_to glassdoor 
   , e_to "No, I didn’t have time to go for a swim." 
   , n_to "The trees blocked completely any travel in that 
          direction. No clues would be found there." 
   , remote_description "Through the door I could see a 
          beautiful beach with water lapping up on the 
                    ocean shore line." 
   , descrip "Beautiful and peaceful. My shoes were half 
          buried in the sand. Water lapped continuously 
          upon the shore merely an arms reach away. " 
   , firsttime "The scenery rendered my thoughts of 
          house murder all but forgotten. "
 ; 
				 




The Study itself should be modified to lead to the adjoining rooms too:


 
 MyRoom Study "The Study" 
   with w_to SteelDoor 
   , e_to library 
   , n_to sunroom 
 . . . 
				 



Now from any room that is adjacent to the library the command "examine library" will provide a remote description. Additionally, from the Sun Room the player can type "look north" to look through the window. From both the Library and the Sun Room, the player can examine the beach. Since the dark door is not transparent as the glass door is, it must of course be open in order for the player to see the beach from the library.

7. ORBox

One of the areas in which Inform falls short of the proverbial mark is in regard to the concept of "parent objects". In particular, an object can either be a supporter and have things put upon it (like a table) or be a container and have things put in it (like a bowl), but not both. This is limiting because in true life, nearly any container that can be opened and closed can also be a supporter (like a jewelry box).

The ORBox library entry simply defines an object which can both contain and support objects and be opened (like a jewelry chest). When open, objects can be inserted or removed from an ORBox. The contents are no longer able to be referenced to when the ORBox is closed, but objects can then be placed on top.

The details behind this library entry are fairly straightforward. The ORBox class defines a property named "contained_within", which defines an array of slots which can potentially contain objects. To define objects inside of a closed box at the start of the game, simply override this property with a list of the contained objects and optionally define a few extra empty slots for other objects as well.

For our tutorial, we will go ahead and create the storage chest along with a few items to place inside and on top of it:


 
 class MyBook 
   class MyObject 
   with short_name "leather bound book" 
   , plural "leather bound books" 
   , descrip "This is a single book, bound in leather. 
          The contents have faded and are no longer 
          legible." 
 ; 
 MyObject Knife "knife" 
   with descrip "The knife was dull. Unpolished and 
          uncared for, it was in shabby condition. " 
   , firsttimepost "Still, I thought as I inspected 
          the blade, it was in fair enough condition 
          to be lethal." 
 ; 
 MyObject StorageChest "storage chest" Library 
   class ORBox 
   has ~open scenery 
   with contained_within knife 0 0 0 0 0 0 0 0 0 0 0 0 
   , name 'wood' 'wooden' 
   , descrip "The storage chest was made of wood." 
 ; 
 MyBook ->-> book1; 
 MyBook ->-> book2; 
 MyBook ->-> book3; 
 MyBook ->-> book4; 
 MyBook ->-> book5; 
 MyBook ->-> book6; 
 MyBook ->-> book7; 
				 


8. ORExamWithContents

Usually, to view the contents of a container, "Look In" must be used. The ORExamWithContents entry is a simple module that causes the contents of a container to be described when it is examined. It takes no additional code to implement. Usin
g our tutorial thus far to demonstrate this module, try examining the storage chest without the ORExamWithContents module. Notice that the books sitting on top of the chest are mentioned in the initial description of the library, but not when the player issues the EXAMINE chest command. In order to see its contents the command LOOK ON CHEST must be used. Now uncomment the USE_ORExamWithContents constant and recompile. Notice that X CHEST will now display the contents.

9. ORSeveral

This module allows multiple objects of the same class to be described with an adjective rather than an exact number. For instance, it may be preferable that the description of 22 gold coins read as "several gold coins."

Two properties and one attribute have been introduced to implement this behavior:

plural_many - Set this property to the actual text to be displayed instead of the number. If this property is not defined for the class of the multiple objects, then the default library behavior takes precedence

many_number - Set this property to the number which must be surpassed
in order for the new behavior to occur. If this property is not defined for the class of the multiple objects then the default is used (3).

specific_number – This attribute is given to a parent object (or
container) to force the old behavior. This is often given to the player so that 22 gold coins reads as such in the player's inventory (instead of "several gold coins")

Although a describing the precise number of book that sit upon our chest is accurate, it seems too exacting of a description. Stating the number in this manner may come across as a needless tedium of detail, akin to saying "there are 216 acorns in the black pot." To avoid this, we will implement the ORSeveral library module and set up MyBook class to leverage it. Note the addition of the plural_many property:


 
 class MyBook 
   class MyObject 
   with short_name "leather bound book" 
   , plural "leather bound books" 
   , plural_many "several" 
   , descrip "This is a single book, bound in leather. The 
          contents have faded and are no longer legible." 
 ; 
				 


We'll keep the many_number set to the default of 3, since that seems a reasonable point to begin counting books. The description of the books now reads as "several leather bound books" instead of listing the exact number "seven." There is one place, however, that we would like to continue to express the exact number: our inventory. To accomplish this, we need to give the player object the specific_number attribute in the Initialize() routine:


 
give player specific_number;



Now there will never be any doubt as to exactly how many books the player is holding.

10. ORDistinctRead
Generally, the commands Read and Examine are treated the same and are mapped to the same verb which simply displays an object's description. This module adds a behavior to make a distinction between reading and just looking at an object.

To do this, ORDistinctRead relies upon a property called "read_value". If present, then the value of this property will be displayed in response to the READ command. If not, then a message is printed explaining that the object "cannot be read, only examined" and the normal description is printed.

To demonstrate this entry, let us declare another book, different from the other books so that it can be referred to (and thus read) uniquely:


 
 MyObject ->-> book8 
   with short_name "red leather book" 
   , descrip "This single book, bound in leather, has a 
          redish hue. Only a few words inside are legible." 
   , read_value "Only the dedication can still be made out. 
          It says, ~To my beloved wife.~" 
 ; 



The tutorial to this point can be found here.



Table of Contents:
Table of Contents
Previous:
Part B: Basic ORLibrary

Next:
Part C2 : Miscellaneous ORLibrary Modules




Copyright 2004 - 2018 : Inform Moderator
OnyxRing.com has been given the potentially non-exclusive right to display the content of this article. However the original author retains all rights. Permission to reproduce this article -- either in part or in whole -- is left strictly to the discretion of the original author.