RB §12.1. Typography

Story files produced by Inform tend not to contain elaborate typographical effects. They would only distract. Like a novel, a classic work of IF is best presented in an elegant but unobtrusive font. Inform does, however, provide for italic and bold-face, and also for a typewriter-style fixed pitch of lettering:

"This is an [italic type]italicised[roman type] word."
"This is an [bold type]emboldened[roman type] word."
"This is a [fixed letter spacing]typewritten[variable letter spacing] word."

Authors making very frequent use of these might like to borrow the briefer definitions in Chanel Version 1.

A very wide range of letter-forms is normally available (and even more in quoted text), so that the writer seldom needs to not worry whether, say, a sentence like

A ticket to Tromsø via Østfold is in the Íslendingabók.

will work. The Über-complète clavier ★★★ is an exhaustive test of such exotica.

Coloured type is trickier, and its availability depends on the story file format. For a Z-machine story, Garibaldi 2 demonstrates this.

Finally, Tilt 3 ★★ combines unusual letterforms (suit symbols) with red and black colours to render hands of cards typographically.

Examples

69. Garibaldi 2

The extension "Basic Screen Effects" provides a few more type styles, in the form of coloured lettering. The colours available are red, yellow, green, blue, white, magenta, and cyan, as well as the usual black; and to restore the player's default screen colour, we say "default letters".

Thus if we wanted to highlight locked and unlocked doors in our security readout example:

paste.png "Garibaldi"

Include Basic Screen Effects by Emily Short.

The security readout is a device. The description of the readout is "The screen is blank."

Instead of examining the switched on security readout:
    say "The screen reads: [fixed letter spacing]";
    say line break;
    repeat with item running through doors:
        say line break;
        say " [item] ([front side of the item]/[back side of the item]): [if the item is locked][green letters]LOCKED[default letters][otherwise][red letters]UNLOCKED[default letters][end if]";
    say variable letter spacing;
    say paragraph break.

The player carries the security readout.

The Docking Bay is a room. The inner airlock is a door. It is north of the Docking Bay and south of the Zocalo. The inner airlock is lockable and unlocked. The outer airlock is lockable and locked. It is a door. It is south of the Docking Bay and north of Space.

The quarantine seal is a door. It is west of the Zocalo and east of Medlab. Quarantine seal is locked.

The security pass unlocks the inner airlock. The player carries the security pass.

Test me with "x readout / turn on readout / x readout / lock inner airlock with security pass / x readout".

Note that this extension does not currently produce the desired effects when compiling with the Glulx setting; to see it working, make sure that the settings tab is set to compile to the Z-machine.

453. Chanel Version 1

HTML uses angled brackets to achieve effects, and places italicised text between <i> and </i> tags; and similarly boldface between <b> and </b>. We can mimic this very easily by setting each up as a segmented substitution:

paste.png "Chanel Version 1"

To say i -- beginning say_i -- running on: (- style underline; -).
To say /i -- ending say_i -- running on: (- style roman; -).
To say b -- beginning say_b -- running on: (- style bold; -).
To say /b -- ending say_b -- running on: (- style roman; -).

Place Vendôme is a room. "[i]Fashion fades, only style remains the same[/i] ([b]Coco Chanel[/b]). And this elegant drawing-room, once a milliner's shop, is a case in point."

Instead of going nowhere, say "[i]Don't spend time beating on a wall, hoping to transform it into a door.[/i] ([b]Coco Chanel[/b]) This one is a wall.".

Test me with "look / e".

We have had to use square instead of angle brackets, but then, "in order to be irreplaceable one must always be different" (Coco Chanel).

(Marking these as substitutions which run on prevents unexpected paragraph breaks if they should appear immediately after the end of a sentence.)

450. Tilt 3 ★★

Books and articles about card-playing traditionally abbreviate card names into a simple two-symbol notation: a number or letter representing the card rank, followed by a symbol indicating the card suit. Suppose that we want to emulate this notation when taking inventory in our poker game.

The trick here is that colored output is done in different ways by the Z-Machine and by Glulx, so we'll need two different versions of the same section in order to produce this output. The relevant source is right at the beginning:

paste.png "Tilt"

Section 0 - Colored Output in Two Forms

For the suit symbols, we'll want the Unicode extension included with Inform:

Include Unicode Character Names by Graham Nelson.

Rule for printing the name of a card (called target) while grouping together:
    say "[rank of the target as abbreviated value][suit of the target as symbol]".

To say (current suit - a suit) as symbol:
    if current suit is diamonds, say "[red letters][unicode black diamond suit][default letters]";
    if current suit is spades, say "[unicode black spade suit]";
    if current suit is clubs, say "[unicode black club suit]";
    if current suit is hearts, say "[red letters][unicode black heart suit][default letters]".

Section 0Z (for Z-machine only)

The Basic Screen Effects extension bundled with Inform includes mechanisms to change the text color, so for the Z-machine, we need only include this:

Include Basic Screen Effects by Emily Short.

Section 0G (for Glulx only)

Under Glulx, we need slightly more set-up: Glulx requires that we define special user font styles when we plan to make display changes. A fuller discussion of this (and of how to define new colors) appears in the documentation of "Glulx Text Effects", but an implementation sufficient to our purposes would be

Include Glulx Text Effects by Emily Short.

Table of User Styles (continued)

style name

