Breaking disambiguation? "south" vs "starboard" (6M62)

Consider the following:

Lab is a room. 

fore is a direction.
aft is a direction. The opposite of fore is aft. The opposite of aft is fore.

port is a direction.
starboard is a direction. The opposite of port is starboard. The opposite of starboard is port.

Understand "f" as fore. Understand "a" as aft. 
Understand "p" as port. Understand "s" as starboard. 

Does the player mean going starboard when the player's command is "s": It is very likely.
Does the player mean going south: it is very unlikely.

Basketball Court is starboard of Lab.

Now consider the following transcript:

Lab

>s

Basketball Court

>p

Lab

>say eureka
(to yourself)
There is no reply.

>s
Which do you mean, the south or starboard?

>starboard

Basketball Court

>p

Lab

>s
Which do you mean, the south or starboard?

>

“s” is understood as starboard at the beginning, but the disambiguation stops working after “say eureka”. The only thing I can see from tracing is that it seems to be calculating the score for south incorrectly (I assume just ignoring the disambiguation rule) after the “say” command, but correctly before it.

Interleaving good commands (“i”, for instance) resets the south/starboard disambiguation.

Any ideas? Or am I just doing starboard wrong?

1 Like

There might be a better way of doing this, but this works… and leaves no ambiguity to resolve.

ship-dir is initially false.

To decide which snippet is the command verb:
  (- ((verb_wordnum * 100) + 1) -)

Rule for supplying a missing noun when an actor going and "[command verb]" is "s":
  if ship-dir is true, now the noun is starboard;
  else now the noun is south.

Understand the command "s" as something new.
Understand "s" as going when ship-dir is false.
Understand "s" as going when ship-dir is true.

Have you had a look at 3.26 in the Inform docs? (Directions) I see an example there called “Fore” which sets up shipboard directions to work only in ‘nautical’ locations. That appears to be one way of having “S” be south or starboard as required.

-Wade

2 Likes

Unfortunately, that’s not the issue. I have the same logic in the game this issue arose in. :frowning:

It almost works. “go s” is now always interpreted as “go south”

After some more stabs in the dark, I think adding the following might work:

check going south when ship-dir is true and "[player's command]" is "go s":
	try going starboard instead;

and eliminating the line

Understand "s" as starboard.

So it works (I think), but we got to the solution by successive work-arounds, which feels unsatisfying. I’d love to know why the original solution doesn’t work. It feels like a bug in Inform, but I’m not qualified to diagnose those. Perhaps @zarf would know?

The example works (and is better than my solution). There is a bug in it, though, that since inside, outside, up, down are are designated nautical, using them on land gets the “Nautical directions can only be used on board ship.” message. But both “s” and “go s” work by land or by sea.

I wouldn’t recommend this—what happens if the player uses another synonym for “go”, such as “walk”? You basically have to re-implement the parsing for this action in another place, and when that happens it’s very easy for the two different implementations to get out of sync.

That said, I’m not sure why the parser is misbehaving in this case. “Does the player mean” rules are fragile in very strange ways. I’ll see what I can figure out.

A tongue-in-cheek suggestion: ensure your ship is always facing east, so that starboard is south, then make fore, aft, port, and starboard synonyms for east, west, north, and south respectively.

Hey, it worked in Starcross. :laughing:

I agree with Draconis.

Something important to understand is that adding a new direction implies that it is distinct from every other direction.

It’s not clear whether you intend for regular directions like south to be meaningful at all in this example. Do you?

If not, then you can just replace the portion of the Standard Rules defining directions to attack the issue at its core. Here’s a 6M62-compatible method:

