Changing and exchanging objects

It’s been a while since I last posted. I’ve been busy trying to learn I7, and for the most part, been having increasing amounts of high-grade fun with it.

Right now, the problem I have isn’t a roadblock. The last project of mine involves changing one object into another, and I threw together a solution that (to me) looks fairly economical. But it did make me wonder, because it looked like a textbook example of things that ought to have been done before.

So, to anyone more versed in Inform, how does this solution work? Are there already extensions that can handle this? Am I missing something obvious in my code that will cause weeping and gnashing of teeth later on? How can I, in short, improve on the code?

"Omelets" by Björn Paulsen

The Hall of Statues is a room. 

The display pillar is a supporter. It is in the Hall of Statues. "In the center of the Hall, flanked by a tasteful array of spotlights, rises a display pillar."

The Ming vase is a container. The description is "This pale china vase embodies the purest artistry in one fragile vessel." It is opaque. It is closed. It is unopenable. The Ming vase is on the display pillar.

Some Ming vase shards are a thing. "On the floor, a handful of delicately fractured shards are all that remains of the ming vase." The description is "Science marches ever forward."

The ancient pickled egg is a thing. It is in the Ming vase. The description is "Preserved throughout the ages inside the Ming vase, this ancient pickled egg can finally be revealed to the world."



To switch (original - a thing) for (replacement - a thing):
	let place be an object;
	let place be the holder of the original;
	if the original holds something:
		repeat with item running through things enclosed by the original:
			if the replacement is a container or the replacement is a supporter:
				now the item is held by the replacement;
			otherwise:
				now the item is held by the place;
	remove the original from play;
	now the replacement is held by the place.

[Some handling rules]

After printing the name of the ming vase:
	omit contents in listing.

After dropping the ming vase:
	say "[italic type]Crack![roman type] You drop the vase, with predictable results.";
	switch the ming vase for the ming vase shards.

After taking the ancient pickled egg:
	say "(Taken.)";
	say "At last! You have discovered the last great secret of the old masters of culinary art - the ability to create an egg that can stand the test of time."

[End handling rules]


Test me with "get vase/drop vase/look/get egg".

I would create this not by changing the object, but simply by describing it differently after it’s been broken. You could create a property with an assertion like “The ming vase can be broken.” but in this case it seems we could just use whether it’s open or closed to keep track of that.

The Ming vase is a closed unopenable container on the display pillar. "[if open]On the floor, a handful of delicately fractured shards are all that remains of the ming vase.[else]A delicate ming vase is here." The description is "[if open]Science marches ever forward.[else]This pale china vase embodies the purest artistry in one fragile vessel." 

Understand "shards" as ming vase when ming vase is open.

The ancient pickled egg is a thing. It is in the Ming vase. The description is "Preserved throughout the ages inside the Ming vase, this ancient pickled egg can finally be revealed to the world."

After printing the name of the ming vase:
   omit contents in listing.

After dropping the ming vase:
   say "[italic type]Crack![roman type] You drop the vase, with predictable results.";
   now ming vase is open.

Um… correct me if I’m wrong, but does work with the idea of actually smashing the vase into something that can no longer be a container? Surely “put egg in Ming shards” would put the egg back inside the shards, which I can’t really parse mentally.

I know I often tend to leave out bits and pieces in my posts, things that would have been relevant to the context, so I’ll try to explain. What I’m after is a facility that is as generalized as possible, allowing for reuse, and I also want it to be as efficient as possible, because that adds to its utility. The Ming vase was a test subject to show the process of switching something and having its contents reacting realistically.

But such solutions don’t always behave in sensible ways. For instance, in this case, I suspect if we were to switch a supporter for a container, the objects on the supporter would suddenly be inside the container. It’s those implications, not to mention whatever bugs (possibly game-breaking) that this sort of code could generate in other games, that I wonder about.

I think the code you posted is pretty good general solution. It sounds like you might be thinking of it as something that could be elaborated into extension. I hope you do that.

The way you’ve handled containers and supporters makes sense–this is probably the best default behavior. But there is at least one missing implication: Right now, if the objects you change is a person, the things carried by the person will be dropped on the floor, when they really ought to become possessions of the new object.

If you are thinking of strongly generalizing this solution, along the lines of an extension, you might consider making the main switching routine into an activity. This would allow easy customization. Here’s one way to do this:

A thing has a thing called the replacement.
	
Replacing something is an activity.

For replacing something (called the original):
	let place be the holder of the original;
	let replacement be the replacement of the original;
	if the original holds something:
		if the replacement is a repository:
			repeat with item running through things enclosed by the original:
				now the item is held by the replacement;
		otherwise:
			repeat with item running through things enclosed by the original:
				now the item is held by the place;
	remove the original from play;
	move the replacement to the place.
	
To decide whether (item - an object) is a repository:
	if the item is a container, yes;
	if the item is a supporter, yes;
	if the item is a person, yes;
	no.
	
[Some command variations to allow flexibility for users]
	
To switch (original - a thing) for its replacement:
	carry out the replacing activity with the original.

To switch (original - a thing) for (replacement - a thing):
	change the replacement of the original to the replacement;
	carry out the replacing activity with the original.

[Examples of customization]

[A chest that is wired to explode, destroying everything inside it]
The chest is a container. The replacement is debris.

Before replacing the chest:
	repeat with item running through things contained by the chest:
			remove item from play.
	
[We have containers that become supporter-containers--a chest that is transformed into a sideboard, for example, with a drawer as part of the sideboard. We prefer that any contents in the chest go into the drawer, rather than onto the top of the sideboard (i.e., onto the supporter)]

Before replacing a container (called the original):
	if the replacement of the original is not a container:
		if the replacement of the original incorporates a container:
			repeat with item running through the things contained by the original:
				move item to a random container incorporated by the replacement of the original.

–Erik

Thank you very much for the input, both of you. Erik’s was closest to the response I was aiming for (not that one would know that by reading my initial post :stuck_out_tongue:), and the idea of making it an extension fits neatly with my plans. I may eventually add relations to connect object(s) to one another as well, as soon as I manage to judge the strengths and weaknesses of that possibility.

Lately, though, I feel I’ve dithered enough with mechanics and code. I’ve had a lot of fun during these months of exploring I7, and I’ve learned a great deal, but recently I’m starting to suspect I’ve been putting things off. So now, before anything else, I’ve resolved to make myself write a game and actually finish it, however small that game might be. The likelihood is pretty high I’ll get nothing done, otherwise.

Again, thanks to you both for taking the time to help.