Recording and restoring initial object location

Thanks, Fellows. All of you have been a big help. My curiosity has been thoroughly tweaked.
I’m going to play with both approaches, for a few days (I have my Spanish class on Monday, so that night is gone).
I’ll try what Sequitur has suggested and then see if I can do it the way Draconix has suggested.
Once I have things working, I’ll post what I have and any observations/questions that are relevant.

Having three relations is a wart resulting from the fact that rooms aren’t things. I actually don’t know why rooms aren’t things; it seems more intuitive that they should be things - especially considering that players can enter non-Room objects - and yet, they are not; if someone knows better than me about the internal design on Inform they could shed some light on it, actually, because it bugs me.

The property and relation solutions are two different ways of accomplishing the same thing, and I don’t think one is inherently superior to the other, just that the relation solution is more idiomatic.

Relations are ‘Informish’ because they’re a feature of Inform, basically; they’re Inform’s solution to the problem of relating objects to one another. Because they’re a well-supported idiomatic feature, they have some advantages. First, relations can be reversible, whereas there’s no elegant way of figuring out whether an object is a property of another object. Relations can be debugged easily. They abstract complexity well in the code, and so on.

Now, were this my project, what I actually would have done is stop and consider whether I need decoys that can home to either a room or a thing; because if not, I can just happily use relations to do this in a transparent, elegant way. Otherwise, I actually like Draconis’ solution better; I hadn’t thought of it before, but it’s true, it’s cleaner. Objects in Inform are ‘dirty’; you can’t do much with an object unless you know whether it’s a thing or a room or something else, so it’s annoying to implement behaviour that does things to objects.

(I posted the relations example for educational purposes; choosing between one way or another of doing things depends on knowing what the project as a whole is supposed to accomplish).

To the best of my knowledge rooms are not things because that’s how it’s always been in Inform, and it would break lots of stuff to change it now.

I’ve seen some other explanations for it too. If rooms are things, can you put a room inside a room? Can you pick a room up? Can you push a room, touch it, etc.? Some of these would break the world model less than others, but in general rooms seem different enough from other things that it makes sense to me that they’re separate.

In Inform 6 rooms aren’t (or at least weren’t) their own special kind; a room was an enterable object without a parent. I believe that Inform 7 changed this because it wasn’t doing anyone any good. There’s been some discussion of this somewhere, but I’m not sure where to find it.

Correct. (Not an object with an “enterable” property, but simply an object that the player might enter by any means.)

Pretty much. In I6 you could change an object from a non-room to a room simply by moving it off-stage. But the library didn’t have good support for this kind of trick, and in fact you had to fight it in some ways to make it happen. (Some properties were interpreted differently, and not in a convenient way.) So I7 dropped that idea and made rooms explicit.

The explicit room kind makes a bunch of features easier. For example, it permits the compiler to understand “A lamp is in every room”.

All that said – I’d think it would be easier to say

Belonging relates one object (called the home) to one decoy.

Then you could do a runtime test to see if the home is a room, container, or supporter.

Sounds like this is not something for which there is much of a precedent.

I think I should clarify that I’m trying to write this “decoy” code to create an extension for use in a number of adventures.
The user would typically wish to create a “world” in which the decoy would return to the place it occupied at instantiation.
As such, I can’t really make the assumption that home will always be a room or always be a thing.

The relationship approach seems to work with the various combinations of objects, odd as it sounds.
However, I am still having troubles with the the drake finding its way home to the hallway desk, when doors are involved.
Hope this isn’t a manifestation of a type mismatch.

I suppose that I could instantiate an “invisible” generic supporter in every room and define “dropping” the decoy, etc., as putting it on that supporter in the current room. I’d need to have a home-room and also a home-object within the room to make this useful. The drop logic would basically drop the decoy on the invisible supporter in the current room, then it would determine whether a path home exists using best route between the current room and the home-room, then potentially move the dropped decoy from the current rooms invisible generic supporter to the home-room object (floor, table, box etc.). In the case of a floor being the home-object, I think I’d have to explicitly define a “floor” supporter. Dropping it on the invisible generic supporter of the home room may not work.

I know my explanation is very rough and far from being either elegant or simple.
However; it would appear to address the mixing of types.

Thoughts?

So this worked for me (some debugging text is left in):

Every turn: repeat with item running through unsecure decoys: if best route from the location of the item to the location of the home of item, using doors is a direction (called indicated direction): say "[The item] spreads its wings and flies [indicated direction] back to [the home of item]."; move the item to the home of item; otherwise: say "[The item] can't find the way home to [the home of item], since the indicated direction is '[indicated direction]'."; if the home of item is not a room: say "We should be seeing if [the item] can get back to [the location of the home of item] by going [best route from the location of item to the location of the home of item]."; showme the best route from the living room to the hallway, using doors.

Note “using doors”; that’s what allows the route to go through the door. Have you tried something like this?

Full compilable code below the spoiler tag. Note that the duck still can’t get home because of that trick we were discussing before, where it’s in the same room as its home so the best route is “nothing.”

[spoiler][code]“Mallard v4” by Gary

A decoy is a kind of thing.

Room-belonging relates one room (called the home) to one decoy.
Supporter-belonging relates one supporter (called the home) to one decoy.
Container-belonging relates one container (called the home) to one decoy.

The verb to belong to (he belongs to, they belong to, he belonged to) implies the reversed room-belonging relation.
The verb to belong on (he belongs on, they belong on, he belonged on) implies the reversed supporter-belonging relation.
The verb to belong in (he belongs in, they belong in, he belonged in) implies the reversed container-belonging relation.