Section Nautical Directions (in place of "Section SR1/4 - Directions" in Standard Rules by Graham Nelson

The specification of direction is "Represents a direction of movement, such
as northeast or down. They always occur in opposite, matched pairs: northeast
and southwest, for instance; down and up."

A direction can be privately-named or publicly-named. A direction is usually
publicly-named.
A direction can be marked for listing or unmarked for listing. A direction is
usually unmarked for listing.

A direction has a direction called an opposite.

Include (-
    has scenery, ! class CompassDirection,
-) when defining a direction.


[might want articles here]
There is a direction called fore.
There is a direction called aft.
There is a direction called port.
There is a direction called starboard.

[per original]
The up is a direction.
The down is a direction.
The inside is a direction.
The outside is a direction.

Fore has opposite aft. Understand "f" as fore.
Aft has opposite fore. Understand "a" as aft.
Port has opposite starboard. Understand "p" as port.
Starboard has opposite port. Understand "s" as starboard.

[per original]
Up has opposite down. Understand "u" as up.
Down has opposite up. Understand "d" as down.
Inside has opposite outside. Understand "in" as inside.
Outside has opposite inside. Understand "out" as outside.

The inside object translates into I6 as "in_obj".
The outside object translates into I6 as "out_obj".
2 Likes

That makes sense, but I think starboard and south are distinct, aren’t they? The use of “s” for both doesn’t really change that.

Actually, in the game I’m working on, no. So I think your solution will work fine. Thanks!

After thinking on it a bit more, if you:

  • Want distinct nautical and non-nautical directions, so you can “go south” on land and “go starboard” on a ship and not vice-versa, and
  • Don’t want to use “does the player mean”, since it doesn’t seem to work here,

I would remove the line defining “s” to mean “south” from the Standard Rules (using a replacement), and use a conditional understand line instead.

Definition: we are at sea if the location is nautical.
Definition: we are not at sea if the location is not nautical.

Understand "s" as starboard when we are at sea.
Understand "s" as south when we are not at sea.

Notably, I would only do this for “s”, not any of the others. “N” should still translate into “go north” and then be rejected by game logic, not by the parser. This is exclusively for the ambiguous “s”, which should mean “starboard” on a ship and “south” otherwise.

1 Like

I had begun to experiment with removing “s” before I made any suggestions, and I noted that just saying–

Understand the command "s" as something new.

– on its own, did not stop S from meaning south, the way using the ‘something new’ method would normally kill any other command that did not have an alternate already defined. I couldn’t see a reason for this exception in the Standard Rules, so wondered if it’s some baked-in thing about directions.

EDIT - What I said after this observation was redundant.

-Wade

Bare directions as a command are treated as a special case by the parser. After a bit of housework, the first thing the parser tries to do is to identify the start of the player’s command as a verb it recognises.

Before trying to match a verb, the parser recognises two exceptions to this:

i) if the start of the command is recognised as a direction, it stops parsing and, if the command ends there, generates an action as if ‘go [direction]’ had been typed
ii) if the start of the command is recognised as ‘[object that can be spoken to][comma]’, it sets the potential actor to to be the ‘person asked’ and restarts parsing from after the comma, assuming this to be either a command or conversation directed to said ‘person asked’.

Examples of i) would be ‘s’ or ‘south’
Examples of ii) would be ‘Bob, open the bag’ or ‘Bob, nice weather’

EDIT: there are other small print special cases for other ‘non-verb’ commands such as ‘g’ or ‘again’

2 Likes

The same question was asked on Stack Overflow before:

where I suggested

Does the player mean doing something with south: it is very unlikely.

@Draconis’ method above looks more complete and foolproof though.

Okay, so with the help of this thread, I don’t have the problem anymore, but does anyone have any idea why “say” would break the south/starboard disambiguation? I guess it doesn’t matter much, but I’d like to understand the cause.

Bare directions are handled as a special case by the parser (for historical reasons) and I’m guessing something about the automatic disambiguation on “say” leaves some register or other in a weird state that messes up that special case.

Most variables used by the parser are global (also for historical reasons) so it’s very easy to accidentally leave one in the wrong state between turns. The “answering it that” action is, you guessed it, also a special case for historical reasons, so I wouldn’t be at all surprised if it changed something and failed to set it back afterward. When you take inventory, that’s a nice normal action, which puts all the variables back in their expected state, so parsing works as expected again afterward.

2 Likes

You are spot on. The global in question is ‘action_reversed’, which should be (at least temporarily) reset to false in ‘Parser Letter B’ before calling NounDomain() on the compass, when searching to match the first word of the command to a direction. Doing so fixes this obscure bug.

5 Likes

To apply a fix without resorting to I6 chicanery (by replacing an edited ‘Parser Letter B’), this should work:

action-reversed is a number that varies.
The  action-reversed variable translates into I6 as "action_reversed".
After reading a command:
	now action-reversed is 0.
1 Like

As a partial aside,

Does the player mean going starboard when the player's command is "s": It is very likely.

doesn’t work as intended as Inform in this context doesn’t automatically ‘cast’ (i.e.convert) the player’s command (a snippet) to text before making the comparison, so it’s never equivalent to the text “s” and the rule never applies.

This works, by forcing the conversion of the snippet to text:

Does the player mean going starboard when "[the player's command]" is "s": It is very likely.

In any event, this is probably a better approach to disambiguating ‘s’ or similar abbreviations for directions when required, as a more generic solution to the one in WI (where rooms are labelled as nautical or not):

Does the player mean going starboard when the room south from the location is nowhere:
	It is very likely.
	
Does the player mean going south when the room starboard from the location is nowhere:
	It is very likely.

(this code still works when the rooms are connected by a door, rather than directly)

1 Like