Take a thing that isn't present in the room (as part of 'fake' dynamic item creation)

I want to create a sort of ‘fake’ dynamic item system, where one item is juggled around in such a way that there appears to be a limitless quantity of it, as the player can only take one at a time. Where this challenge becomes considerably more complex than the Pizza Prince or Extra Supplies examples (from the Recipe Book 10.3) is the fact that I want one container to dispense multiple different ‘limitless’ items.

Here’s some example code that I have:

"Consumables Test" by Theo Court

The breakroom is a room. "A run-of-the-mill breakroom."
		
A beverage is a kind of thing.
Instead of drinking a beverage:
	say "You chug [the noun]. It tastes delicious.";
	now the noun is nowhere;

Understand "take [any visible beverage]" as taking.
Instead of taking a beverage:
	if the player does not have the noun:
		move the noun to the player;
	otherwise:
		say "You already have [a noun]."

A vending machine is a kind of container.
The Dispens-O-Tron is a vending machine in the breakroom. Understand "tron", "dispenser", "vending machine" and "machine" as the Dispens-O-Tron.
The Coca-Cola, the Pepsi, the Sprite and the Fanta are beverages in the Dispens-O-Tron.

According to the googling that I’ve already done, this should work fine. However, upon simply taking an item from the vending machine, I run into a Glulxe stack overflow. What’s going on here?

2 problems

You are trying here to set up a Take action that allows you to take something that isn’t in scope, or even touchable.

The Take action is already defined as needing things to be touchable:

Taking is an action applying to one touchable thing.

You can’t fully override the touchability requirement by saying ‘any’ in your ‘Understand’ phrase- it will allow you to type commands asking to take something which can’t be seen or touched, and generate an action, but the action will fail between the ‘Before’ stage and the ‘Instead’ stage when touchability is tested for.

You can’t override the touchability requirement by saying ‘visible’ in your Understand phrase. ‘Visible’ in the sense you are attempting here can only be applied in action definitions, e.g.

Examining is an action applying to one visible thing.

where it really means ‘in scope’ i.e. something you’re allowed to refer to in typed commands because the player is aware of it.

‘In scope’ is similar to the usual meaning of ‘visible’, i.e. something the player can see, but not quite the same- some things the player can’t see are sometimes in scope, such as his possessions when in darkness, or the directions (north, east etc.) or anything deliberately brought into scope by the author in the activity ‘Deciding the scope’. For more discussion of scope and visibility, see this post.

The unintended effect of using ‘all visible…’ in your ‘Understand’ phrase, where Inform interprets ‘visible’ in the usual sense of ‘something the player can see’ is to send Inform’s scoping routines into an endless recursion of calling each other because the idea of visibility exists in both ‘all’ - which is thinking about ‘things in scope’ and ‘visible’- which is thinking about visible things- hence the stack overflow.

So the Understand phrase needs to be just

Understand "take [any beverage]" as taking.

This achieves the goal of allowing the player to refer to taking any beverage in typed commands, wherever it is, in scope or not.
However, we still need to overcome the problem of the subsequent ‘Take’ action being rejected due to touchability requirements if the beverage is out of scope and untouchable e.g. nowhere, which is where you’re moving drunk items to.

You can do this by intercepting the ‘Take’ action at the ‘Before’ stage, before touchability is tested for.

"___Sprite (other soft beverages are available)" by PB


The breakroom is a room. "A run-of-the-mill breakroom."
		
A beverage is a kind of thing.
Instead of drinking a beverage:
	say "You chug [the noun]. It tastes delicious.";
	now the noun is nowhere;

Understand "take [any beverage]" as taking.
Before taking a beverage:
	if the player does not have the noun:
		move the noun to the player;
		say "Taken." instead;
	otherwise:
		say "You already have [a noun]." instead.

A vending machine is a kind of container. 
The Dispens-O-Tron is a vending machine in the breakroom. Understand "tron", "dispenser", "vending machine" and "machine" as the Dispens-O-Tron.
The Coca-Cola, the Pepsi, the Sprite and the Fanta are beverages in the Dispens-O-Tron.

However, what you really want here is for the Sprite to only be available when the player is in front of the machine- otherwise she’ll be able to take an off-stage Sprite wherever she is. So actually the better solution here is to maintain all the usual need for taken things to be in scope and touchable, but just move them back to the machine when they are drunk, rather than to nowhere.

"___Sprite (other soft beverages are available)" by PB


The breakroom is a room. "A run-of-the-mill breakroom."
		
A beverage is a kind of thing.
Instead of drinking a beverage:
	say "You chug [the noun]. It tastes delicious.";
	now the noun is in the Dispens-O-Tron;

A vending machine is a kind of container. 
The Dispens-O-Tron is a vending machine in the breakroom. Understand "tron", "dispenser", "vending machine" and "machine" as the Dispens-O-Tron.
The Coca-Cola, the Pepsi, the Sprite and the Fanta are beverages in the Dispens-O-Tron.
breakroom
A run-of-the-mill breakroom.

You can see a Dispens-O-Tron (in which are a Coca-Cola, a Pepsi, a Sprite and a Fanta) here.

>take Sprite
Taken.

>take Sprite
You already have that.

>drink Sprite
You chug the Sprite. It tastes delicious.

>take Sprite
Taken.
4 Likes