Meaning of 'take all' and 'drop all'?

In any Quest game, the player can type 'take all' or 'drop all' at any time but these operations don't seem to be well defined. How should they operate? Here is a proposal to help the debate:
TAKE ALL
In any location, attempt to take every non-scenery visible object. If an object is a container, attempt to take any non-scenery visible objects within it, and repeat recursively. If there are no objects to take, display "Nothing here to take."
DROP ALL
Drop all non-scenery visible objects held by the player. If no such object is held, display "Nothing here to drop." (Trying this out on existing games on the site can produce surprising results!)


Hello, DavyB!

I think that is already how those commands work, except it will take scenery objects and it ignores any object with npc_type (male of female objects).

I have modded take so it excludes any object with the attribute not_all set to true, and I'm sending a pull request soon. So, if it passes all of Pixie's tests, it may end up in Quest 5.8.


Sorry KV, perhaps I should have given examples! Curently, if the player goes into a room and finds a table with an apple sitting on it, 'take all' will only pick up the apple if the table can be taken with it, keeping both together. I was suggesting that the apple should be added to the inventory even if the table can't be moved?

For 'drop all', the issue is perhaps the implementation. If I make the player a 'surface' to add characteristics that can be examined, these are included in the inventory even if they are scenery and invisible. So, for example, in my Giantkiller Too game, I've described the character ("look at me") as: "Looking medieval, with hobbit-like feet to match. You are surrounded by a mystical aura guaranteed to keep you from all harm." This meant adding 'feet' and 'aura' as scenery objects to the player, which are invisible until "look at me" has been typed. 'Drop all' mentions both 'aura' and 'feet' even when invisible, which seems wrong.

I didn't realise 'take all' avoided male and female characters. That seems a bit inconsistent as 'take' can be applied directly to such objects?


I was suggesting that the apple should be added to the inventory even if the table can't be moved?

That does reasonable. I guess it would need to check if the container can be taken, and if not, see if the contents is reachable. Can anyone think of how this might badly affect existing games?

I didn't realise 'take all' avoided male and female characters. That seems a bit inconsistent as 'take' can be applied directly to such objects?

Do you think? We tried to make it intelligent enough to realise NPCs cannot be taken. If the player tries to take someone by name, then Quest has to match that person to the command, and by default will say he cannot be taken.


Well Pixie, one simple definition of 'take all' is that it should just be a shorthand for 'for all x do take', where 'x' is anything visible to the player that is not currently held. That means including scenery and NPCs. Such objects do have an 'inventory' tab after all? ...and some games can involve picking up male/female characters...as in my female talking pig in Giantkiller Too!


if the player goes into a room and finds a table with an apple sitting on it, 'take all' will only pick up the apple if the table can be taken with it

I never noticed this.

If a takeable object is in a container and the container cannot be taken, I think it should take the takeable object during TAKE ALL.
But, if the container can be taken, too, I think TAKE ALL should just take the container with any objects still inside of it.

Continue reading.

So, basically, like Pixie says:

I guess it would need to check if the container can be taken, and if not, see if the contents is reachable. Can anyone think of how this might badly affect existing games?

I can't see how it would effect anything, unless an author is depending on it to work the old way for some reason. (Like maybe you can take something and the whole point of the game is to figure out to examine it and take the item out of it.) This would only effect an .aslx being played in the editor, right? So, published games wouldn't be effected. Only works in progress.

The update from 5.6.3 to 5.7.1 broke two of my games in progress, and the update from 5.7.1 to 5.7.2 did the same (to the same two games). My initial solution was to revert to 5.6.3 until my games were completed. Later, once I admitted to myself that I wouldn't be completing those games any time soon, I created a post on this site, asking why TAKE no longer worked, and Pixie fixed me up with some working code within two hours.

My point? Changing this may break someone's game, but we can help them out with it. (What's that saying about making omelettes and breaking eggs?)


I make the player a 'surface' to add characteristics that can be examined, these are included in the inventory even if they are scenery and invisible.

Also, setting the player up as a surface is something Quest is not programmed to check for. Quest just checks for everything inside of the game.pov object. If the object is visible and the drop setting has not been changed, it will be dropped.

even if they are scenery and invisible.

If objects are set to invisible, they shouldn't exist as far as Quest is concerned. Quest is definitely dropping things set to invisible when carried by the player (whether the player is a surface or not, and whether you DROP ALL or specifically DROP OBJECT). I assume this is because Quest doesn't expect the player to be carrying something which is not visible. (SIDENOTE: When a scenery object is taken, Quest changes the scenery attribute to false.)


some games can involve picking up male/female characters

Having defaults in Quest is what makes game-making easier on the whole.

99% of the time, you cannot pick up an NPC. Therefore, I believe this should be the default.

