Rejecting Commands During Scenes

I have run into a brick wall.

Suppose I have a room that you can’t get into without passing a test. The test poses a couple questions to the player, checks the players input, and then decides if you can go in the room.

Normally, I would do this by changing the command prompt and writing after “reading a command” rules to check answers (and prevent the parser from trying to parse the input). I have done this before. It works fine.

Here’s the brick wall: if you try to do this during a scene, stopping the action or rejecting the player’s command seem to also stop anything after that. Any rules you expect to run “when scene ends” aren’t triggered because any rules that you expect to end the scene have to come after you’ve stopped the action.

Suppose I have a scene that starts when the player enters X (a room), and ends when the player is not in X. When the scene starts I change the command prompt to “Are you a wizard? >”. The player can type anything here. After reading the command the rules check what’s typed. If the player says “YES” the test continues. If the player says “NO” we’re supposed to send the player back where they came from and end the scene. If the player types “ZORK” it’s supposed to warn that it’s a simple YES/NO question.

That’s how it’s supposed to work. What actually happens is that typing NO gives the expected response from the after reading a command block, but the scene end code never runs, and the scene doesn’t end even when the conditions for ending are met.

Any ideas on how to reject a player’s command during a scene and still have the scene play out normally?

I have tried doing everything in every turn or instead rules, but here the rules aren’t followed until the parser’s had its crack at the player’s command.

1 Like

Just for the sake of clarification, is there a reason you couldn’t use “if the player consents”?

First-room is a room. X is south of First-room.

After going to X for the first time:
	say "Are you a wizard?[line break]> ";
	if the player consents:
		say "Great! I like wizards.";
	otherwise:
		say "Have it your way, sword lady."

Test me with "s/zork/yes".
1 Like

The problem, I’m pretty sure, is that the scene-changing machinery happens as part of the turn sequence rules. Your password entry code rejects the player’s command, so it never gets parsed into an action and never goes through the turn sequence rules.

One way to fix this might be to manually order Inform to follow the scene change machinery rule at the appropriate time:

Hallway is a room. "Password: whee-boing."

After jumping in the hallway: 
	now the command prompt is "Enter the password >".
	
Password entry is a scene. Password entry begins when the command prompt is "Enter the password >". Password entry ends when the command prompt is ">".

When password entry begins: say "Password entry begun."
When password entry ends: say "Password entry ended."

After reading a command during password entry:
	if the player's command matches "whee-boing":
		say "Correct!";
		now the command prompt is ">";
		follow the scene change machinery rule;
	otherwise:
		say "Wrong!";
	reject the player's command.

If we don’t have the “follow the scene change machinery rule” line in there, this will get stuck in the password entry scene even though we entered the correct password.

Another possibility (at least in this code) might be to check the command prompt instead of using a scene. The scene is going on when and only when the command prompt is changed, so if we made the password check code start with

 After reading a command when the command prompt is the command prompt is "Enter the password >".

I think it would work without the scene change machinery.

Björn,
The main reason I’m not using “if the player consents” is because there’s more than one question, and they’re not all yes/no questions.

Here’s a rough approximation of my code (much shorter and without regex matching or any other bells or whistles).

Playground is a room. 
Transporter is a room. It is north of Playground.
Destination is a room.

Questions answered is initially 0.

Transport_In_Progress is a recurring scene. 
Transport_In_Progress begins when the player is in Transporter. 
Transport_In_Progress ends when the location of the player is not Transporter.

When Transport_In_Progress begins:
	now the command prompt is "Are you a wizard?[line break]".
	
When Transport_In_Progress ends:
	now the command prompt is ">";

After reading a command during Transport_In_Progress:
	if questions answered is:
		-- 0:
			if the player's command matches the text "yes":
				increase questions answered by 1;
				now the command prompt is "Prove it! Say the magic word![line break]";
			otherwise if the player's command matches the text "no":
				say "Very well.[paragraph break][We] are back in the playground.";
				now questions answered is 0;
				move the player to Playground;
			otherwise:
				say "It's a simple YES/NO question, pal.";
		-- 1:
			if the player's command matches the text "dwarf":
				say "I guess [we] really are a wizard. Continue to your destination.";
				now questions answered is 0;
				move the player to Destination;
			otherwise:
				say "Foo! [We] are nothing but a charlatan![paragraph break][We]['re] in the playground again, hanging upside down on the monkey bars.";
				move the player to Playground;
	stop the action.

This works except moving the player doesn’t end the scene. The command prompt doesn’t change back, and any command you give responds with “It’s a simple YES/NO question, pal.”

If you take out “stop the action” the code works, except the parser responds with “That was a rhetorical question.” and “That’s not a verb I recognize.” Even then, the player has to do something before the game finally recognizes he/she is not in Transporter and ends the scene.

I can make the code work easily without the scene. I just thought using a scene would make it easier. It did not.

Matt,
This does the trick.

As I said, I’ve done this before without using a scene and checking the command prompt. Using a scene seemed more structurally sound. Then, once I started playing with the idea I had to make it work.

Ah, I see. Yeah, the way scene changes are structured is the kind of nonobvious that tends to trip me up. In most cases, it works intuitively. That’s fine until it doesn’t.

Another option is to change the text of the player's command to some placeholder verb like NEXT-QUESTION, and then omit the reject the player's command. You’d have to set up NEXT-QUESTION to only be a “typable” command during question scenes.

Transport_In_Progress is a scene.

Next-questioning is an action applying to nothing.

Understand "next-question" as next-questioning when Transport_In_Progress is happening.

Transport_In_Progress begins when the player is in Transporter. 
Transport_In_Progress ends when the location of the player is not Transporter.

 When Transport_In_Progress begins:
	now the command prompt is "Say the magic word:[line break]>>".
	
When Transport_In_Progress ends:
	now the command prompt is ">";

After reading a command during Transport_In_Progress:
	if the player's command matches the text "xyzzy":
		say "Poof.";
		now the player is in the Kitchen;
	change the text of the player's command to "next-question";

That was the solution sitting in the back of my head waving its hands frantically as I tried everything else that didn’t work.