glulx color

special-style-1

g-pure-red

Table of Common Color Values (continued)

glulx color value

assigned number

g-pure-red

16711680

To say red letters: say first custom style.

To say default letters: say roman type.

From here, the rest of the source is mostly as we've seen in previous examples:

Section 1 - Cards

Suit is a kind of value. The suits are hearts, clubs, diamonds, and spades. Understand "heart" as hearts. Understand "club" as clubs. Understand "diamond" as diamonds. Understand "spade" as spades.

A card is a kind of thing. A card has a suit. A card has a number called rank. Understand the suit property as describing a card. Understand the rank property as describing a card.

52 cards are in the card repository.

To say (count - a number) as a card value:
    choose row count in the Table of Value Names;
    say "[term entry]".

Rule for printing the name of a card (called target):
    say "[rank of the target as a card value] of [suit of the target]"

To say (count - a number) as abbreviated value:
    choose row count in the Table of Value Names;
    say "[abbrev entry]".

Table of Value Names

term

value

abbrev

topic

"ace"

"1"

"A"

"ace/A"

"deuce"

"2"

"2"

"deuce/two"

"three"

"3"

"3"

"three"

"four"

"4"

"4"

"four"

"five"

"5"

"5"

"five"

"six"

"6"

"6"

"six"

"seven"

"7"

"7"

"seven"

"eight"

"8"

"8"

"eight"

"nine"

"9"

"9"

"nine"

"ten"

"10"

"10"

"ten"

"jack"

"11"

"J"

"jack/knave/J"

"queen"

"12"

"Q"

"queen/Q"

"king"

"13"

"K"

"king/K"

After reading a command:
    if the player's command includes "of [suit]":
        while the player's command includes "of":
            cut the matched text;
    repeat through the Table of Value Names:
        while the player's command includes topic entry:
            replace the matched text with value entry.

When play begins:
    reconstitute deck.

To reconstitute deck:
    let current suit be hearts;
    now every card is in the card repository;
    while a card is in the card repository:
        repeat with current rank running from 1 to 13:
            let item be a random card in card repository;
            now rank of item is current rank;
            now suit of item is current suit;
            now item is in the deck of cards;
        now current suit is the suit after the current suit.

Section 2 - The Deck and the Discard Pile

The Empty Room is a room. "Nothing to see here."

The deck of cards is in the Empty Room. It is a closed unopenable container. The description is "A standard poker deck."

The discard pile is a closed unopenable container. The description is "Cards in this game are discarded face-down, so the discard pile is not very interesting to see. All you can observe is that it currently contains [if the number of cards which are in the discard pile is less than ten][the number of cards which are in the discard pile in words][otherwise]about [the rounded number of cards which are in the discard pile in words][end if] card[s]."

To decide what number is the rounded number of (described set - a description of objects):
    let N be the number of members of the described set;
    let R be N divided by 5;
    let total be R times 5;
    decide on total.

Rule for printing room description details of something: do nothing instead.

Section 3 - Drawing and Discarding Actions

Understand the commands "take" and "carry" and "hold" and "get" and "drop" and "throw" and "discard" as something new.

Understand "take [text]" or "get [text]" or "drop [text]" as a mistake ("Here, you only draw and discard. Nothing else matters at the moment.").

Understand "draw" or "draw card" or "draw a card" as drawing. Drawing is an action applying to nothing. The drawing action has an object called the card drawn.

Setting action variables for drawing:
    now the card drawn is a random card which is in the deck of cards.

Check drawing:
    if the card drawn is nothing, say "The deck is completely depleted." instead.

Check drawing:
    if the number of cards carried by the player is greater than four,
        say "This is a five-card game; you must discard something before drawing anything further." instead.

Carry out drawing:
    move the card drawn to the player.

Report drawing:
    say "You draw [a card drawn]."

Understand "discard [card]" as discarding. Discarding is an action applying to one thing.

Check discarding:
    if the player does not carry the noun, say "You can only discard cards from your own hand." instead.

Carry out discarding:
    now the noun is in the discard pile;
    if the discard pile is not visible, move the discard pile to the location.

Report discarding:
    say "You toss [the noun] nonchalantly onto the discard pile."

Section 4 - Assessing Hands

Before listing contents while taking inventory: group cards together.

Before grouping together cards:
    if the number of cards carried by the player is 5:
        say "[run paragraph on]";
        follow the hand-ranking rules;
        if the rule succeeded, say "[the outcome of the rulebook]";
        otherwise say "some random cards";
        if the outcome of the rulebook is pair outcome, say " of [rank of the first thing held by the player as a card value]s";
    otherwise:
        say "[number of cards carried by the player in words] assorted cards";
    say " (".

Rule for grouping together cards:
    say "[list hand]".

To say list hand:
    let chosen card be the first thing held by the player;
    while chosen card is a card:
        say "[chosen card]";
        now chosen card is the next thing held after chosen card;
        if chosen card is a card, say "-".

After grouping together cards:
    say ")".

The hand-ranking rules is a rulebook. The hand-ranking rules have outcomes royal flush, straight flush, four of a kind, full house, flush, straight, three of a kind, two pairs, pair, high card.

The hand-ranking rulebook has a truth state called the flushness.
The hand-ranking rulebook has a truth state called the straightness.

