Rules applying to two or more objects

Is it possible to have a rule, not an action rule but a rule in a rulebook, apply to two or more objects?

Changing the relationship of is a thing based rulebook.

Changing the relationship of something (called x) and something (called y) (this is the set placement rule):
         now x is in y;

The error here says that the rule doesn’t describe a thing, and it should because it is a thing based rulebook. I think I understand why this is an error, but I would really like to do something like this correctly. I couldn’t find an example in the documentation that would help with going about doing something like this (not saying it isn’t there, just that I couldn’t find it).

Your question is a little bit ill-posed.

  • Action rules exist in rulebooks like any other rules.
  • A rule can only be based on a single argument, but its condition can refer to any number of terms. Maybe you want to use some global variables here.
  • You could define an action-based rulebook and define a special action (not used by the player). For example:
The player carries the rock.
The player carries the wand.

Changing it with is an action applying to two visible things.
Carry out changing it with:
	follow the relationship-changing rules.

Relationship-changing is an action-based rulebook.

Relationship-changing rule for changing something with the wand:
	say "Wand-zap [noun] with [second noun].";
	stop.

Relationship-changing rule for changing something with something:
	say "Generally zap [noun] with [second noun].";
	stop.

When play begins:
	try changing the rock with the wand.

This is messy (defining both an action and a rulebook, which are only used with each other) but it gives the behavior you want. You can define any number of relationship-changing rules, and you get the expected specific-before-general ordering. Just remember to put in a “stop” on each rule.

(Rather than a relationship-changing rulebook, you could rely on the usual check or carry-out rulebooks. I think a separate, special-use rulebook is tidier.)

Thank you for continuing to answer my questions, zarf.

I’m still trying to get the rule to occur based off of it being in a table, but I’m not sure how to get an action to occur out of a table the same way that another rule does (or else I’m messing up some other part of this syntax because this is getting confusing).

To decide what thing based rule is forcibly cast (R - rule): (- {R} -).

Placing is an action applying to one thing and one thing.

Carry out placing (this is the place this rule):
	now the noun is in the second noun;

The kitchen is a room. 

The player is in the kitchen.

basket is a container in the kitchen. The printed name of basket is "a basket".

Apple is a thing in the kitchen. The printed name of apple is "an apple".

Table of Basket
rule	thing
place this rule	apple

When play begins:
	repeat through Table of Basket:
		let x be forcibly cast the rule entry;
		follow x for the thing entry and basket;

This results in an error, but I don’t know how else I’d invoke the rule based on what is in the table. Can you just directly store an action in the table? It didn’t seem to like that very much either.

Sure:

[code]Lab is a room. A basket is a container in the Lab. An apple is in the lab.

Table of basket
Action
inserting the apple into the basket

When play begins:
repeat through the table of basket:
try the action entry.[/code]

If you want to manipulate the parts of the action, use Editable Stored Actions.

I need the action/rule to be agnostic to the specific item though, so that as I expand on this I can reference what item is being referenced by the rule “dynamically.” If I explicitly put the items affected by the action into the action column, this defeats the purpose of doing it this way. It’s hard to explain the full extent of what I am trying to do in I7 terms without being able to write the full code correctly, but basically I’m trying to get it to where rules and objects can be referenced from one table to the next in a lattice that allows truly dynamic changes to objects and their relationship to other objects.

I tried modifying the attempt I had above with some insights from what you guys have posted above as well though, and I think it’s closer, but in the code below, I think the parser is considering “y into z” (or “y and z” as a derivative I tried) as a single object, instead of two objects “y” and “z”. At least, I think that is what is happening and why this isn’t working:

To decide what thing based rule is forcibly cast (R - rule): (- {R} -).

Placing it into is an action applying to two things.

Carry out placing something (called x) into something (called y) (this is the place this rule):
	now x is in y;

The kitchen is a room. 

The player is in the kitchen.

A thing has a text called id. A container has a text called id.

basket is a container in the kitchen. The printed name of basket is "a basket". The id of basket is "basket".

Apple is a thing in the kitchen. The printed name of apple is "an apple". The id of apple is "apple".

Table of Basket
rule	placed id	container id
place this rule	"apple"	"basket"

When play begins:
	repeat through Table of Basket:
		let x be forcibly cast the rule entry;
		repeat with item running through things:
			if the id of item is "[the placed id entry]":
				let y be item;
				break;
		repeat with items running through things:
			if the id of items is "[the container id]":
				let z be items;
				break;
		follow x for y into z;

You should absolutely check out Editable Stored Actions by Ron Newcomb. This is what it’s designed to do; you can read off an action-name and two things and edit a stored action so that it’s the action name applied to two things. I haven’t updated this extension (because I’m still using it in projects I might update in 6G60) but the following is functional 6G60 code:

[code]Include Editable Stored Actions by Ron Newcomb.

Lab is a room.
A basket is a container in the lab.
An apple is in the lab.

