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

As I have been going through the documentation again – I’m just finishing chapter 10 as of today – I have also been looking through the different parts of the Inform 7 Index so I can have an alternative view on the data and code I am testing. That way, I am also learning how to better utilize the Index in my coding process.

Many of the documentation sections have references to the appropriate part of the Index, but not all of them. Instead, there are documentation links in most of the Index sections that point back to relevant Document sections, like this:

Screenshot 2024-03-11 at 6.41.20 AM

The links are those little blue circles with the question marks in the middle.

I ran into a minor inconvenience in that the order of the Index sections and the order of the Documentation sections are significantly different from one another. For example, although Contents Index - 1. Contents is the first section of the Index, the Documentation section link About extensions links to Chapter 27: Extensions §27.1. The status of extensions.

So, I went through each section of the Index, grabbed all of the documentation links and sorted all the information by Documentation section order. If there wasn’t a link, I took my best guess. The result is a list of relevant Index sections for certain Documentation sections. Is there redundant information? Yes. But I still found it useful to read through a specific documentation section and then know where to go in the Index to see a different view on the coding and data concepts covered in the documentation. Hopefully, it will be useful for others as well:

Chapter 2: The Source Text §2.5. Headings
Contents Index - 1. Contents About headings

Chapter 2: The Source Text §2.12. Use Options
Contents Index - 5. Innards About use options

Chapter 2: The Source Text §2.13. Administering classroom use
Contents Index - 5. Innards - The following use options are in force:
Set from the Options.txt configuration file, or automatically

Chapter 2: The Source Text §2.14. Limits and the Settings panel
Contents Index - 5. Innards About the story file

Chapter 3: Things (the entire chapter)
World Index - 2. Gazetteer (no links, just seemed most relevant)

Chapter 3: Things §3.4. Regions and the index map
World Index - 1. Map (no links, just seemed most relevant)

Chapter 3: Things §3.5. Kinds
Kinds index - 1. Chart About kinds

Chapter 4: Kinds §4.1. New kinds
Kinds index - 1. Chart New kinds of objects

Chapter 4: Kinds §4.5. Kinds of value
Kinds index - 1. Chart Other new kinds

Chapter 4: Kinds §4.12. Values that vary
Kinds index - 3. Values About variables

Chapter 6: Descriptions §6.1. What are descriptions?
Phrasebook Index - 2. Lexicon About descriptions

Chapter 7: Basic Actions §7.1. Actions
Actions Index - 1. Grouped About actions
Actions Index - 2. Alphabetical About actions

Chapter 7: Basic Actions §7.15. Kind of actions
Actions Index - 3. Behaviors About kinds of actions

Chapter 9: Time §9.11. Future events
Scenes Index - 2. Events About timed events

Chapter 10: Scenes §10.1. Introduction to scenes
Scenes Index - 1. Plot About scenes

Chapter 10: Scenes §10.2. Creating a scene
Scenes Index - 3. Rules (no links, just seemed most relevant)

Chapter 10: Scenes §10.3 Using the Scene index
Scenes Index - 1. Plot No specific links

Chapter 10: Scenes §10.5. Linking scenes together
Scenes Index - 1. Plot How they link together

Chapter 11: Phrases §11.1. What are phrases?
Phrasebook Index - 1. Phrases About phrases

Chapter 12: Advanced Actions §12.4. Persuasion
Rules Index - 1. Standards - Rules governing actions

Chapter 12: Advanced Actions §12.5. Unsuccessful attempts
Rules Index - 1. Standards - Rules governing actions

Chapter 12: Advanced Actions §12.7. New actions
Actions Index - 1. Grouped New actions
Actions Index - 2. Alphabetical New actions

Chapter 12: Advanced Actions §12.10. Action variables
Actions Index - 1. Grouped New actions
Actions Index - 2. Alphabetical New actions

Chapter 12: Advanced Actions §12.15. Out of world actions
Actions Index - 1. Grouped Out of world actions (in red)
Actions Index - 2. Alphabetical Out of world actions (in red)

Chapter 13: Relations §13.1. Sentence verbs?
Phrasebook Index - 4. Verbs About verbs

Chapter 13: Relations §13.3. What are relations?
Phrasebook Index - 3. Relations About relations

Chapter 15: Numbers and Equations §15.20. Multiplication of units
Kinds index - 2. Arithmetic About arithmetic

