Then we get:
Then we get:
If this were true, wouldn’t this imply that all privately-named things without an associated Understand would be identical? If there’s nothing you can type to distinguish them, they must be identical.
The Kitchen is a room. A gem is a kind of thing. The ruby is a privately-named gem in the Kitchen. The diamond is a privately-named gem in the Kitchen.
You can see two gems here.
(If you make them privately-named things, with no “gem” kind, you run into a bug where it just says “You can see two here.”)
But not quite identical, as my example above showed:
You can see two gems here.
Edit: I guess that’s better than:
What do you mean: the , or the ?
That is in fact how identical (indistinguishable) objects behave! If the parser thinks you can’t refer to either of them specifically, it’s willing to pick one at random without asking a disambiguation question.
It’s when the objects do have distinct names that the parser insists on asking “What do you want to get?”
(Footnote: not really at random. I think it always picks the first in the object tree.)
Yeah, I know. I was attempting, lamely, to be funny.
I’m really arguing that it doesn’t treat them totally identically since it actually prints their supposedly private names. Wouldn’t a more consistent behavior be to flag this as a runtime error? (I assume not a compile error – the compiler checks for mutually contradictory statements, but doesn’t seem to check for missing information, unless it’s something like no rooms.) I’m not sure it’s a more desirable behavior, on the other hand.
Edit: I’m grading discrete math proofs and it’s making me feel increasingly pedantic.
Thanks for everyone’s responses! They’ve been very educational.
The next chapter is
This is really where Inform shines. Twine borrowed a lot of its text manipulation techniques from Inform. If anyone ever had a real reason to plug Inform into a Unity game, it’d probably be for its adeptness with handling text.
Section 5.1 is ‘Text with Substitutions’. The idea here is that you can put stuff in brackets in the text and define what it actually is later; basically a text variable getting called in runtime. The example given is a little more complex than needed (it uses kinds when it could just be a single object) but it works:
A dead end is a kind of room with printed name "Dead End" and description "This is a dead end. You'll have to go back the way you came, consoled only by [river sound]." A dead end is usually dark. The Undertomb is a dark room. East is a dead end. South is a dead end with printed name "Collapsed Dead End". Northwest is a dead end called the Tortuous Alcove. In the Undertomb is the lantern. It is lit. A dead end has some text called river sound. The river sound of a dead end is usually "a faint whispering of running water". The Tortuous Alcove has river sound "a gurgle of running water".
Section 5.2 is How Inform Reads Quoted Text.
It specifically deals with brackets, apostrophes, and quotes.
To print a left bracket, you type [bracket]. To print a right bracket, you type [close bracket]. (I always try to type [open bracket] and then I get errors).
(As a side-note, one fun fact I’ve seen online is that [ [ ] ] and ] ] [ [ are not palindromes but [ ] ] [ is.)
Apostrophes inside words like contractions are rendered as apostrophes, while apostrophes at the edges of words are rendered as quotation marks. So you have to type [apostrophe] to get an actual apostrophe printed at the edge of a word, or just ['], which is what I do.
The example given is:
Instead of going outside, say "Lucy snaps, 'What's the matter? You don't trust my cookin['] mister?'"
In the very rare instance you want a double quote in the middle of a word, you can type [quotation mark] but not ["], since, as the book says:
(Note that ["] is not allowed; a double-quotation mark is never allowed inside double-quoted text, not even in a text substitution.)
It also mentions line breaks after sentence-ending punctuation, which we’ll get to later.
There are no examples in this chapter so far.
Section 5.2 is Text which names things.
This is about what you can throw into the brackets.
If you have a value that can be printed, you can just throw that into a bracket. His example is:
The description of the wrist watch is “The dial reads [time of day].”
For debugging, I’ll often add a line that says something like:
Every turn: say "The prize level is currently [prize-level]."
and then comment it out when I’m done.
Printing the name of an object has a little bit of subtlety to it. If you just put an object name in square brackets, it will print the printed name of the object.
So code like:
The secret devil is in Churchyard. The printed name of the secret devil is "poodle". When play begins: say "You are confronted by a [secret devil]."
That will print ‘you are confronted by a poodle’.
Sometimes you don’t know if the thing you are going to print is plural, proper-named, or singular, and so you don’t know if you want to put ‘a’ or ‘some’ or nothing in front of it.
In that case, you can move the ‘a’ inside the brackets and Inform deals with it automatically for you:
Instead of examining something (called the whatever): "You can only just make out [a whatever]."
This works with ‘the’ too:
Instead of examining something (called the whatever): "You can only just make out [the whatever]."
In my murder mystery section, I have a woman called ‘Maeve’ who is called ‘a glamorous woman’ before you ask her name, so I have some code saying stuff like
[The maeve] says, 'But I didn't do it!', which reads as ‘The glamorous woman says…’ or ‘Maeve says…’ as needed.
If you capitalize the The or A, the game will too. If you don’t capitalize it, the game won’t.
(Still no examples so far).
Section 5.4 is Text with numbers. Ordinarily, printing a value that is a number will just be digits:
"You've been wandering around for [turn count] turns now."
(This example is also our introduction to the concept of ‘turn count’).
If we want the word written out, we can just say ‘in words’:
"You've been wandering around for [turn count in words] turns now."
Sometimes it’s hard to tell inform to alter text like this when you have other complicated conditions (something like [the number of people in Lobby in words] sometimes makes Inform choke for me), so in that case it’s nice just to make an intermediary variable, like:
let currentnum be the number of people in Lobby; say "[currentnum in words]";
A tester for my game recently pointed out that I said something like ‘1 things’ or something like that due to a substitution. I guess the next hint would be useful for me:
This text substitution prints a letter “s” unless the last number printed was 1. Example:
"You've been wandering around for [turn count in words] turn[s] now."
produces “… for one turn now.” or “… for two turns now.” as appropriate. Note that it reacts only to numbers, not to other arithmetic values like times (or, for instance, weights from the “Metric Units” extension).
The author notes this is only a special case but is useful.
Example 30 is Ballpark, which rounds numbers off and uses approximate words instead:
To say (count - a number) in round numbers: repeat through the Table of Numerical Approximation: if count is less than threshold entry: say "[approximation entry]"; rule succeeds.
Table of Numerical Approximation
|3||“a couple of”|
|1000||“lots and lots of”|
Section 5.5 is Text with lists, which is our introduction to lists. I use these a ton.
To make a list of things, just say ‘[list of (description of objects)]’ like:
"Mr Darcy glares proudly at you. He is wearing [list of things worn by Darcy] and carrying [list of things carried by Darcy]."
I wondered for a long time how to get it to include ‘the’ or ‘a’ in a list for each item, but it’s really easy: just add ‘a’ into the brackets.
So in my code I use [a list of…] 20 times. In one room, there’s basically a treasure hunt where you have to find pole-like objects that are actually spears in disguise and collect them. So I have this:
A weapons rack is behind Arthur[if the number of hidden-spears in weapons-rack is 0], currently empty[otherwise], currently holding [a list of hidden-spears contained by the weapons-rack][end if].
Again, capitalizing the A or The will capitalize it in the printed text (just the first one if the list has more than one item).
If a list has no objects in it, it prints out the word ‘nothing’.
The next part is something I’ve never used or understood, though I’ve seen it. Now it makes sense. It’s basically when you don’t know if the list will have one thing or multiple things, so you don’t know if you should say ‘is [a list of…]’ or ‘are [ a list of…]’, so you just say “[is-are a list of…]”.
You can also make everything that is listed in the list that has contents also list is contents. This is useful if you’re rewriting standard behavior like inventory:
say "[a list of (description of objects) including contents]"
Example 61 is Control Center, which just automatically lists parts of things:
After examining a thing when something is part of the noun: say "[The noun] includes [a list of things which are part of the noun]."
[I]t may be worth noting: because we’ve written our rule as an “After examining…”, anything that pre-empts the operation of the examine command will also prevent that rule from occurring.
Example 62, Tiny Garden, automatically prints out the directions you can go:
A Grassy Room is a kind of room. The printed name of a Grassy Room is usually "Lawn". The description of a Grassy Room is "The grass underfoot is thick and green. The lawn extends to [grassy directions] from here."
Now we’re getting to the good stuff. Section 5.6 is Text with Variations. This is about if statements and such.
Here is a simple if/else statement (I always get annoyed when I try typing ‘otherwise’ in python):
The Customs Wharf is a room. "Amid the bustle of the quayside, [if the cask is open]many eyes stray to your broached cask. [otherwise]nobody takes much notice of a man heaving a cask about. [end if]Sleek gondolas jostle at the plank pier."
To say grassy directions: repeat with that way running through directions: if the room that way from the location is a grassy room, now that way is marked for listing; say "[a list of directions which are marked for listing]"; now every direction is not marked for listing.
Another option is ‘unless’, which I’ve never used but might have used once or twice had I known. It only prints if the condition is not true:
The Customs Hall is a room. "With infinite slowness, with ledgers and quill pens, the clerks ruin their eyesight.[unless the player is a woman] They barely even glance in your direction."
The main use I could see for this is that sometimes Inform doesn’t understand where to parse ‘not’ in a long condition. I tend to remove complicated ‘if’ statement logic into a completely separate block of logic with a ‘to say’ statement for stuff like that:
The description of the desolation-screen is "This monitor is more conspicuous than the others. [monitorloop]." To say monitorloop: if the eye-monitors are unawakened: say "It's turned off, though, like them all"; otherwise if the eye-camera is unawakened: say "It's turned on, but is showing only static"; otherwise if desolation-attempt is 0: say "It's turned on, but is showing only static"; otherwise if desolation-attempt is 1: say "It is currently playing a video of you from earlier...";
The phrase [otherwise] is just like an else statement. And apparently we can type [else] instead of otherwise! Weird.
We can also add else if/elif statements in the middle:
The wine cask is a container. The printed name of the cask is "[if open]broached, empty cask[otherwise if transparent]sealed cask half-full of sloshing wine[otherwise]sealed wine cask"
(I’m still not used to referring to properties of a noun by just the property name. It feels so weird for me to type ‘if transparent’ instead of ‘if the ___ is transparent’.)
At the end of any if or unless statement we need to include an end to it if we want to print normal stuff afterwards:
say "[end if]"
say "[end unless]"
Next is something a bit tricky:
We sometimes need to be careful about the printing of line breaks:
The Cell is a room. "Ah, [if unvisited]the unknown cell. [otherwise]the usual cell."
This room description has two possible forms: "Ah, the unknown cell. ", at first sight, and then “Ah, the usual cell.” subsequently. But the second form is rounded off with a line break because the last thing printed is a “.”, whereas the first form isn’t, because it ended with a space. The right thing would have been:
The Cell is a room. "Ah, [if unvisited]the unknown cell.[otherwise]the usual cell."
My way to handle this (which I feel is pretty standard?) is to just not end any of the variations with punctuation until the very end:
The Cell is a room. “Ah, [if unvisited]the unknown cell[otherwise]the usual cell[end if].”
This of course doesn’t work if one of the variations has a question mark or quotation, which has led to some horribly obtrusive lines in some of my games that are solely there to end a block of text with a period.
I just don’t trust the example in the text, tbh. Whenever I don’t do ‘the punctuation trick’ of saving all punctuation until after the IF statement, inform betrays me.
When varying descriptions are being given for kinds of rooms or things, it can be useful to make use of a special value called “item described”, which refers to the particular one being looked at right now. For example:
A musical instrument is a kind of thing. The tuba and the xylophone are musical instruments. The description of a musical instrument is usually "An especially shiny, well-tuned [item described]."
I never knew when I could use ‘the item described!’. I see now it can be used for kinds of things. And apparently it can be used for individual things, too? So does that mean there are three ways of saying the same thing?
like, if height is a property of objects could we have all three work for the description of an object called ‘cask’?:
"The cask is [height] cm tall." "The cask is [height of the item described] cm tall." "The cask is [height of the cask] cm tall."
This is an area I am always deeply confused on. I usually try something, get it wrong, google, try something else, until it finally works. (I’ll admit, I usually write ‘noun described’ instead of ‘item described’ and wonder why it doesn’t work. I actually did that again while writing this and had a whole deleted diatribe). My current game only uses ‘item described’ once:
The description of an elvis-table is usually "This is a turntable with a record on it labelled [song-first of the item described] [song-second of the item described]. The record seems firmly attached to the turntable at the center, but still able to spin. The turntable has the number [song-length of the item described] on it."
Example 63 is “When”, which just varies the description of a door depending on which side you’re on:
The temporal vortex is an open door. It is west of Yesterday and east of Today. "A whirling temporal vortex leads [if the player is in Yesterday]west[otherwise]east[end if]."
The next example is Whence, a more complicated example of a door that automatically describes itself and the room on the other side
The initial appearance of a door is usually "Nearby [an item described] leads [if the other side of the item described is visited][direction of the item described from the location] to [the other side of the item described][otherwise][direction of the item described from the location][end if]."
Finally, example 65, Persephone, splits up the player’s inventory. My extension, Clues and Conversation, also does this, specifically because I model conversational topics as physical objects.
Here’s persephone’s code:
Instead of taking inventory: say "[if the player carries something][We]['re] carrying [a list of things carried by the player][otherwise][We]['re] empty-handed"; say "[if the player wears something]. [We]['re] wearing [a list of things worn by the player][end if]."
Next is Section 5.7, in some ways Inform’s crown jewels, although it’s not hard to code up in other languages. But where leaders forge, others must follow.
The idea is that you type “[one of]…[or]…[or]…” followed by a special stopping phrase, and then Inform will vary which text between the 'or’s it uses each time, according to the special stopping phrase.
These ending words are:
Then there’s [first time]…[only]:
"The screen door squeaks loudly as when you open it. [first time]Well, you'll get used to it eventually. [only]"
This is exactly equivalent to
"The screen door squeaks loudly as when you open it. [one of]Well, you'll get used to it eventually. [or][stopping]";
This section ends with a useful tip about avoiding these substitutions for situations where the game checks a name internally (I’ve run into a nasty bug in my own code about this which I’ll take more about later on):
Something to watch out for is that texts are sometimes being printed internally for purposes other than actual output which the player can see, and this is particularly true of names. For example:
Before printing the name of the traffic signal: say "[one of]green[or]amber[or]red[cycling] ".
This looks good for some purposes, but may not cycle in the sequence expected, and can result in incorrect indefinite articles being printed – “an red traffic signal”, for example. What’s happening is that the name is being printed internally to see whether it begins with a vowel; that prints “amber traffic signal”, but invisibly to us, and since this does begin with a vowel, “an” is visibly printed; then the name is visibly printed, but now it has changed to “red traffic signal”, and so the result on screen is “an red traffic signal”. There are many ways to avoid this (for example, to give the traffic signal a state which changes every turn, not every time the name is printed), but it’s a trap to look out for.
Example 66 is Radio Daze by Jon Ingold (!):
Every turn when the radio is switched on: say "[one of]Two characters in the radio play have begun an argument[or]The argument continues[or]The play continues[stopping]: [one of]'Did not!'[or]'Did too!'[or]'Did I?'[or]'You did!'[or]'I couldn't have, Martha!'[or]'But you did, Tom!'[cycling]"
(Somehow this reminds me of Zarf’s play at the beginning of So Far, although that was much more complex)
Example 67, Camp Bethel, has numerous examples of random text, including with conversation. It has a human using [cycling], since he has a plan and an order; a cat with [purely at random], since cats “could plausibly stare out the window for five turns in a row.”; and a housefly with [at random] so it does something different every turn.
It includes this fun response:
Instead of asking Jeremy about something: say "'[one of]Sorry,[or]I'm afraid[or]Hm,[at random] [one of]I don't know much about that[or]you've got me there[or]I haven't the faintest[at random],' Jeremy [one of]drawls[or]replies[or]comments[or]exclaims[at random]"; say "[one of][or] huskily[or] throatily[or] silkily[or] in a deep manly voice[as decreasingly likely outcomes]."
Section 5.8 is Line Breaks and Paragraph Breaks.
It claims there are rules to Inform’s line breaks:
There are two principles:
(a) pieces of text ending with full stop, exclamation or question marks will be followed by line breaks (or “new lines”, as some computer programming languages would call them); and
(b) pieces of text produced by different rules in Inform will be separated by paragraph breaks.
But in my experience you just chuck whatever you have at the compiler and try to fix it if its wrong, and if you end up with a double line break at the end of some turns and Rules doesn’t say anything is going on there than you break down and cry for hours before deleting your code.
Anyway, here are some ways to manipulate whitespace:
[line break] makes a line break. I find this most useful for poetry and ascii art.
[no line break] is just completely ignored by Inform no matter how much you beg it to use it correctly (that is my experience. Here is a sample use in the documentation:
"The chorus sing [one of]Jerusalem[or]Rule, Britannia![no line break][at random]."). Apparently it only works when Inform would usually insert a line break after punctuation, and not, as I fervently wished, keep it from putting a paragraph break between text printed by different rules. I think.
Oh, apparently this next one would have done what I wanted. Oh my gosh… the tears I have shed over this. If this actually works, I probably wasted 30+ hours of my life on line breaks (okay maybe 5+ but still):
[run paragraph on] prevents the paragraph break that occurs after text is presented (including, it seems, when the paragraph break is caused by separate rules).
[paragraph break] is a very useful way of making paragraphs. I use this all the time, especially since Inform does not put paragraph breaks between text printed inside the same rule, and does not put paragraph breaks after text ending in brackets. For instance:
To say spelllist: repeat with current running through magic-spells in spell-book: say "[paragraph break][italic type][current][roman type]: [spell-preview of current]"
The next is
[conditional paragraph break], which is very useful. It puts a paragraph break at the end of something unless that would cause multiple white lines. This is a good substitution that I would trust with my life, unlike the backstabbing
[no line break].
I use it here:
Every turn when squipcounter is 7: now squipcounter is 0; say "[one of]It dawns on you that this group of suspects is quite adept at lying. While they have been willing to talk about many subjects, you're beginning to feel that only calling them out directly in their lies will make any real progress.[or][bracket]Talking to suspects about clues can provide useful info, but only clues produced by LINKing one clue to another will produce any real progress[close bracket][stopping][conditional paragraph break]"
Do I even need it here? Maybe not, but it’s safe, and I usually only add it when I noticed before that I sometimes was missing a paragraph break I needed and sometimes not.
The next is
[command clarification break], which I have never used. I’ll just say what he says:
This text substitution produces a line break, and then also a paragraph break if the text immediately following is a room description brought about by having gone to to a different room and looking around, in which case a line break should be dded. In traditional IF, this is used when clarifying what Inform thinks the player intended by a given command.
I don’t think I’d use this much because I’ve noticed people rarely read text printed before a new room description anyway.
The last is
[run paragraph on with special look spacing], which acts like so:
This text substitution produces no text. It’s used only for a side-effect: it indicates that the current printing position does not follow a skipped line, and that further material is expected which will run on from the previous paragraph, but that if no furt er material turns up then a skipped line would be needed before the next command prompt.
Example 68 is “Beekeeper’s Apprentice”. It just uses Run paragraph on in an interesting way:
Studying the vicinity is an action applying to nothing. Report studying the vicinity: if the location does not contain something which is scenery: say "There's little of interest in the [location]." instead; repeat with point of interest running through scenery in the location: say "[point of interest]: [run paragraph on]"; try examining the point of interest. Understand "search" as studying the vicinity.
Section 5.9 is Text with type styles.
This is basically just like HTML tags. Most of them require you to end in [roman type] to turn them off. Some examples:
"Jane looked down. [bold type]Danger[roman type], the sign read." "This is [italic type]very suspicious[roman type], said Peter."
Alternatively, you can use fixed letter spacing, also remembering to turn it off:
"On the door is written: [fixed letter spacing]J45--O-O-O[variable letter spacing]."
Quixe comes equipped with CSS files that handle 2 ‘special styles’, which is great if you want to do fancy-looking web effects.
The next example is Garibaldi 2 by Emily Short, which allows colored lettering (but I swear this only works in z-machine? IDK):
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.
(oh, at the bottom it says it only works for z-machine. That’s what I thought!)
Next is accented letters, Section 5.10. Here’s what Inform can handle just fine:
ä, á, à, ã, å, â and Ä, Á, À, Ã, Å, Â
ë, é, è, ê and Ë, É, È, Ê
ï, í, ì, î and Ï, Í, Ì, Î
ö, ó, ò, õ, ø, ô and Ö, Ó, Ò, Õ, Ø, Ô
ü, ú, ù, û and Ü, Ú, Ù, Û
ÿ, ý and Ý (but not Ÿ)
ñ and Ñ
ç and Ç
æ and Æ (but not œ or Œ)
These can be used in all ways the same as English symbols.
Other symbols don’t survive as well (this is why I use two hyphens instead of em-dashes):
As it reads in the text, Inform silently converts all kinds of dash (en-rules, em-rules, etc.) to simple hyphens; converts the multiplication symbol to a lower case “x”; converts all kinds of space other than tabs (em-spaces, non-breaking spaces, etc.) to simple spaces, and all kinds of quotation marks to “straight” (non-smart) marks.
Some characters can be printed but not used in source or typed in:
All other Latin letter-forms, including the œ ligature, East European forms such as ő, ş and ž, and Portuguese forms such as ũ; the Greek and Cyrillic alphabets, with their associated variants and accents; and the principal currency symbols, such as € and ¥.
and even these aren’t guaranteed to get printed.
Finally, many words don’t work:
The Arabic and Hebrew alphabets are fairly likely to be available; miscellaneous symbols are sometimes legible to the player, sometimes not. Other alphabets are chancier still. (If a work of IF depends on these being visible, it may be necessary to instruct players to use specific interpreters, or to provide a way for the player to test that all will be well.)
Section 5.11 is Unicode characters, which provides an alternative way to print things:
Unicode characters can be named (or numbered) directly in text. For example:
"[unicode 321]odz Churchyard"
produces a Polish slashed L. If the Unicode Character Names or Unicode Full Character Names extensions are included, characters can also be named as well as numbered:
"[unicode Latin capital letter L with stroke]odz Churchyard"
Inform uses decimal rather than hexadecimal for unicode.
There is an extension Unicode Character Names by Graham Nelson that names 2900 of the characters.
But before getting carried away, we should remember the hazards: Inform allows us to type, say, “[unicode Saturn]” (an astrological sign) but it appears only as a black square if the resulting story is played by an interpreter using a font which lacks the relevant sign.
Example 70 is The Über-complète clavier. It has stuff like this:
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.
If you like this kind of thing, you might like the umlaut puncher in Counterfeit Monkey.
Section 5.12 is Boxed Quotations. These look beautiful and amazing in Z-code and hideous and useless in Glulx, due to some baked-in restrictions that will likely never be removed:
After looking in the Wabe, display the boxed quotation "And 'the wabe' is the grass-plot round a sun-dial, I suppose? said Alice, surprised at her own ingenuity. Of course it is. It's called 'wabe,' you know, because it goes a long way before it, and a long way behind it -- -- Lewis Carroll".
It’s a reasonable interpretation of what the name could mean, but
privately-named doesn’t mean any attempt to keep something’s name confidential. It just means no dictionary words are created by default. And once Inform has gotten to “what’s a parser got to do for a noun around here?” it doesn’t care whether or not you could have deliberately referred to it in a command.
Finally, Section 5.13, Making New substitutions.
I use this for everything; it’s literally my favorite thing in the world. Anytime my code inside a quote is getting too complex, I make my own substitution and put it in instead. An example:
The Missile Base is a room. "[security notice]Seems to be a futuristic missile base." M's Office is east of the Missile Base. "[security notice]Admiral Sir M.- M.- glares up from his desk." To say security notice: say "This area is a Prohibited Place within the meaning of the Official Secrets Act 1939. "
The nice thing is, you can actually run code in the ‘to say’ statement! That means every time that thing is printed, your code executes!
Unfortunately this doesn’t work well for a few circumstances, as detailed here. But it works often enough that it’s worth a shot!
Example 71 is a pretty funny example called Fifty Ways to Leave Your Larva:
The Beekeeper's Palace is a room. Wasp is a woman in the palace. Drone is a man in the palace. Instead of kissing someone: say "'[denial], [insult]! [boast]!'";
A person has some text called denial. The denial of a person is usually "Stand back". The denial of Drone is "You forget yourself" A person has some text called insult. The insult of a person is usually "Grasshopper". The insult of Wasp is "Larva". A person has some text called boast. The boast of a person is usually "I am ferocious". The boast of Drone is "I have ferocious allies".
I did a lot of stuff like this in Grooverland, but relying too much on procedural text is dangerous. I got several complaints that the dialogue in that game was flat and lifeless.
Example 72 is Fifty Times Fifty Ways, and has more complex ‘say’ rules:
To say denial for (speaker - a person):
if speaker is calm:
say “You must not”;
otherwise if speaker is female:
say “Stand back”;
say “You forget yourself”.
And that’s Chapter 5! Great chapter!
“Privately-named” has absolutely nothing to do with the object’s printed name or the game’s object-printing code.
You could get the same result this way:
A gem is a kind of thing. A gem called the diamond ruby is in the Kitchen. A gem called the ruby diamond is in the Kitchen.
The two objects have the same synonym lists, so the parser considers them indistinguishable, even though their printed names are different.
Since you’re used to Python, it might help to know that the I6 name of “the item described” is
self. In other words, “the item described” is the thing whose property we’re printing: the thing that owns the description or printed name or whatever it ends up being.
And yep, when you use a property name on its own like that, it means that property of the item described.
This is one of those things you should never actually need, but for the one specific instance when it’s useful, it’s documented. It’s used exactly once, in the implementation of the “looking” action, for some finicky details involving multiple levels of containment.
Honestly I’m not sure why this is documented at all. Many of these obscure internal phrases are left out of the documentation because they’re just confusing.
One of my hopes, now that Inform is open-source, is that we can finally move on from Latin-1 and start using Unicode for everything.
And everything else, for that matter!
Have you ever seen Nathanael Nerode’s Nathanael’s Cookbook extension? It’s not really an extension so much as a reference manual for getting rid of unwanted white space. It helped me stamp out a couple of horrible line break bugs that I’d been struggling with for over a year.
No, sounds cool! Thanks!
“That can’t possibly be right!” - me before carefully rereading it.
Wasn’t this essentially a obsolete nicety since back in the day some mainframes didn’t have monitors so Zork or Colossal Cave were sometimes played by printing the game output?
That’s at least what I remember reading somewhere. SUPERBRIEF was to save paper.
Transcripts were all printed back then, too, so that would have been another consideration
I used a thermal printer terminal with an acoustic coupler, something like this TI Silent 700 (or maybe exactly that). I think I even played Colossal Cave on it.
I printed more than a couple of Enchanter sessions on my Okidata Okimate 10!
(not mine, reference pic)
I expected to not keep up with Brian, but good grief.
Occasionally, we talk as if there are kinds of value, and then there are objects, which have object kinds, but of course “kind of value” is just I7 for what most languages call “type”. Even objects are values and object kinds are kinds of value.
We get most of the list of kinds of value in Chapter 22, but you need the Project Index for the whole whole list. Besides the object kinds of value, there’s:
Not counting the constructed kinds of value like phrases or lists.
This introduces us to saying
usually for kinds’ properties’ defaults.
A lot of different English language constructions are represented in Inform’s syntax. Sometimes I think we’d have been better off with somewhat less variety. Sometimes they come in really handy, but statements with conjunctions cause a lot of errors.
Once a plural, always a plural:
brother in laws remains valid; you can’t undo it.
A thing we’re not told outright is: always name your kinds of value in the singular. If you name it in the singular, you get Inform’s best guess of the plural (which is correct much more often than not) for free, and you can specify your own plural.
If you start
Colors are a kind of value. you would need to say
Some colorss are red, green blue.
You can’t explicitly specify the singular: you were supposed to do that in the assertion declaring the kind.
Bad idea alert! Except that Inform doesn’t actually care about grammatical number in your code most of the time. You could say:
Colors are a kind of value. The plural of colors is color. This, of course, would be regrettable if you came to a place where Inform needed to output the singular or plural name of the kind.
Finally, there’s no need for assertions of plurality like
The plural of brother in law is brothers in law. to refer to things that actually exist. You can go ahead and throw
The plural of octopus is octopodes. into all your games (and why wouldn’t you?)
The term only occurs once in the text (WI 11.18), but something like this is an “enumerated kind of value”.
I’ve gotten into the habit of calling these “specified kinds of value”, but I suppose I should shift to “quantitative kinds of value” or “units”. The former doesn’t occur elsewhere than this section; the source code refers to “units”.
In general, if Inform can find a sensible way to store properties, then it will allow them. But it won’t allow (for example) properties of numbers. There are only a finite number of Bengal tigers in the world (fewer than three thousand, alas), so Inform can easily store individual description texts for each one of them. But there are an infinite range of numbers.
For most kinds of value, you could use
repeat with x running through the <name of kind of value>:.
You can’t with:
numbers, real numbers, texts, unicode characters, snippets, actions, equation names, rulebook outcomes
None of those can have properties, either. The following also can’t have properties (though they could be iterated over):
times, truth states, use options, responses, verbs, table names, action names
You sometimes hear people call either/or properties “attributes”. That’s an Inform 6 term. The Z-machine imposes a hard limit of 48 attributes. But Basic Inform and the Standard Rules start out defining 37, and extensions often add them, so there’s not a lot of room. Fortunately, Inform 7 either/or properties don’t need to be I6 attributes; if it runs out of attributes, it goes on to store them elsewhere and is then limited only by memory. The difference is invisible to your code: they’re all just either/or properties. Unfortunately, attributes are much faster in use than the alternative.
Glulx can do 56… but Inform 7 doesn’t try to use those extra 8. I wanted to fact check the following, but I can’t find where I saw @Zarf talking about this. If my recollection is correct, there’s no reason the NUM_ATTR_BYTES constant couldn’t be set much larger for glulx, and even that glulxe and quixe are already ready for that, but that it would take modifications to Inform 6 as well as I7 itself before I7 could make use of it.
(If we last all the way to 27.22 we’ll finally get a mention of either/or properties sometimes being implemented as attributes and sometimes as properties.)
Inform abhors a vaccuum: variables, properties, everything gets a default. With kinds of objects or enumerated kinds of value, it’s whichever one of them was defined first in the code.
Inform has no trouble with you defining a kind of object or other kind of value without creating any specifics. It’s fine with:
A sausage dog is a kind of animal. A color is a kind of value.
standing alone. But there’s a potential gotcha. If your code also has:
Mrs Murphy's favorite is a sausage dog variable.
you’ll get a compiler error if there are no sausage dogs in the world for Mrs Murphy’s favorite to default to.
Some extensions define kinds of value and create variables for that kind of value, but don’t ever specify any instances of that kind of value, because the point of the extension is for you to create your own (and if you’re not doing that, you can just… not include it). At one point, I thought it was bad design to write an extension whose simple inclusion would cause compilation to fail. Then I wrote one, and it made more sense.
(We won’t get there for a while, but blank rows in tables are an exception: table column entries do not get default values. They’re like null pointers, and if you try to read one before assigning it, you’ll get a runtime error.)
A party guest can be boring, so-so, or riveting. A party guest can be crashing or invited.
Without explicit defaults being asserted, a default party guest would be boring and invited. With enumerated kinds of value (and other things with a finite domain, in general), it’s always the first value defined. With either/or properties it’s always not the first (whether you’ve named a second or not).
Wow that is not a lot of headroom! I’m guessing back in the day people overloaded attributes a fair bit (like, having an attribute that represents one thing when applied to people and another when applied to rooms, or whatever)?
I’ve heard of that happening, cool to know the details!
This checks out.