What activities have you wished for?

Since a new version is on its way, there’s an opportunity to expand the number of activities implemented as part of the core system.

I’ve noticed on a few occasions that I wished there were existing activities to cover certain parts of parser activity. For example:

  • printing the article of something (possibly with variations for definite/indefinite)
  • printing the inferred command

Have you noticed a lack of an activity that you would find helpful?

4 Likes

I’ve mentioned before that I wish moving objects were an activity (i.e., that the kits/standard rules implemented all movement with such an activity).

And, like I said recently, it would be cool to have something similar to activities to put hooks on the establishment and cessation of relations. But you’d really want two parameters for that, and For rules wouldn’t really make sense, so it wouldn’t really be an activity.

[ Edited to add: Doh. I suppose moving things would require two parameters, too. ]

2 Likes

Ooh, I’ve got a good one: inventory item annotation so we could override the default behavior regarding labeling things open, empty, providing light, etc., or even add arbitrary new annotation to things that aren’t containers.

1 Like

Isn’t that the “printing inventory details” activity?

3 Likes

…mmmmmmmmaybe. Hey! Look over there! (runs out of room)

3 Likes

Yeah I thought you could do that already, though I’ve never banged on the details sufficiently to see if there are gaps…

Continuing with the theme of not really knowing what I’m talking about, I believe it’s currently pretty hard to alter particular disambiguation prompts in a clean way – the workaround I usually use is to manually change the relevant response with an “after reading a command when the player’s command includes XX”, then change it back with an every turn rule, which feels like a hack – so maybe an activity would make that simpler? Or possibly there already is an easy way to do that and I’ve just defaulted to hackery out of ignorance.

1 Like

This one’s come up for me several times.

-Wade

1 Like

We have an activity for printing the name of a dark room, why not one for printing the room description header when not dark? Or rather, for printing the name of an object in the room description header (so it would be called for each of the things above the player in the object tree, starting with the room and running down to the direct holder of the player).

It’s trivial to implement, but annoying that you need to replace the entire carry out looking rule to do so.

1 Like

Isn’t it just the room description heading rule that you need to replace to do this?
e.g. (from a recent post of mine)

The zonal room description heading rule
Section - The zonal room description heading rule

[this is a small tweak to the rule that when looking, initially prints (in bold) the name of the location, together with subsidiary information such as '(on the ledge)'.  Here, when the player is within a zone above the ground, we need to provide a more suitable description than the usual "(in [the container])"]
Carry out looking (this is the zonal room description heading rule):
	say bold type;
	if the visibility level count is 0:
		begin the printing the name of a dark room activity;
		if handling the printing the name of a dark room activity:
			say "Darkness" (A);
		end the printing the name of a dark room activity;
	otherwise if the visibility ceiling is the location:
		say "[visibility ceiling]";
	otherwise:
		say "[The visibility ceiling]";
	say roman type;
	let intermediate level be the visibility-holder of the actor;
	let zone mentioned be false;
	repeat with intermediate level count running from 2 to the visibility level count:
		if the intermediate level is a supporter or the intermediate level is an animal:
			say " (on [the intermediate level])" (B);
		[******** Insertion starts here ********]
		otherwise if the intermediate level is a zone:
			if zone mentioned is false:
				now zone mentioned is true;
				let d be the distance between the actor and the low-flying-zone;
				if d is:
					-- 0: say " (above the ground)" (D);
					-- -1: say " (some way above the ground)" (E);
					-- -2: say " (far above the ground)" (F);
					-- otherwise: say " (way, way, up above the ground)" (G);
		[******** Insertion ends here ********]
		otherwise:
			say " (in [the intermediate level])" (C);
		let the intermediate level be the visibility-holder of the intermediate level;
	say line break;
	say run paragraph on with special look spacing.
	
The zonal room description heading rule is listed instead of the room description heading rule in the carry out looking rules.
1 Like

Correct, that’s what I was referring to. I probably should’ve said “an entire carry out looking rule” instead of “the entire carry out looking rule”.

1 Like

Today I wished for a simple activity to know whether action-processing was going on. Then I wished for an activity to know whether a given rulebook was being processed.

A mad science challenge: Would it even be possible to set up an activity to determine whether a given rulebook is being processed, potentially somewhere higher up the call chain of rulebook processing?