Chapter 16: Tables §16.1. Laying out tables
Contents Index - 3. Tables About tables

Chapter 17: Understanding §17.1. Understand
Actions Index - 4. Commands About commands
Actions Index - 5. Tokens
"[anybody]"
"[anyone]"
"[somebody]"
"[someone]"

Chapter 17: Understanding §17.4. Standard tokens of grammar
Actions Index - 5. Tokens About tokens
"[anything]"
"[other things]"
"[something]"
"[something preferably held]"
"[things]"
"[things inside]"
"[things preferably held]"

Chapter 17: Understanding §17.5. The text token
Actions Index - 5. Tokens
"[text]"

Chapter 17: Understanding §17.13. New tokens
Actions Index - 5. Tokens New tokens

Chapter 18: Activities §18.1. What are activities?
Rules Index - 1. Standards About activities
Rules Index - 2. Extras About activities

Chapter 19: Rulebooks §19.1. On rules
Rules Index - 1. Standards About rulebooks
Rules Index - 2. Extras About rulebooks

Chapter 19: Rulebooks §19.4. Listing rules explicitly
Rules Index - 1. Standards Moving or abolishing rules
Rules Index - 2. Extras Moving or abolishing rules

Chapter 23: Figures, Sounds and Files §23.4. Gathering the figures
Contents Index - 4. Figures About figures

Chapter 23: Figures, Sounds and Files §23.7. Recorded sounds
Contents Index - 4. Figures About sounds

Chapter 23: Figures, Sounds and Files §23.11. Files
Contents Index - 4. Figures About files

Chapter 25: Releasing §25.4. The Library Card
Contents Index - 2. Card About the Library Card

Chapter 25: Releasing §25.5. The Treaty of Babel and the IFID
Contents Index - 2. Card About IFIDs

Chapter 27: Extensions §27.1. The status of extensions
Contents Index - 1. Contents About Extensions

1 Like

Good idea. I’ll note for any who might not know that there are online project indices for minimal Inform projects available, for reference when you’re not in the IDE:

1 Like

I think of a phrase as something that that occurs at runtime. Typically, it has some sort of side effect as well. Usually it is changing data state (i.e. at a given point in time, the value of a data object changes).

When I think about data state, I like to start with the create, read, update, and delete (CRUD) model of operations on persistence data (i.e. files and databases). Inform 7 has its own little database of values in the form of global variables and the word data, so it is not a bad starting model for about these ideas.

Of course, the biggest problems with applying the CRUD model to Inform 7 are the create part and the delete part, because you don’t dynamically create or destroy anything in Inform 7 at run time. All of that stuff is defined at compile time with your assertions.

There is an extension called Dynamic Objects by Jesse McGrew (For Glulx Only) which does allow run time object creation. You can also simulate deletion by moving an object to nowhere (i.e. off-stage) but it is still around. It’s just that the player can’t get to it.

So, that leaves us with read data and update (i.e. write) data at runtime. And I have finally arrived at my original point, which is that phrases are for reading and writing data at runtime.

And yes, even the say phrases have a side effect of changing data state in the game because they write to the standard out (i.e. the stdout, which is typically the screen) buffer of your terminal or window. That’s why we can see it and scroll back to previous parts of it. The stdout provides a scrollable history in its buffer, a log of its numerous data state changes throughout the game session.

So, while each of the two lines in the body of To become awesome are both phrases – utilizing the quintessential phrase keyword now – the entire definition of To become awesome is an assertion that defines a procedure that can be invoked at run time by the phrase become awesome;.

The Inform 7 documentation does call this procedure a definition of new phrase, a way to combine and wrap up one or more phrases into another, more complex phrase. Inform 7 for Programmers calls it a Patterned Procedure. It has a similar format to a Rule, with a preamble and a body of phrases. But the preamble for a Patterned Procedure is a pattern that attempts to match an invocation phrase for the procedure. So, again, there are some different names that can be used, and Patterned Procedure just makes more sense for me.

The difference between function and procedure in inform 7 is a function returns something and a procedure doesn’t. So, functions may or may not have side effects – depends on whether the function is pure or not – but procedures are there to affect data at run time.

And, as usual, if I get any of this stuff wrong, please let me know. My understanding of these concepts is still at a novice level.

