(Again) multiple objects. [I7] (SOLVED!)

So I had this brilliant idea of using multiple objects in a game. Cool. G**damn me.

I made these *Gems. I’m actually able to do whatever to them, thanks to help from various people here.

Now: I have one of those *Gems “part of” an object. If I try and take the *gem normally, it gives the response I coded (“It’s stuck in the object! OMG!”).

If I try and take it (TAKE GEM, because those are all the same object in the end) when I’m holding another gem, the game only succeeds in tryin’ and taking the one I’m holding.

What now?

I hope I explained myself, in case, feel free to bash me.

Thanks!

Inform will always assume you mean a takeable thing rather than a non-takeable thing when the player’s command is ambiguous. Since the gems all have identical synonyms, the command TAKE GEM will always be ambiguous, so Inform will always assume you mean the one that’s not part of something.

You might try a “does the player mean” rule:

Does the player mean taking a gem that is not carried by the player: it is very likely.

I don’t have a chance to test that, and messing with “does the player mean” can sometimes be an inexact science, but I think that rule should override Inform’s normal reluctance to try taking parts of things.

Understatement of the year. :slight_smile:

The parser didn’t even realize I added this line of code.

I’ve tried many variations of the Does the player… to no avail. I suppose the solution is somewhere else. Maybe faking the object being part of and just having it lying there…

Dunno.

Thanks for the help, anyway.

Actually, wouldn’t it be sensible for the default behaviour to be altered? For most actions, assuming the player means something they’re carrying rather than something they’re not does seem best… but the obvious example is for the “taking” action.

Maybe this could/should be changed? In Inform’s default, unchanged parser? So that “taking” would always prefer something the player isn’t carrying (I’m not saying “enclosing” because if the player has a holdall and there are gems in there, maybe it does make sense to get the gem out of the holdall), but everything else would prefer something he/she/they is/are?

Okay, here’s a slightly more complex (but probably better) solution:

[code]Test Room is a room.

A gem is a kind of thing.

A gem can be embedded or loose. A gem is usually loose.
Understand “stuck” as embedded. Understand “free” as loose.
Understand the embedded property as describing a gem.

Before printing the name of a gem while clarifying the parser’s choice of a gem, say "[if embedded]embedded [otherwise]loose “.
After printing the name of a gem (called G) while clarifying the parser’s choice of a loose gem:
if G is carried by the player, say " that you are carrying”;
if an embedded gem (called EG) is visible, say “, not the gem stuck in [the random thing that incorporates EG]”.

Understand “in/from/out of/-- [something related by reversed incorporation]” as a gem.

A boulder is here. “A giant boulder rests nearby. Embedded in the stone’s side is a gem.” The boulder incorporates an embedded gem.

Instead of taking a gem that is part of something, say “It’s stuck in [the random thing that incorporates the noun]! OMG!”

The player carries a gem.

test me with " i / take gem / take stuck gem / take embedded gem / take gem out of boulder / take embedded gem from boulder / take the gem stuck in the boulder / drop gem / take gem"
[/code]

This uses techniques described in sections 17.15 - 17.16 in the documentation. The “before/after printing the name” rules help clarify what the parser is doing and give the player hints on how to refer to the stuck jewel. You’ll have to remember to make gems that are part of something “embedded”, and if you give the player some way of acquiring embedded gems (like a miner’s pick or whatever), you’ll have to remember to set the gems to “loose” when that happens.

EDIT: fixed the instead rule so that it mentions whatever the gem is stuck in, rather than just the boulder.

Also, bear in mind that things will swiftly get much more complicated if you have more than one gem embedded in a single object, or multiple gems embedded in mulitple objects in the same room.

Well, this is odd. I was going to tell Peter that for taking, the parser does prefer taking something you’re not holding, as you can see if you modify Mike’s example to put a gem on the floor. But it prefers taking something you’re holding over taking something that’s part of something else.

But that’s not strictly true. If you’re holding two gems, then it prefers taking the gem that you’re not holding, even though it’s part of something else. That is most mysterious behavior.

Anyway, I thought it might be friendly to automatically redirect an attempt to take a gem that you’re carrying to a visible gem, even if it’s embedded. I did something like that in Tea and Toast where the game would try to make you fill the same teacup over and over unless I grabbed it by the nose and forced it toward a better choice.

But… in this case, when I tried to redirect the taking action using a Before rule, it ran after all of Mike’s nice clarifying the choice of the parser stuff, so the parser still clarified its choice of the gem you were holding (even though you’re about to take a different one). This is bad! So I set up an ugly solution–before clarifying the choice of the parser, it checks to see whether the parser should be choosing a different gem. If so, it sets a flag, picks the gem it should be choosing, and then the clarifying the choice of the parser rule checks to see whether you’re really going to be working with a different gem, and the Before rules redirect the action to the new gem.

So (new code after the test script):

[code]Test Room is a room.

A gem is a kind of thing.

A gem can be embedded or loose. A gem is usually loose.
Understand “stuck” as embedded. Understand “free” as loose.
Understand the embedded property as describing a gem.

Before printing the name of a gem while clarifying the parser’s choice of a gem, say "[if embedded]embedded [otherwise]loose “.
After printing the name of a gem (called G) while clarifying the parser’s choice of a loose gem:
if G is carried by the player, say " that you are carrying”;
if an embedded gem (called EG) that is not G is visible, say “, not the gem stuck in [the random thing that incorporates EG]”.

Understand “in/from/out of/-- [something related by reversed incorporation]” as a gem.

A boulder is here. “A giant boulder rests nearby. Embedded in the stone’s side is a gem.” The boulder incorporates an embedded gem.

Instead of taking a gem that is part of something, say “It’s stuck in [the random thing that incorporates the noun]! OMG!”

The player carries a gem.

test me with " i / take gem / take stuck gem / take embedded gem / take gem out of boulder / take embedded gem from boulder / take the gem stuck in the boulder / drop gem / take gem"

Before taking a carried gem when substituting a different gem is true:
try taking the substituted gem instead.

The substituted gem is a gem that varies.
Substituting a different gem is a truth state that varies. Substituting a different gem is false.
Every turn: now substituting a different gem is false.

Before clarifying the parser’s choice of a carried gem while taking when the player can see a gem that is not carried (called jewel):
now substituting a different gem is true;
now the substituted gem is jewel.

For clarifying the parser’s choice of a gem when substituting a different gem is true:
say “([the substituted gem])[command clarification break]”.[/code]

If there are multiple other gems to take, this will arbitrarily choose one (the first one in source code order, I think), but there’s no way to force disambiguation that I know of. Maybe my biggest discontent with Inform 7 is that everything about disambiguation and the parser choosing things is wedged so deep into the parser that there’s no good way to modify it, really; but as has been explained to me the reason is that it’d be really hard to change that stuff without potentially breaking a lot of code.

The solution looks far bigger than the problem, but it worked. I had to compile the game as .z14, but it worked.

Thank you very much, both Mike and Matt!