Let's Play/Read: Inform 7 manuals (Done for now)

The two pronouns that are most useful for this are “we” (us, our, ours) and “they” (them, their, theirs), because all four forms are distinct. Most other pronouns don’t have this property: “it” (it, its, its), “he” (him, his, his), “she” (her, her, hers), “you” (you, your, yours).

Technically “I” (me, my, mine) and “thou” (thee, thy, thine) also work, but most people don’t know how to conjugate verbs for “thou” any more (thou art, thou knowest), and for “I” it’s awkward to write “[I] [are] in a…”. So Inform uses “we” to mean “the pronoun for the player character” and “they” to mean “the pronoun for the most recently mentioned noun”. This generally works pretty well.

There’s also “those”, for if you want a demonstrative, but this runs into the problem you mention: the subject form and object form look the same! Inform’s solution is to assume that capital “[Those]” is a subject and lowercase “[those]” is an object, which mostly works but occasionally produces very annoying bugs. “[Those in the accusative]” and “[those in the nominative]” are actually a later addition to the language, iirc, after these bugs started showing up.

One special thing to note: the name of the verb “to be” is actually “are”, not “be”. (This is so that you can say [They] [are] or [We] [are] instead of [They] [be] and [We] [be].) It used to be that you had to say “[can are]” and “[would are]” and so on, since Inform didn’t realize that “be” and “are” are the same verb. I think this is fixed now.

I didn’t realize this was forbidden. If you want to do Advanced Pronouns™ or anything like that, you need to be able to check this to get your references right. I wonder why they say not to do that?

Anyway, if you want to clear the variable, the other way to do it is “[regarding nothing]”. (Setting this variable is what “regarding” means in general.)

It’s also one of the newest chapters in the book! Inform didn’t originally have these features; if you ever see a project using the extension Plurality by Emily Short, that was a much less elegant stop-gap created to deal with this deficit.

3 Likes

I believe it would be the other way around. If “I” had been chosen, we would have to write "[I] [am]" but "[They] [am]". English is lucky to have the same form for “we” and “they” so I guess it was better to choose those. In French, “tu” was chosen (for having the most distinct forms) so we have "[Tu] [es]" and "[Il] [es]" (instead of “est” for the latter).

Maybe it’s because we can also use regarding open containers (with a description for argument) or regarding 729 (with a number for argument). So the full state is not solely encoded in the prior named object variable. We can see in the English Language that the condition if the prior naming context is plural is used, instead of if the prior named object is plural-named (so that it works if we regarded a number or a description of objects).

But all this information is not that useful for regular authors. (But very useful for translators!)

3 Likes

That is correct. There’s actually three I6 variables in there (prior_named_noun, prior_named_list, prior_named_list_gender). If the first is set to nothing, the other two are ignored. But for other cases, you need to set them all as a group, which is what “[regarding X]” does.

4 Likes

It’s the second-last day of the month, and this is certainly the dorkiest piece of prose I’ve read this month. Good on you, Inform!

-Wade

2 Likes

Thanks for all the fun feedback on this.

Reading the manuals and getting help has been so fun and useful!

For instance, I said earlier I had given up having the player’s actions appearing on a security camera, because I’d have to write custom stuff for each action.

But from these last few lessons, I realized I didn’t have to do every action; I could just come up with descriptions of what the most important actions look like.

Then, I was worried that I wouldn’t know if an action failed or succeeded when showing it on the camera. Then, I realized that that is what Check, Carry out, and Report is for! If it passes ‘check’, then it succeeds; so I split up all my new functions (that only had ‘carry out’) into Check, Carry Out, and Report, and wrote an After rule for functions that adds a message about what the player just did to the list of the camera feed. It only fires for successful functions!

And usually I’d be too scared to add an after rule since it makes the text disappear, but I’ve now learned I can type ‘continue the action!’

This is my current code:

EyeballList is a list of text that varies. EyeballList is {"yourself staring into the camera"}.

To say randomflavor:
	say "[one of]nervously[or]fearfully[or]with great trepidation[or]with terror in [our] eyes[at random] "

After the player doing something when the player is in spell-region:
	say "The current action is [the current action].";
	if the action name part of the current action is a behavior listed in the table of monitored activities:
		choose the row with behavior of action name part of current action in the table of monitored activities;
		let behaviorpart be "[summaries entry]";
		choose the row with locale of the location in the table of Room shorthands;
		let localepart be "[summaries entry]";
		add "[behaviorpart] [if a random chance of 1 in 4 succeeds][randomflavor][end if][localepart]" to EyeballList;
		if the number of entries in EyeballList > 10:
			sort EyeballList in random order;
			truncate EyeballList to the last 10 entries;
	continue the action;

Table 1 - Monitored Activities
behavior	summaries
the taking inventory action	"[the player] looking through [their] possessions"
the anghofioing action	"[the player] wiping [their] memory"
the bywyding action	"[the player] casting a spell and looking at [their] spellbook"
the clapping action	"[the player] clapping"
the closing action	"[the player] closing [the rucksack]"
the crying action	"[the player] crying"
the dancing action	"[the player] dancing"
the deffroing action	"[the player] casting a spell"
the denuing action	"[the player] casting a spell that makes metal fly towards you in a terrifying way"
the dropping action	"[the player] dropping something"
the examining action	"[the player] looking intently at something"
the fladhing action	"[the player] erupting into a pile of black sand"
the flying action	"[the player] soaring through the air"
the going action	"[the player] moving quickly"
the goping action	"[the player] pointing and casting a spell"
the hedfaning action	"[the player] casting a spell and rising into the air"
the hunigoing action	"[the player] sending a shower of black sparks around [themselves]"
the hyblyging action	"[the player] casting a spell that melts bones"
the jumping action	"[the player] leaping"
the kissing action	"[the player] kissing something"
the llosging action	"[the player] bursting into flames"
the looking action	"[the player] staring around"
the nwyding action	"[the player] casting a spell and becoming enraged, running around"
the pydruing action	"[the player] casting a spell and becoming covered in sores, weeping"
the reading action	"[the player] reading"
the searching action	"[the player] searching around"
the shouting action	"[the player] shouting"
the sleeping action	"[the player] dozing off"
the squeezing action	"[the player] squeezing something"
the taking action	"[the player] grabbing something"
the touching action	"[the player] touching something"
the thinking action	"[the player] standing around, thinking"
the waiting action	"[the player] staring at the camera"
the waving hands action	"[the player] waving at the camera"
the wearing action	"[the player] getting dressed"

Table 2 - Room shorthands
locale	summaries
black-dome	"standing in a hemispherical dome"
lonely-room	"in an underground village"
buried-room	"in an impossibly tight crevice"
end-room	"in a graveyard of bodies"
vast-room	"while standing on the edge of a towering cliff"
eye-room	"in this very room"
stranger-room	"standing near a humanoid figure"
desolation-room	"in a room filled with flames"
corruption-room	"in a room crawling with insects of every kind"
flesh-room	"in a room filled with bizarre beasts"
hunt-room	"in an empty room"
slaughter-room	"in a room with a cage"
vast-ladder	"while clinging to a ladder"
web-room	"in a room filled with cobwebs"
spiral-room	"in a bizarre maze of shifting colors"
dark-room	"in front of a completely dark background"
lonely-house	"inside a stone house"
lonely-alley	"between two houses"
north-lonely	"next to a tall crack"
air-scroll	"near a giant stalactite"
air1	"while flying in mid-air"
air2	"while flying in mid-air"
air3	"while flying in mid-air"
air4	"while flying in mid-air"

I would never have been able to do something like this without this thread, so thanks to people who have been following along!

7 Likes

Chapter 15 : Numbers and Equations

I always saw this and the tables and lists chapters as being the most straightforward: here is a niche topic that you will either not use at all or will need to know everything about all at once.

15.1 is How do we measure things?

This section just mentions that usually exact numbers aren’t super useful in fiction and that when they are, units are useful.

You can make up new kinds of numbers with units like this:

A distance is a kind of value. 5 miles specifies a distance.

There are two built-in numerical values: number and real number.

Section 15.2 is Numbers and Real Numbers. This is basically like ints and floats, except that the max size of a ‘number’ in z-machine is 32767, while the max number size for Glulx is 2147483647.

These are pretty low numbers compared to most programming languages, but if you have a game that is using calculations of numbers higher than 2 billion, you’re either Mike Spivey or lost in the woods.

(actually here’s Mike Spivey’s comment on this in his Junior Arithmancer postmortem):

While running my own tests on the game I ran into a problem I hadn’t anticipated. Glulx has a maximum integer capacity of just over 2 billion, and you can combine the spells in ways that will generate numbers larger than that. This was going to ruin the player’s sense of immersion in the game! I was really frustrated and disappointed for about ten minutes, until I remembered the improv motto of “Yes, and…” O.K., let’s just make the integer overflow a feature of the game and write a puzzle where you have to contend with it. (Andrew Schultz later called this a “fun evil” puzzle during testing. I’m good with that.)

Real numbers are truncated to between 6 and 9 decimal places.

showme 1.2345654321;
showme 1.2345667890;

produces

real number: 1.23457
real number: 1.23457

Inform does support scientific notation (I didn’t know this!):
let Avogadro's number be 6.022141 x 10^23;

Inform also recognizes pi and e as real numbers, in lowercase.

If Inform has the Use engineering notation option set, you can write things this way:
6.022141E+23;

I’m trying to think of games that could use these math abilities…I guess the recent Jigsaw let’s play showed how trigonometry is useful…

Example 253 is Alias, about american phone numbers. It uses some tricks we haven’t been taught yet:

A telephone is a kind of thing. Understand "phone" or "telephone" as a telephone.

A phone number is a kind of value. 999-9999 specifies a phone number.

Understand "Stephen" as 555-2513 when the blue paper is examined.

Test me with "dial 555-9999 / call home on the telephone / phone the president / call stephen / open drawer / read paper / call stephen / put phone in drawer / close drawer / call stephen".

Section 15.3 is Real number conversions. It mentions that it’s just here for technical reasons and is not useful for most people.

If a number is expected to be a real number (i.e. a decimal) and a number (i.e. an integer) is used, it’s converted to a decimal.