1 Like

It sounds like those should be flags or queries into the rulebook mechanism, rather than activities.

2 Likes

Too easy!

lab is room.

when play begins:
say current rulebook.

every turn:
say current rulebook.

test me with "z".

To decide what rulebook is the current rulebook: (- top_array_stack(RulebookStack) -)

Include (-
Array RulebookStack --> 2048;

[ push_array a v;
a-->0 = (a-->0) + 1;
a-->(a-->0) = v;
];

[ pop_array a v;
v = a-->(a-->0);
a-->0 = (a-->0) - 1;
return v;
];

[ top_array_stack a;
  return a-->(a-->0);
];

[ FollowRulebook rulebook parameter no_paragraph_skips
        rv ss spv;
        ss = self;
        if ((Protect_I7_Arrays-->0 ~= 16339) || (Protect_I7_Arrays-->1 ~= 12345)) {
                print "^^*** Fatal programming error: I7 arrays corrupted ***^^";
                @quit;
        }
        if (parameter) { self = parameter; parameter_object = parameter; }
        spv = parameter_value; parameter_value = parameter;
        ! we won't need parameter again, so can reuse it
        parameter = debugging_rules;
        if (debugging_rules) {
                DebugRulebooks(rulebook, parameter);
                process_rulebook_count = process_rulebook_count + debugging_rules;
        }
        push_array(RulebookStack, rulebook);
        if ((rulebook >= 0) && (rulebook < NUMBER_RULEBOOKS_CREATED)) {
                rv = rulebooks_array-->rulebook;
                if (rv ~= EMPTY_RULEBOOK) {
                        if (rulebook ~= rulebook_without_variables) MStack_CreateRBVars(rulebook);
                        if (say__p) RulebookParBreak(no_paragraph_skips);
                        rv = rv(no_paragraph_skips);
                        if (rulebook ~= rulebook_without_variables) MStack_DestroyRBVars(rulebook);
                } else {
                        rv = 0;
                }
        } else {
                if (say__p) RulebookParBreak(no_paragraph_skips);
                rv = rulebook();
                if (rv == 2) rv = reason_the_action_failed;
                else if (rv) rv = rulebook;
        }
        if (rv) {
                if (debugging_rules) {
                        process_rulebook_count = process_rulebook_count - debugging_rules;
                        if (process_rulebook_count < 0) process_rulebook_count = 0;
                        spaces(2*process_rulebook_count);
                    if (latest_rule_result-->0 == RS_SUCCEEDS) print "[stopped: success]^";
                    if (latest_rule_result-->0 == RS_FAILS) print "[stopped: fail]^";
                }
        } else {
                if (debugging_rules)
                        process_rulebook_count = process_rulebook_count - debugging_rules;
                latest_rule_result-->0 = RS_NEITHER;
        }
        debugging_rules = parameter;
        self = ss; parameter_value = spv;
        pop_array(RulebookStack);
        return rv;
];
-) replacing "FollowRulebook".
When play begins rulebook
Welcome
An Interactive Fiction
Release 1 / Serial number 240412 / Inform 7 v10.2.0 / D

lab

>test me
(Testing.)

>[1] z
Time passes.

Every turn rulebook

(Written for current development version of Inform.)

3 Likes

I may simply not understand the system properly, but in my most recent endeavor, one of the most headscratchy things I dealt with was trying to wrangle parser responses and behaviors when the parser was cobbling a command together out of an original underspecified command followed by noun(s) additionally prompted from the player. (I was able to kluge a flag-based solution to part of the problem but ended up just taking the L on the rest.)

Would this proposed “inferred command” activity deal with that, or is this something outside the scope of activities?

1 Like

This didn’t address the “is rulebook X being run?” part, so…

Include (-
[ RulebookRunning r i;
for ( i = RulebookStack-->0 : i > 0 : i-- ) if (RulebookStack-->i == r) return true;
return false;
];
-)

To decide if (r - rulebook) is/are being followed: (- RulebookRunning({r}) -)

before doing anything:
say "[current rulebook].";
if action-processing rulebook is being followed, say "following action-processing.";

after doing anything:
say "[current rulebook].";
if action-processing rulebook is being followed, say "following action-processing.";
continue the action;

