One door closes and another opens in your face...

I was testing out KV's fix for container items listed in the Inventory pane when I came upon this anomaly. The set up is as follows:

I am standing beside a beanstalk, holding a beanstalk kit, which is an open box containing a bean and two other items.
I type TAKE BEAN
Question: what happens next? Is it
A: I take the bean out of the box
B: Quest complains that I am already holding the beanstalk kit
C: I climb the beanstalk (which is the script attached to 'take')
D: I am offered a menu asking which 'bean' did I mean?

The response is Option C, which was a surprise!
[Demo no longer available]


I don't think it's that surprising.

The scope of "take" is notheld last time I checked. An object you're holding isn't in scope. So there is only one object in scope that matches the pattern 'bean', and it takes that.

Maybe it would be better if the scope for the "take" command was changed to notheld,contents?
Or possibly change ResolveNameInternal so that if the player types the exact alias of a visible object, that object is considered to be in scope by default (which isn't useful in most cases, but may line up better with what the player expects).

Maybe something like:

  <function name="ResolveNameInternal" parameters="variable, value, objtype" type="object">
    <![CDATA[
    game.pov.currentcommandmultiobjectpending = false

    scope = GetScope(variable, value, objtype)
    if (HasString(game.pov.currentcommandpattern, "scope")) {
      secondaryscope = ScopeVisible()
      // If the player types the exact alias of an object, assume they meant that object
      // even if it's out of scope. Not useful, but intuitive.
      foreach (o, secondaryscope) {
        if ((LCase(GetDisplayAlias(o)) = LCase(value)) and not ListContains (scope, o)) {
          list add (scope, o)
        }
      }
    }
    else {
      secondaryscope = null
    }
   
    return (ResolveNameFromList(variable, value, objtype, scope, secondaryscope))
    ]]>
  </function>

When I tried to force a menu by not giving the full name, this happened:

take bea
Please choose which 'bea' you mean:
1: Beanstalk Kit
2: bean

which is also surprising (to me!) ...now the beanstalk isn't even mentioned? From a user perspective, I would expect precise spelling to be taken first; and otherwise offered all options in a menu.


When I tried to force a menu by not giving the full name, this happened:

Is that after making some changes? In the game you linked above, "take bea" still climbs the beanstalk for me.


Apologies, ignore the example, I must have moved the player out of the garden before I attempted 'take bea'.

The basic point still applies, however: most would expect precise spelling to be considered first; then, if no match, be presented with all reachable alternatives having the same substring.

'take bean', when away from the beanstalk has the desired effect of taking the bean out of the box, without worrying about a name conflict with 'beanstalk kit', and 'take bea' offering a prompt. Perhaps this issue is a result of the last release attempting to reduce the use of the prompt menu?


I tried it and it just said that you had taken the bean. The bean was in inventory and could be looked at??


The basic point still applies, however: most would expect precise spelling to be considered first; then, if no match, be presented with all reachable alternatives having the same substring.

That's what the modified ResolveNameInternal I posted above was supposed to achieve.

Although "all reachable objects", I'd disagree with. If you say "drop bea", it should only present a menu of objects you're holding, because they're the ones for which "drop" is meaningful. If I'm in a room with a yellow lamp, a green lamp, and a blue lamp (turned on), and I type "turn off lamp", it's obvious which one I mean.

Perhaps this issue is a result of the last release attempting to reduce the use of the prompt menu?

Don't think so. It's been like that as long as I've been poking Quest. It's just that the "check if you typed an exact alias" bit of code only considers objects in scope; the special behaviour doesn't apply to "take bean" if you're already holding it, or "drop bean" when it's on the ground.

Thinking about it, the code above is an ugly bodge. Really, this should be done in ResolveNameFromList.
My thought would be changing

    if (ListCount(fullmatches) = 0 and ListCount(partialmatches) = 0 and not secondaryscope = null) {
      foreach (obj, secondaryscope) {
        name = LCase(GetDisplayAlias(obj))
        CompareNames (name, value, obj, fullmatches, partialmatches)
        if (obj.alt <> null) {
          foreach (altname, obj.alt) {
            CompareNames (LCase(altname), value, obj, fullmatches, partialmatches)
          }
        }
      }
    }   

to…

    if (ListCount(fullmatches) = 0 and not secondaryscope = null) {
      secondarymatches = NewObjectList()
      foreach (obj, secondaryscope) {
        name = LCase(GetDisplayAlias(obj))
        CompareNames (name, value, obj, fullmatches, secondarymatches)
        if (obj.alt <> null) {
          foreach (altname, obj.alt) {
            CompareNames (LCase(altname), value, obj, fullmatches, secondarymatches)
          }
        }
      }
      if (ListCount(partialmatches) = 0) {
        partialmatches = secondarymatches
      }
    }

If I'm understanding the structure of the existing code right.

That should mean the order of checking would be is:

  1. Exact match for objects in scope
  2. "him", "her", "it" special cases
  3. Exact match for other visible objects
  4. Partial match for objects in scope
  5. Partial match for other visible objects

At each step, if there's exactly one object found it runs the command, if there's more than one it displays a menu, and if there's none it goes on to check the next set.


I tried it and it just said that you had taken the bean. The bean was in inventory and could be looked at??

Hi Father, did you move out of the garden by any chance? The sequence should be PANES, BEANTEST, OPEN KIT, TAKE BEAN.


I moved into the house, but even so bean kit did not appear as an option.


Although "all reachable objects", I'd disagree with. If you say "drop bea", it should only present a menu of objects you're holding, because they're the ones for which "drop" is meaningful.

I was really just thinking about 'take' but your general point is right. On top of (i) exact match; (ii) all reachable with string subset, there should be adjustments according to context. So, in relation to 'take', it can exclude all items in the inventory at the top level though not within containers. Similarly 'drop' can exclude anything not held. For other verbs, such as 'use' there is probably no optimisation possible. Interestingly though, 'use bean' seems to pick the 'bean' in the box, as I'm guessing preference is given to objects held. Someone must know the current algorithm?


I moved into the house, but even so bean kit did not appear as an option.

You need to stay beside the beanstalk.


...here is another issue...drop the Beanstalk Kit in the garden and then type 'take all'.


K.V.

What would you like to do? Type instructions in the space below.
Type help for play options and more information.

> panes
The game panes are now visible on the right. Type panes again to hide them.

> beantest

> open kit
You open it.
It contains a bean, a compliments slip (on which there is dust) and growing instructions.

> get bean
You make your way slowly up the outside foliage.

You are in the middle of the beanstalk, breathing heavily.


K.V.

drop the Beanstalk Kit in the garden and then type 'take all'.

Are you moving me to the beanstalk when I try to take it???


K.V.

TAKE BEANSTALK is the same as CLIMB BEANSTALK

This is a problem in this scene (although I have done it with stairs in my game, there was no worry about similarly named items in the rooms with the stairs).


> take all
giant beanstalk: You are in the middle of the beanstalk, breathing heavily.
Beanstalk Kit: Garden is not open.


First it takes the beanstalk, which moves me to the beanstalk.

Then, it tries to take the rest of ALL, but you moved me when I took the beanstalk, so I am now inside of the beanstalk container and I can't reach outside of it to grab the beanstalk kit.


K.V.

There is a fix for this in Quest 5.8.

Set not_all to true on the beanstalk.

That would make this happen:

What would you like to do? Type instructions in the space below.
Type help for play options and more information.


> panes
The game panes are now visible on the right. Type panes again to hide them.

> beantest

> drop kit
You drop it.

> get all
Beanstalk Kit: You pick it up.

You can add this to your game in full code view to make this work with your stuff:

  <command name="take">
    <pattern>take #object#; get #object#; pick up #object#</pattern>
    <multiple>
      takeList = NewObjectList()
      foreach (obj, ListExclude(ScopeVisibleNotHeldNotScenery(), game.pov)) {
        if (obj.parent = game.pov.parent) {
          list add (takeList, obj)
        }
      }
      return (takeList)
    </multiple>
    <scope>notheld</scope>
    <multipleobjects type="script">
      game.pov.currentcommandpendingobjectscope = NewObjectList()
      objlist = ListExclude(ScopeVisibleNotHeldNotScenery(), game.pov)
      objlist = ListExclude(objlist, FilterByAttribute(objlist,"not_all",true))
      foreach (obj, objlist) {
        if (obj.parent = game.pov.parent and not DoesInherit(obj, "npc_type")) {
          list add (game.pov.currentcommandpendingobjectscope, obj)
        }
      }
    </multipleobjects>
    <script>
      if (multiple and ListCount(object) = 0) {
        msg ("Nothing here to take.")
      }
      else {
        foreach (obj, object) {
          DoTake (obj, multiple)
        }
      }
    </script>
  </command>

On top of (i) exact match; (ii) all reachable with string subset, there should be adjustments according to context.

This is done by the scope attribute of a command.

So, in relation to 'take', it can exclude all items in the inventory at the top level though not within containers.

At the moment, the take command's scope attribute is "notheld". In my first post in this thread, I suggested that it should be changed to "notheld,contents" in order to correctly handle taking items out of containers.

Similarly 'drop' can exclude anything not held.

The drop command's scope is inventory.

For other verbs, such as 'use' there is probably no optimisation possible. Interestingly though, 'use bean' seems to pick the 'bean' in the box, as I'm guessing preference is given to objects held.

The use command doesn't have a scope, which is equivalent to "all". In this case, the bean is chosen because it's the only exact match for what you typed.

Someone must know the current algorithm?

The "current algorithm" is:

  1. Objects selected by the command's scope that exactly match what the player typed.
  2. The special cases "him", "her", and "it"
  3. Objects selected by the command's scope that have the player's input as a substring
  4. Other visible objects that have the player's input as a substring

So the problem you found in your first post is actually 2 problems. The "take" command's scope should be "notheld,contents", and this algorithm doesn't include a check for objects that exactly match your input but aren't in scope (which should be fixed by the last chunk of code I posted)

(with regard to the "take all" issue, I think I posted a suggestion for how to fix that in another thread a while back. But the not_all attribute as KV suggests is a decent workaround)


KV and mrangel, by way of background, in a previous update I added objects for path and road and implemented 'take' to mean 'follow path' or 'follow road'. When I got to the beanstalk I did the same as it is a route up to the castle in the clouds.

I have no strong feelings about this and am really just flagging it as something that would be nice to sort out in the next release rather than feeling the need to patch my game now. I understood that the 'take all' was failing because the first operation moved the player and glad that the next version of Quest deals with it. If the take order had been different, with the beanstalk last, I would never have noticed!

Thanks for your help as always.


K.V.

It is already sorted out in the next release, but you'd still have to edit your game and add the attribute not_all to those objects and set it to true. You also need to be sure you haven't overridden the take command, otherwise the changes in Quest 5.8 still won't effect your game.

...and then you'd have to apply the wearables fix, if applicable.

If you cover all of those bases, TAKE ALL will ignore those objects.


To add that functionality to your current game now, you can follow these simple steps (I tested this on your game):

http://textadventures.co.uk/forum/quest/topic/yj-4_poo4ek24ppotxmfqq/one-door-closes-and-another-opens-in-your-face#444c3a4a-dcd2-42fb-8f6e-ccd9e76a64ce


NOTE:

Any changes in the next release of Quest will not effect published games. Published games include all of the code from the time they were published, except for C# stuff, playercore.js, desktopplayer.js, player.js, or webplayer.js.


K.V.

DavyB,

I always add a TAKE verb to stairs and paths, too.

I approve of that verb in those contexts, if that's any consolation to ya'.

I've been using the not_all method for quite a few months, and it seems to be the bee's knees.


J_J

I don't know. You take stairs, but you don't take a ladder, or take a tree. You climb items like these. Changing the verb is an easy fix. If you want to keep take for the beanstock... I'm curious. Are you using the take inventory tab for the beanstock, or do you have you made a separate "take" command. I'm assuming that you have it as a command (because of the menu not showing up and because it is overriding the built in take of the bean). To fix this, you just have to add bean as one of the object options in the command.


K.V.

You take stairs, but you don't take a ladder, or take a tree. You climb items like these.

Which is why I only use it for things such as stairs or paths. (Ha-ha!)


J_J

I didn't mean that to sound so pointedly at your comment K.V.
Ha.


K.V.

Oh, no... I was laughing.


Guys, don't let the effect of 'take beanstalk' distract you! If I just indicate that the beanstalk can't be taken with the message "Are you serious?" the following probably illustrates the problem more clearly:

>open Beanstalk Kit
You open it.
It contains a bean, a compliments slip and growing instructions.

> x bean
It looks like an ordinary broad bean.

> take bean
Are you serious?

The issue is Quest selecting the nearby beanstalk rather than the item I have in a container I've just opened, for which I have given the precise spelling.


There is something weird there. I just tried a quick test, and it works as expected for me (even with bean set to scenery). When I set the alias of bean to "broad bean" I got asked which bean I wanted to take, so cannot imagine what is going on there.


K.V.

You have the kit. The bean is in the kit (held).

You say take bean. Quest looks for notheld, finds beanstalk.


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums