Chapter 19: Advanced Text
19.7. Indexed text in variables, properties and tables

So far we have been able to ignore the difference between "text" and "indexed text" because Inform has always been able to convert the former to the latter when needed. But the reverse conversion cannot be made. Ordinary text is stored in a specially compacted, read-only form: it's really part of the program, not part of the data.

The upshot of this is that if we need a variable to contain text which can be internally altered during play, then we must declare this. Instead of writing

The player's forename is a text that varies.

we must write:

The player's forename is an indexed text that varies.

Similarly for a property:

A person has an indexed text called nickname.

For a named "let" value, we have a dilemma. These are normally created by writing something like:

let the target be 17;

and Inform looks at the value - here 17, a number - to deduce that the new value, called "target", must be a number. So if we write:

let the target be "excellent";

the result is that "target" is just a text, not an indexed text. We get around this by writing instead:

let the target be an indexed text;

which creates the value, initially having the empty text as contents, and then

let the target be "excellent";

to subsequently set its initial state.

The same issue arises for table columns, because we are allowed to simply write out values in table columns, and let Inform work out what kind they are. If there are blank entries, we can always write in the kind of value by hand, but suppose the entries are initially all filled in? The answer is that we can imitate this:

Table of Neptune's Moons
moon   surface (indexed text)   
"Nereid"   "utterly unknown"   
"Triton"   "cryovolcanic ridges"   
"Proteus"   "highly irregular and sooty"   

Here the two columns are called "moon" and "surface", so we can talk about the "moon entry" and the "surface entry" once a row has been chosen: but the moon entry is text, and the surface entry is indexed text.

Lastly, suppose we want to define new phrases which deal with text. Here we have two things to remember. First, we need to say that the value decided is indexed text, not text; secondly, that text converts to indexed text by magic, but not vice versa. So:

To decide what indexed text is (T - text) doubled:
    decide on "[T][T]".

works fine so long as we only want to pass text to it, but would not let us double indexed text. This, on the other hand, handles both:

To decide what indexed text is (T - indexed text) doubled:
    decide on "[T][T]".

So for instance:

say "Neptune" doubled.

prints "NeptuneNeptune" because Inform automatically converts "Neptune" to indexed text when "doubled" is used on it.


405
* Example  Identity Theft
Allowing the player to enter a name to be used for the player character during the game.

RB

Let's say we want to allow the player to enter any name he likes for his character. Moreover, we want to reject very long names (which are likely to be mistakes anyway), and we want to extract the player's chosen first name from the rest.

"Identity Theft"

The player's forename is an indexed text that varies. The player's full name is an indexed text that varies.

When play begins:
    now the command prompt is "What is your name? > ".

To decide whether collecting names:
    if the command prompt is "What is your name? > ", yes;
    no.

After reading a command when collecting names:
    if the number of words in the player's command is greater than 5:
        say "[paragraph break]Who are you, a member of the British royal family? No one has that many names. Let's try this again.";
        reject the player's command;
    now the player's full name is the player's command;
    now the player's forename is word number 1 in the player's command;
    now the command prompt is ">";
    say "Hi, [player's forename]![paragraph break]";
    say "[banner text]";
    move the player to the location;
    reject the player's command.

We also want to postpone the proper beginning of the game until we've gotten the name:

Instead of looking when collecting names: do nothing.

Rule for printing the banner text when collecting names: do nothing.

Rule for constructing the status line when collecting names: do nothing.

Your Bedroom is a room. The printed name of Your Bedroom is "[player's forename]'s Bedroom".

The player carries a letter. The description of the letter is "Dear [player's full name], [paragraph break]You have won the Norwegian Daily Lottery! ...".

If we are compiling for Glulx, this is enough to capture not only the player's name but also the capitalization he uses.

If we are compiling for the Z-machine, the player's input will unfortunately be reduced to lower case before we can inspect it. If we would like by default to capitalize the first letter of each word of the name, we might substitute the following after reading a command rule:

After reading a command when collecting names:
    if the number of words in the player's command is greater than 5:
        say "[paragraph break]Who are you, a member of the British royal family? No one has that many names. Let's try this again.";
        reject the player's command;
    now the player's full name is "[the player's command in title case]";
    now the player's forename is word number 1 in the player's full name;
    now the command prompt is ">";
    say "Hi, [player's forename]![paragraph break]";
    say "[banner text]";
    move the player to the location;
    reject the player's command.

406
* Example  Mirror, Mirror
The sorcerer's mirror can, when held up high, form an impression of its surroundings which it then preserves.

RB
407
** Example  The Cow Exonerated
Creating a class of matches that burn for a time and then go out, with elegant reporting when several matches go out at once.

RB


PreviousContentsNext