With the current scripts, if anyone wants to make an NPC object which is takeable, they should simply not set the object up as "male or female named". Just change the object's gender, article, alt, and possessive attributes. (That's all adding the object type actually does (I think), besides excluding the object from TAKE ALL.)

This seems fair to me. The author would already be doing extra coding to make the NPC object takeable. They may as well have to change 4 more attributes to reflect the object's gender, rather than the rest of us having to do extra things to exclude every single NPC object we create from TAKE ALL.


Again, a single not_all attribute would be a good solution (and its currently being considered for the next version of Quest).

Instead of excluding npc_type from TAKE ALL, that line of code could exclude things with not_all set to true. So, since npc_type is added to a named male or female object already, we could add the not_all att to thenpc_type type, setting it to true by default. With this set up, when you make something male or female named, not_all is set to true by default. This would be a checkbox on the object, which you simple uncheck to include the object when entering TAKE ALL. (Sound good?)


I make the player a 'surface' to add characteristics that can be examined

I wonder if we should have a built in container type for NPCs?

Either way, this is another time when we should question if TAKE ALL should apply to the objects. I think not, but I can imagine some will disagree.


I wonder if we should have a built in container type for NPCs?

Sounds good to me.

And, if someone doesn't like it this way, they could easily remove the container type from the object; correct?

Continue reading.

Either way, this is another time when we should question if TAKE ALL should apply to the objects. I think not, but I can imagine some will disagree.

That's where not_all would come into play.


While we're discussing TAKE:

I've always found it odd that objects cannot be taken by default, but TAKE is a default display verb for default objects.

...but I digress.


Here's how I envision things:

All default objects cannot be taken by default, and each object's not_all attribute is set to false by default (or simply doesn't exist as an attribute).

When you change an object to male (named) or female (named), this sets not_all to true. There will be a new checkbox in the editor, on the inventory tab, so this would be easy to change.

When the player's command is TAKE ALL or DROP ALL, objects with the attribute not_all set to true will be ignored.

If an object is in a container and the container can be taken, ALL should include the container only. If the container cannot be taken, the objects it contains which can be taken individually should be included in ALL, but not the container. (Surfaces are types of containers, so they would work the same way.) [Coding this sounds like it would be a little tricky to me, but Pixie has probably already figured out how to do it!]

Another thing that I'd like to change is the way Quest hides objects before examining a container. I think those items should be scenery rather than not visible. On the first play through, it's not a big deal, but, if I die then restart, I know the apple is on the table. I don't need to examine the table to see it this time. So:

>GET APPLE.
I can't see that.

> EXAMINE APPLE
I can't see that.

>EXAMINE TABLE
Nothing out of the ordinary.
It contains an apple.

>GET APPLE
You pick it up.


I've always found it odd that objects cannot be taken by default, but TAKE is a default display verb for default objects.

I think it would make a lot of sense if "(verb) all" was interpreted by the parser as looping over all all objects with that verb in their displayverbs list in a general case. So in the absence of command-specific "all" behaviour, it would just apply a verb to all objects (in scope) that have it.

"take" is probably one of the few commands that would be a special case; because you wouldn't want it to apply to objects inside containers in the same way.


...and the update from 5.7.2 to 5.7.3 did the same...

Is 5.7.3 out already?


Ha! Whoops!

I meant 5.7.1 to 5.7.2.


My point was that the last two updates each broke a work-in-progress, but that's because I was overriding default functions and commands which were changed during each update.


Yes, it would be useful for functions/commands that have undergone important changes since the last update to be listed with the new update. My 1 1/2 cents.


haven't read all of the comments yet...

but 'take' is a special coding/game-design logic, which pixie pointed out the logic of its intended design in his early post (I read that one, but not all the others yet), whereas there should be another such special coding for handling 'npcs', such as a 'follower/whatever' coding(s), as well as any other such 'whatever' game design objects, needing their own special coding, too.


also, this is a big deal with engine design...

we want the engine to be as universal and generalized as possible, as if you do something specific for one person's game design, it'll break everyone elses games and/or they may not want that engine design for their games.

unless fully tested and done well, any new things should be done as libraries, so as to not specialize/ruin the quest engine, ruining it for everyone. Only once something is fully tested and done well, keeping it generalized and universal, should it be added to the engine


also, it's a lot easier fixing a library (or simply removing/not-using the library until it gets fixed or helped with compatibility of your game and the library) then correcting the engine, as every time pixie changes/adds to the engine... he has to help everyone who now suddenly have conflicts between their games and the engine, unless they can figure out what happened on their own, but most people aren't good coders/programmers who can do this on their own and/or aware of being able to do it.


Oh, sorry. I was unclear. I wasn't complaining about that. Pixie did list the changes when he updated Quest.