Yes, it is a dense chapter and there are a lot of ideas represented by the name “Phrase”. Here are the Inform 7 for Programmers categories to help further separate and name these different pieces of functionality.

a) Also called Patterned Procedures.
b) Also called Boolean Functions or To decide whether/if functions.
c) Also called Functions or To decide functions.
d) Also called Say phrase or To say procedures.

You also bring up an interesting point on Text Substitution, that they are like functions returning strings. That’s how I think of them as well. The odd part is the string is “returned” by invoking a say phrase, which is why, I think, it is referred to as a procedure instead of a function.

Typically, a say phrase writes to the screen, but in the case of a Text Substitution, that say phrase writes to the bracketed invocation inside of another say phrase – like the stdout has been temporary redirected to the string buffer of the say phrase – which, as you pointed out, feels much more like a function returning a string than it does a say procedure invocation.

This is a common distinction in some languages, like Pascal. But Inform doesn’t make it.

By default it’s still writing to the screen. Even when a “say” phrase invokes another “say” phrase, it’s writing to the screen as it goes.

String buffers get involved when you write

let X be “[stuff]”;

Then the runtime allocates a string buffer for the X variable and begins filling it in.

Similarly, in the line

if X is “[stuff]”…

…then it has to fill a temporary buffer to be compared stringwise with X. But when just saying phrases, no.

(To be fair, you said “like the stdout has been temporarily redirected”. You can think of it that way! I’m talking about the underlying implementation.)

4 Likes

I appreciate the distinction. I wasn’t totally thinking about it correctly and your example of declaring a local variable and the conditional phrase does make more sense as a true string buffer.

1 Like

I agree that Persuasion is one of the more difficult concepts to grasp in this chapter. I was actually surprised upon rereading this chapter that Persuasion shows up so early. I assumed it would be closer to the end.

I suppose, when dealing with actions, the bare minimum details that need to be considered are, firstly, what is the action, and, secondly, who is the person taking the action (i.e. actor). The noun and the second noun are never even considered when processing commands like “wait” or “Fred, jump”, but the action and the actor are always considered. So, maybe that’s why the actor concepts are introduced so early.

Empirically, I feel like utilizing NPCs in this way is more the exception than the rule in most IF games. Probably because coding NPCs is so difficult in general.

Another detail I noticed as I have been playing around with this code is that both persuasion rules and unsuccessful attempt by rules show up, not somewhere in the Actions Index like I expected, but in the Rules Index - 1. Standards - Rules governing actions section. I see that the before, instead and after rules are in both indices, so I guess that’s where I formed my false assumption that persuasion rules and unsuccessful attempt by rules would be in both indices as well. Regardless, I will update my Documentation and Indices links post to reflect this.

1 Like

Agreed. A really difficult section to read and understand. I think the toughest part of using this functionality as a solution is recognizing the problems that it actually solves. And even then, there are probably other (possibly less elegant?) ways to solve them.

For example, the photographing example appears to be mostly addressing a way to photograph something without specifying that you are using a camera. It’s something I would have probably tried to solve by creating both a photographing action and a photographing it with action, along with a redirect of one action to the other after I had determined whether or not the player was carrying a camera.

Less elegant? Yes. Is there a design problem I’m not thinking about? Probably several. But this would have been my first draft attempt and it might have turned out to be “gud enuff”.

I think it is a little easier to understand the useful scenarios by looking at the few standard actions that use action variables included in Inform 7’s Standard Rules, which @Zed has already mentioned: looking, going, exiting and examining.

Any problems more complex than those, like thinking about the order of action rules or multiple variable computation costs or rules that change the state of their local variables during a multiple rule trigger chain, make my head spin. I figure if I ever run into problems that complex, I’m either getting my answer from someone in this community, or tossing the idea out and doing something simpler.

A couple of other minor things.

I found the title “Action variables” a bit ambiguous. It talks about variables of any type are “owned” by a given action, and not variables that contain values of the Action Kind (i.e. Stored Actions) or of the Action Name Kind.

I had a little trouble locating the Setting action variables rulebook in the indices. I was looking in the Rules Index - 1. Standards at first, but it turns out that all the information about variables owned by actions are also in the details of the Actions Index. For example, here is the Index listing for the photographing action example after compilation:

I will update my Documentation and Indices links post to reflect this.

