Stuck defining a new relation/action for new verb.

Hello,

Well I progress as if wading through treacle.

I am now trying to define a new relation that allows players to put something beside something else. So put duck beside scientist would do as you expect.

I think I need 3 (?) new bits of code for this.

  1. an action to handle the actual putting beside stuff
    2 a relationship so that you can code - if the duck is beside the scientist
  2. a chunk in the looking secton that states ‘the duck is beside the scientist’.

Needless to say I’m not getting very far.

looking at the annotated source it looks like the closest action is Inserting something into, the problem I have is there is no ‘anything’ to insert in as the second noun is in effect a location not a physical item.

There are currently containers and supporters in inform. I’m guessing that these work as relations (?) but honestly cannot get my head around the annototated source for them.

I added an object called near to things ( a thing has an object called near ) thinking that I could somehow add the second noun to the first noun’s near object and then use the following relation…


to decide if something (item - an object) is beside something else (dooda - an object):
	if the near of the item is the dooda, decide yes;
	otherwise decide no; 

I tried defining a new verb (beside) but just kept getting problem messages and I really cannot figure how to tie it all together. (In particular I fail to comprehend how to add rules to the looking rule - or whatever its called ).

Am I heading the right way, or just up a blind alley?

Advice and guidance as always hugely appreciated.

I think the problem is that you’re not actually using relations. See Chapter 13 of WI.

Here’s a quick start on implementing this idea. I used groups because I figured you don’t care whether the box is near the bed, which is near the ball, which is near the banana, and so the banana isn’t near the box—instead all of those things are close enough together to count, for simplicity.

[code]Nearness relates things to each other in groups. The verb to be near implies the nearness relation.

Placing it beside is an action applying to two things. Understand “put [something preferably held] by/beside/near/alongside [something]” as placing it beside. Understand the commands “place” and “position” as “put”.

Check placing something not held beside something held:
say “([the second noun] beside [the noun])[command clarification break]”;
try placing the second noun beside the noun instead.

Check placing something not held beside:
say “(first taking [the noun])[command clarification break]”;
silently try taking the noun;
if the noun is not held, stop the action.

Check placing something beside something held:
say “(first dropping [the second noun])[command clarification break]”;
silently try dropping the second noun;
if the second noun is held, stop the action.

Check placing something fixed in place beside something portable:
say “([the second noun] beside [the noun])[command clarification break]”;
try placing the second noun beside the noun instead.

Check placing something fixed in place beside something fixed in place:
say “[The noun] is fixed in place.” instead.

Check placing something beside when the noun is near the second noun:
if the noun is the second noun, say “[The noun] is already beside itself.” instead;
say “[The noun] is already by [the second noun].” instead.

Last check placing something beside:
silently try dropping the noun;
if the holder of the noun is not the holder of the player, stop the action.

Carry out placing something beside:
now the noun is near the second noun.

Report placing something beside:
say “You position [the noun] by [the list of other things near the noun].”

Last carry out taking:
now the noun is near nothing.

Definition: a thing is other if it is not the noun.[/code]

Obviously you’ll want to check more conditions as needed for your game—most people probably wouldn’t acquiesce to being repositioned by the player, for example—and perhaps other details of placing beside, or other actions which may alter the nearness relation.

You probably want to be able to put things beside things on supporters and inside containers as well, so I suggest replacing the ‘last check’ and ‘carry out’ rules with something like this:

Carry out placing something beside:
	let the target be the holder of the second noun;
	if the target is a container:
		silently try inserting the noun into the target;
	otherwise if the target is a supporter:
		silently try putting the noun on the target;
	otherwise:
		silently try dropping the noun;
	if the holder of the noun is the target:
		now the noun is near the second noun;
	otherwise:
		instead say "You can't put [the noun] by the [second noun]."

Many many thanks for these. Yes I don’t care how close something is to something else, just that it is there. I have a couple of puzzles which require objects to be a certain parts of a location - say to reach a grating in a particular wall by putting a step ladder near (against etc) it and then climbing the ladder. If the ladder is near the wall (which is scenary) and the player is on the ladder they can reach the grating.

I hadn’t come across groups before, Can I just check that having specifed something is near something this way I can then simply say ‘if the mouse is near the elephant’ as a test ?

I forgot about silently trying as well (clot) and was moving things into containers.

Once agan many thanks for this.

That’s right!