I just had some crazy stuff going on in a modified take script. The update to Quest added super-awesome things concerning scope to the take command, and my modified script didn't jibe with the new attributes. Pixie (and mrangel) posted about those changes in numerous places. It was all my fault. And I wasn't the only one who had problems with that, but there weren't very many of us. And we all found the quick fix when we posted about it. (By 'found the quick fix', I mean Pixie promptly posted the code we needed and explained why we needed it. [INSERT LAUGH HERE.])

Anyway... I was just trying to point out that some updates may break games which are still in the creation process when people have crazy mods going on, but, if the updates are worthwhile, I say apply the update. If we can modify the script in the first place, we can find the fix (or post about it).

Also, keep in mind that published games are not effected at all; only works-in-progess.


The discussion here has dropped into implementation detail rather faster than I would have liked!

From a user perspective, when I open a cupboard and see several items, it seems reasonable to type TAKE ALL and expect the items to be removed. Is that a general view?


From a user perspective, when I open a cupboard and see several items, it seems reasonable to type TAKE ALL and expect the items to be removed. Is that a general view?

Seems pretty sensible. However, that couldn't be done with the way the parser's set up now. The parser calls multiple to get a list of objects, and then calls script for each of them. And there isn't actually an easy way to check whether a given object (like the cupboard) can be taken.

I think you'd have to do something like:

<command name="takeall">
  <pattern>^take all$</pattern>
  <script><![CDATA[
    pending = SortObjectList(ScopeVisibleNotHeldNotScenery(), "alias")
    pending = FilterByNotAttribute (pending, "not_all", true)
    untaken = NewObjectList()
    list add (untaken, game.pov.parent)
    taken = true
    while (taken) {
      taken = false
      foreach (obj, ListCompact(pending)) {
        if (Contains (game.pov, obj) or Equal (game.pov, obj)) {
          list remove (pending, obj)
        }
        else if (ListContains(untaken, obj.parent)) {
          list remove (pending, obj)
          taken = true
          // don't display a message saying "I can't take that" for shelves, counters, and other silly things
          if (ListContains (GetDisplayVerbs(obj), "take")) {
            DoTake (obj, true)
          }
          if (ListContains (ScopeVisibleNotHeldNotScenery(), obj)) {
            // The object isn't taken now, and its "take" script hasn't destroyed it
            // So we can try to take its children
            list add (untaken, obj)
          }
        }
      }
    }
  ]]></script>
</command>