Action variables are associated with a particular action in progress. If two actions are going on at the same time, they have separate action variables.

“What,” you say, “how can two actions be going on at the same time?” Well really I mean nested actions. Like if you write

Before going north:
    try Floyd going south;
    continue the action;

Then we have a player going north action with a Floyd going south action inside it. They have distinct nouns (north/south). If there’s doors in the way, they have distinct doors gone through and so on.

So the simplest examples of action variables are noun and second noun… except those two aren’t action variables. They ought to be, but for legacy reasons they’re global variables. To make the above example work, the runtime has juggle the noun global back and forth as actions start and stop. It’s a terrible hack.

(Similarly actor probably ought to be an action variable, but for tedious implementation reasons it’s a rulebook variable of the action-processing rulebook.)

If more of the library made use of action variables, they’d be more intuitive. Unfortunately, as you see, the only examples we’ve got are door gone through and so on, which are a bit obscure.

2 Likes

Okay, I definitely did not know this. I assumed the actor is always a person and is always animate. Maybe because of the word “actor”? I don’t exactly know how it might come in handy, but the fact that the following code actually works?

Lab is a room.

The bar is a thing in the lab.
The foo is a container in the lab.

Fooing is an action applying to nothing.
Understand "foo" as fooing.
Instead of fooing:
	try foo taking bar.

Test me with "foo".

:exploding_head: :exploding_head: :exploding_head:

I just realized something. After reading this section and your summary, I went to the Rules Index - How accessibility is judged section of the Index and there are a bunch of document links there that I do not currently have in my Documentation and Indices links post. For example:

So, I am going to stop exploring the documentation for today, and go back and update the post with all of those links as well.

1 Like

It works, but note that it results in a containment relation, not a carrying relation. Only people can anchor the carrying relation.

3 Likes

I understand what this sentence is saying but not why it is useful. Can you elaborate on why it is a sensible exception? Maybe a specific scenario so I can understand better?

2 Likes

I had the exact same question as @mathbrush, particularly after recently finishing Chapter 12: Advanced Actions §12.10. Action variables. Taking into account my admittedly tenuous grasp of Action Variables, the global variables the container in question and the supporter in question do feel like they could be Action Variables. I imagine reachability rules as, innately, having a very good probability of being nested at some point.

I did try to find out by digging into Standard Rules.i7x and found:

Section 3 - Used when ruling on accessibility

The person reaching -- documented at var_person_reaching -- is an object that varies.
The container in question is an object that varies.
The supporter in question is an object that varies.
The particular possession -- documented at var_particular -- is a thing that varies.

The person reaching variable translates into Inter as "actor".
The container in question variable translates into Inter as "parameter_object".
The supporter in question variable translates into Inter as "parameter_object".

which is precisely what @Draconis described.

Also:

The can't reach inside closed containers rule translates into Inter as
	"CANT_REACH_INSIDE_CLOSED_R" with
	"[The noun] [aren't] open." (A).
The can't reach inside rooms rule translates into Inter as
	"CANT_REACH_INSIDE_ROOMS_R" with
	"[We] [can't] reach into [the noun]." (A).

The can't reach outside closed containers rule is listed last in the reaching outside rules.

The can't reach outside closed containers rule translates into Inter as
	"CANT_REACH_OUTSIDE_CLOSED_R" with
	"[The noun] [aren't] open." (A).

I can only guess that rules and parameters at the Inter level of things are implemented more at the Inform 6 level (closer to the metal?).

So, if I think of these rules as events triggered by certain things, and the parameter_object as something that contains data that describe the specific context of the triggering of the event, that somewhere in the Inform 6 code, it figures out which parameters (if any) are useful and uses them as appropriate. Again, what @Draconis already said. Sometimes it just helps me to better understand after I reiterate concepts in my own words.

Which, I guess, leads me to a question based purely on curiosity and a need to confirm my understanding of Actions Variables: if this part of the code had been implemented purely in Inform 7, would the global variables the container in question and the supporter in question both been good candidates for Action Variables?

Doors and backdrops are “floating” objects; they exist in more than one room at the same time. Except they don’t, really. They just pretend. Inform juggles them around behind the scenes so that they are always either in the player’s current location, or removed from play.

If you check whether a floating object is visible to an NPC (in a different room), the illusion fails.