So cosine of 2 is redirected to cosine of 2.0.

‘divided by’ will find only the whole-number quotient if just numbers are used, and the decimal approximation if any of the numbers involved is real:

3 divided by 2 = 1
3 divided by 2.0 = 1.5
3.0 divided by 2 = 1.5
3.0 divided by 2.0 = 1.5

To round real numbers to whole numbers:

1.4 to the nearest whole number = 1
1.6 to the nearest whole number = 2
-1.6 to the nearest whole number = -2

Sometimes the ‘nearest number’ is just the max number:
6 x 10^23 to the nearest whole number = 2147483647

since we literally can’t go any higher.

Inform also supports infinity:
plus infinity, minus infinity

So showme 1.0 divided by 0.0 is plus infinity, but showme 1 divided by 0 gives a runtime error.

Also instead of runtime errors with real numbers inform will produce a ‘nonexistent real number’ for things like the square root of a negative or logarithm of a negative. It’s the equivalent of NaN.

Section 15.4 is Printing real numbers

We can print to a certain decimal place:

"The semicircle is roughly [pi to 3 decimal places] paces around."
"[1.23457 x 10^8 in decimal notation]"
(the latter prevents inform from using scientific notation)

These can be combined:
"[ (real number) to (number) decimal places in decimal notation]

Or you can just pick scientific notation:
"[the reciprocal of 137 in scientific notation]"

and finally:
say "[(real number) to (number) decimal places in scientific notation]".

Section 15.5 is Arithmetic:

We can do addition with either + or plus, and it respects units:

200 + 1 = 201
10:04 AM + two minutes = 10:06 AM
200 plus 1 = 201

minus:

200 - 1 = 199
10:04 AM - two minutes = 10:02 AM
200 minus 1 = 199

times:

201 times 3 = 603
two minutes times 4 = eight minutes
201 multiplied by 3 = 603
201 * 3 = 603

divided by (which does either the quotient for whole numbers of long division for real numbers):

201 divided by 3 = 67
201 / 3 = 67
202 divided by 3 = 67
202.0 divided by 3 = 67.33334
twenty minutes divided by 4 = five minutes
twenty minutes divided by five minutes = 4

you can divide by 0 in real numbers (getting plus infinity or minus infinity) but not whole numbers.

For modular arithmetic:

remainder after dividing 201 by 5 = 1
remainder after dividing twenty minutes by 7 = six minutes

We can either use symbols or spell out the words for operations

(If we do use the symbols, then spaces around them are obligatory: to Inform, they are words which just happen to be spelt with symbols instead of letters.)

We can round to any granularity:

201 to the nearest 5 = 200
205 to the nearest 10 = 210
10:27 AM to the nearest five minutes = 10:25 AM

We can do approximate square roots, which are slow in z-machine:

square root of 16 = 4 (always gives whole number)

real square root of 2 = 1.41421

cube root of 27 = 3

‘real cube root’ is not supported.

This next part is one where I’ve been tripped up; we can’t use the equal sign for comparisons!

We can type out or use symbols for inequalities:

if the score is less than 10
if the score < 10
if the score is at least 10
if the score >= 10

But we cannot write if the score = 10, we have to write if the score is 10, which is a little goofy but what can you do.

Section 15.6 is Powers and logarithms

First is rounding up:

ceiling of pi = 4.0
ceiling of -16.315 = -16.0

Next is rounding down:

floor of pi = 3.0
floor of -16.315 = -17.0

Next is absolute value:

absolute value of 62.1 = 62.1
absolute value of 0 = 0.0
absolute value of -62.1 = 62.1
absolute value of minus infinity = plus infinity

and reciprocals:

reciprocal of -2 = -0.5
reciprocal of 0.1 = 10.0
reciprocal of 7 = 0.14286
reciprocal of plus infinity = 0.0

(which is nice since 1 / 2 would just give 0)

Now there are powers:

2 to the power 4 = 16.0
100 to the power 0.5 = 10.0
7 to the power -1 = 0.14286
pi to the power 0 = 1.0

In the words of the Glulx specification document (section 2.12), “the special cases are breathtaking”: if you need to know exactly what, say, “minus infinity to the power Y” will do for different cases of Y, refer to the details of the “pow” opcode.

For square roots, don’t do 0.5 power, but for other roots, you can type:

X to the power (reciprocal of N)

For a base of e, we can say ‘exponential of’, which is presumably faster is it probably uses the maclaurin series instead of first plugging in e into the other power equation:

exponential of 0 = 1.0
exponential of 1 = e = 2.7182818
exponential of -10 = 4.53999 x 10^-5
exponential of 10 = 22026.46484
exponential of logarithm of 7.12 = 7.12

(I was teaching students the Maclaurin series for e^x just today!)

Logarithms are like so (man, why are you doing logarithms in an inform game):

logarithm to base 10 of 1000000 = 6.0
logarithm to base 10 of 350 = 2.54407
logarithm to base 2 of 256 = 8.0

and for base e (logarithm and natural logarithm mean the same thing):

logarithm of e = 1.0
natural logarithm of e = 1.0
logarithm of 1 = 0.0
logarithm of 1000 = 6.90776
logarithm of exponential of 7.12 = 7.12

Section 15.7 is Trigonometry.

Inform naturally uses radians (I’m guessing again due to Maclaurin series), but if you want sine and cosine to use degrees, just say so.

Here are some trig examples:

sine of 0 = 0
sine of 45 degrees = 0.70711
sine of (pi divided by 4) = 0.70711
sine of (pi divided by 2) = 1.0
sine of pi = 0
cosine of 0 = 1.0
cosine of 45 degrees = 0.70711
cosine of (pi divided by 4) = 0.70711
cosine of (pi divided by 2) = 0.0
cosine of pi = -1.0
tangent of 0 = 0.0
tangent of 45 degrees = 1.0
tangent of (pi divided by 4) = 1.0
tangent of (pi divided by 2) = plus infinity

