Disambiguation: "X" and "other X"

I am trying to make a very dumb joke that requires two people to have the same name. Let’s call them Mike and Other Mike:

Test chamber is a room.

First-Mike is a person in test chamber.  The printed name is "Mike".  Understand "mike" as first-mike.

Other-Mike is a person in test chamber.  The printed name is "Other Mike".  Understand "other mike/--" as other-mike.

This leads to the following non-helpful results:

>x mike
You see nothing special about Mike.

>x other
You see nothing special about Mike.

>x other mike
You see nothing special about Mike.

This is not ideal! If I add a “does the player mean examining other-mike: it is very likely” rule, I can get X OTHER to find other-mike, but X OTHER MIKE still just finds boring vanilla first-mike. From doing some way-above-my-pay-grade mucking about with higher iterations of the TRACE command, it looks like the trouble is the parser is interpreting “other” as an indefinite article, but I’m not easily finding a way to shift this interpretation.

I assume this is a rock-stupid fix, but after banging my head against this problem for way longer than this very dumb gag deserves, I’m crying uncle and asking for help. Thanks in advance!

1 Like

“Other” is usually used to resolve ambiguities (DM4 p248):

An ⟨other-word⟩ is a word behaving like ‘‘other’’, which Informese understands as ‘‘other than the one I am holding’’. Thus, if the player is holding a sword in a room where there’s also a sword on the floor, then ‘‘examine other sword’’ would refer to the one on the floor.

This behavior is baked into the parser at the I6 level, changing it requires replacing the “Descriptors” routine:

Include (-
[ Descriptors  o x flag cto type n;
    if (wn > num_words) return 0;

    for (flag=true : flag :) {
        o = NextWordStopped(); flag = false;

       for (x=1 : x<=LanguageDescriptors-->0 : x=x+4)
            if (o == LanguageDescriptors-->x) {
                flag = true;
                type = LanguageDescriptors-->(x+2);
                if (type ~= DEFART_PK) indef_mode = true;
                indef_possambig = true;
                indef_cases = indef_cases & (LanguageDescriptors-->(x+1));

                if (type == POSSESS_PK) {
                    cto = LanguageDescriptors-->(x+3);
                    switch (cto) {
                      0: indef_type = indef_type | MY_BIT;
                      1: indef_type = indef_type | THAT_BIT;
                        indef_owner = PronounValue(cto);
                        if (indef_owner == NULL) indef_owner = InformParser;

                if (type == light)  indef_type = indef_type | LIT_BIT;
                if (type == -light) indef_type = indef_type | UNLIT_BIT;
        ! if (o == OTHER1__WD or OTHER2__WD or OTHER3__WD) {
        !     indef_mode = 1; flag = 1;
        !     indef_type = indef_type | OTHER_BIT;
        ! }
        if (o == ALL1__WD or ALL2__WD or ALL3__WD or ALL4__WD or ALL5__WD) {
            indef_mode = 1; flag = 1; indef_wanted = INDEF_ALL_WANTED;
            if (take_all_rule == 1) take_all_rule = 2;
            indef_type = indef_type | PLURAL_BIT;
        if (allow_plurals) {
        	if (NextWordStopped() ~= -1 or THEN1__WD) { wn--; n = TryNumber(wn-1); } else { n=0; wn--; }
            if (n == 1) { indef_mode = 1; flag = 1; }
            if (n > 1) {
                indef_guess_p = 1;
                indef_mode = 1; flag = 1; indef_wanted = n;
                indef_nspec_at = wn-1;
                indef_type = indef_type | PLURAL_BIT;
        if (flag == 1 && NextWordStopped() ~= OF1__WD or OF2__WD or OF3__WD or OF4__WD)
            wn--;  ! Skip 'of' after these
    return 0;

[ SafeSkipDescriptors;
	@push indef_mode; @push indef_type; @push indef_wanted;
	@push indef_guess_p; @push indef_possambig; @push indef_owner;
	@push indef_cases; @push indef_nspec_at;
	@pull indef_nspec_at; @pull indef_cases;
	@pull indef_owner; @pull indef_possambig; @pull indef_guess_p;
	@pull indef_wanted; @pull indef_type; @pull indef_mode;
-) instead of "Parsing Descriptors" in "Parser.i6t".

(Doing this will of course remove that option for disambiguation, which may or may not be an issue in your game.)

1 Like

That did it – thanks for this (and the warning about what it might muck up later)!

It actually won’t mess up anything. The associated functionality is disabled in 6M62’s version of ScoreMatchL():

[ ScoreMatchL context its_owner its_score obj i j threshold met a_s l_s;
!   if (indef_type & OTHER_BIT ~= 0) threshold++;
    if (indef_type & MY_BIT ~= 0)    threshold++;
    if (indef_type & THAT_BIT ~= 0)  threshold++;
    if (indef_type & LIT_BIT ~= 0)   threshold++;
    if (indef_type & UNLIT_BIT ~= 0) threshold++;
    if (indef_owner ~= nothing)      threshold++;

    !      if (indef_type & OTHER_BIT ~= 0
    !          &&  obj ~= itobj or himobj or herobj) met++;
    if (indef_type & MY_BIT ~= 0 && its_owner == actor) met++;
    if (indef_type & THAT_BIT ~= 0 && its_owner == actors_location) met++;
    if (indef_type & LIT_BIT ~= 0 && obj has light) met++;
    if (indef_type & UNLIT_BIT ~= 0 && obj hasnt light) met++;
    if (indef_owner ~= 0 && its_owner == indef_owner) met++;

Note that the lines referencing OTHER_BIT are all commented out.

EDIT: Uh oh – wait, it’s not entirely disabled, just for the case that @ArdiMaster was pointing out, I think. I’ll see if I can figure out what “other” still does.


I think that the only thing that the word “other” functionally does any more is put the parser into indefinite mode, and to consume the word from player input. That interferes with your own parsing of Other Mike, unless the functionality was disabled as per @ArdiMaster’s example. Another way to excise that is to remove OTHER2__WD and OTHER3__WD from the parser code. (The sole and questionable advantage being to retain the current functionality of the word “another” in player input.)

(For more on the key phrases used, see WWI 17.17 Understanding when.)

"Other Mike"

Test Chamber is a room.

Understand "person" as a person.

First-Mike is a person in test chamber.  The printed name is "Mike".  Understand "first" or "mike" or "first mike" as First-Mike.

Other-Mike is a person in test chamber.  The printed name is "Other Mike". 

Understand "other" or "other mike" as Other-Mike.

Understand "mike" as Other-Mike. [this version results in prompting, which I think you want to retain]

[Understand "mike" as Other-Mike when the player can see Other-Mike and the player cannot see First-Mike.] [that version makes just "mike" mean First-Mike when both are present]

Test me with "x mike / other / x mike / first / x other mike / x first mike".


! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
! Language.i6t: Vocabulary (modified)
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====

Constant AGAIN1__WD     = 'again';
Constant AGAIN2__WD     = 'g//';
Constant AGAIN3__WD     = 'again';
Constant OOPS1__WD      = 'oops';
Constant OOPS2__WD      = 'o//';
Constant OOPS3__WD      = 'oops';
Constant UNDO1__WD      = 'undo';
Constant UNDO2__WD      = 'undo';
Constant UNDO3__WD      = 'undo';

Constant ALL1__WD       = 'all';
Constant ALL2__WD       = 'each';
Constant ALL3__WD       = 'every';
Constant ALL4__WD       = 'everything';
Constant ALL5__WD       = 'both';
Constant AND1__WD       = 'and';
Constant AND2__WD       = 'and';
Constant AND3__WD       = 'and';
Constant BUT1__WD       = 'but';
Constant BUT2__WD       = 'except';
Constant BUT3__WD       = 'but';
Constant ME1__WD        = 'me';
Constant ME2__WD        = 'myself';
Constant ME3__WD        = 'self';
Constant OF1__WD        = 'of';
Constant OF2__WD        = 'of';
Constant OF3__WD        = 'of';
Constant OF4__WD        = 'of';
Constant OTHER1__WD     = 'another';
Constant OTHER2__WD     = 'x,y'; ! "untypeable" -- see DM4 for details
Constant OTHER3__WD     = 'x,y'; ! "untypeable"
Constant THEN1__WD      = 'then';
Constant THEN2__WD      = 'then';
Constant THEN3__WD      = 'then';

Constant NO1__WD        = 'n//';
Constant NO2__WD        = 'no';
Constant NO3__WD        = 'no';
Constant YES1__WD       = 'y//';
Constant YES2__WD       = 'yes';
Constant YES3__WD       = 'yes';

Constant AMUSING__WD    = 'amusing';
Constant FULLSCORE1__WD = 'fullscore';
Constant FULLSCORE2__WD = 'full';
Constant QUIT1__WD      = 'q//';
Constant QUIT2__WD      = 'quit';
Constant RESTART__WD    = 'restart';
Constant RESTORE__WD    = 'restore';

-) instead of "Vocabulary" in "Language.i6t".
1 Like