4 Likes

Not really, because they are needed for every action that checks accessibility. Inform doesn’t have a notion of an action variable that’s generalized across all actions (or a kind of action).

EDIT: It probably makes sense to think of them as activity variables. Although I haven’t really dug into how that would work.

MORE EDIT: I see I caused this confusion, in part, by saying that noun and second noun ought to be action variables. The same objection applies! They are used by lots of actions, and Inform doesn’t support that idea.

Even handwaving this, I think that container in question doesn’t match up well with being an action variable. An accessibility check involves many containers in question as we walk up and down the tree. There’s not a single value associated with the current action.

1 Like

As zarf said, I think they would make sense as variables tied to “reaching inside” and “reaching outside” (which aren’t actions).

But really, they’re symptoms of a kind of strange hack—there’s no standard, built-in way in I7 to access the parameter that was passed to a rulebook or activity except by using “called” in the rule preamble! That parameter is stored in a global variable while those rules are being run, much like noun/second/actor for an action, and the “container in question” and “supporter in question” are two special-case phrases that let you access this parameter because there’s no more general way to do it.

1 Like

I’m just going to tie in a general writing idea here because the above examples matches it so well…

One of the techniques for writing dialogue, outlined in The Marshall Plan for Novel Writing is called F-A-D. It stands Feelings, Actions and Dialogue, and describes a natural way to present lines of written dialogue.

First we think or feel something. Then we non-verbally – and often unintentionally – express or communicate those thoughts and feeling through Actions like facial expressions or gestures or behaviors. Finally, we make a decision to verbally communicate (or not), often in an indirect way, with our original thoughts and feelings acting as the subtext for the filtered words that come out of our mouths.

As you can see in the quote above, first the Feelings (or Thoughts) of the Player Character are placed in a Before rule. Then, the Instead rule encapsulates what we imagine to be the Action of the Player Character opening their mouth to speak, and the subsequent reaction of the invigilator. Finally, when the Player Character refuses to read the room, and speaks the Dialogue – presumably in a Report rule that is not presented here – the After rule addresses the shocked reaction of everyone else in the location.

Whether or not all of the F-A-D parts are utilized, stopped, redirected, etc., is up to the interactive nature of the game, but all of the pieces are definitely represented with these action rule examples.

1 Like

I have some confusion regarding Verbs, and this confusion spans two chapters. So, technically, this reply is not just about Relations and Sentence Verbs, but also about Chapter 14. Adaptive Text and Responses: §14.3 More on adapting verbs.

Regarding the Index, and specifically, the Phrasebook Index - 4. Verbs. The description text states:

Screenshot 2024-03-27 at 4.50.09 AM

I am confused by the phrase ‘Verbs listed as “for saying only”…’. Is the phrase “for saying only” supposed to show up in this index somewhere? Because that would be helpful in distinguishing between Sentence Verbs that are connected to a relation and Sentence Verbs that are used for Adaptive Text and Responses. But I don’t see that phrase anywhere.

Here’s what I do see:

For Sentence Verbs that are used for Adaptive Text and Responses, defined like this:

To achieve is a verb.

The index lists them like this:

Screenshot 2024-03-27 at 5.17.07 AM

For Sentence Verbs that are connected to relations (are they actually called “Assertion Verbs”?), defined like this (example from documentation sample code):

Suspicion relates various people to one person.
The verb to suspect means the suspicion relation.
The verb to be suspicious of means the suspicion relation.

The index lists them like this:

Screenshot 2024-03-27 at 5.34.40 AM

Now, I see that to achieve has an ellipses after it and nothing else. Was there supposed to be a “for saying only” string after the ellipses? On the other hand, to suspect does have its associated relation the suspicion relation listed after the ellipses.

So, there is a way to distinguish between these two Sentence Verb scenarios, but there still seems to be some sort of documentation bug. FYI, I’m on a Mac, maybe it is just a Mac problem.

My other point of confusion is what I should be calling these Verbs. Are both “Sentence Verbs” except, in one case, they use an association with a relation and in another case they don’t? Are the Sentence Verbs associated with a relation actually called “Assertion Verbs”? The difference between these two behaviors feels significant enough to warrant more specific names.

Yes, if you test with 9.3 you’ll see this.

I don’t see a bug filed for this – I’ll do that.

1 Like