(I was going to say that adding something like that to the core would be bad, because it would break take all for games with backdrop scope scripts. But then, I realise that the existing script won't deal with those anyway)

I would like to see a default "all" behaviour included in the parser (and "take" is one of the few commands where it would need to be overridden) but I think it would be quite difficult to ensure you didn't end up breaking existing games. Unless, maybe, it was added as a "feature" that could be checked or unchecked.

(and now my brain's coming up with really silly things. Like a turnscript that loops over all reachable items and combines their verb lists, to dynamically change the pattern of a command whose pattern ends up like ^(?<text_command>drop|take|look|lick|open|close|eat|kick) all$. Of course, that could never work)


when I open a cupboard and see several items, it seems reasonable to type TAKE ALL and expect the items to be removed. Is that a general view?

From a player's or author's perspective, I agree with this.

The discussion here has dropped into implementation detail rather faster than I would have liked!

Sorry. It's all about implementation, but discussing it means it may get fixed.


What about this?

Check out some code
THIS CODE HAS BEEN REMOVED TO AVOID CONFUSION

For archival purposes, it can be found here: 
https://github.com/KVonGit/QuestStuff/wiki/Taking-All

Another test game (with a closed box)

Check out some code
THIS CODE HAS BEEN REMOVED TO AVOID CONFUSION

Passing all the tests in Visual Studio doesn't necessarily mean this modification wouldn't break older games, does it?


I think KV and I have slightly different ideas about how the script should behave.

If there's a briefcase chained to a shelf, and you don't have the bolt cutters yet, should "TAKE ALL" take its contents? I think KV's solution says no, because the briefcase has a 'take' script even if you can't take it now. My script says yes, try to take it first and if that fails take the stuff out of it.

Which would a player more likely expect?


I think mine will try to take the contents if the briefcase's take attribute does not return true, it has no script, and it is open.

I was just messing around and following the same rules as lookat when in darkness. If you have a script, the script takes precedence over everything. So, when you examine something with a look script, that script runs whether or not darkness could prevent you from seeing it. (I guess it is assumed that you are prepared to handle the extra scripting since you're already adding a script.)

Anyway...

mrangel's method (checking to see if something has been taken, then trying to take its contents if not) is probably much more efficient.


I think mine will try to take the contents if the briefcase's take attribute does not return true, it has no script, and it is open.

Yes; if the object's "take" attribute is neither true nor a script.
It seems that if the take attribute is a string, yours will still attempt to take its children. Not sure, but I think that's not expected behaviour.

I went for the other approach; rather than trying to consider all the possible attributes that could affect an object's takeability, just attempt to take it and if that fails consider its children instead. For the briefcase with a 'take' script, my "take all" will attempt to take it, and if that fails will take its children instead.

I'm not sure which behaviour a player is more likely to expect.

I figured that using the displayverbs to govern which objects a player might attempt to take is reasonable. Because having a "take" attribute is a reasonable indication "this object can be taken" or "this object will do something if you attempt to take it", which is hard to distinguish between. But in most games, it seems that a "take" display verb is a reasonable indication "this is an object that a typical person might attempt to take".


I agree with you about everything but the "Take" display verb. I think that is a default display verb on everything that isn't a room or an npc_type. (I grumble obscenities every time I make a game while removing all the "Take" display verbs from the things I haven't changed to "Object can be taken" or added a take script.)


I think that is a default display verb on everything that isn't a room or an npc_type.

The same things that the default behaviour attempts to take when running "take all".

I grumble obscenities every time I make a game while removing all the "Take" display verbs from the things I haven't changed to "Object can be taken" or added a take script.

I'm not sure about the exact usage; but I expect that if you're going through those objects removing the default "take" verb, you probably wouldn't want "take all" to consider them. In most of my games, I think the objects that I've removed the "take" display verb from are the same ones that you will have given a "not_all" attribute.

To me, the display verbs are a way of the player character saying to the player "I think I might be able to take that object"; which is probably the same logic you might expect when the player says to the player character "take everything".


the display verbs are a way of the player character saying to the player "I think I might be able to take that object"

Exactly. Objects cannot be taken by default, BUT "Take" is a default display verb.

I go through each object I never want taken (and think it wouldn't make sense to try to take), removing "Take" from each display verb list, and setting notall to true on each one, too.

...but sometimes (not often) I remove display verbs that will still work when entered as a command (like "Take").


...but sometimes (not often) I remove display verbs that will still work when entered as a command (like "Take").

I can see that. But that's an odd and specific case.

It seems like in most cases, removing the display verb and adding your "notall" attribute are ways of expressing the same thing ("trying to take this object isn't an intuitive action") to different parts of the code.

If you go through doing both of those things to large numbers of objects… doesn't it seem easier to have both pieces of code expect to see the same message in the same way?

I can see exceptions. Like one of my first games, there was a large treasure chest. It's so heavy that you can only carry it if you're not holding anything else, and you can't pass through doors (except double doors) while holding it. That would have the "notall" attribute, but can be taken specifically.
But unless you're globally removing the display verbs for certain commands, I can't think of a case where an object that doesn't have a "take" verb displayed should be collected by "take all".


Your logic is sound. (I say that as if you didn't know. Ha-ha!) I guess I'd just rather check a boolean attribute than depend on an object's display verbs list, when it comes down to it. (I've recently seen two games (by different authors) in which the display verbs lists were being totally overwritten when performing certain actions on objects. This was not happening on purpose.)

I am now thinking of adding a bit of code that removes "Take" from the display verbs list of anything with notall set to true.


Okay, if there is general agreement that TAKE ALL should take any object visible to the player, I'm ready to move on to the implementation. Humour me! ...

The discussion here is much more involved that I would have expected. I know, for example, that the Quest function ScopeReachableNotHeld returns a list of "all objects which the player can reach in the current room (not including those the player currently has in their inventory)," so why is that not the starting point?

I can see that handling a script associated with a take operation is problematic so perhaps it is reasonable to just say "TAKE ALL is not available here" if any object in the scope list has a take script? ...forcing the player to take items one at a time. That still seems like an improvement over what currently happens?


The discussion here is much more involved that I would have expected. I know, for example, that the Quest function ScopeReachableNotHeld returns a list of "all objects which the player can reach in the current room (not including those the player currently has in their inventory)," so why is that not the starting point?

It is. But if there's a box on the floor, you don't want to take the box and then take all the items out of it.

So my 'take all' command works from the top down: it sorts ScopeReachableNotHeld to process the items that are directly in the room first, and then only takes each item if it's not inside a container that was already taken. Whereas KV's option was to filter that list down to only the objects whose parent is immovable. (Just thought: If I have a purse with a hidden pocket inside it, then the pocket clearly can't be taken out of the purse. So I've got a takeable container with a non-takeable container inside it. Do the command(s) presented so far deal with that sensibly?)


Ah, yes I see! I knew I should stay out of implementation discussions!! Happy to act as a tester if/when needed.


I reiterate:

I was just fooling around with the code.

mrangel's method would be the best way to handle things.


Log in to post a reply.

Support

Forums