Attributes in Inform 6

From IFWiki

What is an attribute?

An attribute in Inform 6 is a named characteristic of an object, represented internally by a single bit in that object's data structure. Attributes can only have two possible values: 0 or 1. Programmers might call this a flag or a boolean which can be set (1) or cleared (0).

Using bits to store common either-or properties for every object results in a smaller story file than any other scheme for storing them. In the 1980's, using a byte or two to store a boolean value was wasteful. It was an overriding concern that Z-code files compile small enough to fit in the Z-machine and therefore be able to run on personal computers. Modern machines may have far more memory, but the Z-machine's limitations remain.

A small disadvantage to this scheme is that authors must learn and use a different set of syntaxes to manipulate attributes than they would for manipulating all the other properties of an object. Some programmers might find Inform 6's syntax for handling attributes to be esthetically unpleasing for this reason.

(For more about this general programming concept, see boolean datatype, bit, and flag (computing) on Wikipedia.)

Using attributes

Creating new attributes

The Inform library predefines 31 attributes, such as open, animate, etc., most of which are free for authors to use in their code. New attributes are declared using the Attribute declaration, for example:

Attribute burnable;
Attribute readable;

Place any Attribute declarations near the beginning of your source code, but after the Include "Parser" line.

The effect of an Attribute declaration is global. For example, any object may now be initialized as burnable, set as burnable later in the game, or tested to see if it is burnable. By itself, the Attribute declaration only defines an abstract either-or property that objects may have; additional code must be written if "burnable" or "readable" is to mean anything.

Initializing an object with attributes

Use the has segment of an object's definition to initialize it with the desired attributes. For example:

! The newspaper is burnable and readable.
Object newspaper "newspaper"
  with name 'newspaper',
  has burnable readable;

! The bathroom door is initially unlocked and open.
LockableDoor bathroom_door "bathroom door"
  with name 'bathroom' 'door',
  has ~locked open;

Note:

  • Attributes may be listed in any order in a has segment.
  • Do not insert commas between attributes.
  • By default, attributes for an object are unset. Put a tilde before an attribute you explicitly want unset, e.g. ~locked. This may be necessary if you're using a class with preset attributes that for some instances you want cleared.

(By convention, the has segment is listed last in an object's definition, but this is not required. If an object is declared without any attributes set, the has segment may be omitted.)

Setting an attribute

Use the give statement to set object attributes, for example:

give box open;
give hat worn;

Clearing an attribute

Again, use the give statement, but put a tilde before the attribute that you want to clear. For example:

give diary ~locked;
give flashlight ~on;

Note that multiple attributes can be set or cleared in the same give-statement, e.g.:

give fragile_door open ~locked ~lockable ~openable;

Testing an attribute

Use the has operator to test if an object has a particular attribute set. For example, here we test if the player character is wearing the 3D-glasses when examining a poster:

Object poster "groovy poster"
with name 'groovy' 'poster',
  description [;
    print "The poster on the back of the door is one of those seemingly-abstract
           designs made from an overlapping jumble of red and blue shapes. ";
    if (glasses has worn)
       "But with the 3D-glasses on, a hidden message is revealed:
        ~BEWARE THE HYPNOTIST!~";
    else
       "It hurts your eyes just trying to make any sense of it.";
  ],
has static;

Likewise, use the hasnt operator to test if an attribute is not set, e.g.: if (glasses hasnt worn). Note that the hasnt operator is spelled without an apostrophe.

Pre-defined attributes

The Inform library predefines the following 31 attributes:

  • absent. The object is currently not at its usual location(s).
  • animate. The object is some sort of creature or person.
  • clothing. The player character can wear this object; it's clothing.
  • concealed. The object is here but can't be seen.
  • container. This object can have other objects inside it.
  • door. The object is a door.
  • edible. The object is edible; it's food.
  • enterable. The PC can be located inside or on top of this object.
  • female. The object is female, or has the female gender.
  • general. No predefined meaning. The author may mark an object as "general" for any reason.
  • light. The object provides light; it is lit.
  • lockable. The object can be locked and unlocked.
  • locked. The object is locked.
  • male. The object is male, or has the male gender.
  • moved. The object has been moved from its original location.
  • neuter. The object has the neuter gender.
  • on. The object is turned on; it is activated.
  • open. The object is open.
  • openable. The object can be opened and closed.
  • pluralname. The object has a plural name, such as "clouds".
  • proper. The object has a proper name, such as "Robert".
  • scenery. The object is a feature of its location; compare with static.
  • scored. The points associated with this object have been awarded.
  • static. The object is fixed in place; compare with scenery.
  • supporter. This object can have other objects on top of it.
  • switchable. The object can be turned on and off.
  • talkable. This object can be talked to, e.g.: telephone, microphone.
  • transparent. The object's contents can be seen (assuming there's light).
  • visited. The player character has visited this location.
  • workflag. This object has been temporarily selected by the Inform library for some reason.
  • worn. The player character is currently wearing this object.

Technical details

  • Inform library: The standard attributes are defined in the linklpa.h file.
  • Z-machine: The maximum number of attributes is 48. (See DM4 §45, note 6.) Since the Inform library predefines 31, this means an author may only define 17 new attributes. If this isn't enough, an author might instead use properties, or try overloading existing attributes, or create a property containing an array of flags, or move the project to Glulx.
  • Glulx: Glulx Inform gets a default maximum of 56 attributes, represented in a 7-byte field, but this limit can be increased by changing the $NUM_ATTR_BYTES memory setting. (See The Glulx Inform Technical Reference.)

Code Compare

Further reading

  • DM4 §3.7   Declaring objects 4: has and give
  • DM4 §A1   Library attributes - Summarizes the 31 attributes predefined by the Inform library.