Roger Firth's IF pages

Home

InFancy -- using Inform objects

Email
Back up

Now that we've got the theory out of the way, we can start defining some real objects. First, we'll talk about how you can refer to your objects -- the name property and its associates.

"name" property

The name property holds a list of dictionary words, given in single quotes '...', which along with the implicit THE and A, may be used when referring to an object. Inform actually allows double quotes "..." also to be used here (elsewhere, something in double quotes is a string) but I recommend that you avoid confusion by sticking to apostrophes in the name property. There's one exception to this rule: if you need to give an object a one-character name, you can't use single quotes alone, since one character in apostrophes -- for instance 'X' -- is an ASCII character constant. Instead, for a one-character name either follow the character with two slashes 'X//', use double quotes "X", or employ the decidedly obscure construct #n$X. Here's our simple object tree again, with suitable name values (and also a handful of appropriate attributes):

 
Object  kitchen "Kitchen"
  with  description "Oddly, there are no exits."
  has   light;

Object  kitchen_table "table" kitchen
  with  name 'battered' 'pine' 'table'
  has   static supporter;

Object  bottle "bottle" kitchen_table
  with  name 'green' 'glass' 'bottle'
  has   transparent;

Object  label "label" bottle
  with  name 'faded' 'label';

Object  cork "cork" bottle
  with  name 'cork';

Object  glass "glass tumbler" kitchen_table
  with  name 'chipped' 'glass' 'tumbler';

In this example, the kitchen object (to which we've added a minimal description property to avoid run-time errors) doesn't have a name property. Inform assumes that you never need to refer to a room by name, and so offers a room's name as a suitable place to hold a list of 'irrelevant' words -- ones whose use triggers the response "That's not something you need to refer to in the course of this game". Often, but not always, that's a sensible option... but see also the discussion of scenic.h on a later page.

The attributes we're using are mostly self-evident; the kitchen object has light (or else we'd be blundering around in the dark), and the kitchen_table object is a static supporter (so that it's not takeable, and its children -- the bottle and the glass -- are properly listed in the room description). The oddest attribute is the bottle's transparent. This doesn't refer to the fact that it's made of glass, but rather ensures that the bottle's children -- the label and the cork -- are in scope and can be examined (though they don't yet appear in the bottle's description).

"parse_name" property

Given only this basic set of properties and attributes, we can compile and test the room. Even in this minimal state, it all works remarkably well, insofar as the room's contents can be examined and manipulated. You can refer to the only piece of furniture as THE TABLE, THE BATTERED PINE TABLE, PINE, and so on. The most obvious problem is with the word GLASS, used in both the bottle and the tumbler. You can refer to THE GLASS BOTTLE and THE GLASS TUMBLER easily enough, but if you mention simply THE GLASS, Inform will ask which of the two objects is meant. Here, it's fairly clear that a player using THE GLASS would expect to address the tumbler rather than the bottle. To fix this, we need to teach the bottle not to respond to the word GLASS alone. We do this by supplementing or replacing its name property with a parse_name property. In this example, we replace name completely:

 
Object  bottle "bottle" kitchen_table
  with  parse_name [ wd adj_count noun_count;
        if (parser_action == ##TheSame) return -2;
        wd = NextWord();
        while (wd == 'green' or 'glass' or 'wine' or 'corked')
            { wd = NextWord(); adj_count++; }
        while (wd == 'bottle' or 'flask' or 'flagon')
            { wd = NextWord(); noun_count++; }
        if (noun_count > 0) return noun_count + adj_count;
        return 0;
        ]
  has   transparent;

The primary job of an object's parse_name routine is to count the number of consecutive input words which could apply to that object. In the example code above (shamelessly stolen from Neil Cerutti's excellent Ditch Day Drifter tutorial), zero or more adjectives can precede one or more nouns, so that GREEN GLASS BOTTLE returns a count of 3, GLASS BOTTLE returns 2, BOTTLE returns 1 but GLASS returns 0. Since the bottle now effectively ignores the solitary word GLASS, the tumbler is free to recognise it unambiguously. (You can also write a parse_name routine which returns -1, in which case you must additionally supply a name property which Inform then uses in the conventional way.)

A parse_name routine has a secondary role: helping the parser to choose between apparently identical objects. The test on the first line -- if (parser_action == ##TheSame) -- ensures that we deal with that situation separately. Here's a short run-time example of what we've built so far:

 
Kitchen
Oddly, there are no exits.

You can see a table (on which are a bottle and a glass tumbler) here.

>EXAMINE THE TABLE
You see nothing special about the table.

>TAKE THE BOTTLE
Taken.

>EXAMINE IT
You see nothing special about the bottle.

>INV
You are carrying:
  a bottle

>EXAMINE LABEL
You see nothing special about the label.

>TAKE IT
That seems to be a part of the bottle.

>TAKE GLASS
Taken.

While the player uses words defined in name and parse_name properties, the game itself refers to an object by its xname. More on that next.