(technically the last one should be plus infinity from the left and negative infinity from the right but man if you’re doing tangent of (pi divided by 2) in an actual Inform game the heavens have abandoned you anyway and you must bear your curse alone.

We also can do arcsine, arccosine, arctangent, hyperbolic sine, hyperbolic cosine, hyperbolic tangent, hyperbolic arcsine, hyperbolic arccosine (come on now Mr. Nelson, this is going too far), and hyperbolic arctangent.

Section 15.8 is units:

To assign a number to a person you can say:

A person has a number called height.

Inform claims this is dumb, as then you’d have to say Isabella has height 68 (which is exactly what I did with my rockclimbing rocks).

Instead, Inform wants you to be able to write ‘Isabella is 5 foot 8’ and have it understood.

We begin this by saying something like:

A weight is a kind of value. 10kg specifies a weight.

This is different from other kinds of values, where we explicitly listed all of the possibilities:

A colour is a kind of value. The colours are red, green and blue.

This is basically the separation between categorical and numerical data in stats.

The ‘10’ in ‘10 kg’ isn’t really important, it’s just showing inform what a typical weight might look like. So after that line you can say stuff like this:

The maximum load is a weight that varies. The maximum load is 8000kg.

if the maximum load is greater than 8000kg, ...

And inform doesn’t let numbers of different unit types mix.

You can now use the numerical values like numbers, except that units will print:

For instance, we can write:

The Weighbridge is a room. "A sign declares that the maximum load is [maximum load]."

…which will produce the text “A sign declares that the maximum load is 8000kg.”

The default is whole numbers only.

If you want a real number, type this kind of thing:

1.0 kg specifies a weight.

For whole number specifications, we can only use positive numbers. If you want negatives, say this:

-10 kg specifies a weight.

Time for examples!

Exampe 254 is rBGH:

A counter, a one-way mirror, and a stool are scenery in the Facility. The stool is an enterable supporter. The counter supports a plate.

Height is a kind of value. 5 feet 11 inches specifies a height. 5'11 specifies a height. A person has a height.

Definition: a person is tall if its height is 6 feet 0 inches or more.

Definition: a person is short if its height is 5 feet 4 inches or less.

When play begins:
now the height of the player is a random height between 5 feet 2 inches and 6 feet 4 inches;
now the right hand status line is "[height of player]".

Instead of examining the player:
say "You, Test Subject, are [height of the player] tall."

The growth pill is a kind of thing. A growth pill is always edible. The description is usually "It is leaf-green and has a reassuring logo of a curling vine on the side. Nothing to worry about, nothing at all." Two growth pills are on the plate.

After eating the growth pill:
increase the height of the player by 0 feet 6 inches;
say "Your spine does something frightening and painful, and you find yourself looking down on the room from a wholly new angle.";
try looking.

Example 255 is Lethal concentration 1:

This is a very complex example, which reminds me of an old XYZZY nominee called Oxygen (or something). I can’t copy everything, but here’s the idea:

A concentration is a kind of value. 200.9ppm specifies concentration. 200.9 ppm specifies concentration.

A room has a concentration called current concentration. A room has a concentration called former concentration.

Probability inverse is a number that varies. [This is expressed as an inverse of the actual probability of diffusion from one room to another, to avoid error.] Probability inverse is 20. [That is, any given molecule of gas has a 5% chance of leaving by a given doorway at any given minute. Probability inverse should never drop below 10, the maximum number of exits from the room.]

A diffusion rule (this is the gas movement rule):
    repeat with space running through rooms:
        let sum be 0.0 ppm;
        repeat with way running through directions:
            let second space be the room way from the space;
            if second space is a room:
                let difference be the former concentration of the second space minus the former concentration of the space;
                increase sum by the difference;
        let sum be sum divided by probability inverse;
        now current concentration of the space is the former concentration of the space plus the sum.

This kind of diffusion is exactly how amenability is studied in geometric group theory, and my advisor did this stuff a lot.

This example also gives a text map of the whole game with concentrations marked, and has gas sources and sinks, etc. Pretty wild!

Example 256 is Wonderland

An altitude is a kind of value. 1000 feet specifies an altitude. A room has an altitude.

Definition: a room is low if its altitude is 3000 feet or less. Definition: a room is high if its altitude is 5000 feet or more.

Instead of going down:
    if an adjacent room is lower than the location:
        let the valley be the lowest adjacent room;
        let the way be the best route from the location to the valley;
        say "(that is, [way])[paragraph break]";
        try going the way;
    otherwise:
        say "You're in a local valley: there's no down from here."

Instead of going up:
    if an adjacent room is higher than the location:
        let the peak be the highest adjacent room;
        let the way be the best route from the location to the peak;
        say "(that is, [way])[paragraph break]";
        try going the way;
    otherwise:
        say "You're on a local peak."

Example 257 is Lethal Concentration 2

This makes gas more likely to sink down than up:

To decide what number is the probability inverse between (space - a room) and (second space - a room):
    let guess be 20;
    let way be the best route from space to second space;
    if way is up, let guess be 50;
    if way is down, let guess be 10;
    if the guess is less than 10, decide on 10;
    decide on guess.

Section 15.9 is Multiple notations

You can have mutliple units for a weight, including versions with spaces or multiple words:

A weight is a kind of value. 10kg specifies a weight. 10kg net specifies a weight. 10 kg specifies a weight.

You can also scale units:

1 tonne specifies a weight scaled up by 1000.

You can specify singular and plural:

1 tonne (singular) specifies a weight scaled up by 1000.
2 tonnes (plural) specifies a weight scaled up by 1000.

Which of the 3 version of kg will inform print? I will find out.

Hmmm, I made a value using ‘10kg net’ and it printed as ‘10kg’, so I assume it prints with the first format you use.

Section 15.10 is Scaling and equivalents

If you use whole numbers in your original definition, inform will require you to use whole numbers all along.

So if you say 1 kg specifies a weight, you can’t have fractions.

But… you can scale things up and down.

A length is a kind of value. 1m specifies a length.
1km specifies a length scaled up by 1000.
1cm specifies a length scaled down by 100.

So you can type 3cm, 0.03m, and 0.00003km all mean the same thing, and inform starts using decimals.

Inform takes the smallest ‘scale’ and lets that go up to the max number (around 2 billion for glulx), so if you scale things by 2 billion, the largest scale can only go up to 2!

You can pick the scaling yourself like this:
A length is a kind of value. 1m specifies a length scaled at 10000., and inform will only let meters go up to about 2 hundred thousand, and can be specified to 4 decimal places.

You can also make unit conversions:
1 mile specifies a length equivalent to 1609m.

Section 15.11 is Named notations:

Let’s say we write this:

A weight is a kind of value. 10kg specifies a weight.
1 tonne (singular) specifies a weight scaled up by 1000.
2 tonnes (plural) specifies a weight scaled up by 1000.

Then inform prints it like this:

45kg -> "45kg"
1000kg -> "1 tonne"
2500kg -> "2.5 tonnes"
80000kg -> "80 tonnes"

So it automatically converts to convenient units (the documentation says it is minimising the integer part of the unit, but trying to keep it non-zero. So Inform prefers "45kg" to "0.045 tonnes".).

If you want to force it to be printed a certain way, you can name your notation (in this example, it’s the part after the comma in the parentheses):

1 tonne (singular, in tonnes) specifies a weight scaled up by 1000.
2 tonnes (plural, in tonnes) specifies a weight scaled up by 1000.

and then can use it like this:

"The weighbridge warns you not to exceed [the maximum load in tonnes]."

Section 5.12 is Making the verb ‘to weigh’

This is really useful and I had to get help from many people when making rockclimbing to do what this section is saying (although the tile of this section is a bit misleading).

Basically you can create a verb for a value:

Weight is a kind of value. 1kg specifies a weight. Every thing has a weight.

The verb to weigh means the weight property.

A thing usually weighs 1kg. The lead pig weighs 45kg.

What makes this exceptionally useful is that you can now use this verb in descriptions for finding lists, random things, and conditions.

Example 258 is Dimensions:

A length is a kind of value. 10m specifies a length. An area is a kind of value. 10 sq m specifies an area. A length times a length specifies an area.

Hmm, this is something entirely new: a length time a length specifies an area. Wild!

A weight is a kind of value. 10kg specifies a weight. Everything has a weight.

The verb to weigh means the weight property. A thing usually weighs 1kg.

Definition: A thing is light if its weight is 3kg or less.

Definition: A thing is heavy if its weight is 10kg or more.

The balance platform is a supporter in the Weighbridge. "The balance platform is 10m by 8m, giving it an area of [10m multiplied by 8m], currently weighing [the list of things on the platform]. The scale alongside reads: [total weight of things on the platform]. [if two things are on the platform]Average weight is: [the total weight of things on the platform divided by the number of things on the platform]. Heaviest item is [the heaviest thing on the platform], at [weight of the heaviest thing on the platform]. Lightest item is [the lightest thing on the platform], at [weight of the lightest thing on the platform].[otherwise]It seems to be able to weigh several things at once."

Example 259 is Lead Cuts Paper

A weight is a kind of value. 10kg specifies a weight. Everything has a weight. A thing usually has weight 1kg.

A container has a weight called breaking strain. The breaking strain of a container is usually 50kg. Definition: A container is bursting if the total weight of things in it is greater than its breaking strain.

A lead pig, a feather, a silver coin and a paper bag are in a room called the Metallurgy Workshop. The paper bag is a container with breaking strain 2kg. The lead pig has weight 50kg.

Every turn when a container (called the sack) held by someone visible (called the chump) is bursting:
say "[The sack] splits and breaks under the weight! [if the player is the chump]You discard[otherwise][The chump] discards[end if] its ruined remains, looking miserably down at [the list of things in the sack] on the floor.";
now all of the things in the sack are in the location;
now the sack is nowhere.

Sectoin 15.13 is The Metric Units Extension.

If you want tons of units and specifications, there are built in extensions:

(a) The built-in extension “Metric Units by Graham Nelson” sets up a whole range of scientific units, with all the notations we are likely to want. Real numbers are used throughout, so large and small-scale calculations can be carried out quite accurately. Like the other built-in extensions, it has its own documentation and examples.

(b) The built-in extension “Approximate Metric Units by Graham Nelson” does the same but using whole numbers, scaled about right for human situations. This won’t be much use for extensive calculations, and won’t be as accurate, but it will work reasonably well if real arithmetic isn’t available.

Absent from all of this chapter is how to make Inform print commas every 3 digits, which someone in chat was asking about. It turns out to be pretty hard.

Section 15.14 is Notations including more than one number

This is like heights with feet and inches, or time with minutes and seconds.

So you can say stuff like:
A running time is a kind of value. 3'59 specifies a running time.

or
A height is a kind of value. 5 foot 11 specifies a height.

You can make up to 8 numbers in each specification.

Referring back to the ‘3’59’ example:

The choice of "3" here makes no difference, much as the choice of "10" in the weight examples was arbitrary. But the "59" is significant. Numbers after the first one are expected to range from 0 up to the value we quote - so in this case, the number of seconds can be anything from 0 to 59.

Hmm, I didn’t know that! So for parts like this you need to make something as close to ‘ticking over’ as possible. Actually, you could do binary math like this with having a specification like `1 a 1 b 1 c 1 d 1 e 1 f 1 g 1 h’.

Haha, this works great, I just tried running this:

A binary number is a kind of value. 1 a 1 b 1 c 1 d 1 e 1 f 1 g 1 specifies a binary number.

baseCounter is always 0 a 0 b 0 c 0 d 0 e 0 f 0 g 1.
Counter is a binary number that varies. Counter is 0 a 0 b 0 c 0 d 0 e 0 f 0 g 1.

Every turn:
	say counter;
	now counter is counter plus basecounter;

This just counts up in binary! Although now I realize I didn’t need to use letters, I could have just used apostrophes.

Only the first number in something like this can be negative, and only if you specify negative in the original:

A secret sign is a kind of value. -2x17 specifies a secret sign with parts mystery and enigma.

Notations can’t have double quotes (even though arcs have them) but other punctuation is okay between digits:

A monetary value is a kind of value. $1.99 specifies a monetary value.

An aspect ratio is a kind of value. 16:9 specifies an aspect ratio.

Section 15.15 is the parts of a number specification. It lets you name the different chunks of a number:

A monetary value is a kind of value. $1.99 specifies a monetary value with parts dollars and cents.

We can now find the relevant parts like so. Suppose that “sum” is a monetary value. Then:

dollars part of sum
cents part of sum

are both numbers, so for instance we can

say "Looks like around [dollars part of sum in words] dollar[s]."

We can also go the other way:

monetary value with dollars part 4 cents part 72

produces the monetary value $4.72. (Note the lack of commas or "and"s, and that the parts have to be given in the right order.)

Naming parts of numbers lets you add other stuff onto it:
A monetary value is a kind of value. $1.99 specifies a monetary value with parts dollars and cents (optional, preamble optional).

This lets you type dollars without cents (optional), and omitting the decimal (preamble optional). Note that both options apply to cents since they are right next to cents. Apparently you can’t make the first part optional though (dollars), as I just tried doing that.

The other option is 'without leading zeroes", used when one of the parts is specified as multiple digits but we might not want that:

An aspect ratio is a kind of value. 16:20 specifies an aspect ratio with parts width and height (without leading zeros).

This ensures that when the ratio 4:3 is printed, it will be printed as “4:3” and not “4:03” as would otherwise happen.

Example 260 is Zqlran Era 8.

A Zqlran date is a kind of value. 14-88 specifies a Zqlran date with parts zqls and frbs. Current zqlran date is a zqlran date that varies. The current zqlran date is 8-22. Previous zqlran date is a zqlran date that varies. The previous zqlran date is 8-20.

The Zqlran time rule is listed instead of the advance time rule in the turn sequence rules.

This is the Zqlran time rule:
    increment turn count;
    now the previous zqlran date is current zqlran date;
    increase the current zqlran date by 0-02;
    repeat through the Table of Zql Schedule:
        if era entry is greater than previous zqlran date and era entry is not greater than current zqlran date:
            say event entry;
            say paragraph break;
            blank out the whole row.

Section 15.16 is Understanding specified numbers:

You can just throw values that are specified numbers into ‘understand’ commands:

The Oval Office is a room. Josh and Toby are men in the Oval. A height is a kind of value. 5 foot 11 specifies a height. A person has a height. Josh is 5 foot 8. Toby is 5 foot 10.

Height guessing is an action applying to one thing and one height. Understand "guess [someone] is [height]" as height guessing.

Check height guessing: if the noun is not a person, say "You can only guess the height of people." instead. Carry out height guessing: if the height of the noun is the height understood, say "Spot on!"; if the height of the noun is greater than the height understood, say "No, [the noun] is taller than that."; if the height of the noun is less than the height understood, say "No, [the noun] is shorter than that."

Example 261 is Snip:

A string is a kind of thing. A string has a length. The length of a string is usually 36 inches.

Before printing the name of a string, say "[length] piece of ". Rule for printing the plural name of a string: say "[length] pieces of string".

Understand the command "cut" as something new. Understand "cut [length] from/off [something]" as trimming it by (with nouns reversed). Understand "cut [something] by [length]" as trimming it by. Understand the command "trim" as "cut".

Trimming it by is an action applying to one thing and one length.

This is a very complex example, but the above is a taste.

Section 15.17 is Totals:

This is just a way of adding stuff up. With some preamble:

A weight is a kind of value. 10kg specifies a weight. Everything has a weight. A thing usually has weight 1kg. A man usually has weight 80kg. A woman usually has weight 67kg.

Definition: A thing is light if its weight is 3kg or less.
Definition: A thing is heavy if its weight is 10kg or more.

we can say:
The balance platform is a supporter in the Weighbridge. "The balance platform is currently weighing [the list of things on the platform]. The scale alongside reads: [total weight of things on the platform]."

This only works because ‘everything has a weight’.

You can also use superlatives:

the weight of the heaviest thing on the platform
the weight of the lightest thing on the platform

Example 262 is Nickel and Dimed

This is a very complex example involing a monetary system using US money. It includes different coins and denominations.

3 Likes

Chapter 15, continued:

Section 15.18 is Equations. The examples in this section use the Metric Units extension by Graham Nelson.

Equations are defined very similar to tables. First, some preliminary definitions before the actual equation:

The acceleration due to gravity is an acceleration that varies. The acceleration due to gravity is usually 9.807 m/ss. A thing has a mass. The mass of a thing is usually 10g.

Next th equation itself:

Equation - Newton's Second Law
    F=ma
where F is a force, m is a mass, a is an acceleration.

It’s hard to tell from the formatting, but it looks like equations might have to have whitespace in front of them.

An equation has to take the form of one formula equals another, where each formula is made up from symbols defined afterwards. The symbols can be defined as definite values (as “g” is defined in the Galilean Equation), or just by telling Inform their kinds of value (as “v” and “t” are defined).

Inform makes no distinction between upper case and lower case.

Once you have equations, you can say stuff like “let F be given by Newton’s Second Law where a is the acceleration due to gravity;”.

If you only use an equation once, you can do this:

let KE be given by KE = mv^2/2 where KE is an energy;

The Phrasebook page on the index lists all math functions that can be used.

Example 263 is Widget Enterprises:

Equation - Profit Equation
    P = nV - (F + nC)
where P is a monetary value, F is the fixed cost, C is the unit cost, V is a monetary value, and n is a number.
Carry out setting price to:
    let V be the monetary value understood;
    let n be the units sold at the monetary value understood;
    let P be given by the Profit Equation;
    say "You set the price of your widgets to [V], resulting in sales of [n] unit[s] and ";
    if P is less than $0.00:
        let L be $0.00 - P;
        say "a loss of [L].";
    otherwise if P is $0.00:
        say "break even.";
    otherwise:
        say "a profit of [P].".

Section 15.19 is Artihmetic with units

Inform does some automatic dimensional analysis, and won’t let you equate things with different types of units.

Multiplying by a scalar is always allowed:
The Weighbridge is a room. "A sign declares that the maximum load is [100kg multiplied by 3]."

On the other hand, you can’t do something like ‘122 divided by 10 kg’.

Example 264 is Frozen Assets. This is basically just a simple shopping model where when you buy something your money goes down.

Instead of buying something:
    decrease the price of the money by the price of the noun;
    say "You fork over [the price of the noun] for [the noun], leaving yourself with [the price of the money].";
    if the money is free:
        now the money is nowhere;
    now the price of the noun is $0.00;
    now the player is carrying the noun.

with special rules for money itself:

The player carries a wallet. The wallet contains money. The price of the money is $4.50. The printed name of the money is “[price of the money] in cash”. Understand “cash” as the money.

Instead of taking the money:
say "Best to leave it alone until you need to buy something."

Instead of buying something free:
say "[The noun] is yours already."

Instead of buying the money:
say "The money belongs to you; you buy things with it."

Example 265 is Money for Nothing

This is a system for bartering.

Check offering it for:
    if the price understood is greater than the wealth of the player, say "You don't have that kind of cash." instead;
    if the second noun is not carried by someone, say "There's no one in a position to sell you [the second noun]." instead;
    if the second noun is carried by the player, say "[The second noun] is already yours." instead;
    if the minimum value of the second noun is greater than the price understood, say "[The holder of the second noun] cackles disdainfully. 'If yer just here to insult me you can take your business elsewhere!' he says." instead;
    if the desired value of the second noun is greater than the price understood:
        let difference be the desired value of the second noun minus the price understood;
        let difference be difference divided by two;
        decrease the desired value of the second noun by difference;
        now the last object offered is the second noun;
        say "'How about [desired value of the second noun]?' suggests [the holder of the second noun]." instead;
    otherwise:
        unless the desired value of the second noun is the price understood:
            say "From the avaricious gleam in the eye of [the holder of the second noun], you guess you could've gotten this purchase for less..."

Carry out offering it for:
    increase the wealth of the holder of the second noun by the price understood;
    decrease the wealth of the player by the price understood;
    move the second noun to the player.

Report offering it for:
    say "You spend [the price understood], and now you possess [the second noun]."

When play begins: now right hand status line is "Your funds: [wealth of the player]".

Example 266 is Lemonade

This is a section about liquid amounts.

A volume is a kind of value. 15.9 fl oz specifies a volume with parts ounces and tenths (optional, preamble optional).

A fluid container is a kind of container. A fluid container has a volume called a fluid capacity. A fluid container has a volume called current volume.

The fluid capacity of a fluid container is usually 12.0 fl oz. The current volume of a fluid container is usually 0.0 fl oz.

Liquid is a kind of value. The liquids are water, milk, lemonade, and iced tea. A fluid container has a liquid.

Pouring it into is an action applying to two things.

Check pouring it into:
    if the noun is not a fluid container, say "You can't pour [the noun]." instead;
    if the second noun is not a fluid container, say "You can't pour liquids into [the second noun]." instead;
    if the noun is the second noun, say "You can hardly pour [the noun] into itself." instead;
    if the liquid of the noun is not the liquid of the second noun:
        if the second noun is empty, now the liquid of the second noun is the liquid of the noun;
        otherwise say "Mixing [the liquid of the noun] with [the liquid of the second noun] would give unsavory results." instead;
    if the noun is empty, say "No more [liquid of the noun] remains in [the noun]." instead;
    if the second noun is full, say "[The second noun] cannot contain any more than it already holds." instead.

Carry out pouring it into:
    let available capacity be the fluid capacity of the second noun minus the current volume of the second noun;
    if the available capacity is greater than the current volume of the noun, now the available capacity is the current volume of the noun;
    increase the current volume of the second noun by available capacity;
    decrease the current volume of the noun by available capacity.

Report pouring it into:
    say "[if the noun is empty][The noun] is now empty;[otherwise][The noun] now contains [current volume of the noun in rough terms] of [liquid of the noun]; [end if]";
    say "[the second noun] contains [current volume of the second noun in rough terms] of [liquid of the second noun][if the second noun is full], and is now full[end if]."

Example 267 is Savannah
This has more liquid stuff.

The bucket is a fluid container carried by the player. The liquid of the bucket is seawater. The current volume of the bucket is 64.0 fl oz.

The fire is a fixed in place thing in the beach. "A low fire crackles here, left over from an attempt at s'mores much earlier in the evening."

Instead of touching or rubbing or taking the fire, say "You're not such a glutton for punishment."

Instead of pouring something into the fire:
now the fire is nowhere;
now the current volume of the noun is 0.0 fl oz;
say "[The second noun] goes out in a great hiss."

Finally, section 15.20 is Multiplication of Units

This tells inform what new units you should get when you multiply other units (this showed up in an example earlier and is automatic in ‘metric units’):

A length is a kind of value. 10m specifies a length. An area is a kind of value. 10 sq m specifies an area.

A length times a length specifies an area.

Example 268 is Depth:

A length is a kind of value. 10 cm specifies a length. An area is a kind of value. 10 sq cm specifies an area. A length times a length specifies an area. A volume is a kind of value. 10 cu cm specifies a volume. A length times an area specifies a volume.

A thing has a length called height. A thing has a length called width. A thing has a length called depth. The height of a thing is usually 10 cm. The width of a thing is usually 10 cm. The depth of a thing is usually 10 cm.

To decide what volume is the exterior volume of (item - a thing):
    let base area be the height of the item multiplied by the width of the item;
    let base volume be the base area multiplied by the depth of the item;
    decide on the base volume.

Example 269 is Fabrication. This lets values have properties!

A material is a kind of value. The materials are silk, velvet, cotton, and wool.

Price is a kind of value. $1.99 specifies a price.

Area is a kind of value. 5 sq yards specifies an area.

Cost is a kind of value.. $1.99 per sq yard specifies a cost. A cost times an area specifies a price.

A material has a cost.

The cost of silk is usually $5.75 per sq yard. The cost of velvet is usually $9.50 per sq yard. The cost of cotton is usually $2.29 per sq yard. The cost of wool is usually $4.75 per sq yard.

Finally, example 270 is The Speed of Thought. It’s a way to turn normal units into weird units:

1 pencil (in conceptual units, in pencils, singular) or 2 pencils (in conceptual units, in pencils, plural) specifies a length equivalent to 18cm.
1 bathtub (in conceptual units, in bathtubs, singular) or 2 bathtubs (in conceptual units, in bathtubs, plural) specifies a length equivalent to 152cm.
1 Olympic swimming pool (in conceptual units, in Olympic swimming pools, singular) or 2 Olympic swimming pools (in conceptual units, in Olympic swimming pools, plural) specifies a length equivalent to 50 meters.
1 Empire state building (in conceptual units, in Empire State buildings, singular) or 2 Empire State buildings (in conceptual units, in Empire State buildings, plural) specifies a length equivalent to 443m.

Report reporting:
    if the extent of the noun is greater than 0mm and the surface of the noun is greater than 0 sq cm:
        contextualize "'[The noun] has a length of [about] [extent of the noun in conceptual units] and an area of [about] [surface of the noun in conceptual units].'";
    otherwise if the extent of the noun is greater than 0mm:
        contextualize "'[The noun] has a length of [about] [extent of the noun in conceptual units].'";
    otherwise if the surface of the noun is greater than 0 sq cm:
        contextualize "'[The noun] has an area of [about] [surface of the noun in conceptual units].'";
    otherwise:
        say "'[The noun] is... pretty hard to imagine,' you say weakly. That's not going to go over well."

I can think of a lot of ways to implement the stuff in this chapter but very few that players would enjoy. I feel like people generally enjoy the appearance of deep implementation as much as deep implementation itself. Now I just need to figure out a reason for a game to include the inverse hyperbolic cosine (maybe calculating the length of a suspension bridge given the height of cables at different points?)

2 Likes

Though you can define it yourself if you want!

To decide what real number is the real cube root of (X - a real number):
    decide on X to the power reciprocal of 3.

You can do this!

To decide whether (X - value of kind K) = (Y - K):
    decide on whether or not X is Y.

Kind variables will come up eventually, but this is the sort of thing they’re for.

I was going to blame this one on zarf, since I thought Inform just exposed the floating-point math opcodes that are built into Glulx. But actually no, Glulx has a relatively small array of floating-point operations built in: arithmetic, rounding, sqrt, exp, log, pow, the six basic trig functions, and atan2.

The rest of these are defined by Inform, with definitions like this:

To decide which real number is the hyperbolic arctangent of (R - a real number)
    (documented at ph_hyperbolicarctangent)
    (this is the arctanh function inverse to tanh):
    let x be given by x = 0.5*(log(1+R) - log(1-R)) where x is a real number;
    decide on x.

Equations in action! The “this is the arctanh function inverse to tanh” part tells Inform that, if it sees arctanh in an equation, it should call this phrase; and if it needs to calculate the inverse of that (say you have the equation x = arctanh(y) and you ask it to solve for y), it should call whatever phrase it knows as the tanh function.

I’m told that in the sequel to Jigsaw, you need to fly a B29 over long enough distances that the Earth’s curvature comes into play and Cartesian coordinates are insufficient. You have to start using haversines:

To decide which real number is the haversine of (R - a real number)
    (this is the hav function inverse to archav):
    let x be given by x = sin(R/2)^2;
    decide on x.

Then all you have to do is use the famous Haversine Formula to calculate hav(θ) from the differences in longitude and latitude, and the archaversine of that will give you your bearing!

2 Likes

Perhaps my favorite Inform easter egg is their textual representations:

  say minus infinity;
  say logarithm of -1;
  say plus infinity;

produces:

-∞⚠∞

3 Likes

It’s unfortunate (to me) that it uses “.” as a parts separator when it’s meant as a decimal point. This prevents this from working:

A complex number is a kind of value.

2.3 + 4.5i specifies a complex number with parts real and imaginary.

I will not be satisfied until I can perform complex analysis in my game.

EDIT: Ah, I see. I have to use “.0” to indicate a real number.

EDIT 2: Hmm. Seems there are more problems with modeling complex numbers: (1) the second part cannot be negative; and (2) the second part must have an upper limit.

1 Like

I suppose I could have included sinh/cosh/tanh; I’m just exposing underlying mathlib functions, which are pretty much the same in every programming language. But I’ve never in my life run into code that used the hyperbolic trig functions. Nobody’s asked either.

I’m pretty sure that the CPU cost of floating-point math is dominated by encoding and decoding 32-bit Glulx values into native floats, which we have to do every opcode. The cost of the actual math function is probably trivial, since those are intensively optimized C code. (Which I’ve never looked at, of course.)

2 Likes

I’m going to take this opportunity to give scary warnings about units even though you’re joking.

Units are made of separate integers; beware of letting the ‘.’ lull you into expecting real number behavior.

With the dollars and cents monetary values, $1.00999 > $1.90 > $1.9.

Also note that while the initial number in a specification is bounded by the usual integer bounds (other than that it can’t be negative unless the specification included a minus sign, at least), each other digit specifies the maximum value a digit in that place can have.

Also, one of my least favorite 10.1 bugs is that this won’t compile:

let x be the monetary value with dollars part 4 cents part 72;
4 Likes

I think you’ll need Dannii’s structs for that.

1 Like

Here’s the code from Code. (Egad, I was more thorough than I remembered.)


Include (-
[ codeSignedCompare x y;
if (x > y) return 1;
if (x < y) return -1;
return 0;
];

[ spaceship v1 v2 k cmp cmp_result;
  if (k == NUMBER_TY) cmp = codeSignedCompare;
  else cmp = KOVComparisonFunction(k);
  cmp_result = cmp(v1,v2);
  if (cmp_result > 0) return 1;
  if (cmp_result < 0) return -1;
  return 0;
];
-)

To decide what number is (v1 - a value of kind K) <=> (v2 - a K):
    (- spaceship({v1},{v2},{-strong-kind:K}) -)

To decide if (v1 - a value of kind K) == (v2 - a K):
  decide on whether or not v1 <=> v2 is 0;

To decide if (v1 - a value of kind K) <>/!= (v2 - a K):
  decide on whether or not v1 <=> v2 is not 0;

Edited to add: With another year of Inform, all that becomes just:

To decide if (v1 - an arithmetic value) == (v2 - an arithmetic value): decide on whether or not v1 is v2.
To decide if (v1 - a value of kind K) == (v2 - a K): (- (~~((KOVComparisonFunction({-strong-kind:K}))({v1}, {v2}))) -)
2 Likes

That was fun, Brian. Thanks for sharing!

Mike

1 Like

Chapter 16: Tables

I haven’t used tables a lot, but a ton of Emily Short’s examples use them. I feel like they’re pretty useful!

Tables are written with a top line that is a title, with the first word necessarily being the word Table, followed by a number, a name or both:

Table 2.3
Table of Population Statistics
Table 2.3 - Population Statistics

Then each column has a name, and everything in each column must be the same ‘kind’ (number, text, action, etc.)

A sample table:

Table 2.1 - Selected Elements

Element Symbol Atomic number Atomic weight
“Hydrogen” “H” 1 1
“Iron” “Fe” 26 56
“Zinc” “Zn” 30 65
“Uranium” “U” 92 238

(posting tables on here is weird so this is the way I’m posting them).

I don’t anticipate having a lot of insights in this chapter, it’s a fairly straightforward workhorse chapter.

Section 16.2 is Lookin up entries

Given the table above, you can say:
symbol in row 3 of the Table of Selected Elements

and that means ‘Zn’.

The word ‘symbol’ here is just the name of the column; if we changed that column’s name to anything else, we’d just change our sentence above to use the new name.

You can repeat through rows this way (although we’ll find another way later):

 repeat with N running from 1 to the number of rows in the Table of Selected Elements:
    say "The atomic weight of [element in row N of the Table of Selected Elements] is [atomic weight in row N of the Table of Selected Elements

and this prints out:

The atomic weight of Hydrogen is 1.
The atomic weight of Iron is 56.
The atomic weight of Zinc is 65.
The atomic weight of Uranium is 238.

Note that Inform starts counting from 1, not 0, and that we used the phrase ‘number of rows in the Table of Selected Elements’.

Section 16.3 is Corresponding Entries

This is just a way to look up rows by the entries in them rather than the row number itself:

the atomic number corresponding to a symbol of "Fe" in the Table of Selected Elements

I almost never use tables in my own code, but I had exactly one in The Magpie Takes the Train:

Table 1 - Aliases
Alias	Honorific	Costumes	PithyPhrase
"Major Springbottom"	"Major"	military costume	"'It was my turn to be demobbed, ma'am, and I thought I'd take a ride on the best rail car the States can muster up before heading back. Spent a pretty penny, too!'"
"Doctor Weatherford"	"Doctor"	doctor costume	"'The engineer conductor said I should ride in this car. In case my services are required.'"
"Professor Spinner"	"Professor"	professor costume	"'I've made a study of luxury rail cars, and I've heard that this one is the jewel of the west. May I observe it?'"
"Sir Highwater"	"Sir"	aristocrat costume	"'I believe Ms. Hogg is a distant relation on the distaff side. It's all rather dull, I know, but I thought I might make an appearance, seeing I'm in the area.'"

When play begins, I have some text like this:

"You give a small bow, letting her see your [Costumes in row CurrentAlias of the Table of Aliases]. [PithyPhrase in row CurrentAlias of the Table of Aliases][paragraph break]'Very well, [honorific in row CurrentAlias of the Table of Aliases],' she says. 'You will be permitted to visit Ms. Hogg's observation car. The following are prohibited: solicitation, disorderly behavior, religious proselytising, sales pitches, unlicensed scientific research, fireworks, poking the parrot, and wearing disguises.'"

Looking up things that don’t exist can give errors, so you may want to check it first:
if there is an atomic number of 27 in the Table of Selected Elements ...

or more specifically:
if there is an element corresponding to an atomic number of 27 in the Table of Selected Elements ...

Example 271 is Dubai. It implements an elevator with a table of floors:

Table of Floors

level floor
0 Al Mahara
1 Burj al-Arab Lobby
2 Al Iwan
3 Juna Lounge
4 Sahn Eddar
15 Al Falak Ballroom
18 Assawan Spa
24 Presidential Suite
25 Royal Suite
27 Al Muntaha
The elevator exterior is a backdrop. It is not scenery. The initial appearance of the elevator exterior is "You can enter the elevator here." It is in Generic Floor, Al Mahara, the Lobby, Al Iwan, Juna Lounge, Sahn Eddar, Al Falak, Assawan Spa, Presidential Suite, Royal Suite, and Al Muntaha.

Before entering the elevator exterior, try going inside instead.

Instead of going inside in the presence of the elevator exterior:
    if there is a level corresponding to a floor of the location in the Table of Floors:
        let the present level be the level corresponding to a floor of the location in the Table of Floors;
        now the current level of the Lift is the present level;
    otherwise:
        now the current level of the Lift is the current level of Generic Floor;
    move the player to the Lift.

Carry out pressing button:
    now the current level of the Lift is the number understood;
    say "You press button [the number understood]. The lift whirs into action and moves to the correct level."

Section 16.4 is Changing entries:

Are we almost to the part about blanking lines? Every time I see a fancy Emily Short game there’s some part about repeating through a table and blanking lines. But I think that’s not yet.

Here is a sample table for this section:

Table 4 - Recent Monarchs

Name Accession Family
“Anne” 1702 Stuart
“George I” 1714 Hanover
“George II” 1720 Hanover
“George III” 1760 Hanover
“George IV” 1820 Hanover
“William IV” 1830 Hanover
“Victoria” 1837 Hanover
“Edward VII” 1901 Saxe-Coburg-Gotha
“George V” 1910 Windsor
“Edward VIII” 1936 Windsor
“George VI” 1936 Windsor
“Elizabeth II” 1952 Windsor

The right side is defined by this:
Dynasty is a kind of value. The dynasties are Stuart, Hanover, Saxe-Coburg-Gotha and Windsor.

And we can change it as so:

Instead of attacking the Succession:
    now the family corresponding to an accession of 1720 in the Table of Recent Monarchs is Stuart;
    now the name in row 4 of the Table of Recent Monarchs is "Graham I";
    now the name in row 5 of the Table of Recent Monarchs is "Trixibelle IV";
    say "You deface the English succession, making suitable amendments with a quill pen. Considering it is supposed to be mightier than the sword the effect is a little disappointing."

So we just use ‘now’ and ‘is’ with a description specifying the entry we want to change.

If we type ‘Showme the contents of ______’ in th code, it will print the table during testing.

We can also say [current table row] to print entries from a whole row (although we haven’t talked yet about how to make a current row), or say [row 5 in table ___] to print row 5, or print a column with the column name like say [element in table ____] in the table of elements.

Section 16.5 is Choosing rows.

This is a lot like [regarding the noun] for text. It just establishes the current context. Once that is established, you can just say ‘such and such entry’ instead of saying what row it’s in:

To list the succession:
    say "The Succession List runs as follows...";
    repeat with N running from 1 to the number of rows in the Table of Recent Monarchs:
        choose row N in the Table of Recent Monarchs;
        say "[accession entry]: [name entry] ([family entry]).";

Here the words before ‘entry’ are just the names of columns.

You can also ‘choose’ rows like so:
choose row with a name of "Victoria" in the Table of Recent Monarchs;

You can also choose a random row:
choose a /the/-- random row in /from (table name)

Hmm, I was looking back to see if I did use tables in the past, and apparently my very first game Ether used tables (I made that game by taking Emily Short’s Glass and copying bits, and I think she used tables). So I had a table like this:

Table of Weather
level	temperature	wind	pressure
-4	"Thin strands of steam are leaking from your tentacles[if the player is in Battlezone] and flames lick your shell[end if]. You may not be able to withstand further heat."	"[if the player is in Aloft]The air is still and peaceful. You find yourself tired, your tentacles drooping. Any further west and you might fall asleep.[otherwise]You stand right on the edge of the great horror to the west. You are close enough to touch the eye.[end if]"	"The thick air squeezes your shell from all sides. You find yourself somewhat uncomfortable, and wonder if your shell could take any more pressure."
-3	"Waves of heat roll at you from every direction[if the player is in Battlezone] and jets of flame scorch your shell from time to time."	"[If the player is in Aloft]The air flows slowly here, with torpid spirals that you idly spin in[otherwise]The air is thick and dull here, like the eye of a storm. To the west lies the enormous eye.[end if]."	"The air is soupy and uncomfortably thick down here."
-2	"The air is hot and humid[first time] here, in stark contrast to the north. The southern horizon is filled with nebulous masses that glow red and churn slowly, occasionally flaring out bursts of steam. A dry heat bakes your tentacles, only to be suddenly replaced by a shell-drenching humidity that is quickly swept away. The air gets quite a bit hotter to the south, although it is still manageable[only]."	"[if the player is in Aloft]The wind here is slower and mild[otherwise]You are still some distance from the great eye to the west, but its red glare chills your soul[end if][first time]. Unlike the other directions, you notice that the west is peaceful, clear, and free, with gentle air and thick, pillowy cloud formations that drift slowly by. You realize when you see it how deeply tired you are. You shake yourself, determined to press on[only]."	"You notice that the air is thicker than usual down here[first time]. The air far below you is so compressed and thick that it has become liquid, its surface constantly bubbling and popping. Even here, much higher, you can feel a slight, uncomfortable pressure on your shell.[only]."
-1	"The air is warm and moist."	"There is a faint breeze[if the player is in Battlezone], nudging you towards the eye to the west[end if]."	"The air weighs on your shell a bit more than usual."
0	"The temperature is [if the player is in Aloft]pleasant and [end if]mild."	"You feel a mild breeze."	"The air pressure matches your natural buoyancy."
1	"The air is cool and fresh[first time]. You pause in awe at the wintry spectacle to the north. Massive pillowy clouds blot out the horizon, shedding enormous snowflakes that hurl about in blizzards to the northeast and clump together in snowbergs and icebergs to the northwest. Even here, close to you, a few small snowflakes spill out and dance around you. The air becomes noticeably chiller to the north[only]."	"The brisk wind ruffles your tentacles."	"The air is a bit thin up here."
2	"You feel a chill in the air."	"The stiff wind blows you off course for a moment. You struggle to remain in place[first time]. A particularly nasty blast of wind comes from the east, whose vast space is filled by colossal black stormclouds constantly shredded by small tornadoes and gales. Occasional lightning bolts flash, followed by deep grumbling thunder. Even this far away, the wind is still uncomfortably strong[only]."	"The atmosphere is weak and thin here[first time]. You look up, and far above you, the clouds and snowflakes and all other details that enrich this world slowly phase out into empty nothingness. Here, where you are, the air is thin, but you can still manage to go up a bit further[only]."
3	"Thin snowflakes litter the air here. Puffs of mist come from your gills."	"A gale blows here, making it difficult to fly. You feel your shell trembling."	"You find yourself slightly drowsy in the thin air."
4	"Thick frost clusters on your shell and sticks your tentacles together. You may not be able to go any further to the north."	"Terrifying winds buffet you about. You revel in the excitement, but know that you may not be able to withstand stronger winds."	"You struggle mightily to keep alert and aloft in the thin atmosphere. You may not be able to go any higher."

and code like this:

choose the row with a level of eastness in Table of Weather;
say "[wind entry][if QuantOnOff is 1] The windspeed is [eastness plus four].[paragraph break][otherwise][paragraph break][end if]";

Anyway, Section 16.6 is repeating through tables:

To list the succession:
    say "The Succession List runs as follows...";
    repeat through the Table of Recent Monarchs:
        say "[accession entry]: [name entry] ([family entry])."

This is the same as finding the number of rows, repeating from 1 through the number of rows, and then choosing that row.

Note that there is no loop variable here, unlike in other forms of “repeat”, because it’s the choice of row which keeps track of how far we have got.

To go backwards:
repeat through (table name) in reverse order:

Or to sort through things in alphabetical/numerical/lexicographical order:

repeat through the Table of Recent Monarchs in name order: ...
repeat through the Table of Recent Monarchs in accession order: ...

Or reversing that order:

repeat through the Table of Recent Monarchs in reverse name order: ...
repeat through the Table of Recent Monarchs in reverse accession order: ...

Example 272 is Port Royal 4. We haven’t revisited Port Royal for many chapters!

To say current denizen:
    repeat through the Table of Occupations and People:
        if the date attested entry is the current year:
            say "[nickname entry] [family entry], [trade entry]";
            blank out the whole row;
            rule succeeds;
    say "absolutely no one"

Table of Occupations and People

Trade nickname family Date attested
“architect” “Robert” “Snead” 1684
“baker” “William” “Wingar” 1683
“barber” “William” “Alcocke” 1676
“blacksmith” “William” “Davidson” 1679
“bricklayer” “Samuel” “Richardson” 1683

(The above table was truncated)
New New Prison is a room. "You have a not very interesting room. Through the window you see passing [current denizen]."

Section 16.7 is Blank entries

You can leave things blank with two hyphens:

Table 2.1 - Selected Elements

Element Symbol Atomic number Atomic weight
“Hydrogen” “H” 1 1
“Iron” “Fe” 56
“Zinc” 30 65
“Uranium” “U” 92 238

(this forum converts two hyphens to an m-dash when displaying text)

You can check for blankness with:

if there is a symbol corresponding to an atomic number of 30 in the Table of Selected Elements ...
if there is an atomic number in row 2 of the Table of Selected Elements ...

if there is no symbol corresponding to an atomic number of 30 in the Table of Selected Elements ...
if there is no atomic number in row 2 of the Table of Selected Elements ...

An entirely blank column is bad because Inform can’t tell what data type it is:

Table 2 - Selected Elements

Element Symbol Atomic number Atomic weight
“Hydrogen” “H” 1
“Iron” “Fe” 26
“Zinc” “Zn” 30
“Uranium” “U” 92

So as long as you have a blank column, put the kind you will use in the top spot of the column:

Table 2 - Selected Elements

Element Symbol Atomic number Atomic weight
“Hydrogen” “H” 1 a number
“Iron” “Fe” 26
“Zinc” “Zn” 30
“Uranium” “U” 92

This won’t conflict with actual entries because if you have actual entries the column isn’t blank in the first place.

The end of a row can be left blank without typing --.

Table 2 - Selected Elements

Element Symbol Atomic number Density Specific gravity
“Hydrogen” “H” 1 a number a number
“Iron” “Fe” 26
“Zinc” “Zn” 30
“Uranium” “U” 92

Example 16.9 is blank rows. You can just tell Inform to throw some blank rows in at the end of a table:

Table 2 - Selected Elements

Element Symbol Atomic number Atomic weight
“Hydrogen” “H” 1 a number
“Iron” “Fe” 26
“Zinc” “Zn” 30
“Uranium” “U” 92
with 3 blank rows

Or just have an entirely blank table (this example uses the previously undocumented ability to specify kinds in parentheses after the column name. Does this only work for completely blank tables?)

Table 3 - Undiscovered Periodic Table

Element (text) Symbol (text) Atomic number (a number) Atomic weight (a number)
with 92 blank rows

Blank rows are skipped when repeating through rows. You can check if the whole table is empty as so:

if the Undiscovered Periodic Table is empty, ...

I think blank rows are there because you can’t dynamically add rows (maybe?)

Example 273 is If it hadn’t been for:

Table of Recorded Content

time stamp sound
a time some text
with 60 blank rows.
To record (noise - some text):
    if the number of blank rows in the Table of Recorded Content is 0, rule succeeds;
    choose a blank row in the Table of Recorded Content;
    now time stamp entry is the time of day;
    now sound entry is noise.

Carry out someone closing something in the presence of the switched on recorder:
    record "A creaking followed by a slam."

Carry out someone going to a room (called destination) in the presence of the switched on recorder:
    if the destination is the holder of the recorder, record "Footsteps, growing louder.";
    otherwise record "Footsteps, fading out."

etc.

Section 16.10 is adding and removing rows.

Yeah, looks like we can’t add rows dynamically, just edit old ones:

choose a blank row in Table 3;
now element entry is "Fluorine";
now symbol entry is "F";
now atomic number entry is 9;
now atomic weight entry is 19;

That’s reasonable to me.

You can count rows like this:

the number of blank rows in Table 3
the number of filled rows in Table 3

You can’t say ‘now such and such entry is blank’ since ‘blank’ isn’t a value.

So you just say ‘blank out’ (all of this stuff is very standard database stuff).

choose row 1 in the Table of Fish Habitats;
blank out the salinity entry;

We can also do what I’ve seen Emily Short do a lot:

choose row 1 in the Table of Fish Habitats;
blank out the whole row;

and what I’ve never really seen:
blank out the whole salinity column in the Table of Fish Habitats;

Or remove the whole table!
blank out the whole of the Table of Fish Habitats;

It says:

This is only really useful when a Table is being used to hold working space for some calculation or other.

Hmm, interesting.

Example 274 is Odyssey:

Table of Athena's Movement
destination
Thebes
Delphi
Thebes
Athens
Corinth
Mycenae

Every turn when Athena is active:
    repeat through the Table of Athena's Movement:
        let last space be the location of Athena;
        if Athena can be seen by the player, say "Athena heads to [the destination entry].";
        move Athena to destination entry;
        if Athena can be seen by the player, say "Athena arrives from [the last space].";
        blank out the whole row;
        break.

I don’t really see why we blank out the line. It says:

By blanking out the table line by line, we make sure that we never lose our place in the path.

But what does that mean? If someone can explain it to me that would make me feel smart.

Oh…wait…Thebes is in here twice! So then we have to delete the first Thebes so we can get different behavior the second time.

Section 16.11 is Sorting:

This is specifically about sorting the order of rows.

sort the Table of Recent Monarchs in random order;

sort the Table of Recent Monarchs in accession order;
(accession being the name of a column)

sort the Table of Recent Monarchs in reverse name order;
(here name being the name of a column in that Table)

Sorting text puts all uppercase letters before all lowercase and puts accented letters at the end.

Even when sorting by reverse, rows with the same value remain in the same order. So if there’s a column, for instance, where everything has the same value ‘1’, and you sort that column in reverse order, nothing happns.

Example 275 is a deck of cards. It has a table with 52 lines in it (which I will not represent here), as well as some shuffling code:

Understand "shuffle" as shuffling. Shuffling is an action applying to nothing.

Carry out shuffling:
    sort the Table of Cards in random order;
    say "You expertly rearrange the cards.".

When play begins:
    sort the Table of Cards in random order.

This gives me fond memories of the Tarot deck in Curses!, although the implementation is wildly different (I assume).

Section 16.12 is Listed in…

Using ‘listed in’ is a way of searching for something in a table and selecting the row it is found in.

if the newfound object is an item listed in the Table of Treasures...

or, a different, bigger, example:

  if there is no time entry:
        now the time entry is the time of day;
        increase the score by the value entry;
    say "Taken!"

Table of Treasures

Item Value Time
brooch 5 a time
tiara 8
coronet 10

So the table is a convenient way to handle three rules at once (which is what the book says, although I’m only seeing two rules here).

Example 276 is Noisy Cricket:

It has a bunch of fluid rules, and a table:

Table of Mixtures

rating creme de menthe comp vodka comp cacao comp adjectival descriptor nominal descriptor
0.0 fl oz 1 0 0 minty creme de menthe
0.0 fl oz 0 1 0 chocolatey vodka
0.0 fl oz 0 0 1 chocolatey creme de cacao
0.0 fl oz 1 2 0 chocolatey mintini
0.0 fl oz 1 0 1 chocolatey grasshopper
(only partially reproduced)

And some very complex code scoring how well the drink matches the various descriptions. It also includes the reciprocal square root but laid out in a table, which is pretty wild.

Section 16.13 is Topic Columns

Text in quotes is always assumed to be the ‘text’ kind in tables, unless you specifically call a column ‘topic’, then that’s used for “comparing against what the player has typed”.

Apparently the only thing you can do with columns is the ‘listed in’ thing.

Examples:
After asking the Sybil about a topic listed in the Table of Sybil's Replies, say "The Sybil declaims for a while, the gist being that the muse in question looks after [muse entry]."

Table of Sybil’s Replies

Topic Muse
“calliope” “epic poetry”
“clio” “history”
“erato” “love poetry”
“euterpe” “music”
“melpomene” “tragedy”
“polyhymnia” “sacred poetry”
“terpsichore” “dancing”
“thalia” “comedy”
“urania” “astronomy”
“monica” “tidiness”
“phoebe” “massage”
“rachel” “oval hair-cuts”

Nice Friends references.

Topics can be more elaborate like this:
"Bridget" or "Bridge" or "Bridget Jones"

or

"flora/eve"

Example 277 is Merlin:

Understand "remember [text]" as remembering.

Remembering is an action applying to one topic.

Carry out remembering:
say "Nothing comes to mind.".

Instead of remembering a topic listed in the Table of Recollections:
say "[response entry][paragraph break]".

Table of Recollections
Topic Response
“rain/weather” “You’ve seen worse, but not often: it’s falling so hard now that the tin rattles and the runoff, on the low side of the roof, would be a tenable source of hydroelectric power.”
“hydroelectric power” or “power/hydroelectric” “It’s not as though you have any sort of light bulb in here to turn on, even if you could power it.”
“light bulb” or “light/bulb” “Light bulbs, like so much else, are a thing of your past. Or is it your future? Tricky, the way the world loops round on itself.”
“past/time/future” “Living backwards has its drawbacks. A tendency to confuse and annoy your friends, being one; the total inability to maintain a stable relationship; and a deep dissatisfaction with most of the bodily processes people enjoy, since they ultimately make you hungrier, colder, or-- no point dwelling on it, really.”
“backwards” “It’s not even exactly backwards, now is it? It’s more like a series of forwardses stuck back to back. As though someone had taken each track of a CD and put them in the exactly wrong order. You miss that. The music on demand.”

Section 16.14 is Another Scoring example:

To record (T - text) as achieved:
choose row with a citation of T in the Table of Tasks Achieved;
if there is no time entry:
now time entry is the time of day;
increase the score by the points entry.

The phrase above expects to see a table like this one:

Table of Tasks Achieved

Points Citation Time
1 “pride” a time
3 “anger”
2 “avarice”
4 “envy”
1 “lust”
2 “gluttony”
3 “sloth”

I guess this is a cool way of doing this, since, it prevents the score from being assigned twice.

Wait, I have an exact situation I could use this! I have an escape room in my game with seven rooms themed after the seven deadly sins, with 1 score point assigned per room and a place where past winners brag about their completion times. I could put this directly in my game! Probably won’t but it’s pretty funny.

Before eating, record "gluttony" as achieved.

Example 280, Goat-chese and Sage Chicken, is similar. It uses the kind of table shown above and then assigns the ‘table of rankings’ as we saw earlier in another chapter.

1 Like

#Chapter 16, continued

Section 16.15 is Varying which table to look at

This is just make a table name that varies. So check this out:

Table 1 - Nifty Opening Plays in US Scrabble

word score
“muzjiks” 128

Table 2 - Nifty Opening Plays in UK Scrabble

word score
“quartzy” 126
“squeezy” 126
The lexicon is a table name that varies. The lexicon is Table 1.

To flip tables:
    say "You exchange dictionaries, lexically crossing the Atlantic. ";
    if the lexicon is Table 1, now the lexicon is Table 2;
    otherwise now the lexicon is Table 1;
    choose a random row in the lexicon;
    say "Did you know that according to [the lexicon], [word entry] scores [score entry]?"

Example 281 is Farewell

Table of Tina’s Chatter

topic reply summary turn stamp
“aasvogel” “‘Oh, it’s a vulture.’” “that an aasvogel is a vulture” a number
“acaudate” “She shrugs, mid-pour. ‘Means something doesn’t have a tail.’” “that acaudate means ‘tailless’”
“absorptiometer” “‘It’s a thing that measures the solubility of gases in a liquid,’ she explains gently, as to a child.” “that an absorptiometer measures solubility of gasses in a liquid”

Table of George’s Chatter

topic reply summary turn stamp
“baccaceous” “‘Something that has or bears berries,’ says George, without looking up.” “that baccaceous means berry-bearing or berry-like” a number
“bagheera” “‘Oh, that’d be a velvet-like textile.’” “that bagheera is a velvet-like textile”
“balistarius” “‘That’s a crossbow-man,’ George replies instantly.” “that a balistarius is a crossbow-man”
A person has a table name called conversation.

Instead of asking someone about something:
    let the source be the conversation of the noun;
    if topic understood is a topic listed in source:
        if there is a turn stamp entry:
            say "[The noun] has already told you that [summary entry].";
        otherwise:
            now turn stamp entry is the turn count;
            say "[reply entry][paragraph break]";
    otherwise:
        say "[The noun] stares at you blankly."

Hmm, this is pretty similar to my own conversation extension, but I didn’t use tables, as a lot of the responses are quite long and often have extra effects.

Section 16.16 is Defining things with tables

This is used when you want to define a large group of similar objects but don’t want to fill out a long and tedious template:

The Staging Area is a room. A jersey is a kind of thing. A jersey is wearable. Some jerseys in the Staging Area are defined by the Table of Honorary Jerseys. The description of a jersey is "Since [year established], the Tour de France has awarded this jersey to the [citation]."

Table of Honorary Jerseys
jersey year established citation
a yellow jersey 1919 “race leader”
a polkadot jersey 1933 “King of the Mountains”
a green jersey 1953 “highest point scorer on sprints”
a white jersey 1975 “best cyclist aged 25 or less”

The first column provides names for the things, and it automatically creates the properties ‘year established’ and ‘citation’ for each thing.

Given a blank space, that thing is just not input. You can also make kinds this way, like ‘some kinds of jerseys are’).

This would be a convenient way of handling boring scenery items. You could have a column for the internal name, a column for the room it’s in, a column for its description, a column for synonyms, a column for printed name, and a column for interaction message.

Example 282 is Sweeney:

This is a complex example I won’t reproduce here. It has multiple tables, each table corresponding to a conversation topic, and each table having multiple questions and answers.

Example 283 is Introduction to Juggling:

toy cost restriction description difficulty outcome
an economy bounce ball set $10.00 “comes in set of three” “A fairly ordinary rubber ball, solid color.” moderate “You create of the balls a cascade of moving color.”
an acrylic contact ball $14.00 “should be bought with ball polish” “A large clear ball, not for throwing but for using in various hand tricks.” hard “You rotate the ball between your fingers and pass it over the backs of your hands.”
a UV-reactive contact ball $55.00 “appears to glow in dark rooms” “Similar to the ordinary acrylic contact ball, but UV-reactive.” hard “The ball glows as it passes between your fingers and over the backs of your hands, rolls up to your wrist, snaps through the air-- all apparently of its own accord.”
a ball polish set $10.00 “useful only with acrylic contact balls” “Three bottles of polish and a rag for keeping acrylic contact balls scratch-free.” hard “You juggle the polish bottles with difficulty, since they are full of sloshing liquid.”
a teaching beanbag set $8.00 “set of three” “Soft, easily-juggled bag.” easy “You juggle the beanbags with basic competence.”
a stage ball set $13.50 “comes in set of three” “Not much different in appearance from the economy bounce ball, but larger so as to be visible from a stage.” moderate “You create of the balls a cascade of moving color, visible from quite a distance.”
a fireball set $33.00 “will not be sold to minors” “A ball has wicking and a fuel-source inside so that it will burn while being juggled.” hard “You juggle the fireballs rapidly, careful never to hold any of them a moment longer than necessary.”

Section 16.17 is Defining values with tables

It’s a convenient way for defining values with associated properties:

Solar distance is a kind of value. 1000 AU specifies a solar distance. Planet is a kind of value. The planets are defined by the Table of Outer Planets.

Table of Outer Planets

planet semimajor axis
Jupiter 5 AU
Saturn 10 AU
Uranus 19 AU
Neptune 30 AU
Pluto 39 AU

With these definitions, one can say:
say "Pluto orbits at [semimajor axis of Pluto]."

Columns are created one at a time, so you can use earlier columns in later columns:

Table of Outer Planets

planet semimajor axis centre of government
Jupiter 5 AU Jupiter
Saturn 10 AU Saturn
Uranus 19 AU Saturn
Neptune 30 AU Pluto
Pluto 39 AU Pluto

Column names can’t coincide with any other names of properties of other things, so goofier column names are better here.

Two technical footnotes. In a table used to define a kind of value, blank entries are not left blank: they are filled in with suitable default values. For instance, if the semimajor axis column had been all "–"s except for listing Neptune at “30 AU”, say, Inform would deduce that the column was meant to hold a value of kind “solar distance”, and would set the solar distances for all of the other planets to be “0 AU”. It does this to ensure that “solar distance of P” exists for any planet P.

The second technical note is that we must not sort such a table, because it is used during play to store the properties, and if it were to get rearranged then so would the properties be - with probably disastrous results.

Section 16.18 is Table continuations

This is something vital for using many extnsions and even some core Inform stuff (like the table used for questions after beating the game).

You can start making a table:

Table of Outer Planets

planet semimajor axis
Jupiter 5 AU
Saturn 10 AU
Uranus 19 AU
Neptune 30 AU
Pluto 39 AU

and then finish it later:

Table of Outer Planets (continued)

planet semimajor axis
Orcus 39 AU
Quaoar 43 AU
Xena 68 AU
Sedna 524 AU

This is useful for extensions especially.

The continuation must have the same name as the original, because it is the original.

Some fun side notes are included in this section:

At time of writing the International Astronomical Union has not yet consented to name 2003 UB313 after Xena, the Warrior Princess, but this is surely only a bureaucratic delay. (Footnote: on 24 August 2006 it was demoted to dwarf planet status, like the luckless Pluto, and on 13 September renamed Eris; though its moon’s official name, Dysnomia, is an ingenious double-meaning to do with the name of Xena’s actress, Lucy Lawless.)

Example 284 is Food Network Interactive

It shows how to continue a table used in extensions.

Include Basic Screen Effects by Emily Short. Include Menus by Emily Short. Include Basic Help Menu by Emily Short.

Table of Basic Help Options (continued)
|title|subtable|description|toggle|
| — | — | — | — |
|“Recipes in This Game”|Table of Recipes|–|–|
|“Contacting the Author”|–|“If you have any difficulties with [story title], please contact me at fakeaddress@gmail.com.”|

And then another table later for a sub-menu (this is not a continuation, just a feature of the extension that turns tables into submenus:

Table of Recipes

title subtable description toggle
“Salmon Tartare” “First, be sure to buy extremely fresh salmon. Raw fish should be served on the day it was caught, if possible. To guarantee this, visit an Asian supermarket or specialty store, and buy salmon marked ‘sashimi grade’…”
“Pecan Brownies” “Begin by shelling half a pound of pecans…”

Whole Foods is a room.

Finally, section 16.19 is Table amendments

It just replaces rows in a table.

Table of Plans

moment outcome
10 AM “takeover of Mars”
11:30 AM “canals reflooded”
11:45 AM “chocolate bar production doubled”

Table of Plans (amended)

moment outcome
11:45 AM “volcanic cave production doubled”

Amendment rows may be given in any order. The process of matching a row begins at the left-most column: Inform tries to see if any single row in the original table has a matching entry. If none does, a Problem is issued. If more than one do, Inform then looks at the second column, and so on. For instance:

Enthusiasm is a kind of value. The enthusiasms are pumped, wired and languid.

Table of Mental States

feeling extent consequence
pumped 1 “you feel able to run for your life”
pumped 2 “you feel able to run for President”
wired 1 “you feel able to run”
languid 1 “you feel”

Table of Mental States (amended)

feeling extent consequence
pumped 2 “you feel able to run for the Nebraska State Legislature”

Here the amendment is made to the second row of the original table. The value in the leftmost column, “pumped”, matches two rows in the original, so Inform moves on to the next column, reads “2”, and finds that only one row in the original still qualifies - so that is the one replaced.

Example 285 is Trieste:

This just modifies an extension’s help menu:

Table of Standard Instructions (amended)

help-topic reply
commands “The only commands this game recognizes are HOLD, MOVE, CONVOY, SUPPORT MOVE, and SUPPORT HOLD. No others are necessary.”

I don’t have many comments here; tables seem like straightforward implementations of relational databases (is that the phrase?) and I don’t really use them much. To me this is like browsing a hardware store and getting to the fastener aisle. Essential, useful, but dull.

Any table fans reading along that want to speak up in favor of tables?

2 Likes

Oh, I’m not technically savvy enough to advocate for tables, but I did use several in the WIP.

Excluding my large (bloated?) menus implementation and adding to table of final q’s, my soon-to-be-released game has fourteen.

I think a big part of it was my decision to use something close to the footnote example in the Ibid. recipe early on. I figured it out and it seemed reliable, so I looked around for other stuff to do with tables. Mechanically, it turned out to be a good way to track actions/events and feed them back to the player on demand.

Though really, anything I figured out once I wanted to use again, which is probably not much of a design principle :joy_cat:

1 Like

Nope, it works for any table. It’s sometimes useful when Inform can’t decide what type the column should be—for example, a literal topic can look a lot like literal text, so you can put “(topic)” after the column name to clarify.

Yeah, tables are just chunks of memory allocated at compile-time, so you can’t change their size at runtime.

The Standard Rules use this to keep track of all the things that need to be printed in a room description: they’re kept in the Table of Locale Priorities. Oddly enough, it doesn’t use that phrase:

Before printing the locale description (this is the initialise locale description rule):
    now the locale paragraph count is 0;
    repeat through the Table of Locale Priorities:
        blank out the whole row.

Emily Short likes to do this: every turn, the rule finds the first non-blank row of the table, does something with it, then blanks out that row and returns. I don’t like it because it means you can’t go backward or reset to the beginning, so I just use another variable to keep track of the current position instead.

3 Likes

Tables are kind of like statically allocated relational database tables without any of the power of SQL and keys and joins and all that. That said, they’re indispensable to me. I use tables to organize loads of little bits of text in one place rather than scattered all over the file like object descriptions are. I have a table to hold all the custom “can’t go that way” messages for instance. When combined with a To decide phrase it’s pretty convenient.

1 Like