Go North vs Go Through Door

Hello. I’m fairly new to Inform 7, and still coming to grips with it.

Can anyone tell me why this Report rule doesn’t fire when the player types “go through the mysterious door”?

The Silent Dungeon is a room.
Description is "You are in the Silent Dungeon. How will you ever escape?"

The player is in the Silent Dungeon.

The Sunny Field is a room.
Description is "You are in a Sunny Field. That was easier than I thought."

The Mysterious Door is a Door.
The Mysterious Door is north of the Silent Dungeon and south of the Sunny Field. It is open.

Report going north from the Silent Dungeon:
	say "Executing the 'Report going north from the Silent Dungeon' rule.";
	make no decision.

Since the player has to go north when they go through the door, I thought it would fire. It does fire when the player types “go north”.

However, if I define the rule like this:

Report going through the Mysterious Door from The Silent Dungeon:
	say "Executing the 'Report going through the Mysterious Door from The Silent Dungeon' rule.";
	make no decision.

it fires whether the player types “go north” or “go through the mysterious door”. Which makes sense to me. If you are going north you have to go through the Mysterious Door, so the rule fires. But why doesn’t the first example work the same way? If you go through the Mysterious Door you are going north.

Any help appreciated.

Thanks,
Davf

If you type ‘actions’ while testing your scenario, it will afterwards help you by showing which actions Inform is generating in response to your typed commands.

In this instance:

Silent Dungeon
You are in the Silent Dungeon. How will you ever escape?

You can see a Mysterious Door here.

>actions
Actions listing on.

>n
[going north]
Executing the "Report going north from the Silent Dungeon" rule.

Sunny Field
You are in a Sunny Field. That was easier than I thought.

You can see a Mysterious Door here.

[going north - succeeded]

>s
[going south]

Silent Dungeon
You are in the Silent Dungeon. How will you ever escape?

You can see a Mysterious Door here.

[going south - succeeded]

>go door
[entering the Mysterious Door]
[(1) going the Mysterious Door]

Sunny Field
You are in a Sunny Field. That was easier than I thought.

You can see a Mysterious Door here.

[(1) going the Mysterious Door - succeeded]

[entering the Mysterious Door - succeeded]

>s
[going south]

Silent Dungeon
You are in the Silent Dungeon. How will you ever escape?

You can see a Mysterious Door here.

[going south - succeeded]

>enter door
[entering the Mysterious Door]
[(1) going the Mysterious Door]

Sunny Field
You are in a Sunny Field. That was easier than I thought.

You can see a Mysterious Door here.

[(1) going the Mysterious Door - succeeded]

[entering the Mysterious Door - succeeded]

which shows you that typing ‘n’ generates a going north action, but typing ‘go [through] [the] [mysterious] door’ or ‘enter [the] [mysterious] door’ first generate a entering the Mysterious Door action, which is subsequently converted to a going the Mysterious Door action- hence Report going north... does not fire.

EDIT 2: in detail The reason Report going north... does not fire is that, although a [going …] action is generated, so the ‘Report going…’ rulebook is run through, the object of the action is the Mysterious Door and ‘north’ never comes into it.
Conversely, the reason Report going through the Mysterious Door... does fire when the action is [going north] is that when [going a direction] involves a door (as well as when the action is [going a door]), the action variable the door gone through is set to that door, and this is used to match action patterns like ... going through ... in subsequent rule definitions of the going action.

This behaviour is defined in the Standard Rules here:

The going action has an object called the door gone through (matched as "through").

which is essentially saying “when parsing action patterns during processing of the [going] action, match ‘… through something …’ against the object represented by ‘the door gone through’”. ‘(matched as “through”)’ just creates syntactic sugar, allowing the writing of neater rules like Report going through *a door* rather than the equivalent Report going when the door gone through is *a door*.

Similarly, there are action variables ‘the room gone from’ (matched as “from”) and ‘the room gone to’ (matched as “to”), so that convoluted rules like `Report going when the room gone from is the Silent Dungeon and the room gone to is the Sunny Field and the door gone through is the Mysterious Door…’ can be condensed into ‘Report going from the Silent Dungeon to the Sunny Field through the Mysterious Door…’

See Writing with Inform §12.10. Action variables

EDIT 3:
So in summary:
Report going through *a door*... will fire in response to any of ‘go a direction’ or ‘go a door’ or ‘go through a door’ or ‘enter a door’;
Report going *a direction*... will fire in response to ‘go a direction’ but NOT ‘go a door’ or ‘go through a door’ or ‘enter a door’;
Report going *a door*... will fire in response to ‘go a door’ or ‘go through a door’ or ‘enter a door’ but NOT ‘go a direction

small print
Interestingly, the Standard Rules extension, where all this is taking place, uses an undocumented syntax to convert one action to another, e.g.:

Check an actor entering (this is the convert enter door into go rule):
	if the noun is a door, convert to the going action on the noun.

rather than the documented try the actor going the noun syntax.

The result of using this undocumented syntax is that although the original action may be recorded as succeeding if the action it is converted to succeeds (as in the above transcript), it is nevertheless aborted immediately after the convert..... phrase- so if, as in the example above, the conversion takes place during the Check stage, the Carry Out, After and Report rules of the original action do not run.

The end result is similar to the documented syntax of

try the actor going the noun;
stop the action;

EDIT: this undocumented syntax is defined in the Standard Rules here:

To convert to (AN - an action name) on (O - an object):
	(- return GVS_Convert({AN},{O},0); -) - in to only.
To convert to request of (X - object) to perform (AN - action name) with
	(Y - object) and (Z - object):
	(- return ConvertToRequest({X}, {AN}, {Y}, {Z}); -).
To convert to special going-with-push action:
	(- return ConvertToGoingWithPush(); -).
3 Likes

Thanks very much for that.

Regarding your summary:

So in summary:
Report going through *a door*... will fire in response to any of ‘go a direction’ or ‘go a door’ or ‘go through a door’ or ‘enter a door’;
Report going *a direction*... will fire in response to ‘go a direction’ but NOT ‘go a door’ or ‘go through a door’ or ‘enter a door’;
Report going *a door*... will fire in response to ‘go a door’ or ‘go through a door’ or ‘enter a door’ but NOT ‘go a direction

It sounds like if we have doors defined in our games, and we need rules that fire when moving from one room to another, we should all be using “going through a door” in our rule definitions, not “going a door”, or “going a direction”.

It would be great if that was spelled out very clearly in the documentation somewhere! If it was there I didn’t find it. :slightly_smiling_face:

Regards,
Davf

Yes, it’s half-mentioned sort of in passing in §7.14. Going by, going through, going with: (Note that these apply whether the action is "going east" or "entering the green baize door", each having the same effect.) but without spelling the nuances out with the clarity one might wish…

For example, Report going north through the Mysterious Door... is not going to fire in response to ‘enter the Mysterious Door’… because the action generated would be ‘going Mysterious Door’ with action variables represented by (from Silent Dungeon) (to Sunny Field) (through Mysterious Door). To have this reliably fire in response to all typed variations of ‘go/enter’ but for one direction of travel only, one would need to write e.g. Report going from the Silent Dungeon through the Mysterious Door...

I’ll make sure I do that from now on.

Thanks again,
Davf

Here’s a little example of setting an action variable that allows rules such as Report going through the Mysterious Door heading north... that respond to any valid typed variation of ‘go/enter through/-- a direction/ a door’:

The going action has an object called heading (matched as "heading").
Last rule setting action variables for going: [need to have already set the door gone through and the room gone from before reaching this rule]
	if the noun is a direction: [for cases such as 'go north']
		now heading is the noun;
	else:
		if the door gone through is not nothing: [for cases such as go/enter through/-- *a door*]
			repeat with D running through directions:
				if the door gone through is the door D from the room gone from:
					now heading is D;
					break;
2 Likes

This thread has gotten into some technical stuff, but it’s worth also giving the simple answer!

You want one of the commands GO THROUGH DOOR and GO NORTH to be converted into the other, so that you can write a single rule that catches both.

But you don’t want each command to be converted to the other one, because then you’ve got an infinite loop! So you, or actually Graham Nelson, has to pick one to be the “fundamental” command – the one that all the others resolve to. It happens to be GO THROUGH DOOR.

3 Likes

I’m not sure this is quite the right way to describe what’s going on.

There are 2 sorts of typed command: GO/ENTER THROUGH/-- DOOR, GO DIRECTION which resolve to the same game effect- moving the actor to the ‘other side’ of the door- but they resolve to 2 different actions: ‘going door’ and ‘going direction’. These 2 different actions can be resolved to a single action pattern in Report (or other) rules using ‘… going through a door…’, but this is achieved by setting ‘the door gone through’ action variable for both actions, not by converting one type of command/action to the other.

That the wording of ‘…going through a door…’ in action patterns for rules happens to be the same as one of the sorts of typed command that ends up matching it (GO THROUGH DOOR) is not a given- the latter is a function of the parser generating an action from the typed command, the former derives from ‘(matched by “through”)’ in the declaration of ‘the door gone through’ action variable and it could equally have been ‘(matched by “via”)’ or ‘(matched by “traversing”)’

A neat idea, and definitely a quality of life improvement for authors.

The only minor downside is the looping through all directions to find the one corresponding to the door. That can be avoided with a minor I6 inclusion.

To decide which direction is the apparent direction of (D - door):
    (- ({D}.door_dir()) -). [a remnant of older functionality useful in this case]

As you point out, the machinery of going is different in I7’s Standard Rules than it is in the I6 Standard Library. There’s apparently a redundant rule (the determine map connection rule, which seems to be only repeating some of the functionality of the standard set going variables rule). The actual relocation happens via the move player and vehicle rule, which makes use of the action variable room gone to to determine the new location.

That means that it’s fine to change the noun after room gone to is set, so:

"The Logic of Going"

Place is a room.

A door called a sturdy door is east of Place.

Other Place is east of the sturdy door.

Yet Another Place is north of Place.

To decide which direction is the apparent direction of (D - door):
    (- ({D}.door_dir()) -). [a remnant of older functionality useful in this case]

The going action has an object called the direction gone (matched as "heading").

Last setting action variables for going (this is the ensure direction is noted when heading through doors rule):
    if the noun is a direction:
	    now direction gone is the noun;
    otherwise if the noun is a door:
	    now direction gone is the apparent direction of the noun;
	    now the noun is direction gone;
    otherwise:
	    now direction gone is nothing.

After going: [heading seems to always work]
    say "<heading = [direction gone]>[line break]";
    continue the action.

After going through a door: [seems to work whether going direction or entering door]
    say "<door traversed>[line break]";
    continue the action.

After going east: [could just as well use "... heading ..." or "... direction gone through is ..."]
    say "<eastward travel>[line break]";
    continue the action.

The determine map connection rule is not listed in any rulebook. [doesn't seem to be missed]

Bob is a man in Place.

Definition: A direction is Bob-valid if the room-or-door it from the location of Bob is not nothing. [kludgey but quick]

Every turn:
    let D be a random Bob-valid direction;
    try Bob going D.

[all the waiting is to try to catch Bob coming through both the doored and non-doored entrances]
Test me with "n / s / e / w / go through door / g / z / z / z / z / z / z / z / z / z / z / z / z".
3 Likes

No, it’s the simple answer to explain to newcomers why Inform works the way it does.

I appreciate people taking the trouble to give the technical explanation, but the simple answer is all I really need at the moment!

Thanks everyone,
Davf

Well, perhaps that explanation is simple- but it’s also incorrect, or at best misleading.

The workings of this in Inform are not to do with converting commands or actions to one single ‘fundamental command’, avoiding infinite loops (although it could in theory have been coded that way). That explains why both ‘Report going north…’ and ‘Report going Mysterious Door…’ still catch some but not all of the relevant commands- because ‘going direction’ and ‘going door’ both make it through to the Report stage as valid actions. ‘Report going through door…’ is simply designed in such a way as to catch both types of action.

Better to say ‘you don’t necessarily need to understand how this works under the hood, but this is how to write your Report rule so it does what you want’ than offer a misleading justification, imho.

A simple if superficial explanation, avoiding talk of converting commands, is just to say that Inform has a special syntax for catching all typed commands to ‘go a direction’ (when that direction leads through a door), ‘enter a door’, ‘go through a door’ or ‘go a door’ and that syntax is ‘Report going through a door…’. But the thread author had already discovered that, and was rather asking why ‘Report going north…’ didn’t behave as expected.