(Printing the name of) Activity loops with Run-time problem P12 + Stack overflow

I would like to understand something. This code works well (compilation OK, no bug in game):

Before printing the name of a direction (this is the Before printing the name of a direction rule):
	say "[bold type]";
	
After printing the name of a direction (this is the After printing the name of a direction rule):
	say "[roman type]";

But not this one (compilation OK, bug in game):

Rule for printing the name of a direction (called LocalDirection) while looking toward (this is the Printing the name of a direction when looking toward rule):
	say "[bold type][LocalDirection][roman type]";

Result below:

[Rule "check stage rule" applies.]
[Rule "F067 - Check looking toward rule" applies.]
[Rule "carry out stage rule" applies.]
[Rule "F067 - Carry out looking toward rule" applies.]
From your location, toward 
*** Run-time problem P12: Too many activities are going on at once.

Glulxe fatal error: Stack overflow in callstub.

I wonder why because I wrote “while looking toward” (also tried with “when”) to avoid this loop…

This version tries to print out the name of a thing (LocalDirection) whose name the rule is trying to print out, creating an infinite loop.

Here’s a simpler case you can consider that generates the same loop:

Rule for printing the name of a thing (called THINGY):
	say "[THINGY]";

-Wade

2 Likes

Yes I knew that, in fact I misunderstood an old thread.

Here is the solution:

Rule for printing the name of a direction (called LocalDirection) while looking toward (this is the Printing the name of a direction when looking toward rule):
	say "[bold type][printed name of LocalDirection][roman type]"

In this case, the (printing the name of) activity does not fire in the “say” linecode.

To clarify : I thought the solution was to specify the context of the rule when in reality we need to prevent the activity from being triggered within this same rule. Sorry if I was imprecise.

1 Like

It’s possible to build a safety valve into the underlying I6 routine:

WARNING: untested at scale
Include (-

! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
! Printing.i6t: Object Names I
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====

[ PSN__ o     i  max ;
	if (o == 0) { LIST_WRITER_INTERNAL_RM('Y'); rtrue; }
	switch (metaclass(o)) {
		Routine:  print "<routine ", o, ">"; rtrue;
		String:   print "<string ~", (string) o, "~>"; rtrue;
		nothing:  print "<illegal object number ", o, ">"; rtrue;
	}
	RegardingSingleObject(o);

	! BEGIN ADDITION
	for ( i = 1, max = activities_sp - 1: i < max : i++ )
		if (activities_stack-->i == (+ printing the name activity +) &&
		   activity_parameters_stack-->i == o) {
			print "<object name recursion halted for object ", o, ">";
			rfalse;
		}
	! END ADDITION
	CarryOutActivity(PRINTING_THE_NAME_ACT, o);
];

-) instead of "Object Names I" in "Printing.i6t".

That’s 6M62 format; you’ll need to adapt the Include syntax for 10.1.2.

1 Like

Thank you very much @otistdog, this is very interesting and helpful to have a solution like this to handle anti-loop protection directly at the Inform 6 layer.
Tell me, do you see any drawback or risk in using the substitution “[printed name of…]” for such and such usecase in the long term to avoid loops, without applying the more radical approach you suggest?

Fixing the substitution is the “correct” solution. You don’t want to rely on breaking out of the recursion only when it’s already got out of hand. What the I6 “safety valve” provides is a way to make the error visible and then let you continue the game for now, rather than crashing the VM.

2 Likes

Understood, thanks for the explanations. I must confess that I’m not proficient in Inform 6 programming, which is why I had misunderstood the purpose of the code @otistdog proposed.

Yes, jwalrus explained it well – the safety valve is just to prevent the stack overflow crash.

For your question, just be aware that the printed name property holds a text… but an I7 text is allowed to invoke routines via substitutions, so there is the possibility of indirect recursion.

1 Like