Can Inform “Behaviours”/ kinds of actions be nested?

In inform 7, kinds of actions can be created by saying things like:

Eating is physical stuff. Drinking is physical stuff.

And then it shows up in the Behaviours tab of the Index as a kind of action.

Frequently I want to include all of one kind of action as another kind of action. For instance, I currently have kinds of actions called Spellcasting and Freeacting. I’d like every spellcasting action to be a freeacting action.

I’ve tried “Spellcasting is Freeacting” and “Spellcasting is a kind of freeacting”.

The “type” of Spellcasting that comes up in error messages is “a described action”.

Does anyone know if there’s a way to make every Spellcasting action a Freeacting action?

1 Like

What are you trying to achieve? Can you make a new kind of action and have spellcasting and freeacting that kind?

I’m certain you can’t make one action be another action, how would it decide what rules to use?

1 Like

This has come up before; see Use already-defined kinds of action to define new kinds of action? for a related discussion.

The relationship between kinds of action and actions is many-to-many, so a given action can qualify as more than one kind of action, but I don’t think that nesting of definitions is allowed.

4 Likes

Spellcasting and Freeacting are already kinds of actions. Freeacting is supposed to include everything you can do without moving:

Examining is Freeacting. Looking is Freeacting. Taking inventory is Freeacting.

Spellcasting is a kind of action including a lot of spell actions I invented:

Fladhing is Spellcasting. Denuing is Spellcasting.

The point is to write rules like:

Instead of doing anything other than freeacting during gripped-scene:

This works just fine, and I can even say:

Instead of doing anything other than freeacting or Spellcasting during gripped-scene:

And that compiles perfectly and is mostly what I want (I didn’t have this working at the time I posted).

But I’d like to just be able to say “hey, every action that is Spellcasting is also freeacting” so I don’t have to type both every time.

I didn’t see your response while I was typing. An adjective seems like a great solution!

Hmm, could you get around this with a when play begins rule that runs through the spellcasting actions, or some other workaround like that?

Edit: nm, saw the adjective/definition thing.

1 Like

It seems like your adjective solution can be used to substitute for Behaviors, as well as expanding the functionality beyond what Behaviors are capable of doing (e.g. nesting). Is it safe to say that avoiding Behaviors altogether might be a reasonable idiom when creating categories of Actions, or can Behaviors do something that adjective definitions cannot do?