And thanks, Felix. I thought of enterable containers/supporters, hence the “holder of” bits, but not wanting to put things near others in/on regular containers/supporters.

This is great thank you.

I had a thought that it would be nice to be able to tell how a player has placed something (either beside, against etc) so that I could say the ball is beside the pig if the player had placed it beside and the ball is near the pig if they had placed it near. Its easy enough to store (a thing can be beside, near, against … etc) but I cannot find a way of getting at the players verb construct. Nouns are easy (noun, second noun etc) but verb - nope stuck.

I cannot find anything on the net either. It looks like Inform 7 uses verbs as commands - but if you have a synonym you cannot find out which has been typed. You cannot, as far as I can tell say if the verb is flubdingle, do something.

I guess I could define a bunch of insteads? So instead of putting something against… try placing it near. I just wonder if there is another way?

It actually works the same way for nouns. If you tell Inform to print [the noun], it won’t print the word that the player used for that object - it’ll print the name of that object in the normal way.

To get the action that’s going on, the thing you’re looking for is stored actions (see Writing with Inform 12:20: Stored actions), specifically the action name part of. But it’ll still use the normal rule for printing the name of that action, regardless of what language the player used to perform it.

So I think the way to do this would be either to, as you say, define several actions with identical mechanical effects but slightly different messages (ugly), or use reading a command to detect the exact word the player uses, storing it somewhere, and then accessing it in the report rules (or wherever).

It is possible to sneak in (at the I6 level) and look at the player’s first verb word; the parser uses this for certain error messages.

For this case, I think you want to define several different actions. You don’t have to repeat a lot of code to make this work. They could all be “thin” bits of code that invoke a common internal action which does all the real work.

Sneakier idea: use a grammar token for the preposition that records which word was used in a global variable. (This is the advanced solution, though.)

A warning: players are unlikely to grasp the subtleties of the difference between putting things beside or near other things. If a puzzle depends on it they will most likely only solve it by chance. It’s similar to using adverbs or distinguishing examine and search: don’t do it.

Hi,

Thanks for thw warning its a good point, thankfully the puzzles won’t care. I’ve added the sublety for players who might expect it. For example it would be a bit odd to put something against ‘me’ where as putting something by me makes sence. Equally if the player types ‘put the step-ladder against the north wall’ and then types look. This allows me to say ‘A step-ladder is resting against the North wall.’ Instead of ‘a generic There is a step-ladder near the North wall.’

Equally it’s enabled a bit of extra colour -

‘Put the broom against the table’
Done.
‘get the table’
The broom falls over.

So nothing much but I hope it’ll add a bit of polish to the final game and is helping me learn Inform.

Sounds like good work, PaperThing. It’s little touches like these, if you implement enough of them, that make the difference between an obviously gamey world, and something that feels like a rich representation of a real world. As long as the game is still liberal in what it accepts…

Hmmm,

I confess I have just got stuck on this. All works with the exception of reporting multiple items against/near something.

Heres some generated text regarding people to illustrate what I am trying to achieve;

So multiple people are listed as ‘are ’ and single ones as ‘is ’

The actions of the people are just text (“knitting” in the case of the cat and Mrs Jones) and I work out how many people are doing something with loops and counts.

This has resulted in some grotty code but it works.

I would like to have something similar for objects, so a description of a room might include…

The placement of the objects is again just text (“beside” in the case of the table) and once again it looks like I’m going to end up with loops and counts to figure how may objects are beside/near etc another.

I’m just wondering if there isn’t an easier way of doing this. I know the objects are either near or not near each other using the relation nearness - could there be some way to sub-divide this somehow so I can say something like

let count be the number of things that are near and against the object.

where object is a loop of things in a room/location etc.

If I follow what you’re doing, Inform can take care of a lot of it automatically. If nearness is a relation you could have

Say "Near the table [is-are a list of things near the table]."

at the appropriate point in your code. The “is-are” will automatically print “is” if there’s one thing near the table and “are” if there’s more than one. Saying “a list…” will make sure that everything gets prefaced with its indefinite article, so you get “a sofa and a standard lamp” instead of “sofa and standard lamp.” See section 5.5 of the documentation. Note that you have to make sure there’s something near the table before you print this, or you’ll get “Near the table .” which is obviously bad!

(Also, you probably can’t use “object” as a loop variable – “object” already has a meaning, as the most general category in the hierarchy of kinds, so not only things but also rooms and directions are objects. It’s more customary to use “item” as the variable.)

To use the loop variable you should just be able to say:

if a thing is near the item: say "Near [the item] [is-are a list of things near the item].";

Note that those spaces are really a tab stop.

Hi,

Many thanks for the reply. I have a relation called nearness, but also have some text for each thing called placement This text is “against”, “by”,“next to”, “near” and a few others I can’t remember right now.

So saying if item is near thingy works as you’ve suggested. My issue - and sorry for not explaining clearly - is that in order to find out how many things are specifically “against” I have to loop through all the items that are near thingy checking for the specific placement of “against” and then do the same for all those that are “next to” and do the same for all the other options.

This is a pain and I’m wondering if there is a way of defining a relation, or sub relation so that I can just say all the things against or all the things next to and so on while keeping the nearness relation or something.

Sorry I suspect I still haven’t explained very well…

OK, I think I see what you’re getting at. Here’s how I might try a subrelation.

Againstness relates various things to one thing. [This should make it so that, e.g., the tube can't be against both the table and the desk, but more than one thing can be by the table. See section 13.5.] The verb to be against implies the againstness relation. [This means we can test things with "If X is against Y" -- and since we used "to be" here we don't have to worry about telling Inform the conjugations. See sections 13.9 and 13.10. Given that you've already got some relations up and running, you probably know this already.] Byness relates various things to one thing. The verb to be by implies the byness relation. Nextness relates various things to one thing. The verb to be next to implies the nextness relation. Nearness relates various things to one thing. The verb to be near implies the nearness relation. [And now the key part, from section 13.12:] Closeness relates a thing (called X) to a thing (called Y) when X is against Y or X is by Y or X is next to Y or X is near Y. The verb to be close to implies the closeness relation.

And now you can write tests like (once again, the spaces should be appropriate tab stops):

Instead of entering the absurdly large chair: unless the stepladder is close to the absurdly large chair: say "You can't reach the chair without something to stand on."; otherwise: say "You clamber up the stepladder to the chair!"; continue the action.

which will work whether the stepladder is by, against, next to, or near the chair. And you’ll still be able to use [is-are a list of things that are against the item] and the like.

Note that in this case you can’t say in your code “Now the stepladder is close to the chair.” Inform wouldn’t know whether to put the stepladder by, against, next to, or near the chair. (It’d be like saying “Now x is less than 5.”) You have to declare a specific one of the subrelations, like “Now the stepladder is against the chair,” and then the definition of “close to” will guarantee that the stepladder is close to the chair automatically.

Hello and many thanks for the reply. That closeness code is just what I needed.

Unfortunatly this is getting more complex than I expected, probably due to my lack of understanding but also English’s wonderful vageness. There’s probably a posh word for the current problem but I can best describe it as expected size listing. Or - you normally notice large stuff before small stuff.

An example…

What I am getting though is…

Its correct, just an odd way of saying something. The above is created from a table which stores the oject’s level (location, supporter, container) what it is (table, duck, broom), if its close to something (in this case the duck entry has broom here) and how it is close (again for the duck “beside”).

I guess I could add the obects size (a single number) to this table but I haven’t a clue how to sort/ loop through just part of a table. In order to build the above I have to loop through the table x times and this is getting slow on playfic (a web site the allows you to develop inform 7 code as there is no ui for Android)

It could be I am going to have to rethink this - my initial idea was to build a relational tree - until I realised I hadn’t got a clue how even start this in Inform 7.

Anyone any suggestions?

It’s admirable that you’re working on getting your description to sound natural! This isn’t built-in functionality and generally I think people tend to let the descriptions fall where they may, but I think it’s good to try to put the biggest first.

I’d need to see your code more to give detailed advice about what to do, and if looping through the table many times is causing performance problems that’s not something I’d know how to do anything about it. But you could give an effect of sorting part of a table by doing multiple sorts. For instance, if you first sort your table in reverse size order (so the biggest entry in the size column comes first) and then sort another way so, e.g., everything that’s close to the broom is grouped together, the second sort should preserve the size ordering within the things that are close to the broom. See section 15.11 for more about sorting tables.

Or if the problem is that you want to make sure the biggest thing is first – well, that’d mean some more work writing your descriptions. And I’d love if you posted your code or linked to it on Playfic, because I’m mildly obsessed with different ways of generating smooth-flowing descriptions, and this could give me a kick in the pants to work on it more.