The hand-ranking rulebook has a number called the pair count.
The hand-ranking rulebook has a number called the triple count.
The hand-ranking rulebook has a number called the quadruple count.

A card can be sorted or unsorted. A card is usually unsorted.

Definition: a card is high if its rank is 11 or more.
Definition: a card is low if its rank is 4 or less.

A hand-ranking rule (this is the initial sort rule):
    now every card is unsorted;
    while the player carries an unsorted card:
        let item be the lowest unsorted card held by the player;
        move item to the player;
        now the item is sorted;
    if sort-debugging is true, say "-- after initial sort: [list hand]".

A hand-ranking rule (this is the finding flushness rule):
    let called suit be the suit of a random card carried by the player;
    if every card carried by the player is called suit, now flushness is true.

A hand-ranking rule (this is the finding straightness rule):
    now straightness is true;
    let N be the rank of the highest card which is carried by the player;
    repeat with current rank running from N - 4 to N:
        now the test rank is the current rank;
        unless the player carries a matching card:
            if the current rank is N - 4 and the current rank is 9 and the player carries an ace card, do nothing;
            otherwise now straightness is false.

A card can be quadrupled, tripled, paired or uncombined.

Test rank is a number that varies. Definition: a card is matching if its rank is the test rank.

A hand-ranking rule (this is the counting multiples rule):
    now every card is uncombined;
    repeat with current rank running from 1 to 13:
        now test rank is current rank;
        let N be the number of matching cards held by the player;
        if N is 4:
            increment the quadruple count;
            now every matching card held by the player is quadrupled;
        if N is 3:
            increment the triple count;
            now every matching card held by the player is tripled;
        if N is 2:
            increment the pair count;
            now every matching card held by the player is paired.

