Put a thing on a soft thing automatically in I7

I’m trying to modify example 97 (Ming Vase) so that if there is a “soft thing” in the room, a fragile object will be dropped on it. But I can’t get it to work. Code for my object set up:

A Ming vase is in the Office.
The Ming vase is fragile.

A porcelain sculpture is in the Office.
The porcelain sculpture is fragile.

A pillow is in the Office.
The pillow is a portable supporter.
The pillow is soft.

A cushion is in the Office.
The cushion is a soft portable supporter.

Here’s the code for handling the dropping:

A thing can be soft or hard.
A thing is usually hard.

A thing can be strong or fragile.
A thing is usually strong.

Instead of attacking or dropping a fragile thing:
	now the noun is nowhere;
	say "[The noun] breaks into pieces."

Instead of dropping a fragile thing when a soft thing is in the location:
	try putting the noun on the soft thing instead.

After putting a fragile thing on a soft thing:
	say "You set [the noun] down gently on [the second noun]."

The problem is the second instead rule. You can’t say “try putting the noun on the soft thing” – you are told it’s too vague. So then I tried changing that to this:

Instead of dropping a fragile thing when a soft thing is in the location:
	try putting the noun on the second noun instead.

But that doesn’t work because then if I try “drop sculpture” (when the cushion is on the ground), I get this:

I get why that’s happening. But I’m not sure how to word this instead rule.

Ah, wait. I tried this:

Instead of dropping a fragile thing when a soft thing (called the item) is in the location:
	try putting the noun on the item instead.

That seems to work.

I notice that you say ‘instead’ in that rule twice. I wonder if that might be a problem?

Also, could it be that there is more than one soft thing in the location, and you need to be more specific?

Maybe you should say something like–

Instead of dropping a fragile thing when a soft thing is in the location: say "Rather than dropping that here, you wonder whether you should put it on something soft..??"

Hope this is helpful.

The problem with your original code is that Inform does not know how to understand “the soft thing”. Clearly you intend it to refer to something that matches “a soft thing” in the rule preamble. But Inform doesn’t know that, and so “the soft thing” doesn’t seem to refer to a unique object.

This works:

Instead of dropping a fragile thing when a soft thing (called the cushion) is in the location:
	try putting the noun on the cushion instead.

By the way, if the soft thing is not a supporter, then this “try putting the noun on” will fail. So if you have soft non-supporter things, you’ll need to write a rule about that.

Interesting point. That’s exactly how it is in the documentation example. “Ming Vase” reads:

Instead of dropping a fragile thing when the pillow is in the location: try putting the noun on the pillow instead.

Two "instead"s. I didn’t even really think about it. I removed the second “instead” and everything works still, but, yeah, interesting catch.

oops I goofed.

Also, as jrb suggests, instead of saying ‘soft thing’, or ‘fragile thing’, say

Check dropping something: if the noun is fragile: if there is something which is soft in the location: instead say "Why don't you try putting that onto something soft?"

You created ‘soft’ and ‘fragile’ as properties–which explains the ‘which is’ in my example–which cannot be referred to as ‘a fragile thing’ or ‘a soft thing’. One option is that you can create these things as kinds.

A softie is a kind of thing. The pillow and the cushion are softies. A breakable is a kind of thing. The vase and the sculpture are breakables.

An “instead of” rule is, strictly speaking, a rule that is followed during the “instead of” rulebook. This rulebook happens whenever the player tries an action, after the “before” rulebook (which is the first rulebook to be consulted for an action) and before the “check” rulebook (which is for rules that block actions that you’d like to be generally illegal, like trying to take something already held).

The thing about rulebooks is that they must end with either success or failure. Success means you move on to the next rulebook for the action. Failure means you stop the action completely. The “instead of” rulebook is defined so that any rule placed in it will automatically generate a failure outcome, and hence stop the action. This is why your rule works as intended and replaces the normal functionality of dropping something.

The phrase “instead,” meanwhile, is simply shorthand for “and stop the action.” “Say X instead,” means the same thing as “Say X; stop the action,” or even “Say X; rule fails.” When Inform 7 encounters any if these phrases, it ends the rule, and the rulebook, in a failure outcome, regardless of the default outcome of the rulebook. This means we can write something like Before doing something: say "You wouldn't even dream of doing that!" instead. and it will function similarly to an “instead of” rule. Conversely, if we write Instead of doing something: say "Okay, well..."; continue the action. the action will, as stated, continue to the next rule.

To conclude, writing “Instead of X: Do X instead,” is redundant, since any “instead of” rule will stop the action by default. Nevertheless, Emily Short might have gotten in the habit of writing this way to confirm that every rule has a defined outcome and works as she intends it to, instead of defaulting to the rulebook’s definition.

Are you sure? Referring to a “male person” or a “fixed in place thing” works as far as I know.

Actually, CKY, I am not sure, thank you for pointing that out. So far I have written only one game–I posted a question about a new game(which you responded to) and was looking over this board and thought I could help. Maybe I should leave that to the experts…

No worries. There’s no shame in being mistaken, and getting corrected is the best way to learn.

RIDICULOUS NITPICK AHEAD

There’s actually an extremely subtle difference between “rule fails” on the one hand and “instead” and “stop the action” on the other hand:

This almost never should make a difference for any practical purpose. It only came up for me because I was doing something fancy where I had to call a custom rulebook, pass its results to another custom rulebook, and then use the “if rule failed” test to check whether that rulebook had done anything. Code here using this extension, in case anyone wants to look.

But again, it’s very unlikely that you’ll encounter a case where this makes a practical difference.

Only problems you might run into:

If you have a situation where the player or the soft thing is inside a closed container, the parser will accomplish this action even though it shouldn’t be possible.

Check dropping a fragile thing (called F): if the player can touch a soft supporter: try putting F on a random touchable soft supporter instead.

I specify “supporter” because if you declare something soft that is not a supporter it could cause a compiler error. Using “check” rather than “instead” lets inform run its accessibility rules to prevent the player from putting a fragile object on a soft object they cannot actually reach. IFAddicted used a check in a previous suggestion but I just wanted to point out why. :smiley: