Implicit grab with full inventory capacity

Before displaying the implicit message “(first taking the …)”, shouldn’t the inventory be checked for fullness?
The behavior is the same with PunyInform or with the standard library.

You can see a hat here.                                              
> wear hat                                                           
(first taking the hat)                                               
You are carrying too many things already.
Constant MAX_CARRIED 0;

Include "globals.h";
Include "puny.h";

Object Library "The Library"
   with description "You are in a library.",
   has light;

Object hat "hat" Library
   with name 'hat',
   has clothing ~worn;

[ Initialise; ];

I couldn’t agree more. It’s one of the many reasons why I hate implicit take (or implicit anything, for that matter). In the case of a worn object, it doesn’t count towards your inventory, so why can’t it just be worn in the first place?

There are facilities in the standard library to restrict implicit actions, which indicates that we are not the only ones who are bothered by this. I thought PunyInform would get rid of it, but it doesn’t.

I tried to disable _ImplicitGrabIfNotHeld() and _ImplicitDisrobeIfWorn() in PunyInform, which seemed to be pretty straightforward, but I failed.

I just found out that there is, in PunyInform, a global variable update_moved = true to be updated when putting an object directly into the inventory with the move instruction, which I often do. I should read, or reread, the documentation from time to time!

Edit: I deleted my example which was not exemplary.

You probably should :slight_smile:

The standard library scans all objects held by the player each turn to see if any of them have just been picked up. This gets a little expensive on 8-bit computers when you’re carrying a lot, so we demand that the programmer sets update_moved whenever moving an object to the player’s inventory using move.

  1. Because if your hands are already full, how can you put on a hat?
  2. DM4 states that if you want to intercept an object entering the player’s possessions, you only need to trigger on Take and Remove. I think this is a good thing.
1 Like

I know, I know. I was just playing the devil’s advocate. I get criticised when I explain that my character is not a Mack truck and he/she cannot carry 100 items. Imagine the reaction when I say you have to drop an item, get hat, wear hat, then get the dropped item. Modern players are really, really lazy.

Except that you can’t trigger on Take and Remove if you can’t take it in the first place.

There’s also multiple issues related to containers and supporters. For example, I once had a bucket and I needed to put water from a stream into the bucket. It would first do an implicit Take (because Put uses a held token), but my before routine wouldn’t allow you to take the water in your hands. I resolved that one by changing the grammar.

On another occasion, I had to put something on a pedestal. I don’t remember the exact details. but it would first do an implicit drop, then an implicit take (or something like that, maybe vice versa) and then it would fail. Anyway, it was really weird and took quite a bit of skullduggery to work around the standard library’s issues.

Transfer is another action that is badly handled in the library. Everyone forgets about that one. As a player, you can often work around Drop, Take, Insert etc. issues with Transfer, but you shouldn’t be able to.

As long as the object is in scope and the parser can make sense of your sentence, you can trigger on any action in a before routine or react_before routine. I.e. you can trigger on “take ferry” (where the ferry is static) or “put ball in floor” (where the floor insn’t a container).

You can’t trigger on “drop ferry” because the parser expects a held object and you’re not holding the ferry.

No you can’t. If the grammar uses a held token, it never gets to your before routine. The parser spits the dummy and gives you an error response before you get a chance to intervene. I get around this by changing the grammar so that held is replaced by noun. It’s one of the many joys of the standard library’s implicit actions.

That’s what I was trying to say.

I have sometime thought it would be better if special tokens like held, worn, creature etc meant “prefer objects that adhere to the requirement” rather than “only consider objects that adhere to the requirement”.

However, PunyInform has a tricky position in this kind of issue. Its behaviour only deviates from the standard library’s behaviour when we think there’s a really good reason to do so, and we would like it to be reasonably simple to write games or extensions that work with both libraries. Changing this in PunyInform may make it a bit too different.

Is this also necessary when removing an object from the player inventory with the instruction remove?
remove apple;

No. You set update_moved to make the library check what’s new in the player’s inventory. If there is something there which doesn’t have moved, it will get moved. Also, if it has scored, the player will get points. There are no such effects to care about when an object is removed from the player’s inventory or indeed removed from the game world.

If an object starts off in your inventory, but can never be removed (I’m thinking of clothing), should you use update_moved in your Initialise routine?

In most situations it doesn’t matter, because the object can never be moved, but you might have some generic routine that checks whether an object has moved and then it could have an impact.

There’s no need. All objects that are in the player’s inventory right after Initialise has been run get the moved attribute and lose the concealed attribute.

1 Like

Gotcha. Thanks.

1 Like