Repeat loop ignores 'follow' rules

I have a loop but it seems to ignore the follow rule within that loop.

When play begins:
	repeat with N running from 1 to 4:
		say "The value of N is [N]";		
		now advNext is entry N in OrdList;
		follow the name catching rule;		

When the game starts, I get four outputs in a row telling me the value of N, but the name catching rule is called with N=4. I have had this problem before but thought I better stop now and figure out what is going on.

Try using RULES before triggering this, to see if it’s actually being called four times or not.

You might need this phrase to turn on rules before play begins:

To turn on rules:
	(- RulesOnSub(); -);

Good idea, but that syntax gives me a compile error.

**Problem.** You wrote 'When play begins' [![](blob:https://intfiction.org/29142a23-46c5-4fb5-ba63-035ad034ed8b)](source:story.ni#line34): but only 'to...' phrases can be given inline Inform 6 definitions, and in particular rules and adjective definitions can't.
When play begins:
	(- RulesOnSub(); -);

Is there a typo or something?

I used the ancient print statements method of checking if the routine is being called multiple times. Yes, the N value is printed 4 times before the rule is executed once. ?!

You can only use (- Inform 6 syntax -) to define phrases, not rules. So you need this:

To turn on rules tracing:
	(- RulesOnSub(); -);

When play begins:
    turn on rules tracing;
    [do your other stuff here]
2 Likes

We’ll need to see more of your code to diagnose. I’ve tried to extrapolate from what you’ve given and the behavior seems to be as expected.

The Lab is a room.

advNext is some text that varies.
OrdList is a list of text that varies.
OrdList is {"dog", "cat", "can", "bag"}.

This is the name catching rule:
	say "[advNext].".
	
When play begins:
	repeat with N running from 1 to 4:
		say "The value of N is [N]";		
		now advNext is entry N in OrdList;
		follow the name catching rule.

Gives this output:

The value of N is 1
dog.
The value of N is 2
cat.
The value of N is 3
can.
The value of N is 4
bag.

Intfic2
An Interactive Fiction by Bad Parser
Release 1 / Serial number 240406 / Inform 7 v10.1.2 / D

Lab

>
1 Like

Daniel,
Yes, thank you. That worked fine.

This looks great, but it did not improve anything. I left the Rules command in to show that looping is not occurring. What I get in the first question is
“What is the name of the fourth adventure?”
It also does not echo check the value of N.

AdvNext is some text that varies.
OrdList is a list of text that varies. Ordlist is {"first", "second", "third", "fourth"}.

[Enable the Rules tracing option from the code.]
To turn on rules tracing:
	(- RulesOnSub(); -);

[Assigning the name from the player to the adventuer.]
Rule for printing the name of an adventurer:
	say "[advname of Z]".

When play begins:
	turn on rules tracing;
	repeat with N running from 1 to 4:
		say "The value of N is [N]";
		now advNext is entry N in Ordlist;
		follow the name catching rule;

This is the name catching rule:
	now current question is "";
	now current prompt is "What is the name of the [advNext] character? ";
	now punctuation removal is true;
	ask an open question, in text mode;

I’m beginning to think that the ‘repeat’ command does not work outside its code block. I have been thinking about a global loop counter instead.

What exactly is the output from this version? I have an idea of what it might be now.

In order to get your code to compile, I added:

The Lab is a room.
Include Questions by Michael Callaghan.
An adventurer is a kind of person. 
An adventurer has some text called the advname.

and edited one code block:

Rule for printing the name of an adventurer (called Z):
	say "[advname of Z]".

The result was this:

Rules tracing now switched on. Type "rules off" to switch it off again, or "rules all" to include even rules which do not apply.
The value of N is 1
[Rule "name catching rule" applies.]
The value of N is 2
[Rule "name catching rule" applies.]
The value of N is 3
[Rule "name catching rule" applies.]
The value of N is 4
[Rule "name catching rule" applies.]
[Rule "fix baseline scoring rule" applies.]
[Rule "display banner rule" applies.

As you can see, your rule is firing as expected. It is just not doing what you expect. When I look at the extension, the code ask an open question, in text mode; doesn’t actually ask a question, it merely sets up the command prompt and sets appropriate flags for the next time the player gets a command prompt. This won’t happen until after the “when play begins” rule and all the other rules for that sequence run.

3 Likes

This is probably not helpful at this point, but I had something in one of my recent games that let you name 9 different locations. I’ve taken that code and stripped it down to make it work for your game. It doesn’t require extensions. I don’t recommend trying this since you’re already so invested in other methods, but you can try it if nothing else works.

Code
"Sandbox" by Brian Rushton

Starting Place is a room.


Namenum is a number that varies. Namenum is 1.

To next-bump:
	increment Namenum;
	if Namenum > 4:
		now Namenum is 1;
	
Namingtime is a truth state that varies.


Table of adventurer names
nameorder	advname	ordinal	changedname
1	""	"first"	false
2	""	"second"	false
3	""	"third"	false
4	""	"fourth"	false


When play begins:
	continue naming;


To continue naming:
	choose the row with a nameorder of Namenum in the table of adventurer names;
	if advname entry is "":
		now the command prompt is "What will you name the [ordinal entry] adventurer? >";
		now namingtime is true;
	otherwise:
		say "You previously named this adventurer '[advname entry]'. Would you like to change the name?";
		if the player consents:
			now the command prompt is "What will you name the [ordinal entry] adventurer? >";
			now namingtime is true;
		otherwise:
			say "Name change cancelled.";

After reading a command when namingtime is true: 
	let temp be the player's command;
	choose the row with a nameorder of Namenum in the table of adventurer names;
	now the advname entry is temp;
	now the changedname entry is true;
	next-bump;
	choose the row with a nameorder of Namenum in the table of adventurer names;
	unless "" is a advname listed in the table of adventurer names:
		say "You have finished naming all adventurers!";
		repeat through the table of adventurer names:
			say "The [ordinal entry] adventurer's name is [advname entry].";
		now the command prompt is "";
		now namingtime is false;
		reject the player's command;
	otherwise:
		continue naming;
		reject the player's command;
Output
Sandbox
An Interactive Fiction by Brian Rushton
Release 1 / Serial number 240407 / Inform 7 build 6M62 (I6/v6.33 lib 6/12N) SD

Starting Place

What will you name the first adventurer? >brian
What will you name the second adventurer? >bob
What will you name the third adventurer? >joe
What will you name the fourth adventurer? >albert
You have finished naming all adventurers!
The first adventurer's name is brian.
The second adventurer's name is bob.
The third adventurer's name is joe.
The fourth adventurer's name is albert.
1 Like

Sorry,
I had those top lines of code in my source, but they didn’t quite make it into the question.
I can get my code to compile but I always get the “fourth adventurer” question. Notice that N is at max before the question is asked.
I see that the name catching rule is invoked each time, but the QUESTION is never asked until N is 4. Why is that? Why does this loop not ask the question for each iteration of N?
The name catching rule says it should.
The text response to the name catching rule is only invoked once. This is the typical paradigm-confusion of using the Questions extension.

I think I am going to assume that rule following does not work across the question prompt, and try to create a global-type loop instead of a repeat loop in a single code block.

1 Like

Here’s a version which hews closely to the previous versions from the other threads and which lets the player create four different adventurers, using a list which we deplete one item at a time. The properties always refer to the “current adventurer” variable.

At the end of a character’s creation, we remove the first entry from the list and check whether the list is not empty. If it isn’t empty, we still have to create another character, so we set the “current adventurer” to the new first entry, and set the stage to stName again, to start with that stage for the next character.

Look further below for the output, which I think is roughly as desired.

Include Questions by Michael Callaghan.

Lobby is a room. 
Description of Lobby is "Welcome to the Ugly Ogre Inn! Excitement-starved adventurers meet here to form teams. We are meeting now so all players can define their adventurers.";

An adventurer is a kind of person. 
A fighter, cleric, scout, and magician are kinds of adventurers.

An adventurer has some text called adv_name.
An adventurer has some text called adv_class.
An adventurer has a number called dex.

Char1 is a male fighter.
Char2 is a male fighter.
Char3 is a male fighter.
Char4 is a male fighter.

The character-list is a list of adventurers which varies.

The current adventurer is an adventurer that varies.

Data is a kind of value. The data are teamSize, stName, stSex, stClass, stDex, and complete.
Stage is data that varies.

After looking for the first time:
	now the character-list is {Char1, Char2, Char3, Char4};
	now the current adventurer is Char1;
	now stage is stName;
	follow the every turn rules;
	follow the advance time rule;
	
Every turn when stage is stName:
	now current question is "";
	now current prompt is "What is the name of the character? ";
	now punctuation removal is true;
	ask an open question, in text mode;
	
A text question rule when stage is stName:
	now the adv_name of the current adventurer is the current answer;
	now stage is stSex;
	exit.
	
Every turn when stage is stSex:
	say "What is the gender of the character?";
	now current question menu is {"male", "female"};
	now current prompt is "Enter the number of an option: ";
	ask an open question, in menu mode;

A menu question rule when stage is stSex:	
	if the number understood is 2:
		now the current adventurer is female;
	now stage is stClass;
	exit;
	
Every turn when stage is stClass:
	say "What is the class of the character?";
	now current question menu is {"fighter", "cleric", "scout", "magician"};
	now current prompt is "Enter the number of an option: ";
	ask an open question, in menu mode;
	
A menu question rule when stage is stClass:
	let C be the number understood;
	now the adv_class of the current adventurer is entry C in the current question menu;
	now stage is stDex;
	exit;

Every turn when stage is stDex:
	now the dex of the current adventurer is a random number from 8 to 18;
	say "[line break]Okay, you created [adv_name of the current adventurer], [if current adventurer is male]male[otherwise]female[end if] [adv_class of the current adventurer], with a dexterity of [dex of the current adventurer].[paragraph break]";
	remove entry 1 from character-list;
	if character-list is not empty:
		say "Proceeding to the next character...[paragraph break]";
		now the current adventurer is entry 1 in the character-list;
		now stage is stName;
		follow the every turn rules;
		follow the advance time rule;
	otherwise:
		now stage is complete;

Output:

Release 1 / Serial number 240407 / Inform 7 v10.1.2 / D

Lobby
Welcome to the Ugly Ogre Inn! Excitement-starved adventurers meet here to form teams. We are meeting now so all players can define their adventurers.

What is the name of the character? Alice
What is the gender of the character?
1 - male
2 - female

Enter the number of an option: 2
What is the class of the character?
1 - fighter
2 - cleric
3 - scout
4 - magician

Enter the number of an option: 1

Okay, you created Alice, female fighter, with a dexterity of 13.

Proceeding to the next character…

What is the name of the character? Bob
What is the gender of the character?
1 - male
2 - female

Enter the number of an option: 1
What is the class of the character?
1 - fighter
2 - cleric
3 - scout
4 - magician

Enter the number of an option: 2

Okay, you created Bob, male cleric, with a dexterity of 10.

Proceeding to the next character…

What is the name of the character? Carla
What is the gender of the character?
1 - male
2 - female

Enter the number of an option: 2
What is the class of the character?
1 - fighter
2 - cleric
3 - scout
4 - magician

Enter the number of an option: 3

Okay, you created Carla, female scout, with a dexterity of 10.

Proceeding to the next character…

What is the name of the character? Dave
What is the gender of the character?
1 - male
2 - female

Enter the number of an option: 1
What is the class of the character?
1 - fighter
2 - cleric
3 - scout
4 - magician

Enter the number of an option: 4

Okay, you created Dave, male magician, with a dexterity of 9.

There are still some TO DO points, such as relating the adv_class to the kind of adventurer, for example. But I thought it would be helpful to get the basic mechanism going, at least.

2 Likes

The key is that asking a question isn’t blocking, in programming language jargon—it doesn’t make the loop stop and wait until the player answers. The code just keeps running, overwriting that question with another one again and again until it reaches the last one.

3 Likes

Draconis,
Yes, I thought as much. I have used a global loop and now it works. I am trying to clone adventurers now and keep them in a List (or array?).

1 Like