A hand-ranking rule (this is the move aces up unless there's a low straight rule):
    unless the straightness is true and the lowest card carried by the player is an ace card and the rank of the highest card carried by the player is 5,
        now every ace card which is carried by the player is carried by the player;
    if sort-debugging is true, say "-- after ace movement rule: [list hand]".

A hand-ranking rule (this is the move pairs forward rule):
    while the player carries a paired card:
        let selection be the lowest paired card which is carried by the player;
        move the selection to the player;
        now the selection is uncombined;
    if sort-debugging is true, say "-- after pairs movement: [list hand]".

A hand-ranking rule (this is the raise ace pairs rule):
    if the player carries exactly two ace cards:
        repeat with item running through ace cards which are carried by the player:
            move item to the player;
    if sort-debugging is true, say "-- after paired-ace movement: [list hand]".

A hand-ranking rule (this is the move multiples forward rule):
    while the player carries a tripled card:
        let selection be the lowest tripled card which is carried by the player;
        move the selection to the player;
        now the selection is uncombined;
    while the player carries a quadrupled card:
        let selection be the lowest quadrupled card which is carried by the player;
        move the selection to the player;
        now the selection is uncombined;
    if sort-debugging is true, say "-- after multiples movement rule: [list hand]".

Definition: a card is ace if its rank is 1.
Definition: a card is king if its rank is 13.

A hand-ranking rule (this is the royal-flush rule):
    if flushness is true and straightness is true and the highest card carried by the player is king and the lowest card carried by the player is ace, royal flush.

A hand-ranking rule (this is the straight-flushes rule):
    if flushness is true and straightness is true, straight flush.

A hand-ranking rule (this is the four-of-a-kind rule):
    if the quadruple count is 1, four of a kind.

A hand-ranking rule (this is the full-house rule):
    if the pair count is 1 and the triple count is 1, full house.

A hand-ranking rule (this is the flushes rule):
    if flushness is true, flush.

A hand-ranking rule (this is the straights rule):
    if straightness is true, straight.

A hand-ranking rule (this is the three-of-a-kind rule):
    if triple count is 1, three of a kind.

A hand-ranking rule (this is the two-pair rule):
    if the pair count is 2, two pairs.

A hand-ranking rule (this is the pair rule):
    if the pair count is 1, pair.

A hand-ranking rule (this is the default rule):
    high card.

Sort-debugging is a truth state that varies.

Section 5 - Testing hand identification - Not for release

Understand "debug sorting" as debugging hand sorting. Debugging hand sorting is an action out of world.

Carry out debugging hand sorting:
    if sort-debugging is false, now sort-debugging is true;
    otherwise now sort-debugging is false.

Report debugging hand sorting:
    say "Sort debugging is now [if sort-debugging is true]on[otherwise]off[end if]."

Test me with "draw / g / g / g / g / force hand / g / g / g / g / g / g / g / g / g / g / g / g".

Table of Testing Hands

set suit

set rank

spades

1

[royal flush]

spades

13

spades

12

spades

11

spades

10

clubs

12

[straight flush]

clubs

11

clubs

10

clubs

9

clubs

8

diamonds

8

[four of a kind]

hearts

8

spades

8

clubs

8

clubs

3

clubs

1

[full house]

spades

1

hearts

10

spades

10

clubs

10

hearts

2

[flush]

hearts

5

hearts

7

hearts

11

hearts

12

hearts

1

[straight]

spades

13

diamonds

12

clubs

11

hearts

10

hearts

2

[three of a kind]

spades

2

clubs

2

clubs

4

spades

3

diamonds

6

[two pairs]

spades

6

clubs

7

diamonds

7

hearts

9

diamonds

6

[two pairs, ace high]

spades

6

clubs

1

diamonds

7

hearts

1

hearts

12

[pair]

spades

12

diamonds

10

spades

7

clubs

4

diamonds

13

[high]

hearts

11

spades

9

clubs

7

diamonds

5

hearts

1

[tricky sorting: low straight]

diamonds

2

spades

3

diamonds

4

diamonds

5

Understand "force hand" as forcing a hand. Forcing a hand is an action out of world.

Current marker is a number that varies.

Carry out forcing a hand:
    repeat with item running through cards which are carried by the player:
        increment current marker;
        if current marker is greater than the number of filled rows in the Table of Testing Hands, now current marker is 1;
        choose row current marker in the Table of Testing Hands;
        now the suit of item is the set suit entry;
        now the rank of item is the set rank entry.

Report forcing a hand:
    try taking inventory.

70. The Über-complète clavier ★★★

The following example puts Inform's support for exotic lettering through its paces. It was useful in testing Inform but is not a very instructive read: still, it does provide a test story file for interpreters, so we are including the source here as an example.

paste.png "The Über-complète clavier"

The story headline is "Pushing the Limits of Unicode in IF". The story description is "This is a demanding test for Unicode compliance by Z-machine interpreters."

Include Unicode Character Names by Graham Nelson.

Include Basic Screen Effects by Emily Short.

The Château Bibliothèque Français is east of the Deutsche Universität Bücherei. "From this Borgesian construction, doorways lead into anterooms in each of the four cardinal directions." South of the Bibliothèque is the Miscellany Mañana. North of the Bibliothèque is the Íslendingabók. East of the Bibliothèque is Alphabet Soup.

A framed photograph of Icelandic Prime Minister Halldór Ásgrímsson, a ruler measuring Ångströms, a Bokmål-Lëtzebuergesch Lëtzebuergesch-Bokmål dictionary and a ticket to Tromsø via Østfold are in the Íslendingabók.

A paper by Karl Weierstraß, a general feeling of Ärger, an old Österreich passport and the Bach Clavier-Übung open at the fugue à 4 are in the Bücherei.

The painting of École normale superiéure students singing Ça ira, the frankly lesser-known journal of Niccolò Polo, Così fan tutte on CD, an extract of Herodotus concerning Artaÿctes and the exit sign reading À BIENTÔT are in the Bibliothèque.

A wicker basket marked CHLOË is in the Bibliothèque. A ginger cat is in the basket.

A guide to Æsop for naïve æsthetes, Lönnrot's Kalevala, a creed according to the Bahá'ís, FALARÃO magazine, an Estonian poem by Tõnu Trubetsky, a Portuguese-Italian recipe for macarrão, a stripy hanging CANDY PIÑATA bag, a ¿¡Punctuation Turned Upside Down¿¡ pamphlet, an Italian brewers' anti-violence poster declaring BÓTTE NON BÒTTE, a map of È and a dusty book titled The Parnasum of Luís Vaz bearing CAMÕES on its spine are in Miscellany Mañana.

The description of the map is "È is a province in the People's Republic of China."

In Mañana is something called ÂÊÎÔÛ - The Official Journal of the Society for Vowels bearing Circumflexes.

In Mañana is something called âêîôû comic - the youth edition.

The description of Alphabet Soup is "A bewildering place of glyphs, sigils and signs. The Library proper leads back west: steps lead upwards to an Observatory, or downwards into what seems to be a dangerous area. A gaming lounge lies to the south."

The Greek Alphabet, the Cyrillic Alphabet, the Hebrew alphabet, and the embossed plaque are in Alphabet Soup. The description of the Greek alphabet is "αβγδεζηθικλμνξοπρςστυφχψω.". The description of the Hebrew alphabet is "אבגדהוזחטיךכלםמןנסעףפץצקרשת.". The description of the Cyrillic alphabet is "абвгдежзийклмнопрстуфхцчшщъыьэюя.".

Instead of examining the plaque:
    say "It seems to be a sign in Braille: ";
    say unicode Braille pattern dots-24, " (I), ",
        unicode Braille pattern dots-1345, " (N), ",
        unicode Braille pattern dots-124, " (F), ",
        unicode Braille pattern dots-135, " (O), ",
        unicode Braille pattern dots-1235, " (R), ",
        unicode Braille pattern dots-134, " (M)."

The Gaming Lounge is south of Alphabet Soup. The chess position and the book of puzzle canons are in the Gaming Lounge.

The Georges de la Tour painting Le Tricheur is in the Gaming Lounge. "Hanging on one wall is Georges de la Tour's masterpiece Le Tricheur (the card-sharp). Visible are 8[unicode black diamond suit], 9[unicode black diamond suit], A[unicode black diamond suit], A[unicode black spade suit], 6[unicode black club suit] but not one of them has a [unicode black heart suit]."

The description of Le Tricheur is "If they'd been dice-players instead, they might have thrown [unicode die face-1], [unicode die face-2], [unicode die face-3], [unicode die face-4], [unicode die face-5] or [unicode die face-6], but as it is they stick to cards."

The description of the book of canons is "A typical fugue is no. 13 (Tovey: [unicode eighth note] = 110) in F[unicode music sharp sign] minor, but you can also make out keys like A[unicode music flat sign] and G[unicode music natural sign]."

The empty square text is text that varies. To say empty: say the empty square text.

To display the board:
    say empty, empty, empty, empty, empty, empty, unicode black chess king, empty, line break;
    say empty, empty, empty, unicode black chess queen, empty, empty, unicode black chess pawn, empty, line break;
    say unicode black chess pawn, empty, empty, unicode black chess bishop, unicode black chess pawn, empty, empty, unicode black chess pawn, line break;
    say empty, empty, empty, unicode black chess pawn, empty, unicode black chess rook, empty, empty, line break;
    say empty, unicode black chess pawn, empty, unicode white chess pawn, unicode black chess pawn, empty, empty, empty, line break;
    say empty, empty, empty, unicode black chess bishop, unicode white chess queen, empty, unicode white chess pawn, unicode white chess pawn, line break;
    say unicode white chess pawn, unicode white chess pawn, empty, unicode white chess bishop, empty, unicode black chess rook, unicode white chess bishop, empty, line break;
    say empty, unicode white chess knight, empty, empty, unicode white chess rook, empty, unicode white chess rook, unicode white chess king, line break.

Instead of examining the chess position:
    say "Fritz Saemisch - Aron Nimzowitsch, Copenhagen 1923: the Immortal Zugzwang Game. Nimzowitsch (black), observing that white will very soon have to play a terrible move, has just advanced his h pawn for no reason other than to wait. So it is white to play...";
    say "[fixed letter spacing]......k. [line break]...q..p. [line break]p..bp..p [line break]...p.r.. [line break].p.Pp... [line break]...bQ.PP [line break]PP.B.rB. [line break].N..R.RK [variable letter spacing][line break]";
    say "'White must, willy-nilly, eventually throw himself upon the sword', in Nimzowitsch's commentary. ";
    say "We will now try to display the same position using chess-piece symbols in a Unicode font.";
    say fixed letter spacing;
    now the empty square text is " ";
    display the board;
    say variable letter spacing.

The Astrological Observatory is above Alphabet Soup.

The planets are in the Observatory. "Diagrams of the planets are scattered across the dome: Sun [unicode Sun], Mercury [unicode Mercury], Venus [unicode Female Sign], Earth [unicode Earth], Moon [unicode First Quarter Moon] and [unicode Last Quarter Moon], Mars [unicode Male Sign], Jupiter [unicode Jupiter], Saturn [unicode Saturn], Uranus [unicode Uranus], Neptune [unicode Neptune], Pluto [unicode Pluto] and one or two comets [unicode Comet]. Fainter, but all around, you see stars black [unicode black star] and white [unicode white star]."

The constellations are in the Observatory. "Ringing the dome are the constellations: Aries [unicode Aries], Taurus [unicode Taurus], Gemini [unicode Gemini], Cancer [unicode Cancer], Leo [unicode Leo], Virgo [unicode Virgo], Libra [unicode Libra], Scorpius [unicode Scorpius], Sagittarius [unicode Sagittarius], Capricorn [unicode Capricorn], Aquarius [unicode Aquarius], Pisces [unicode Pisces]."

The weather almanac is in the Observatory. The description of the almanac is "Here nightly observers scrawl in hasty abbreviations for the current weather conditions: clear weather [unicode Black Sun with Rays], cloudy [unicode cloud], rain [unicode umbrella], snow [unicode snowman], lightning [unicode lightning], thunderstorm [unicode thunderstorm]."

The Danger Zone is below Alphabet Soup. The printed name of the Danger Zone is "[unicode skull and crossbones] Danger Zone [unicode skull and crossbones]".

The warning signs are in the Danger Zone. "A variety of international-standard warning standards suggest that this may not be the safest place: [unicode skull and crossbones], [unicode caution sign], [unicode radioactive sign], [unicode biohazard sign]."

This example text was used to produce a story file which has been tried against both Zoom for Mac OS X and Windows Frotz. The Latin, Greek, Cyrillic and Hebrew text all functioned perfectly on both, but a point of difference showed when writing the Hebrew alphabet: Zoom wrote this right-to-left, Windows Frotz left-to-right. The exotic symbols displayed on Zoom (though others not mentioned above, such as "[unicode staff of hermes]", did not): but most appeared only as black squares on Windows Frotz, exceptions being the astrological signs for Venus and Mars and the musical note.

RB §12.2. The Status Line

The status line is the reverse-coloured bar along the top of the window during play, which conventionally, but not necessarily, shows the current location, the score (or sometimes the time of day) and the number of turns so far. It has been highly traditional since the early 1980s (Infocom's customer newsletter was for many years called "The Status Line"): it has become the visual identifier of IF. It plays the same role for IF that a header with chapter name and page number plays in a printed book.

The status line is ordinarily printed from two named pieces of text, the "left hand status line" and the "right hand status line". These can be changed during play, so for instance,

When play begins, change the right hand status line to "Time: [time of day]".

The examples below offer miscellaneous alternatives, and are fairly self-descriptive.

See also

Viewpoint for a way to make the status line list the player's current identity

Examples

114. Politics as Usual

Suppose a game with a large map entirely subdivided into regions. We could define:

paste.png "Politics as Usual"

When play begins:
    now the right hand status line is "[map region of the location]".

Washington is west of Idaho.

Red is a region. Blue is a region. Idaho is in red. Washington is in blue.

Test me with "e / w".

Note that, since regions can be stacked, we technically can be within more than one region at once. In the Port Royal example, for instance, the Tavern region is inside the Inland region. If there is any ambiguity, "the map region of the location" will be construed as "the smallest region that the location belongs to": so we would see "Tavern" rather than "Inland" in the status bar, when the player was in the Feathers or the Feathers Bedroom.

Some extra finesse would be necessary if the names of map regions were very long or if there were some rooms that were not considered to belong to any region at all.

350. Ways Out

A not-uncommon device in games with large maps is a list of available exits printed in the status bar. We might do this so:

paste.png "Ways Out"

When play begins:
    now left hand status line is "Exits: [exit list]";
    now right hand status line is "[location]".

To say exit list:
    let place be location;
    repeat with way running through directions:
        let place be the room way from the location;
        if place is a room, say " [way]".

We may find that printing out full directions makes the status line unpleasantly crowded. Fortunately, it isn't hard to provide a set of abbreviations to use in this context:

Rule for printing the name of a direction (called the way) while constructing the status line:
    choose row with a heading of the way in the Table of Abbreviation;
    say "[shortcut entry]".

Table of Abbreviation

heading

shortcut

north

"N"

northeast

"NE"

northwest

"NW"

east

"E"

southeast

"SE"

south

"S"

southwest

"SW"

west

"W"

up

"U"

down

"D"

inside

"IN"

outside

"OUT"

Dome is a room. North of Dome is North Chapel. South of the Dome is South Chapel. West of the Dome is Western End. Quiet Corner is northwest of the Dome, north of Western End, and west of North Chapel. Loud Corner is east of North Chapel, northeast of Dome, and north of Eastern End. Eastern End is north of Dim Corner and east of Dome. Dim Corner is southeast of Dome and east of South Chapel. Ruined Corner is southwest of Dome, west of South Chapel, and south of Western End.

The church door is east of Eastern End and west of the Courtyard. The church door is a door.

Test me with "w / n / e / e / s / e".

Everywhere else, the names of directions will still be printed out in full in the usual way.

387. Blankness

Occasionally we want to print something as our first screen and then pause the game. By default, Inform will print a rather odd status line, with "You" on the left side and "0" on the right. This is because the left hand status line is set to display the location, but (because we're not done with the when-play-begins rules) the player has not yet even been moved to a room.

We can tidy this up in the "starting the virtual machine" activity, by temporarily changing the status line content. We will not provide game-pausing code here, because that is easily done by extension; so:

paste.png "Blankness"

Include Basic Screen Effects by Emily Short.

When play begins:
    say "take me home";
    wait for any key;
    say " yeah";
    wait for any key;
    say " yeah";
    pause the game;
    now the left hand status line is "[location]";
    now the right hand status line is "[turn count]".

Before starting the virtual machine:
    now the left hand status line is "";
    now the right hand status line is "".

Paradise City is a room. The description of Paradise City is "The grass is green and the girls are pretty."

Quite a modest effect, but occasionally useful.

412. Capital City

Not much is needed for this. The only noteworthy point is that it doesn't work by changing the LHSL to "[the player's surroundings in upper case]": it cannot do this because "the player's surroundings" is not a value. Instead, "[the player's surroundings]" is a text substitution sometimes printing the name of a room, sometimes printing "Darkness", and so on. We must therefore load it into a text first, and then apply "...in upper case".

paste.png "Capital City"

Capital City is a room. East is Lower Caissons. South of Lower Caissons
is San Seriffe. East of San Seriffe is a dark room.

To say the player's capitalised surroundings:
    let the masthead be "[the player's surroundings]" in upper case;
    say the masthead.

When play begins:
    now the left hand status line is "[the player's capitalised surroundings]".

Test me with "e / s / e".

452. Status line with centered text, the hard way

Making major changes to display features, such as the construction of the status line, sometimes requires that we rely on Inform 6 in bulk; here is how we might produce the Trinity-style status line, with the location centered at the top center of the screen.

paste.png "Corner of No and Where"

No is a room. Where is west of No.

Rule for constructing the status line:
    print the location in the center of the status line;
    rule succeeds.

To print the location in the center of the status line:
    (- PrintCenteredStatus(); -).

Include (-

Array printed_text --> 64;

[ PrintCenteredStatus i j;
    @set_cursor 1 0;
    i = 0->33;
    spaces(i);
    @output_stream 3 printed_text;
    print (name) location;
    @output_stream -3;
    j = (i - (printed_text-->0))/2;
    @set_cursor 1 j;
    print (name) location;
    spaces j-1;
];

-)

Test me with "w / e".

In fact, as we've already seen, many extra modifications to the display behavior are possible using Basic Screen Effects.

351. Guided Tour ★★

It may sometimes be helpful to prompt the player with a list of exits printed up in the status line. For instance, here is a status line that will print the names of nearby rooms, as well as all the doors the player can see:

paste.png "Guided Tour"

When play begins:
    now left hand status line is "Nearby: [if a room is adjacent][the list of adjacent rooms][end if][if a room is adjacent and a door is visible] and [end if][if a door is visible][the list of visible doors][end if]";
    now right hand status line is "".

Of course, we may not want to tell the player what glories are to be found in locations he hasn't yet explored.

Rule for printing the name of an unvisited room (called the target) while constructing the status line:
    let aim be the best route from the location to the target;
    say "something [aim]".

Even when we have seen a room, we might still want a reminder about how to get there:

After printing the name of a visited room (called the target) while constructing the status line:
    let aim be the best route from the location to the target;
    say " ([aim])".

We may also find that printing out full directions makes the status line unpleasantly crowded. Fortunately, it isn't hard to provide a set of abbreviations to use in this context:

Rule for printing the name of a direction (called the aim) while constructing the status line:
    choose row with a heading of the aim in the Table of Abbreviation;
    say "[shortcut entry]".

Table of Abbreviation

heading

shortcut

north

"N"

northeast

"NE"

northwest

"NW"

east

"E"

southeast

"SE"

south

"S"

southwest

"SW"

west

"W"

up

"U"

down

"D"

inside

"in"

outside

"out"

Everywhere else, the names of directions will still be printed out in full in the usual way. And now we give it a little map to work with:

Dome is a room. North of Dome is North Chapel. South of the Dome is South Chapel. West of the Dome is Western End. Quiet Corner is northwest of the Dome, north of Western End, and west of North Chapel. Loud Corner is east of North Chapel, northeast of Dome, and north of Eastern End. Eastern End is north of Dim Corner and east of Dome. Dim Corner is southeast of Dome and east of South Chapel. Ruined Corner is southwest of Dome, west of South Chapel, and south of Western End.

The church door is east of Eastern End and west of the Courtyard. The church door is a door.

Test me with "n / w / s".

Note that while this looks fine in some places, other locations exceed the limits of what the status-line can hold: if any given room is going to have a large number of exits, this kind of listing will almost certainly not fit. So apply cautiously.

115. Centered ★★★

If we want to lay out the status line in some other way than with left-hand and right-hand entries, it is possible to do this as well. Later we will learn about the "rule for constructing the status line", but here is a basic effect using this rule and an Inform extension included as part of the standard distribution, called Basic Screen Effects.

paste.png "Centered"

When play begins:
    say "After months of boring through the Earth's crust in this metal-jawed vehicle, you break through..."

The Hollow Core is a room. "Truly a magnificent sight: the land curves up away from you in every direction, covered with the cities and fields of the Core People. Molten rock runs in the canals, bringing heat and light to every home.

At the center of the Earth hangs a dense black sun."

Include Basic Screen Effects by Emily Short.

Rule for constructing the status line:
    center "[location]" at row 1;
    rule succeeds.

Test me with "look".

Basic Screen Effects also provides a mechanism for building complicated status lines of more than one row. To read its documentation, we include the extension, press Go!, and then consult the contents index that results.

RB §12.3. Footnotes

Ibid. ★★ provides a version of the traditional Infocom-style approach to footnotes, which number off in the order encountered.

Examples

300. Ibid. ★★

"Hitchhiker's Guide to the Galaxy" introduced the idea of footnoted descriptions, and various IF games since have toyed with the idea. The recommended implementation in Inform 6 involved keeping an assortment of footnote objects around, but in Inform 7 the table is a much tidier way of handling the same problem.

paste.png "Ibid."

The Ship Inn is a room. "Here you are in a lovely pub which your guidebook assures you is extremely authentic. [1 as a footnote].

To your left sits a party of Italians, with their guidebook.

To your right is a silent, but not unappealing, young man.".

A party of Italians and a silent young man are people in the Ship Inn. The Italians and the young man are scenery.

The table is a supporter in the Ship Inn. On the table is a mysterious pie. The description of the pie is "Your waitress told you it was the specialty of the day, Steak and Owl Pie. [2 as a footnote]." The pie is edible.

Table of Footnotes

assignment

note

a number

"Francis Drake ate here, if the sign on the door is to be believed"

--

"this is unlikely, considering that owls are protected animals in England these days [3 as a footnote]"

--

"moreover, you can't imagine that owl would be very tasty"

Footnotes mentioned is a number that varies.

Whenever we mention a footnote for the first time, we need to assign it a number, which we will use consistently thereafter. And it's probably a good idea to protect ourselves against the author accidentally using a number too large for the footnote table, too. So:

To say (footnote - a number) as a footnote:
    if footnote > number of filled rows in the Table of Footnotes:
        say "Programming error: footnote assignment out of range.";
    otherwise:
        choose row footnote in the Table of Footnotes;
        if there is an assignment entry:
            say "([assignment entry])";
        otherwise:
            increment footnotes mentioned;
            choose row footnote in the Table of Footnotes;
            now assignment entry is footnotes mentioned;
            say "([assignment entry])".

Now, in order to let the player view these footnotes, we'll need to parse numbers.

Understand "footnote [number]" as looking up a footnote.

Looking up a footnote is an action applying to one number.

Check looking up a footnote:
    if the number understood > footnotes mentioned, say "You haven't seen any such footnote." instead;
    if the number understood < 1, say "Footnotes are numbered from 1."

Carry out looking up a footnote:
    choose row with assignment of number understood in the Table of Footnotes;
    say "([assignment entry]): [note entry]."

Test me with "footnote 1 / examine pie / footnote 2 / footnote 3".

This method does require us to keep track of where a footnote appears in the table. If we found this inconvenient, we could add a column to the footnote table so that we could invoke it with tags like "[appearance quip as a footnote]".

RB §12.4. Timed Input

Inform normally expects a purely turn-based story: the player acts, the story responds and waits for the player to act again.

Occasionally, however, we may want to offer a different mode of interaction, for instance with turns in which the player has limited time to come up with his next act. Likewise, we might want to have text that printed itself to the screen gradually, to represent dialogue with pauses, or the speed of a typewriter placing letters on a page.

It's best to be careful with these effects: overdone, they can be very annoying to players who prefer to read at a faster speed. Nonetheless, they do have their uses.

Inform does not have standard syntax to handle real-time delays and output, but there are several extensions that provide this capacity. Erik Temple's extension Real Time Delays, for instance, allows us to specify a delay in milliseconds before continuing with whatever aspect of the story is currently in progress.

See also

The Passage Of Time for ways to keep track of clock-time within the story

RB §12.5. Glulx Multimedia Effects

Glulx is one of the two basic story file formats to which Inform can work. It is the more powerful of the two, and modern-day Inform uses it by default. At one time it was a less universally playable format, but today players rarely have any trouble getting it to work.

Among its powers are the ability to display images, play back sound effects, and read and write external files to the disc. With care and a certain amount of fuss, this can even give a playing story file limited Internet connectivity, although it should be stressed that this can only be done if the player sets up his computer just right and runs an auxiliary program beside the story itself. That will mostly be too much to ask, if the player is playing offline, but when the story file is being run on an interpreter running at a server - so that the player simply sends commands to it and sees responses back on a web page - one could easily imagine setting up the server to provide these auxiliary programs, without any extra difficulty for the player.

Many of the more advanced multimedia abilities of Glulx are best unlocked using extensions available from the Inform website or the Public Library. As of this writing, extensions exist to help authors create complex multi-windowed displays (including per-location pictures, visual status bars, and even limited animations and gradually-revealed maps).

There is also work in progress on sound-management to allow the author to play sounds in multiple channels at once, to change sound volumes, and to create fade-in and fade-out effects.

Without extensions, all these abilities are within reach for an author who is willing to do some fairly advanced programming.

Examples

445. Flathead News Network ★★★

This example can only work if we have a separate program running in the background while the story file is being played, and as such it will only work if we set things up in a special way. Exactly how to do this will vary from platform to platform.

First, the source text for the Inform end of the communication line:

paste.png "Flathead News Network"

The file of RSS Requests is called "rssrequest".

The file of RSS Responses (owned by project "RSS-SCRIPT") is called "rssreply".

To request (RSS feed address - text):
    mark the file of RSS Responses as not ready to read;
    write the RSS feed address to the file of RSS Requests.

Newsroom is a room. "This is the secret nerve-centre of FNN, the Flathead News Network."

The BBC button is in the Newsroom. Instead of pushing the BBC button: say "Bong!"; request "newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml".

The NASA button is in the Newsroom. Instead of pushing the NASA button: say "Bang!"; request "www.nasa.gov/rss/breaking_news.rss".

The WHO button is in the Newsroom. Instead of pushing the WHO button: say "Bing!"; request "http://www.doctorwhonews.net".

A screen is in the Newsroom.

Instead of examining the screen:
    if ready to read the file of RSS Responses, say "From the screen you read:[line break][text of the file of RSS Responses]";
    otherwise say "The screen remains blank for now."

As far as the story file is concerned, then, it sends a request down the communication line by writing the chosen RSS feed to the file named "rssrequest", and expects a reply to come back down the line by being written to the file "rssreply". However, the story file needs to expect that this might take some time. (Maybe forever, if there is no program responding, or if the Internet connection is not working.) The story file marks the "rssreply" file as not ready before it makes a request; if it subsequently finds that the file is now ready, that must mean that the other program has done the honours, and that all is well. In the mean time, "The screen remains blank for now."

Now for the RSS-SCRIPT program. The following provides a crude but workable program suitable for running as a Perl script on a system which provides the standard Internet fetching program "curl": Mac OS X, for instance. (If you have OS X, you can paste the following into a (Unix-format) text file called "rss-script.pl", place it in your home folder, open the Terminal utility, type "perl rss-script.pl", and then hide the Terminal window again.)

for (;;) { # repeat forever:
    system("sleep 1"); # wait 1 second
    open REQUEST, "rssrequest.glkdata" or next;
    # the request file has been detected:
    $header_line = <REQUEST>; # the header line
    $rss_feed = <REQUEST>; # the actual content - the RSS feed URL
    close REQUEST;
    if ($header_line =~ m/^\*/) { # if the request file is marked ready
        $rss = system("curl $rss_feed >rawrss.txt"); # download the RSS feed
        # read the RSS XML into a single Perl string:
        open RAWRSS, "rawrss.txt" or next;
        $raw = "";
        while ($nl = <RAWRSS>) {
            $raw = $raw." ".$nl;
        }
        close RAWRSS;
        # look for the title and description of the first item:
        if ($raw =~ m/\<item\>\<title.*?\>(.*?)\<\/title\>.*?\<description.*?\>(.*?)\<\/description\>/) {
            # write the reply:
            open REPLY, ">rssreply.glkdata" or next;
            print REPLY "* //RSS-SCRIPT// rssreply\n", $1, "\n", $2, "\n";
            close REPLY;
            # request safely dealt with, so we can remove it:
            system("rm 'rssrequest.glkdata'");
        }
    }
}