Defining the relation "vertical arrangement"

Hi again!

I’ve searched high and low to find some extension that contains this relation but somehow I cannot find any.
I’m trying to relate objects that have a vertical relation, i.e. “over”, “under”, or “vertically unrelated”. I need this to eventually stack things but right now I need it to push something under something else, e.g. push a chair under a window - this relates the chair as being “under” the window and the window being “over” the chair. I also want to print their relation to each other in the printed name once I want this to be. So I want the printed name of “chair” be “chair (under window)”.
I’m not sure how to define the new relation, but that’s what I’ve got:

[code]Vertical arrangement relates things to each other.
The verb to be under of means the vertical arrangement relation.
The verb to be over of means the vertical arrangement relation.

Pushing it under is an action applying to two things.
Understand “push [something] under [something]” as pushing it under.
Report pushing it under:
say “You push [the noun] under [the second noun].”
Carry out pushing it under:
now the noun is under the second noun;
now the second noun is over the first noun.[/code]
I know that I’ll have to restrict the relation to something like “directly under” but that’s for later. For now I just want to relate two objects. I thought that the above text was enough but Inform doesn’t recognize the last two sentences. What do I need to add?
It would be nice to also have an adjective describing if something is able to be above something or below something else.
While we’re at it, we can also define a horizontal relation of “(directly) next to”.

Thanks for your help, you’re really a goldmine of information here! :slight_smile:

Regards, Timo

To directly solve your problem, the reason your last two lines don’t work is because of these two lines:

The verb to be under of means the vertical arrangement relation. The verb to be over of means the vertical arrangement relation.

You would have to write “The noun is under of the second noun” or “the second noun is over of the first noun” in order for Inform to understand it. You could simply rewrite them as:

The verb to be under means the vertical arrangement relation. The verb to be over means the vertical arrangement relation.

But I would recommend making this relation more robust. As it is, the relation cannot distinguish between things being over or under other objects. I would rewrite your first three lines to this:

Overtopping relates one thing to one thing. The verb to be over means the overtopping relation. The verb to be under means the reversed overtopping relation.

… so that the relation is one-to-one, and is not reciprocal. In addition, you can get rid of this line:

now the second noun is over the first noun.

… due to being redundant. (Inform doesn’t understand “first noun”, by the way; it’s either “noun” or “second noun”.)

[code]Overtopping relates one thing to one thing.
The verb to be over means the overtopping relation.
The verb to be under means the reversed overtopping relation.

Pushing it under is an action applying to two things.
Understand “push [something] under [something]” as pushing it under.
Report pushing it under:
say “You push [the noun] under [the second noun].”
Carry out pushing it under:
now the noun is under the second noun.[/code]

This is more complex than you probably think. Before going down this road, be sure that your game really needs a general model of this rather than an ad hoc impl.

Here’s a rough draft. See the comments for open issues.

Section 1 - Vertical Arrangement

[This assumes that we want to allow multiple things to be under the same thing.]

Vertical arrangement relates various things to one thing (called the uber).
The verb to be under means the vertical arrangement relation.
The verb to be over means the reversed vertical arrangement relation.

Definition: a thing is sub if it is under something.

Definition: a thing is super if it is over something.

Rule for printing room description details of a sub thing (called S):
	say " (under [the uber of S])"

After examining a sub thing:
	say "[The noun] [are] under [the uber of the noun].";
	continue the action.

After examining a super thing:
	say "Underneath [the noun] [we] [can] see [the list of things under the noun with indefinite articles].";
	continue the action.
	