Definition: A decoy is secure if it is in its home or it is on its home or it is enclosed by the player.
Definition: A decoy is unsecure if it is not secure.

Every turn:
repeat with item running through unsecure decoys:
if best route from the location of the item to the location of the home of item, using doors is a direction (called indicated direction):
say “[The item] spreads its wings and flies [indicated direction] back to [the home of item].”;
move the item to the home of item;
otherwise:
say “[The item] can’t find the way home to [the home of item], since the indicated direction is ‘[indicated direction]’.”;
if the home of item is not a room:
say “We should be seeing if [the item] can get back to [the location of the home of item] by going [best route from the location of item to the location of the home of item].”;
showme the best route from the living room to the hallway, using doors.

[---------------------------------- Main -----------------------------------------]

Hallway is a room.
The Hall table is a supporter in the hallway.
The drake is a decoy on the hall table. The drake belongs on the hall table.

The Passage Door is a closed door. It is west of the hallway and east of the living room.

The Living room is a room.
The mallard is a decoy in living room. The mallard belongs to the living room.

The Dining room is west of living room.
The box is a container in dining room. The duck is a decoy inside the box. The duck belongs in the box.

Test me with “take drake / w /close door / drop drake / look / open door / take mallard / w / put mallard in box / look / take duck / drop duck / look / e”

[/code][/spoiler]

I can’t test this myself at the moment, but didn’t Sequitur say earlier that this didn’t work because you can’t have a relation of objects to things?

You’re right – I was thinking of properties rather than relations. My mistake.

This gets back to the “do it with a property” suggestion, and you’ve already posted sample code for that.

Matt;

Thanks. I had unwittingly used “using doors” and so I still had the drake flying through the apparently closed door. Seems the door needs to be locked, because best route assumes unlocked doors can be opened.

Will look at how fixing the in-same-room issue.

Yeah, I’m not sure if there’s any way to test the best route using open doors but not closed ones, at least not easily.

Sequitur posted a fix for the same room issue that I think should work; just test for that before you test for “best route.”

Thanks, Matt. Will give the “same room” fix a try and post an update on how things go.

I really appreciate the help of all of you.
Now I’ve just got to get more familiar with relations and definitions.
They seem to be a more “elegant” way of attacking this sort of issue.

The following seems to work pretty well.
If you have other suggestions, I’m always open to such things.


"Mallard v7" by Gary

A decoy is a kind of thing.

Room-belonging relates one room (called the home) to one decoy.
Supporter-belonging relates one supporter (called the home) to one decoy.
Container-belonging relates one container (called the home) to one decoy.

The verb to belong to (he belongs to, they belong to, he belonged to) implies the reversed room-belonging relation.
The verb to belong on (he belongs on, they belong on, he belonged on) implies the reversed supporter-belonging relation.
The verb to belong in (he belongs in, they belong in, he belonged in) implies the reversed container-belonging relation.

Definition: A decoy is secured if it is in its home or it is on its home or it is enclosed by the player.
	
Definition: A decoy is unsecured if it is not secured.

To decide which room is the home-room of (item - a decoy):
	let H be the home of item;
	if H is a room, decide on H;
	if H is a thing, decide on the location of H.

Definition: a decoy (called item) is free to go:
	let the best way be the best route from the location of item to the home-room of item, using doors;
	if the best way is a direction, decide yes;
	if the location of item is the home-room of item, decide yes;
	decide no.

Every turn: [You could do this with an every turn rule, or an after rule.]
	repeat with item running through unsecured decoys:
		if the item is free to go:
			say "[The item] spreads its wings and flies back to [the home of item].";
			move the item to the home of item;
		otherwise:
			say "[The item] flaps about uselessly, unable to find its way."		

[---------------------------------- Main -----------------------------------------]

Hallway is a room.
The Hall table is a supporter in the hallway.
A brass key is on the Hall table.
The drake is a decoy on the hall table. The drake belongs on the hall table.

The Passage Door is a an open lockable door. It is west of the hallway and east of the living room.
The brass key unlocks the Passage Door.

The Living room is a room.
The mallard is a decoy in living room. The mallard belongs to the living room.

The Dining room is west of living room.
The box is a container in dining room. The duck is a decoy inside the box. The duck belongs in the box.


Test all with "test drake / test mallard1 / test mallard2 / test duck".

Test drake with "take drake / take brass key / w / close door / lock passage door with brass key/ drop drake / look / unlock passage door with brass key / open door / e"

Test mallard1 with "w / take mallard / drop mallard / take mallard / w / drop mallard / e /e".

Test mallard2 with "w / take mallard / w / take duck / put mallard in box / look / e /e".

Test duck with "w / w / take duck / drop duck / look / e / e".

That’s actually the first thing I tried, but Inform doesn’t allow it:

Also…

Couldn’t that be achieved by making rooms a kind of thing, rather than a king of object? The compiler understands, for example, “An LED is part of every device.”

Edit: And yeah, I think the property solution is probably better at this point, since it bulldozes over the rooms-aren’t-things issue, especially using definitions to complement it as Draconis suggested.

Okay, but you lose the converse – the ability to make definitions on all things which are not rooms. The point is, that’s really the common case.

Could you define a thing to be “nonroom” if it is not a room, then assign parts and properties to “every nonroom thing”? But I have no idea if this would work, and it certainly wouldn’t be elegant.

Try it. :slight_smile:

I wrote:

I think we’ve fuzzed together two different questions – “should ‘room’ be defined by a class or situationally by the world layout?” vs “if ‘room’ is a class, should it be a subclass of ‘thing’?” Probably this is more analysis than the thread needs, mind you.