When play begins:
repeat through the Table of Opening Stuff:
let the new action be a stored action;
now the action name part of the new action is the action entry;
if there is a noun entry:
now the noun part of the new action is the noun entry;
if there is a second noun entry:
now the second noun part of the new action is the second noun entry;
try the new action.

Table of Opening Stuff
action noun second noun
the inserting it into action apple basket
the jumping action – –
the examining action basket --[/code]

Now this is all going to be actions performed by the player, which may not be what you want. (You could make them into NPC actions using Editable Stored Actions, but that’s still probably not what you want.) Still, as far as actions go this should be doable.

It seems like you want to use the table instead of a rulebook. That is you want to run down the entries of the table and apply the matching one, rather than using the built-in behavior of running down the entries of a rulebook and applying the matching one.

If so, it would be easier to forget rules and rulebooks (and actions and activities) entirely. Make a table full of functions (phrases) and call them. A function can have any number of arguments.

Thanks for that… I think I know what you are saying. This is incomplete, but before I added a few new parameters to the function/tables it was working for fewer examples. I wanted to post what I have so far to make sure I’m on the right track:

The prop room is a room.
There are 100 things in the prop room.

A thing has a text called id.

To do-table-stuff with (psuedo-rule - a text) and (thing-one - a text) and (thing-two - a table name) and (p1 - a number) and (p2 - a number):
	if psuedo-rule is "set id":
		repeat with x running through things in the prop room:
			do nothing;
	if psuedo-rule is "place into room":
		repeat with x running through rooms:
			do nothing;
	if psuedo-rule is "place into":
		repeat with x running through things:
			if the id of x is thing-one:
				repeat with y running through things:
					if the id of y is thing-two:
						now y is in x;
						break;
				break;
	if psuedo-rule is "set color":
		say "[thing-one]";
		say "[p1]";
		repeat with x running through things:
			if the id of x is thing-one:
				if p1 is:
				-- 0: now the color of x is red;
				-- 1: now the color of x is blue;
				break;	
	

The kitchen is a room. 

The player is in the kitchen.

basket is a container in the kitchen. The printed name of basket is "a  basket". The id of basket is "basket".

Apple is a thing in the kitchen. The printed name of apple is "a [color of the item described] apple". The id of apple is "apple".

Table of Apple
psuedo-rule (text)	thing-one (text)	thing-two	p1 (number)	p2 (number)
--	--	--	--	--

Table of Kitchen
psuedo-rule (text)	thing-one (text)	thing-two	p1 (number)	p2 (number)
"place into room"	"kitchen"	Table of Basket	

Table of Basket
psuedo-rule (text)	thing-one (text)	thing-two	p1 (number)	p2 (number)
"set id"	"basket"	--	0	0
"set color"	"basket"	--	1	0
"place into"	"basket"	Table of Apple	0	0

When play begins:
	repeat through Table of Kitchen:
		do-table-stuff with the psuedo-rule entry and thing-one entry and thing-two entry and p1 entry and p2 entry;

Basically, like you said, a normal rule is too restrictive because it can only have certain kinds of things, whereas I need to be able to pass whatever parameters I want at all times. Again, I know the above is under construction and some parts are dead ends, but you should be able to see where I am going with it. Are there any “gotchas” to the above (besides complexity and it not being the standard way of doing things)?

I was going to say, isn’t this exactly the sort of thing that phrases are for? I feel like dootdoot is having trouble because rulebooks, while powerful, are too specialized for his situation.

To do-table-stuff with (psuedo-rule - a text) and (thing-one - a text) and (thing-two - a table name) and (p1 - a number) and (p2 - a number):
	if psuedo-rule is "set id":

That works.

You could also do:

The Kitchen is a room.

To do-set-id with (thing-one - a text) and (thing-two - a table name) and (p1 - a number) and (p2 - a number)(this is set-id-phrase):
	say "...set ID [thing-one]...".

To do-place-room with (thing-one - a text) and (thing-two - a table name) and (p1 - a number) and (p2 - a number) (this is place-room-phrase):
	say "...place room [thing-one]...".

Table of Default
number
0

Table of Kitchen
phrase (phrase (text, table name, number, number) -> nothing)	thing-one (text)	thing-two	p1 (number)	p2 (number)
place-room-phrase	"kitchen"	Table of Basket	0	0

Table of Basket
phrase (phrase (text, table name, number, number) -> nothing)	thing-one (text)	thing-two	p1 (number)	p2 (number)
set-id-phrase	"basket"	Table of Default	0	0

To apply (function - phrase (value of kind K, value of kind L, value of kind M, value of kind N) -> nothing)
	to (input - K) and (second input - L) and (third input - M) and (fourth input - N):
        (- {-primitive-definition:function-application}; -).

When play begins:
	repeat through Table of Kitchen:
		apply the phrase entry to thing-one entry and thing-two entry and p1 entry and p2 entry;

Here we give each phrase a name, so it can be used as a value. (See 22.3.)

I had to define a four-argument version of “apply”, because the standard rules only define up to three-arg versions. I also filled in the blank entries of each table, which is a nuisance, but you have to do it because Inform won’t let you read blank entries.