when play begins:
say "[current rulebook].";
if action-processing rulebook is being followed, say "following action-processing.";

every turn:
say "[current rulebook].";
if action-processing rulebook is being followed, say "following action-processing.";

It’d be nice to have an I7-accessible repeat loop through the rulebook stack, but I was having some trouble with that. I’ll try again later.

2 Likes

Yes, that’s correct.

2 Likes

A flag can work for a particular rulebook, but I was looking for something that would work for all rulebooks.

The existing rulebook template code doesn’t keep a stack or anything like that. (At least, I don’t think it does.) Did you mean some extended form of the mechanism?

EDIT: The existing rulebook mechanism does keep a stack – sort of. Within FollowRulebook() the call to MStack_CreateRBVars will create a frame on the MStack… if the rulebook has variables. By default this is true only for the action-processing rulebook and the specific action-processing rulebook. Likewise, a call to ActionPrimitive() will create a frame for any action that has action variables (by default: the going action, the exiting action, the looking action and the examining action).

1 Like

ok, same FollowRulebook as before…

Include (-
Constant ARRAY_STACK_SIZE = 500;

Array RulebookStack --> ARRAY_STACK_SIZE;
-)

to repeat with (x - nonexisting rulebook variable) through the/-- rulebook stack begin -- end loop:
  (- for ( {-my:0} = 1, {x} = RulebookStack-->1 : {-my:0} <= RulebookStack-->0 : {x} = (RulebookStack-->( ++{-my:0}))) -)

To say rulebook stack:
repeat with x through rulebook stack begin;
  say x;
  unless x is the current rulebook, say " -> ";
end repeat;

To decide if (r - rulebook) is/are being followed:
  repeat with x through the rulebook stack begin;
    if x is r, yes;
  end repeat;
  no.

Include (-
[ RulebookRunning r i;
for ( i = RulebookStack-->0 : i > 0 : i-- ) if (RulebookStack-->i == r) return true;
return false;
];

[ push_array a v;
a-->0 = (a-->0) + 1;
if ((a-->0) == ARRAY_STACK_SIZE) print "** Stack overflow^";
else a-->(a-->0) = v;
];

[ pop_array a v;
if ((a-->0) == 0) { print "** Stack underflow^"; return 0; }
v = a-->(a-->0);
a-->0 = (a-->0) - 1;
return v;
];


-)

To decide what rulebook is the current rulebook: (- RulebookStack-->(RulebookStack-->0) -).
To decide what rulebook is the foremost rulebook: (- RulebookStack-->1 -).

to say rulebook status:
say "current: [current rulebook].";
say "[unless action-processing rulebook is being followed]not [end unless]following action-processing.";
say "[rulebook stack].";

before doing anything: say rulebook status

after doing anything: say rulebook status; continue the action.

when play begins: say rulebook status

every turn: say rulebook status

[…]

current: When play begins rulebook.
not following action-processing.
Startup rulebook -> When play begins rulebook.

Welcome
An Interactive Fiction
Release 1 / Serial number 240412 / Inform 7 v10.2.0 / D

current: Before rulebook.
following action-processing.
Startup rulebook -> Action-processing rulebook -> Before rulebook.

lab
current: After rulebook.
following action-processing.
Startup rulebook -> Action-processing rulebook -> specific action-processing rulebook -> After rulebook.

>z
current: Before rulebook.
following action-processing.
Turn sequence rulebook -> Action-processing rulebook -> Before rulebook.

current: After rulebook.
following action-processing.
Turn sequence rulebook -> Action-processing rulebook -> specific action-processing rulebook -> After rulebook.

Time passes.

current: Every turn rulebook.
not following action-processing.
Turn sequence rulebook -> Every turn rulebook.

>
2 Likes

Clarifying the parser’s choice of a second noun would be delightful.

3 Likes

To follow up on zarf’s suggestion above: Although the default template code provides a stack (MStack) that is used when processing certain rulebooks and actions, the use of the stack is limited to those with rulebook or action variables. It is possible to modify template code such that a stack entry is made for every rulebook or action being processed, whether they have variables or not.

The only functional difference obtained by this approach is that then rulebooks, actions and activities all share the same stack, so it is possible to determine whether one of these is “inside” another (i.e. lower in the call chain). I haven’t come up with a use case where that matters, though.

1 Like