[TODO: need a flag (and check rule) for things that it doesn't make sense to push things under, like the ball.]

Section 2 - Pushing It Under

Pushing it under is an action applying to two things.
Understand "push [something] under [something]" as pushing it under.

Check pushing it under when the noun is the second noun (this is the can't push something under itself rule):
	instead say "[We] [can't push] [the noun] under [themselves]." (A).

Check pushing it under when the player encloses the noun (this is the can't push something held under rule):
	instead say "[We] [can't push] [the noun] while [we]['re] carrying [regarding the noun][them]." (A).

Check pushing it under when the player encloses the second noun (this is the can't push something under something held rule):
	instead say "[We] [can't push] [the noun] under [the second noun] while [we]['re] carrying [regarding the second noun][them]." (A).

[May need to relax this for pushing furniture around]
To move is a verb.
Check pushing a fixed in place thing under (this is the can't push fixed in place things under rule):
	instead say "[We] [can't move] [the noun]." (A).

Check pushing it under when the noun is under the second noun (this is the can't push something under its uber rule):
	instead say "[The noun] [are] already under [the second noun]." (A).

Check pushing it under when the noun is over the second noun (this is the can't push something under its subordinate rule):
	instead say "[We] [can't push] [the noun] under [the second noun], because [the second noun] [are] under [the noun]." (A).

Check pushing it under when the second noun encloses noun (this is the can't push something under its container or supporter rule):
	instead say "[We] [can't push] [the noun] under [the second noun], because [the noun] is already [if the second noun is a container]in[else]on[end if] [the second noun]." (A).

Check pushing it under when the noun encloses the second noun (this is the can't push something under its contents rule):
	instead say "[We] [can't push] [the noun] under [the second noun], because [the second noun] [are] in [the noun]." (A).	

[TODO: component parts. See tests with bucket handle.]

Carry out pushing it under:
	now all things under the noun are not under the noun;
	now the noun is under the second noun.
	
Report pushing it under (this is the report pushing it under rule):
	say "[We] [push] [the noun] under [the second noun]." (A).

[TODO: If we have pushing it under, we should probably have putting it under as well]

Section 3 - Severing the Relation

The pushing action has an object called the old uber.

Setting action variables for pushing:
	now the old uber is nothing.

Before pushing a sub thing:
	[save the uber before clearing it so we can use it in our report rule later]
	now the old uber is the uber of the noun.

After taking or pushing a sub thing:
	now the noun is not under the uber of the noun;
	continue the action.
	
After taking or pushing a super thing:
	now all things under the noun are not under the noun;
	continue the action.
	
Report pushing when the old uber is not nothing (this is the report pushing a sub thing rule):
	instead say "[We] [move] [the noun] out from under [the old uber]." (A).
	
The report pushing a sub thing rule is listed first in the report pushing rules.

[TODO: if the chair's under the window and the ball's under the chair and we move the chair, should the ball be placed under the window rather than not under anything?]

Section 4 - Living Room

Living Room is a room. "The is the living room. There's a window on one wall and a clock on another."

The window is scenery in the Living Room.

The clock is scenery in the Living Room.

The chair is an enterable portable supporter in the Living Room.

The bucket is a container in the Living Room. The description is "The bucket has a handle."
The handle is part of the bucket.
A rubber ball is in the bucket.

Section 5 - Tests

Test ok with "push chair under chair / push window under chair / x chair / x bucket / x window / x clock / push chair under window / l / x chair / x window / push chair under window / push bucket under window / l / x bucket / x window / push bucket under clock / x bucket / x clock / x window / push ball under bucket / push bucket under ball / take ball / push ball under chair / drop ball / take chair / push ball under chair / drop chair / push ball under chair / x ball / x chair / x window / push chair under window / x ball / x chair / x window / move chair / l".

Test fail with "push handle under bucket / push bucket under handle / push handle under ball / push ball under handle".

Test me with "test ok / test fail".

First of all, thanks a lot for this detailed solution! :smiley: It comes really naturally to me, although I’d change a thing or two, which I will try myself later (so you don’t need to work it out - I’ll get back to you as soon as I’ve succeeded or decided I’ve failed). I’d really implement the whole thing to have the possibility to work with it as my project will be really long if I decide to go through with it (a whole book…).

These are my ideas (you can skip them if you don’t want to be bothered by unnecessary text :wink: ):[spoiler]- adding the verb “put [something] under/over [something]” (really easy)

  • adding the possibility to put more than one thing under another (maybe a bit harder?)
  • trying to implement a uber-capacity (probably not that easy)
    I thought the last point can be interesting when you have some relation between something fixed on a wall and something that is lying or standing underneath it because then the uber-capacity would be 1. On the other hand, if you have a light source like a roof window you can leave out the capacity and put as many things under it as you like. Of course after a certain number of things put under the light source it gets unrealistic but I think for the moment it absolutely suffices. My idea is to define a kind of container (called a contuber :wink: ) that can be part of a[n] (uberistic? :wink: ) thing. It is transparent and enterable only if the thing under the uber thing is an enterable supporter. Of course you’ll need a workaround if you take the uber thing while standing on the supporter but that’s a thing I can work out myself. Something like “now the contuber is nowhere” after putting all the things in it in the room itself will absolutely suffice.[/spoiler]
    Ok, well, I’ll see you in a couple of hours with my results.

Cool. Interested in what you come up with.

A quick note:

The example already does this (hence “various things to one thing” instead of “one thing to one thing”). Try “push chair under window. push bucket under window. x window”.

Ok, I’ve begun to define some things but currently I’m at a halt because there’s something I don’t know how to do:

I need to list the contents of contubers (i.e. just transparent and enterable kinds of containers) in the room description which doesn’t work as I would like it to. This:Rule for printing room description details of a contuber: say "[if noun is non-empty] under which you can see [the list of things in the noun with indefinite articles] lying on the floor.[end if]"; continue the action.
does work for nondescript contubers but I want it to work with nondescript contubers as well - just adding a sentence behind the description.
An ideas?

Here’s another one, that doesn’t work - while trying to check some things like trying to put something under something else when the capacity is depleted:

[code]Putting it under is an action applying to two things.
Understand “Put [something] under [something]” as putting it under.

Check putting it under when the second noun is full (this is the put in full contuber rule):
instead say “There’s no more space to put it. You’ll have to remove things from under [the second noun].”

Carry out putting it under:
silently try inserting the noun into the second noun;
say “[line break]You place [the noun] under [the second noun].”.

Definition: a container is full if the number of things in the noun is the carrying capacity of the noun.[/code]
The error message printed is that (if the noun is not a container) the noun is not allowed to have a capacity. What’s the confusion here?

I will also need to change all the standard messages for containers and substitute the “in” with “under”.

Try this to handle things that have an initial appearance (i.e., things that are not nondescript):

Rule for writing a paragraph about a thing (called T):
	if the initial appearance of T is empty, continue the activity;
	say "[The initial appearance of T][if T is super] Underneath [them], [we] [can see] [the list of things under the T with indefinite articles] lying on the floor.[no line break][end if][line break]"

The above is written for my earlier example rather than for use with contubers, because I don’t really get the need for contubers. It also assumes that you don’t have other rules for writing a paragraph about things. I think we’d also need a different solution for supporters without an initial appearance that have a paragraph written about them because they have objects on them.

You said:

If you just want to implement capacity for uber things, I would do something like this:

A thing has a number called coverage capacity. The coverage capacity of a thing is usually 0.

Definition: a thing is uberfull if the number of things under it >= its coverage capacity.

Check pushing it under when the second noun is uberfull (this is the can't push something under an uberfull thing rule):
	instead say "[if the coverage capacity of the second noun is 0][We] [can't put] anything under [the second noun][else][The second noun] already [have] too many things under [them][end if]." (A).
	
The coverage capacity of the window is 1.

For the sake of testing, we make the window the only thing with a coverage capacity and give it a capacity of 1. Add this code to the earlier example and then try “push chair under clock. push chair under window. push bucket under window”.

To address something that you haven’t asked about yet: if you implement putting it under as well as pushing it under, you’ll likely find that many of the check rules are duplicated across both actions. You can get rid of this duplication by putting the duplicate rules in their own rulebook and giving each action a check rule that abides by the shared rulebook.

Ok, I’ve implemented most of the cases including the last part - thanks a lot. I digressed from the idea of the contuber because it isn’t intuitive speech and too many things would have to be changed from the standard.
I have problems regarding:

Before putting a sub thing: now the old uber is the uber of the noun. or

After putting a sub thing: now the noun is not under the uber of the noun; continue the action. Because putting is an action that already exists. Is it possible to limit this to “putting it under”?
I also get the error message “Variable unavailable for this action, activity or rulebook: internal ID number 20038/0” when I try to put something under. So maybe this is a bit more complicated after all? Or should I just use an instead rule like “Instead of putting something under something, try pushing the noun under the second noun.”?

Another thing I’d like to implement is actually “uberistic”. If I define the new adjective for things, can I directly use this in the rules you defined? I mean, can I write “uberistic thing”?

Thanks a LOT for going through all this trouble for my problem! I’m learning quite a lot by this example.

P.S.: Sadly, I have no idea how to make something abide and all the things with rulebooks. :blush: I’ll get to it soon and try to understand how it works. After all, I want to finish the project some time and so I’ll need to learn a lot of things.

It is possible to limit your rules to putting it under. You’d say “before putting a sub thing under” or “before putting a sub thing under something”. There’s a subtle distinction in the case where you have a rule for supplying a missing second noun, but you probably don’t need to worry about that now. I’d go for the former if in doubt.

Generally, there’s nothing wrong with modifying an action that already exists, so long as you understand its current behavior. It’s often helpful to look at the information in the Actions Index for a given action and to open up the standard rules (File → Open Installed Extension → Graham Nelson → Standard Rules) and search for it.

In this specific instance, I don’t understand the purpose of the two rules that you wrote. Note that the similar rules in my example were for the pushing action (already defined) and not the pushing it under action (which we defined). The idea was that vague movement via “move ” or “push ” of a sub thing would move it out from under its uber and make it no longer under anything. The ‘old uber’ action variable exists because, by the time the report rule runs (that says “You move the out from under the ”), the relation has already been severed by the ‘after pushing a sub thing’ rule.

In the example, ‘old uber’ is defined as an action variable (see §12.10) for the pushing action. This error means that you’re trying to use it in a different action.

IIRC, I7 won’t let you have action variables with the same name for two different actions, so, if you do define it for putting, you’ll need to give it a different name. However, I don’t know why you’d need it. Putting requires that the noun be held, which means that it won’t be under anything, which means that it will have no uber to save. I could see it being useful for the taking action, though, if you wanted “You remove the from under the ” instead of “Taken”.

If you did this, it would use all of the check rules for the pushing it under action, not all of which are appropriate for putting something under something (e.g., the one about the noun being carried by the player).

If, by uberistic, you mean something under which something else can be put, then I think that, despite my code comment about “need a flag (and a check rule)”, we get this for free with the coverage capacity property.

Definition: a thing is uberistic if its coverage capacity > 0.

After defining this, you can write rules about uberistic things. The check rule that I wrote in my previous post, with the embedded conditional about whether coverage capacity is 0, gives us most of what we need (it won’t let something be pushed under a non-uberistic thing), but it could perhaps be made clearer with this definition.

Here’s a simple example of two actions sharing a rulebook for checking.

Section 1 - Foobar Rules

The foobar rules is a rulebook.

A foobar rule when the noun is scenery (this is the can't foobar scenery rule):
	instead say "[We] [can't do] that to [the noun], because it's scenery." (A).
	
A foobar rule when the turn count is odd (this is the can't foobar on odd-numbered turns rule):
	instead say "[We] [can't do] that to [the noun] right now, because the turn count ([turn count]) is odd. Try again soon!" (A).

Section 2 - Fooing

Fooing is an action applying to one thing.
Understand "foo [something]" as fooing.

Check fooing (this is the check fooing rule):
	abide by the foobar rules.
	
Report fooing (this is the report fooing rule):
	say "[We] [foo] [the noun]." (A).
	
Section 3 - Baring

Baring is an action applying to one thing.
Understand "bar [something]" as baring.

Check baring (this is the check baring rule):
	abide by the foobar rules.

Report baring (this is the report baring rule):
	say "[We] [bar] [the noun]." (A).

Section 4 - Verbs

To foo is a verb.
To bar is a verb.

Section 5 - Status Line

When play begins:
	now the right hand status line is "Turns: [turn count]".

Section 6 - Living Room

Living Room is a room. "This is the living room. There's a window on one wall."

The window is scenery in the living room.

The chair is an enterable portable supporter in the Living Room.

Section 7 - Tests

Test me with "foo window / bar window / foo chair / foo chair / bar chair / bar chair".

You may have noticed that I cheated a bit and avoided using the name of the action in the output, instead using the vague phrasing “You can’t do that”. I did this to simplify the example. Here’s a way to fix that. This replaces sections 1 and 4 of the above example:

Section 1 - Foobar Rules

The foobar rules is a rulebook.
The foobar rulebook has a verb called the current verb.

First foobar rule (this is the set the current verb rule):
	now the current verb is a random verb that describes the action name part of the current action.

A foobar rule when the noun is scenery (this is the can't foobar scenery rule):
	instead say "[We] [can't] [infinitive of the current verb] [the noun], because it's scenery." (A).
	
A foobar rule when the turn count is odd (this is the can't foobar on odd-numbered turns rule):
	instead say "[We] [can't] [infinitive of the current verb] [the noun] right now, because the turn count ([turn count]) is odd. Try again soon!" (A).

Section 4 - Verbs

[See example 250: History Lab]
Describing relates various verbs to various action names. The verb to describe means the describing relation.
To foo is a verb. The verb foo describes the fooing action.
To bar is a verb. The verb bar describes the baring action.

For cutting and pasting convenience, here’s the full program with the replacement code substituted in:
[rant][code]
Section 1 - Foobar Rules

The foobar rules is a rulebook.
The foobar rulebook has a verb called the current verb.

First foobar rule (this is the set the current verb rule):
now the current verb is a random verb that describes the action name part of the current action.

A foobar rule when the noun is scenery (this is the can’t foobar scenery rule):
instead say “[We] [can’t] [infinitive of the current verb] [the noun], because it’s scenery.” (A).

A foobar rule when the turn count is odd (this is the can’t foobar on odd-numbered turns rule):
instead say “[We] [can’t] [infinitive of the current verb] [the noun] right now, because the turn count ([turn count]) is odd. Try again soon!” (A).

Section 2 - Fooing

Fooing is an action applying to one thing.
Understand “foo [something]” as fooing.

Check fooing (this is the check fooing rule):
abide by the foobar rules.

Report fooing (this is the report fooing rule):
say “[We] [foo] [the noun].” (A).

Section 3 - Baring

Baring is an action applying to one thing.
Understand “bar [something]” as baring.

Check baring (this is the check baring rule):
abide by the foobar rules.

Report baring (this is the report baring rule):
say “[We] [bar] [the noun].” (A).

Section 4 - Verbs

[See example 250: History Lab]
Describing relates various verbs to various action names. The verb to describe means the describing relation.
To foo is a verb. The verb foo describes the fooing action.
To bar is a verb. The verb bar describes the baring action.

Section 5 - Status Line

When play begins:
now the right hand status line is “Turns: [turn count]”.

Section 6 - Living Room

Living Room is a room. “This is the living room. There’s a window on one wall.”

The window is scenery in the living room.

The chair is an enterable portable supporter in the Living Room.

Section 7 - Tests

Test me with “foo window / bar window / foo chair / foo chair / bar chair / bar chair”.
[/code][/rant]
As a final note, I’m still not happy with the ‘rule for writing a paragraph about a thing’ from my previous post. It has too many caveats. I think we could do something better, perhaps using the ‘marked for listing’ status of the various items (assuming that it’s set or not set early enough). I need to take a closer look at §18.26 and the corresponding code in the standard rules.

Me too!

Cool, thanks a lot for the example, that made some things quite clear to me! :slight_smile:

About “uberistic”: I actually want to define it the other way round if it is somehow possible. Meaning that
1 - a thing usually has a covering capacity of 0
2 - if a thing is uberistic, its covering capacity is usually infinite (or 999 for that matter).
How do I achive the second one?
Else, I’ll try to implement some check for something that is un-uberistic. In my story I found it inconvenient to always set the coverage capacity of a thing and thought it simpler to just define something as uberistic and automatically have the covering capacity coming with it (similar to containers, that’s why I initially thought of contubers) as well as vice versa. So if a thing has a coverage capacity, it’s automatically uberistic as well as if a thing is defined as uberistic, it’s coverage capacity is 999 unless said otherwise. Is this even possible in Inform 7?

I’ve decided that I leave out putting for now because it gives me quite a headache at the moment. :wink: However what I’ll try to implement is an action “stand under [something]”, just to see if I can manage it. I already have the problem that I don’t know how to change the printed name in the room description (the headline) to [printed name of location] (under [something]) as well as the status line. I know it’s easy so maybe you could just write it out for me so I know it from now on. :slight_smile:

I found it convenient to write a rule like this:Check standing under when the noun is non-uberistic (this is the can't stand under a non-uberistic thing rule): instead say "There's no place to stand under [the noun]. " (A). without the need to define a coverage capacity. I don’t know if something like that sounds sensible. :wink:

Another thing that doesn’t work is

Instead of going when the player is standing under something (called an actor header): say "[We] first [move] out from under [the actor header]."; now the player is not under the actor header.
What’s wrong here?

Forget it, I found out how to deal with it. This works fine:Before going: if the player is under something (called the header): say "[We] first [move] out from under [the header]."; now the player is not under the header; continue the action;
:slight_smile:

Just a note–you don’t need “continue the action” in a Before rule if you want the action to continue–by default Before rules don’t stop the action.

And you do need “continue the action” in an Instead rule if you want the action to continue, because Instead rules by default do stop the action. That might have been your problem.

Thanks for the hints. :slight_smile:

However, I had another problem with the other code that didn’t work: Inform 7 didn’t recognize the action “going when the player is under something”. I’m quite positive that there is a way to do this without the if-clause. How can I change this line to work?

Inform was fine with this (added to the test program we’ve been discussing here):

Before going when the player is under something (called the header):
	say "[We] first [move] out from under [the header].";
	now the player is not under the header.

You could also do:

Before going when the player is sub:
	say "[We] first [move] out from under [the uber of the player].";
	now the player is not under the uber of the player.

Note that “before going” will trigger even if the player is attempting to go in a direction with no exits. You can change this by modifying the rule to “before going somewhere”.

I’m not sure what the problem in your program was, but I notice that your instead rule from a few posts ago says “standing under something” while the before rule says “under something”. What verb phrase did you give the vertical arrangement relation in your program?

Testing my example here also revealed an issue: we need a check rule to prevent “push self under window”.

Check pushing it under when the noun is the player (this is the can't push yourself under rule):
	instead say "[We] [can't push] [ourselves] under anything." (A).

Ok, tested these things and they work. Thanks for your help! :slight_smile:

Here are some other issues I want to work out but need help with for now:

  • if a thing is defined as being uberistic, it should automatically be given a coverage capacity of 999
  • I need to define a putting under action
  • if there’s an enterable supporter under something and the player tries to put something under the uber thing that exceeds the coverage capacity, the thing should automatically put on the supporter
  • if an enterable supporter is under the uber which has a coverage capacity of 1: when the player tries to stand under the uber, he should automatically enter the supporter
  • if the player puts something on a supporter that is under something, the thing he puts on the supporter should also be under the uber
  • if an enterable supporter is under an uber thing and the player enters the supporter, he should automatically be under the uber thing
  • if the player stands under something, I’d like to add a “(under the [uber])” to the room title (like with containers or supporters)
  • if the player is on an enterable supporter that is under something, I’d like to add “(on the [supporter] under the [uber])” to the room title
  • I need to print a list of things which are not the player (regarding the standing under action I’ve defined) - “[the list of things under the noun which are not the actor]” doesn’t work; I always get “yourself” listed.

P.S.: Why aren’t enterable supporters pushable? They are automatically defined as fixed in place but I don’t think that’s really sensible because in most cases these are pieces of furniture which CAN normally be pushed around. If a supporter should be fixed in place, you can simply define it that way. I get the feeling that Inform is too intrusive here.

You can define an enterable supporter (or any other supporter) as pushable between rooms; having things not be pushable between the rooms is the default. If you do it like this:

Furniture is a kind of supporter. Furniture is always enterable. Furniture is always pushable between rooms. The chair is furniture in Games Room.

then the chair, and anything else you define as “furniture” will always be an enterable pushable between rooms supporter. (They’ll still be fixed in place, though; that’s a separate property, which means you can’t fix them up.)

There are lots of reasons why something might not be pushable between rooms–maybe they don’t have wheels, or maybe the supporter is something like a pedestal that’s not a separate pushable thing, or maybe your “rooms” are separate parts of a forest or something that where pushing a chair around doesn’t make much sense. Since this is a separate complication, I think it makes sense for Inform to leave “pushable between rooms” off by default and let you turn it on if it’s something you want. (And everything is by default not pushable between rooms, even things you can pick up.)

Ok, that makes sense but even if I define furniture as pushable between rooms, I cannot push a supporter under something - which is what I need here. I want Push chair under window to work. How do I manage this? Can I somehow overwrite the “all supporters are fixed in place” rule?