§9.6. Reading Matter
Many things can be read, from warning notices to encyclopaedias, and a range of techniques is needed to provide them because the quantity of text, and how it presents itself, can vary so much. With a small amount of very large type, the player should not need any command at all to read the text:
If the print is smaller, or the object portable, the player will expect to use the EXAMINE command:
But if the object is a leaflet, say, EXAMINE should only describe the cover: READ would be the command a player would expect to use to get at the text itself. Inform normally defines READ to be the same command as EXAMINE, which is good for things like the business card, but counter-productive here. The Trouble with Printing shows how to separate these two commands, allowing any thing to have a property called its "printing" for text produced by READ, which will be different from its "description", the text produced by EXAMINE.
If the object is a lengthy diary, say, nobody would read it from cover to cover in a single IF turn. We might then want to allow the player to turn the pages one by one, with commands like READ PAGE 4 IN DIARY or READ THE NEXT PAGE: see Pages.
If the object is an encyclopaedic reference work, the player would consult named entries: see Costa Rican Ornithology, which allows commands like LOOK UP QUETZAL IN GUIDE.
Still larger sources of text often occur in IF: libraries or bookshelves, where many books are found together, and it is clumsy to write them as many individual items. One approach is to simulate an entire bookshelf with a single thing: see Bibliophilia. (This is much like looking up topics in a single book, except that each topic is a book in itself.) Another is to provide each book as an individual item, but have them automatically join together into a single portable collection: see AARP-Gnosis.
Signs, leaflets and encyclopaedias, being printed, have a wording which will never change during play. But sometimes the player reads something which acts of its own accord. Text substitutions are usually all that is needed to achieve this:
This is easy because we know all the variations we want. But what if we want the player to write his own text, for instance, adding to a diary? This is trickier, because it means storing text as the player typed it, and replaying it later. (And suppose the player types reams and reams of text, not just a few words as we might have hoped?) The Fourth Body and The Fifth Body show how to use an external file - a multimedia trick requiring features only available if the project is set to the Glulx story file format - to handle even the most difficult cases.
Should we want a computer that responds to vocal commands, as in ASK COMPUTER ABOUT KLINGONS, the built-in extension Inanimate Listeners will allow the player to talk to inanimate objects as well as people.
"The Trouble with Printing"
A thing has some text called printing. The printing of a thing is usually "blank".
Understand the command "read" as something new. Understand "read [something]" as reading. Reading is an action applying to one thing, requiring light. Check reading: if the printing of the noun is "blank", say "Nothing is written on [the noun]." instead. Carry out reading: say "You read: [printing of the noun][line break]". Report reading: do nothing.
The Archive is a room.
Berkeley's report is a thing in the Archive. The description is "A report from Governor Sir William Berkeley of Virginia, in 1671, in answer to the queries sent by the Commissioners of Plantations the year previous. Of this report the better part is burned and only a tail fragment remains." The printing of Berkeley's report is "I thank God, [italic type]there are no free schools[roman type] nor [italic type]printing[roman type], and I hope we shall not have these hundred years; for [italic type]learning[roman type] has brought disobedience, and heresy, and sects into the world, and [italic type]printing[roman type] has divulged them..."
Test me with "examine report / read report".
Since we defined reading as an action requiring light, we could further distinguish reading and examining (if we wanted) by writing some different visibility rules for it.
|
ExamplePages
A book with pages that can be read by number (as in "read page 3 in...") and which accepts relative page references as well (such as "read the last page of...", "read the next page", and so on).
|
|
Suppose we have a book that the player must consult page-by-page, and we want to be able to accept all of the following input:
> READ BOOK (to choose a random page and read it)
> READ PAGE 1 IN BOOK
> READ PAGE 2
> READ THE LAST PAGE OF THE BOOK
> READ THE NEXT PAGE
> READ PREVIOUS PAGE IN BOOK
> READ THE FIRST PAGE
One approach would be to write many different understand rules and actions: one action for reading randomly, one for reading a specific page, one for reading the first page, one for reading the previous page, one for reading the next page, and one for reading the last page. But this gets tedious to construct and maintain.
More usefully, we could consider that all of the last four options are essentially the same action at heart: the player is asking to read a page in the book using a name rather than a number, and we will have to perform a minor calculation to discover what the number should be. Here's an implementation using named values to resolve this problem:
"Pages"
The Library is a room. The sinister book is carried by the player. The sinister book has a number called the last page read. The sinister book has a number called the length. The length of the sinister book is 50.
Understand the command "read" as something new.
Understand "read [something]" or "consult [something]" or "read in/from [something]" as reading. Reading is an action applying to one thing, requiring light.
Understand "read [number] in/from/of [something]" or "read page [number] in/from/of [something]" or "look up page [number] in/from/of [something]" or "consult page [number] in/from/of [something]" as reading it in. Reading it in is an action applying to one number and one thing, requiring light.
Named page is a kind of value. The named pages are first page, last page, next page, previous page.
To decide what number is the effective value of (L - last page):
decide on the length of the book.
To decide what number is the effective value of (F - first page):
decide on 1.
To decide what number is the effective value of (N - next page):
let X be the last page read of the book plus 1;
decide on X.
To decide what number is the effective value of (P - previous page):
let X be the last page read of the book minus 1;
decide on X.
Understand "read [named page] in/from/of [something]" or "read the [named page] in/from/of [something]" as reading it relatively in. Reading it relatively in is an action applying to one named page and one thing, requiring light.
Does the player mean reading something in the sinister book: it is very likely.
This is the book requirement rule:
if the player is not carrying the sinister book, say "You're not reading anything." instead.
Check reading it relatively in:
if the second noun is not the sinister book, say "There are no pages in [the second noun]." instead;
abide by the book requirement rule.
Carry out reading it relatively in:
let N be the effective value of the named page understood;
now the number understood is N;
try reading N in the book.
Check reading it in:
if the second noun is not the sinister book, say "There are no pages in [the second noun]." instead;
abide by the book requirement rule.
Check reading it in:
if the number understood is greater than the length of the sinister book, say "There are only [length of sinister book in words] pages in the book." instead;
if the number understood is less than 1, say "The page numbering begins with 1." instead.
Carry out reading it in:
read page number understood.
Check reading:
if the noun is not the sinister book, say "There are no pages in [the noun]." instead;
abide by the book requirement rule.
Carry out reading:
let N be a random number between 1 and the length of the sinister book; now the number understood is N;
say "You flip the pages randomly and arrive at page [the number understood]:[paragraph break]";
try reading the number understood in the sinister book.
Table of Book Contents
page
|
content
|
2
|
"dhuma jyotih salila marutam / samnipatah kva meghah / samdes arthah kva patukaranaih / pranibhih prapaniyah"
|
13
|
"amathesteron pws eipe kai saphesteron"
|
50
|
"Rrgshilz maplot..."
|
To read page (N - a number):
now the last page read of the sinister book is N;
if there is a content corresponding to a page of N in the Table of Book Contents:
choose row with a page of N in the Table of Book Contents;
say "You read: '[content entry]'[paragraph break]";
otherwise:
say "Page [N] appears to be blank."
To read page (N - 47):
say "Your eyes burn; your ears ring. Beneath your gaze, the dreadful sigils writhe, reminding you of that which lies outside the edges of the universe...";
end the story saying "You have lost your remaining sanity".
Test me with "read from the sinister book / read the book / read the next page / read page 2 / read previous page / g / read the first page / read the last page of the book / read the next page / read 47 in book".
Some mystery games supply the player with an in-game system for taking notes, in case he doesn't want to rely on scraps of paper next to the computer. One way of doing this is to write out all the player's notes and observations into a notebook file, whose contents can be retrieved during play (or, indeed, after it).
We'll first invent a general system for writing text into notebooks, by creating a new kind called jotter. Each individual jotter will have its own disc file, and there will be basically three things which can be done with jotters: erasing, reading and writing.
"The Fourth Body"
A jotter is a kind of thing. A jotter has an external file called the text file. A jotter can be fresh or used. A jotter is usually fresh. A jotter has a text called the heading.
The currently erased jotter is an object that varies.
To erase (pad - a jotter):
now the currently erased jotter is the pad;
write "[heading of the currently erased jotter][paragraph break]" to the text file of the pad;
now the pad is fresh.
To write in (pad - a jotter):
append "[the time of day]: [topic understood][line break]" to the text file of the pad;
now the pad is used.
To read (pad - a jotter):
say "You read: [paragraph break][text of the text file of the pad]".
This is all as might be expected, except perhaps for the business of the "currently erased jotter". Why copy "pad" into this - why not simply write "[heading of the pad]"? The answer is that "pad" is a temporary "let" value, and cannot be used inside other phrases, such as the "write ... to ..." phrase.
We want to erase any jotters when play begins, as otherwise text left over from any previous games will still be visible:
When play begins:
repeat with pad running through jotters:
erase the pad.
Now we need to create rules to allow the player to control reading, writing and erasing. Reading we will handle with the ordinary examining action, but we create new actions for writing and erasing. A nice little trick allows WRITE WHATEVER to default to writing WHATEVER in a notebook being carried.
Instead of examining a used jotter (called the pad):
read the pad.
Instead of examining a fresh jotter (called the pad):
say "There is nothing of note in [the pad]."
Understand "write [text] in [something preferably held]" as writing it in. Understand "write [text]" as writing it in. Writing it in is an action applying to a topic and one thing. Rule for supplying a missing second noun while writing: if a jotter (called the pad) is carried, now the second noun is the pad; otherwise say "You will have to specify what to write that it."
Check writing it in:
if the second noun is not a jotter, say "It would be better to write in a notebook." instead.
Carry out writing it in:
write in the second noun.
Report writing it in:
say "Under the current time, you write '[the topic understood]' into [the second noun]."
Understand "erase [something preferably held]" as erasing. Erasing is an action applying to one carried thing.
Check erasing:
if the noun is not a jotter, say "It's hard to see how." instead.
Carry out erasing:
erase the noun.
Report erasing:
say "You scrub out all the entries in [the noun]."
That completes a general-purpose implementation of jotters, and we put it to use:
The player carries a jotter called your notebook. The file of Player's Observations is called "notebook". The text file of your notebook is the file of Player's Observations. The heading of your notebook is "Observations in the Pottingham Green Case".
The Damp Hillside is a room. "It is just after dawn: among the trees there is misty and pale blue light. [if Havers is in the location]The only saturated color in view is the orange-and-yellow jacket of [Detective Havers]. She is trying unsuccessfully to light a cigarette. [end if][paragraph break]The body itself is further down, closer to the bottom of the ravine. It would be foolish to speculate before seeing it, but the odds are that the corpse was rolled down after death. The ground is not steep enough for the fall itself to be deadly."
Detective Havers is a woman in the Damp Hillside. The description is "She gives you a weak smile when you look at her: you know she hasn't slept more than three hours any of the last few nights." Havers is scenery.
Havers is carrying a jotter called Barbara's notebook. The file of Barbara's Observations is called "barbara". The text file of Barbara's notebook is the file of Barbara's Observations. The heading of Barbara's notebook is "I could murder a cup of tea".
The time of day is 6:32 AM.
Instead of examining your notebook when your notebook is fresh:
say "Your notebook is blank. Back in the office, of course, there are a stack of others. But you brought a fresh notebook in a kind of weary hope. You're going to pretend, just for now, that this body might be unrelated to the graphic string of murders you're already investigating."
|
ExampleBibliophilia
A bookshelf with a number of books, where the player's command to examine something will be interpreted as an attempt to look up titles if the bookshelf is present, but otherwise given the usual response.
|
|
Suppose we want a bookshelf with a very large number of books on it. They aren't to be taken or carried around in the game, but they should be mentioned, and the player should be allowed to look them up by name. Furthermore, the player's attempts to examine something unrecognized should be understood as an attempt to look up a title -- but only when the player is in the presence of the books. The rest of the time such requests should be rejected in the usual way.
"Bibliophilia"
The Graduate Lounge is a room. "Shabby sofas; plastic cups remaining from the afternoon's pre-lecture espresso; a collection of Xena and Hercules figurines posed for ironic effect. It's somewhat depressing at this hour, when everyone has gone home."
The Classics Reading Room is south of the Lounge. "Not as large a collection as the one in the Library, but it contains copies of everything really essential for reference."
Understand "examine [text]" as examining as a book when the player is in the Reading Room. Understand "look up [text]" as examining as a book when the player is in the Reading Room.
Examining as a book is an action applying to one topic.
Carry out examining as a book:
say "You can't find any such text."
Instead of examining as a book a topic listed in the Table of Book Titles:
say "[description entry][paragraph break]"
Table of Book Titles
topic
|
title
|
description
|
"Reading Greek Death" or "reading/greek/death" or "greek death"
|
"Reading Greek Death"
|
"A dense orange paperback treatise on the development of Greek eschatology."
|
"TAPA/Transactions/134-2"
|
"TAPA 134-2"
|
"Transactions of the American Philological Association from 2004."
|
"Oxford Classical Dictionary" or "OCD/dictionary/classical/oxford"
|
"Oxford Classical Dictionary"
|
"A hefty reference with short articles on everything from Greek meter to ancient cosmetics."
|
"Collected Dialogues of Plato" or "Plato/dialogues/hamilton/cairns"
|
"Collected Dialogues of Plato"
|
"All the Platonic dialogues -- some, admittedly, in rather tired translations -- but still a useful single volume, ed. Edith Hamilton and Huntington Cairns."
|
"Adobe Illustrator CS User Guide" or "user guide" or "adobe illustrator" or "adobe/illustrator/cs/user/guide"
|
"Adobe Illustrator CS User Guide"
|
"Hello, how did this get here? A suspiciously familiar name is scribbled inside the front cover..."
|
Some books are scenery in the Reading Room. Understand "copies" or "book" or "shelf" or "shelves" as the books. Instead of examining the books:
choose a random row in the Table of Book Titles;
say "You scan the shelves and notice, among others, a volume entitled [italic type][title entry][roman type]."
Test me with "south / examine ocd / examine books / examine books / examine plato / n / x hercules / s / x hercules".
Now if we type >X HERCULES in the Lounge, we will get
>x hercules
You can't see any such thing.
thanks to our somewhat slovenly implementation of the Lounge scenery; but in the Reading Room,
>x hercules
You can't find any such text.
In practice we might also want to extend our coverage somewhat to handle a case where the player tried to take books from the bookshelf: currently that would not be understood.
|
ExampleAARP-Gnosis
An Encyclopedia set which treats volumes in the same place as a single object, but can also be split up.
|
|
Suppose we have a complete Encyclopedia in our game. The player is allowed to pick up the whole set (there must not be too many volumes), but also to do things with individual volumes, and indeed to scatter these volumes all over the place. Putting a volume back in the same place as the rest of the Encyclopedia should, however, restore it to the collective. We will start out by defining general rules for collectives like this:
"AARP-Gnosis"
Fitting relates various things to one thing (called the home). The verb to fit means the fitting relation. Definition: a thing is missing if it is not part of the home of it.
A collective is a kind of thing.
Before doing something to something which is part of a collective:
let space be the holder of the home of the noun;
move the noun to the space.
Instead of examining a collective:
say "[The noun] consists of [the list of things which are part of the noun]."
Now the real work begins. One reason to make this an activity is that we might easily want to override it for specific objects; for instance, the generic collecting activity here would not deal properly with collectives of clothing where some items might be worn and others not. In that case, we would want to write another, more specific "collecting" activity to handle the complexities of fashion.
Collecting something is an activity.
Every turn:
repeat with item running through collectives:
carry out the collecting activity with the item.
To remove (item - a thing) when empty:
let space be the holder of the item;
if the number of things which are part of the item is 0:
now the item is nowhere;
if the number of things which are part of the item is 1:
let the last thing be a random thing which is part of the item;
move the last thing to the space;
now the item is nowhere.
Before collecting a thing (called the item):
remove item when empty;
let space be the holder of the item;
if space is not a thing and space is not a room:
if something (called the other space) contains at least two things which fit the item, move item to the other space;
if a room (called the other space) contains at least two things which fit the item, move item to the other space;
if someone (called the owner) carries at least two things which fit the item, move item to the owner.
Rule for collecting a thing (called the item):
let space be the holder of the item;
if space is a thing or space is a room:
repeat with component running through things held by the space:
if the component fits the item, now the component is part of the item;
remove item when empty.
And now for a cheerful scenario:
The Boise Memorial Library is a room. "A concrete box of a room, roughly eight feet by fourteen, which contains all the fallout shelter has to offer by way of entertainment. Someone with a grim sense of humor has tacked a READ! literacy poster to the door, as though there were anything else to do while you await the calming of the Geiger counters." The shelf is a supporter in the Library. "A battered utility shelf stands against the south wall."
The New Idahoan Encyclopedia Set is a collective. Volume A-Aalto fits the Encyclopedia. It is part of the Set. Volume AAM-Aardvark fits the Encyclopedia. It is part of the Set. Volume Aarhus-Aaron fits the Encyclopedia. It is part of the Set. Volume AARP-Gnosis fits the Encyclopedia. It is part of the Set. Volume Gnu-Zygote fits the Encyclopedia. It is part of the Set. The Set is on the shelf.
Let's have the Encyclopedia describe itself differently depending on whether it's all in one place:
After printing the name of the Set when something missing fits the Set:
say " (missing [a list of missing things which fit the Set])"
Before printing the name of the Set when the number of missing things which fit the set is 0:
say "complete ".
Test me with "get aarhus-aaron / look / inventory / get aam-aardvark / look / get gnu-zygote / look / get aarp-gnosis / look / inventory / drop set / look / get set / get a-aalto / inventory".
|
ExampleThe Fifth Body
An expansion on the notebook, allowing the player somewhat more room in which to type his recorded remark.
|
|
The implementation here is much like that of the previous example, except that we allow the player to write his notebook input as a separate command, leading to an exchange such as
>write in my notebook
You open your notebook and prepare to write in it.
>>Am beginning to think that HT and BGG are in this together.
You finish writing and fold your notebook away.
>read my notebook
You read:
Wednesday morning
Am beginning to think that HT and BGG are in this together.
The opening is much as before:
"The Fifth Body"
A jotter is a kind of thing. A jotter has an external file called the text file. A jotter can be fresh or used. A jotter is usually fresh. A jotter has a text called the heading.
The currently erased jotter is an object that varies.
To erase (pad - a jotter):
now the currently erased jotter is the pad;
write "[heading of the currently erased jotter][paragraph break]" to the text file of the pad;
now the pad is fresh.
To write in (pad - a jotter):
append "[the time of day]: [player's command][line break]" to the text file of the pad;
now the pad is used.
To read (pad - a jotter):
say "You read: [paragraph break][text of the text file of the pad]".
When play begins:
repeat with pad running through jotters:
erase the pad.
Instead of examining a used jotter (called the pad):
read the pad.
Instead of examining a fresh jotter (called the pad):
say "There is nothing of note in [the pad]."
Target jotter is an object that varies. The target jotter is usually nothing.
Understand "write in [something preferably held]" as writing in. Writing in is an action applying to one thing.
Check writing in:
if the noun is not a jotter, say "It would be better to write in a notebook." instead.
Carry out writing in:
now the command prompt is ">>";
now the target jotter is the noun.
Report writing in:
say "You open [the noun] and prepare to write in it."
Now what happens is that the player, having typed WRITE IN NOTEBOOK, will be faced with a ">>" prompt instead of the usual ">": a sign that the input mode has changed.
The next code is to react to reading a command. Whatever the player types at the >> prompt when the target jotter is set will now be recorded in the notebook, though with a character limit of about 60-100 characters depending on how much upper-case and punctuation he uses. (There are ways to lift the character length restriction as well, but they would take us into deeper waters.)
After reading a command when target jotter is a jotter:
now the command prompt is ">";
write in target jotter;
now target jotter is used;
say "You finish writing and fold your notebook away.";
now the target jotter is nothing;
reject the player's command.
Understand "erase [something preferably held]" as erasing. Erasing is an action applying to one carried thing.
Check erasing:
if the noun is not a jotter, say "It's hard to see how." instead.
Carry out erasing:
erase the noun.
Report erasing:
say "You scrub out all the entries in [the noun]."
The player carries a jotter called your notebook. The file of Player's Observations is called "notebook". The text file of your notebook is the file of Player's Observations. The heading of your notebook is "Sunday Morning".
The Vestry is a room. "[Havers] hangs back by the door: the forensics expert is not finished with a preliminary examination of the body. From here you can't see much, except that the expert has peeled back and laid to one side a liturgical vestment that someone at the church used to cover the corpse until the police came. What was once a cream silk with festive Easter embroidery is now stained with blood-colored handprints."
Detective Havers is a woman in the Vestry. The description is "She looks glumly back. There's still a purple-ish bruise on her cheekbone from the disaster Thursday afternoon." Havers is scenery.
Havers is carrying a jotter called Barbara's notebook. The file of Barbara's Observations is called "barbara". The text file of Barbara's notebook is the file of Barbara's Observations. The heading of Barbara's notebook is "Sun. AM".
The time of day is 9:11 AM.
The following relies on quite a number of features we haven't met yet: tables, rules for printing names, instructions for understanding the player's commands. It is offered simply as an example of how a fully implemented book might be handled in Inform.
"Costa Rican Ornithology"
A book is a kind of thing. Understand "book" as a book. A book has a table name called the contents.
Instead of consulting a book about a topic listed in the contents of the noun:
say "[reply entry][paragraph break]".
Report consulting a book about:
say "You flip through [the noun], but find no reference to [the topic understood]." instead.
With this "topic understood" phrase, we're telling Inform to print back the word or phrase that the player was attempting to look up. This overrides the more general default response, "You discover nothing of interest in the book."
We now have the essential elements to construct whatever books we like. Now let's have an example of a specific book:
The Guide to Central American Birds is a book carried by the player. The contents of the Guide is the Table of Listed Birds.
We will come back to the idea of tables and table names later, but for now the important thing is that we have instructed Inform to look up its answers to consulting the bird guide in this form:
Table of Listed Birds
topic
|
reply
|
"[red]" or "[red] bird/macaw"
|
"You flip through the Guide for a while and eventually discover a reference to the [scarlet macaw], which appears to correspond with what you see before you."
|
"quetzal/trogon" or "resplendent trogon"
|
"The entry on the quetzal is quite lyrical, describing its brilliant plumage, flashing and igniting in the sunshine, which is supposedly sufficient to lure birdwatchers from all over the world. Unfortunately, the quetzal is described as being bright emerald in color, with a pink fuzz on its head and a long soft tail 'like a feather boa'. None of these describes your visitor."
|
The topic column is a bit special: it matches the player's input, and is not meant to be printed out again. Topic columns will be discussed further in the chapter on Tables. (Note also that, however it may appear in the documentation, the topic column should not be spanning multiple lines in our source text.)
We may also compress long or complicated topics by creating bracketed abbreviations, and in fact it's useful to do so now, to explain the red token we just used:
Understand "red-orange" or "bird" or "red" or "orange" as the scarlet macaw. Understand "red-orange" or "red" or "orange" or "scarlet" as "[red]".
This technique is discussed further in the chapter on Understanding.
If we wanted more books, we could define those in the same way, giving each its own separate contents table to be used for consultation. But for the sake of the example we will keep it simple, and move on to the scenario itself:
The Veranda is a room. "From here you can see a considerable expanse of dense-growing jungle plants, and eventually the open water beyond."
The scarlet macaw is an animal in the veranda. "A vibrantly-colored [scarlet macaw] perches on the rail."
A thing can be known or unknown.
Before printing the name of the scarlet macaw while consulting:
now the scarlet macaw is known.
Rule for printing the name of the unknown scarlet macaw: if the macaw is unknown, say "red-orange bird of unknown species".
Test me with "look up penguins in the guide / look up quetzal in guide / look up silver nuthatches in the guide / look / look up red bird in the book / look".