[I7] change the printed name of one instance of a kind, based on location?

For example, if I had:

A fruit is a kind of thing.
The player holds a fruit called an apple. The player holds a fruit called an orange. The player holds a cucumber.

The box of fruity obscuration is an open container.

how would I go about printing the name as “mystery fruit”, only when it’s in the container? This looks like it should work:

Rule for printing the name of a fruit:
    if the fruit is in the box of fruity obscuration, say "mystery fruit" instead.

…but instead, when ANY fruit is in the box, ALL fruits have the printed name “mystery fruit”. How do I disambiguate?

It’s worse than that; if no fruit is in the box then your rule will not print the name of any fruit, due to the default behaviour of rules (you didn’t make no decision in the other case).

You can fix both of those problems with this:

Rule for printing the name of a fruit when the item described is in the box of fruity obscuration:
	say "mystery fruit".

This unfortunately does also affect the message printed when reporting putting a fruit into the box (it’s already a mystery fruit), since the report rules fire after the carry out rules (and so the fruit is already in the box).

In theory you should be able to fix this by checking if the item described was in the box, but this appears to upset Inform for some reason.

2 Likes

You could eschew the entire idea of naming the fruits in the source. That would make them identical objects. Then, you could give them a text property, which you understand them as when they are not in the box, and have them print properly.

Or a simpler idea still: give each fruit a “mystery fruit” (Every fruit has a mystery fruit.). The mystery fruit is a subkind. Anytime you insert a fruit into the box, swap them. Every time you take a mystery fruit from the box, swap back.

I find that swapping items around is never the simple path. You have to update “it” pronouns manually, and you can run into other issues like misfired history tracking and state being attached to the wrong object.

2 Likes

The past tense stuff only works with specific things, not variables. (Presumably because that would require remembering the past location of every fruit.)

It would be possible to manually track whether a fruit was in the box at the start of the turn. (For example, a fruit can be initially boxed. Have an every turn rule that sets all the fruit in the box to initially boxed. When removing fruit from the box, make it not initially boxed.)

But if it’s just one box, it’s probably simpler to override the report rule for inserting fruit into the box.

You could do this.

There is a room.
A fruit is a kind of thing.

A fruit is a kind of thing.
The player holds a fruit called an apple. The player holds a fruit called an orange. The player holds a cucumber.

The box of fruity obscuration is an open container.

Rule for printing the name of a fruit (called the f) while listing contents of the box of fruity obscuration:
	say "mystery fruit" instead.

The box of fruity obscuration is an open container. It is here.

It still leaves the fact that if you put both fruits into the box, you are told it’s a mystery fruit and a mystery fruit (which reads a bit oddly). That, I think, could be solved by grouping them and then handling the printing that way. And you’d have to override the understanding.

The core problem that you’re facing is pretty deep in 6M62: The parse_name routines that are generated will automatically avoid declaring objects of the same kind as “indistinguishable” (see DM4 pp.212-213) under the old I6 rules. There’s a seemingly hardcoded line:

if (parser_action == ##TheSame) return 0;

near the top of each generated parse_name, and what you want is to return -1 when the fruits are in the box.

That said, perhaps it can be worked around.

"Mystery Fruit Hack" by "Otis"

Playground is a room.

A fruit is a kind of thing.   

Understand "fruit" as a fruit. [forces generation of parse_name for kind]

Include (- with orig_parse_name, -) when defining a fruit. [to hold originally-generated parse_name routine]

Definition: A fruit is mysterious if it is in the box of fruity obscuration.

Rule for printing the name of a mysterious fruit:
	say "mystery fruit".

Rule for printing the plural name of a mysterious fruit:
	say "mystery fruits".

The player holds a fruit called an apple. The player holds a fruit called an orange. The player holds a cucumber.

The box of fruity obscuration is an open container. It is in Playground.

Include (-

[ AltFruitParse ;
	if (parser_action == ##TheSame && (+ mysterious +)(self))
		return -1;
	else
		return self.orig_parse_name();
];

[ ModParse o ;
	objectloop(o ofclass (+ fruit +))
		{
			o.orig_parse_name = o.parse_name;
			o.parse_name = AltFruitParse;
		}
];
-).

To modify parse routine:
	(- ModParse(); -).

When play begins:
	modify parse routine.
	
Test me with "i / put all in box / look / take orange / x box".

which yields:

>[1] i
You are carrying:
  an apple
  an orange
  a cucumber

>[2] put all in box
apple: Done.
orange: Done.
cucumber: Done.

>[3] look
Playground
You can see a box of fruity obscuration (in which are a cucumber and two mystery fruits) here.

>[4] take orange
Taken.

>[5] x box
In the box of fruity obscuration are a cucumber and a mystery fruit.

You don’t need to dip into I6 for that; this does the trick:

There is a room.

A fruit is a kind of thing.
The player holds a fruit called an apple.
The player holds a fruit called an orange.
The player holds a cucumber.

The box of fruity obscuration is an open container.  It is here.

Rule for printing room description details of the box of fruity obscuration:
	if the box of fruity obscuration contains a fruit:
		say " (in which ";
		list the contents of the box of fruity obscuration, as a sentence, prefacing with is/are;
		say ")";
		omit contents in listing.

Before listing contents of the box of fruity obscuration:
	group fruit together.

Rule for printing the name of a fruit while listing contents of the box of fruity obscuration:
	say "mystery fruit".
	
Rule for grouping together fruit while listing contents of the box of fruity obscuration:
	say "[listing group size in words] mystery fruit".
	
Test me with "i / put orange and cucumber in box / x box / put apple in box / x box / l"

(I don’t know if there’s a more elegant way to do the room description details rule – without that, everything works for x box but it would still print the actual fruit names in the room description. But adding that does fix it as is.)

Of course, in order for the player to actually do anything with these mystery fruit, they’d need to remember what they were (or have some other means of emptying the box, such as tipping it over). If you add these:

Understand "fruit" as a fruit.
Understand "mystery" as a fruit when the item described is in the box of fruity obscuration.

Then it will work as expected – until there’s two or more fruit in the box, at which point Inform “helpfully” de-mystifies them for you:

> get mystery fruit
Which do you mean, the apple or the orange?

Perhaps this is a feature rather than a bug? :laughing:

(You can also get all mystery fruit, which also reveals the names – but that’s after you’ve taken them, which seems fair enough.)

Ok, this part does require dipping into I6, because the necessary list isn’t exposed by default:

Include (-

[ LIST_OF_TY_Mal list len i;
	if ((list==0) || (BlkValueWeakKind(list) ~= LIST_OF_TY)) return 0;
	len = number_matched;
	LIST_OF_TY_SetLength(list, len);
	for (i=0: i<len: i++)
		LIST_OF_TY_PutItem(list, i+1, match_list-->i);
	return list;
];

-).

To decide what list of objects is the disambiguation list:
	(- LIST_OF_TY_Mal({-new:list of objects}) -).

Rule for asking which do you mean:
	let L be the disambiguation list;
	repeat with T running through L:
		if T is a fruit and T is in the box of fruity obscuration:
			say "The fruit in the box of fruity obscuration are too mysterious to be handled individually." instead;
	continue the action.

Now, if a fruit in the box is involved in any disambiguation, it’ll print a rejection rather than revealing the names. But you can still get all mystery fruit – and if you happen to know that there’s an orange in there, then you can still refer to it individually. (There’s ways that could be prevented too, but it doesn’t seem unreasonable.)


If you’re going to be messing with disambiguation a lot, it might be worth considering use of Disambiguation Control by Jon Ingold; for example the below behaves similarly to the above (except that it has a less friendly error message; I’m not sure how to fix that):

Include Disambiguation Control by Jon Ingold.

Should the game choose doing something to a fruit (called the mystery) when the mystery is in the box of fruity obscuration:
	if the player's command includes "all", it is a passable choice;
	never.

@mirality, nice solution. I’ve clearly been reading too much DM4 and not enough WWI lately!

How about

Rule for printing the name of a fruit when doing something other than 
inserting and the item described is in the box of fruity obscuration:
	say "mystery fruit" instead.