§20.7. Making new text with text substitutions
Substitutions are most often used just for printing, like so:
say "The clock reads [time of day].";
But they can also produce text which can be stored up or used in other ways. For example, defining
To decide what text is (T - text) doubled:
decide on "[T][T]".
makes
let the Gerard Kenny reference be "NewYork" doubled;
set this temporary variable to "NewYorkNewYork".
There is, however, a subtlety here. A text with a substitution in it, like:
"The clock reads [time of day]."
is always waiting to be substituted, that is, to become something like:
"The clock reads 11:12 AM."
If all we do with text is to print it, there's nothing to worry about. But if we're storing it up, especially for multiple turns, there are ambiguities. For example, suppose we're changing the look of the black status line bar at the top of the text window:
now the left hand status line is "[time of day]";
Just copying "[time of day]" to the "left hand status line" variable doesn't make it substitute - which is just as well, or the top of the screen would perpetually show "9:00 AM".
On the other hand, looking back at the phrase example:
To decide what text is (T - text) doubled:
decide on "[T][T]".
"[T][T]" is substituted immediately it's formed. That's also a good thing, because "T" loses its meaning the moment the phrase finishes, which would make "[T][T]" meaningless anywhere else.
What's going on here is this: Inform substitutes text immediately if it contains references to a temporary value such as "T", and otherwise only if it needs to access the contents. This is why "[time of day]" isn't substituted until we need to print it out (or, say, access the third character): "time of day" is a value which always exists, not a temporary one.
Using the adjectives "substituted" and "unsubstituted", it's always possible to test whether a given text is in either state, should this ever be useful. For example,
now the left hand status line is "[time of day]";
if the left hand status line is unsubstituted, say "Yes!";
will say "Yes!": the LHSL is like a bomb waiting to go off. Speaking of which:
The player is holding a temporal bomb.
When play begins:
now the left hand status line is "Clock reads: [time of day]".
After dropping the temporal bomb:
now the left hand status line is the substituted form of the left hand status line;
say "Time itself is now broken. Well done."
This is making use of:
substituted form of (text) ... text
This takes a text and makes substitution occur immediately. For example,
substituted form of "time of death, [time of day]"
produces something like "time of death, 9:15 AM" rather than "time of death, [time of day]". It's entirely legal to apply this to text which never had any substitutions in, so
substituted form of "balloon"
produces "balloon".
Note that there's no analogous phrase for "unsubstituted form of...", because once text has substituted, there's no way to go back.
| ExampleMirror, Mirror The sorcerer's mirror can, when held up high, form an impression of its surroundings which it then preserves.
|
|
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 a text that varies. The player's full name is a 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 substituted form of "[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.
| ExampleIdentity Theft Allowing the player to enter a name to be used for the player character during the game.
|
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 a text that varies. The player's full name is a 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 substituted form of "[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.
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 a text that varies. The player's full name is a 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 substituted form of "[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.
|
|  ExampleThe 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.
|
|