As was pointed out in an old post I came across (Kinds of action - #3 by Ron_Newcomb), the internal structure of a “behavior” is just a routine returning a boolean/truth state. For example, given

Jumping is behaviorA.

Waving hands is behaviorA.

the I7 compiler produces something like

[ NAP_0 ;
	if ((((action ==##Jump)))) rtrue;
	if ((((action ==##WaveHands)))) rtrue;
	rfalse;
];

The routine has no parameter, it just examines the action global used by the parser and templates – essentially inspecting a part of the current action. It’s not exactly the same type of thing as what’s produced for a definition, which is a routine that takes a parameter (of some type) and returns a truth state. I’m not sure how much functional difference that makes at the I7 level, though, because the compiler allows use of a behavior as an adjective on a stored action (e.g. if the current action is On-Task...). It seems that, when testing for applicability of a behavior, the generated code also looks at actor and/or act_requester at the point of checking NAP_0(), so the I6 routine by itself is not the whole story.

Note that using an adjective as shown is not really allowing nesting of behaviors, it’s just simulating that ability (sort of). I wouldn’t say that behaviors should categorically be avoided. Certainly use of behaviors would be easier to read and understand in the source code than a very complicated definition.

I can’t think of anything that is uniquely available only to behaviors, but if I do I’ll come back to post it. (And I encourage anyone else to chime in if they can think of one.)

A side note for the Mad Scientists’ Club: I’m noticing that in 6M62, it’s possible to define rules like

After behaviorA:
	...

After an actor behaviorA:
	...

but there doesn’t seem to be an equivalent capability to write one like

After someone behaviorA:
	...

I’ve been experimenting with action patterns in my lab, too. From Syntax.preform:

<action-pattern> ::=
        asking <s-ap-parameter> to try <ap-three-present> |
        <s-ap-parameter> trying <ap-three-present> |
        an actor trying <ap-three-present> |
        an actor <ap-three-present> |
        trying <ap-three-present> |
        <ap-three-present> |
        <actor-description> <ap-three-present>

It turns out that there’s not something special about someone that excludes the player: there’s something special about an actor that it includes the player. It’s the norm for Inform to exclude the player from descriptions of actors except for these cases:

  • the absence of any actor-description, e.g., before examining:
  • yourself (or if the player isn’t yourself, whichever appropriate object name) [see below]
  • the player (but not other object variables and I really don’t get that one)
  • an actor

In fact, if you say the actor or just actor instead of an actor, then you’re dealing with the actor variable and not the an actor special case and the player is excluded!

I suspect including an actor description with a named action pattern isn’t meant to be allowed and should be a compiler error. One can also use the other patterns above:

Examining yourself is vanity.

Before an actor vanity: say "an actor.".
Before trying vanity: say "trying.".
Before asking someone to try vanity: say "asking someone to try".
Before an actor trying vanity: say "an actor trying vanity".
3 Likes

I had a running joke for a while about “double secret documentation” that moved up to “triple” then “quadruple” and so on. At this point I’ve lost track, so I don’t know how to characterize Syntax.preform, but thank you for pointing out yet another revelatory text.

2 Likes

The literate source is the double secret documentation! But now the secrets are kept chiefly through sheer quantity and the degree to which it feels like you need to understand the whole to understand any part.

if-module Chapter 4: Actions

1 Like

Actually, (and unexpectedly) a specific named object which is the player but is not the yourself object is excluded in the actor clause of action patterns. In other words, if the player is Bob

Before Bob jumping: say “Wheeeeee!”.

will not fire after the typed command jump

(because the compiled I6 includes if (actor ~= player) )

1 Like

oops, I forgot you told me that!

1 Like

Mad Scientist responding…

The syntax of action patterns is interesting and often slightly obscure to me even after perusing the literate source.

Furthermore, the parsing of them has changed slightly between 9.3 and 10.1.2, such that some slightly ambiguous things that were incorrectly parsed or wouldn’t compile at all in 9.3 now work.

The full structure of an action pattern (excluding requested actions, for simplicity) is exemplified by the following:

Before
a knighted person                                            [actor clause]
going inside                                                 [basic action pattern- can't include 'it' here: so 'putting' or 'putting on' rather than 'putting it on']
to the Cave                                                  [this and the next line represent a list of clauses aliased by action variables]
with a lit thing which is in a carried transparent container [with => along with a pushed item*]
in the Cave Entrance	                                     [location (of the actor) clause] 
in the presence of the page                                  [in the presence of clause]
when the dragon is in the Cave                               [when clause- this is the only clause allowed an 'and' or 'or']
for the first time                                           [no. of times clause**]
during sunrise:                                              [during a scene clause]
	say "The page looks at you quizzically in the early dawn light.".

[* the pushing it to action internally invokes a going action, with the pushed item temporarily carried by the actor during the going action before being set down again at the destination, at the end of the pushing it to action. As an illustration of the difficulties of parsing, we can’t write ‘held by the actor’ or ‘carried by the actor’ here because ‘held’ and ‘carried’ are adjectives defined in the Standard Rules and so this clause would be parsed as two separate aliased action variable clauses: ‘with a lit thing which is carried’ and ‘by the actor’ (meaning ‘travelling by the actor’ as in ‘travelling by vehicle’). Even with the above phrasing, 9.3.incorrectly parses this clause as implying that the ‘lit thing’ in its container is contained by the Cave Entrance, rather than that the actor’s location is the Cave Entrance. Ver 10.1.2 parses it correctly] (9.3’s interpretation can be forced in Ver 10.2.1 by bracketing the two clauses together- (a lit thing which is in a carried transparent container in the Cave Entrance) ).

[** this is the no of times the action has occurred with all preceding parameters being true, i.e. excluding the scenery one. So if the fully-described action occurs for the first time while sunrise is not happening, this rule will never fire. The easiest way of thinking about this is that the ‘no. of times’ clause is bracketed with the preceding clauses, so the rule fires if and only if (all this happens together for the first time) during sunrise.]

[A named action pattern is only allowed to have some of the clauses of a full action pattern.]
[NB named action patterns must be defined in source AFTER the actions they refer to]
[behaviour characterised by named action patterns can only specify the action not the actor: as a result, it cannot include requests to other people to do things (asking someone to try doing something), nor can the actor be specified or restricted]
[clauses aliased from action variables, a ‘location clause’ and/or an ‘in the presence of clause’ are permitted but not ‘when’ or ‘for x times’ or ‘during’ clauses. The last three may occasionally seem to compile, but only non-functionally due to misparsing. The exception is that when <description of objects> e.g. ‘when Bob’ or ‘when an undescribed man’ seems, surprisingly, to compile such that the pattern matches only when the actor is Bob or an undescribed man respectively. This last strange quirk may be unintended behaviour by the compiler (given the statement above- taken from the literate source of the compiler- that actors cannot be stated or restricted in named action patterns), so may be best not relied upon, especially in extensions]

So, for example:

going down                      [basic action pattern]
to the Root Cellar              [ this and the next 2 lines represent a list of clauses aliased by action variables]
through a door                         
with a lit thing 
in the Kitchen			        [location clause] 
in the presence of Scooby Doo   [in the presence of clause]
when Shaggy                     [actor clause (of doubtful reliability)]
is behaving dangerously.

small print there is currently a bug in the compiler whereby rooms referenced by action variable aliases in named action patterns, e.g. ‘to the Root Cellar’, must be previously explicitly declared in the source as rooms (Root Cellar is a room) not simply through mapping relations (Root Cellar is down from Kitchen)

more small print calls to create local rule variables in declarations of named action patterns- e.g. to the Root Cellar (called the destination)- will compile but don’t in fact create said local variables in rules where e.g. ‘behaving dangerously’ subsequently forms part of the preamble.

As noted previously, named action patterns used in action rule preambles can be prefaced only by ‘an actor’ (which matches any actor) or nothing (which matches only the player) as actor clauses.

So

Before behaving dangerously....

OR

Before an actor behaving dangerously...

The latter offers an alternate and perhaps more reliable way to specify the actor(s) able to trigger a rule via a named action pattern, by inserting a when clause:

Before an actor behaving dangerously when the actor is Shaggy:

or, more elaborately:

Before
an actor
behaving dangerously
in the Mystery Machine
in the presence of Velma
when (the actor is Shaggy or the actor is Daphne) and Scooby Doo is asleep
for the first time
during moonlight:

NB although the named action pattern (behaving dangerously) itself cannot represent a request for someone other than the player to do something, with the above in place typing a command successfully persuading Shaggy or Daphne to behave dangerously while at the same time all the other parameters of the Before rule preamble are met WILL trigger the rule.

NB2 if we want to intervene before persuasion has had a chance to take place, we can also write-

Before asking Shaggy to try acting dangerously...etc...
3 Likes

I had thought that when and during were generically a part of any rule preamble and not part of an action pattern per se.

edited: ah, now I see your qualification about when. Yes, I think you’re right that the compiler probably doesn’t mean to admit that.

Perusing the literate source (and the generated I6) it seems clear that an action pattern includes all of the preamble to a rule of an action-based rulebook following the name of the rulebook, (including what it calls the ‘duration’ clause e.g. ‘for the third time’) and calls to create local variables (e.g. (‘called the chaise’) but excepting any final ‘during’ conditional relating to scenes which might be running.

Small print is that preambles to rules for what the literate source calls parameter-based rulebooks (which have no list of matching action names) e.g. ‘Reaching inside’, are also a category of action pattern.

This qualification only relates to ‘when’ clauses in named action patterns.