Inconsistent Scene Endings

Scenes can have multiple endings. When two scene endings trigger the same code, one expects to see the same results. I’m not sure why I don’t see the same results. The SCENES debug command shows that the scene is ending correctly, but one ending ends immediately, and the other is delayed.

The scenario is simple. A mad doctor wanders around threatening the player with a lobotomy every time they run in to each other. The encounter is a scene. When the player and the doctor are in the same location, the scene begins. The scene can end abruptly if the player moves to a different room. It can end violently if the player attacks the doctor. And it can end medically if the player waits around until the doctor decides to perform the lobotomy (3 minutes after the scene starts).

The following code illustrates:

Code
The Dispensary is a room.
The Examination Room is a room. It is south of the Dispensary.
The Maintenance Room is a room. It is west of the Dispensary.
The Office is a room. It is north of the Dispensary.
EW Hall is a room. It is east of the Dispensary.
Padded Room is a room. "You are in a small square room." It is north of EW Hall.

A person can be lobotomized or not lobotomized.

Every turn when the player is lobotomized:
	meander the player.

The MadDoctor is a man in the Office.
	The printed name is "Doctor".
	Understand "mad/-- doctor" as the MadDoctor.

Every turn:
	unless Lobotomy Practice is happening:
		traipse the MadDoctor.

Rule for printing a locale paragraph about the MadDoctor:
	now the MadDoctor is mentioned.

After the MadDoctor going when the room gone to is the location of the player: 
	do nothing.

To lobotomize the player:
	move the MadDoctor to the Office;
	now the player is in Padded Room;
	[move the player to Padded Room, without printing a room description;]
	now the player is lobotomized.	

To meander the player:
	let rando be a random number between 1 and 20;
	if Lobotomy Practice has ended:
		say "<[minutes part of the time since Lobotomy Practice ended] mins>[line break]";
	else:
		say "<still practicing>[line break]";
	if the time since Lobotomy Practice ended is at least 1 minute:
		if rando is at most 5:
			say ">west[command clarification break]";
			try going west;
		otherwise if rando is at most 10:
			say ">east[command clarification break]";
			try going east;
		otherwise if random is at most 15:
			say ">north[command clarification break]";
			try going north;
		otherwise:
			say ">south[command clarification break]";
			try going south;
	follow the scene change machinery rule.

To traipse (npc - a person):
	let rando be a random number between 1 and 20;
	if npc is not the player:
		if rando is at most 5:
			try npc going west;
		otherwise if rando is at most 10:
			try npc going east;
		otherwise if rando is at most 15:
			try npc going north;
		otherwise:
			try npc going south.
						
Lobotomy Practice is a recurring scene.
Lobotomy Practice begins when the MadDoctor is in the location.
Lobotomy Practice ends medically when the time since Lobotomy Practice began is 3 minutes.
Lobotomy Practice ends violently when the current action is attacking the MadDoctor.
Lobotomy Practice ends abruptly when the location is not the holder of the MadDoctor.

When Lobotomy Practice begins:
	say "You hear a noise and notice a short, stocky, unshaven man wearing a bloody white surgical gown and holding a large hypodermic is staring at you."

When Lobotomy Practice ends medically:
	say "The doctor says, 'I[']m afraid I[']m going to have to give you a frontal lobotomy!' he sticks you with his hypo and you pass out. When you awaken, you feel somewhat indifferent to your surroundings. You feel like wandering...";
	lobotomize the player.
	
When Lobotomy Practice ends violently:
	say "The doctor sticks you with his hypo. 'I[']m afraid I[']m going to have to give you a frontal lobotomy!' he says and you pass out. When you awaken, you feel somewhat indifferent to your surroundings. You feel like wandering...";
	lobotomize the player.

Every turn during Lobotomy Practice:
	if the time since Lobotomy Practice began is at least 1 minute:
		let rando be a random number between 1 and 20;
		say "The doctor says, ";
		if rando is at most 6:
			say "'You are not being a good little patient! Now return to your cell, or you will need a lobotomy!'";
		otherwise if rando is at most 12:
			say "'I grow tired of dealing with you inferiors!'";
		otherwise:
			say "'What are you doing here? Go where you belong!'".

Plughing is an action applying to nothing.
Understand "plugh" as plughing.

Carry out plughing:
	if the player is lobotomized:
		now the player is not lobotomized;
		say "You get better.";
	otherwise:
		say "Sorry, that doesn't work right now."

Test violent with "n / attack doctor / look / s / z".
Test medical with "n / z / z / look / s / z".

As intended, if the scene ends violently or medically, a routine is called (lobotomize the player) that moves the doctor to the office, moves the player to the padded room, and makes the player lobotomized. When the player is lobotomized, an every turn rule calls a routine (meander the player) that makes the player move in a random direction. This routine has some debug code to show the number of minutes since the scene ended, and won’t make the player wander until 1 minute after the scene ends.

The issue I’m having is that, if the scene ends violently, everything works fine and meander the player is called after the player is moved. If the scene ends medically, everything works fine, but meander the player isn’t called.

Using just your demo code, both >TEST VIOLENT and >TEST MEDICAL seem to demonstrate the “meandering” behavior that you describe.

There is a difference in the turns involving the >LOOK command for each test scenario.

For >TEST VIOLENT (meander):

>[3] look
Padded Room
You are in a small square room.

<1 mins>
>north
You can't go that way.

For >TEST MEDICAL (no meander):

>[4] look
Padded Room
You are in a small square room.

<0 mins>

Is that what you’re talking about? You would like the meandering behavior to apply in the first turn after transition to the cell no matter which way the previous scene ends?

If you look at the Index, under Rules / Standards / The top level / turn sequence rules, you will see two blank-looking lines in the list of rule in the rulebook. #1 is between the generate action rule and the every turn stage rule, and #2 is between the update chronological records rule and the adjust light rule.

These are actually nameless rules. Their declarations can be found in the Standard Rules in “Section SR2/8 - The Standard Rules”:

A first turn sequence rule: follow the scene changing rules. [4th.]
...
A last turn sequence rule: follow the scene changing rules. [3rd from last.]

The difference between the two scenarios is which of these rules is triggering the scene change. #1 is before the advance time rule, while #2 is after it. If the scene change occurs via #2, it also occurs after the every turn rules are consulted, so your meandering behavior doesn’t occur in the first turn.

There’s a long discussion thread somewhere about this, and the upshot of it was that because of the two different scene-changing rules, using time-based scene changes is not a great idea even though there are some examples in the documentation that do so.

You might try creating a new scene called “Lobotomized” or something, and link the meandering behavior to that scene. You can then set that scene to start when the player is in the cell. Since I’m not 100% sure what you’re trying to achieve, I’m not sure how to construct an example.

3 Likes

That is what I’m talking about.

I tried giving the mad doctor a frustration level, incremented every turn during the scene, and ending the scene medically when the frustration level reached 2, but that didn’t change anything.

This is a little trickier than it seems.

To resolve your problem, you would need to ensure that both methods of ending the scene are handled by the same scene changing check to get consistent behavior. Anything driven by an action-related state change will cause a scene change earlier than one driven by a time-related state change.

I think the following is doing what you want:

MadDoctor modified
"Mad Doctor"

The Dispensary is a room.
The Examination Room is a room. It is south of the Dispensary.
The Maintenance Room is a room. It is west of the Dispensary.
The Office is a room. It is north of the Dispensary.
EW Hall is a room. It is east of the Dispensary.
Padded Room is a room. "You are in a small square room." It is north of EW Hall.

A person can be lobotomized or not lobotomized.


The MadDoctor is a man in the Office.
	The printed name is "Doctor".
	Understand "mad/-- doctor" as the MadDoctor.

Every turn:
	unless Lobotomy Practice is happening:
		traipse the MadDoctor.

To lobotomize the player:
	now the player is lobotomized.	

To meander the player:
	say "<MEANDER CHECK>[line break]";
	let rando be a random number between 1 and 20;
	if rando is at most 5:
		say ">west[command clarification break]";
		try going west;
	otherwise if rando is at most 10:
		say ">east[command clarification break]";
		try going east;
	otherwise if random is at most 15:
		say ">north[command clarification break]";
		try going north;
	otherwise:
		say ">south[command clarification break]";
		try going south.


To traipse (npc - a person):
	let rando be a random number between 1 and 20;
	if npc is not the player:
		if rando is at most 5:
			try npc going west;
		otherwise if rando is at most 10:
			try npc going east;
		otherwise if rando is at most 15:
			try npc going north;
		otherwise:
			try npc going south.
						
Lobotomy Practice is a recurring scene.
Lobotomy Practice begins when the MadDoctor is in the location.
Lobotomy Practice ends medically when the MadDoctor can see the player for four turns.
Lobotomy Practice ends abruptly when the location is not the holder of the MadDoctor.

When Lobotomy Practice begins:
	say "You hear a noise and notice a short, stocky, unshaven man wearing a bloody white surgical gown and holding a large hypodermic is staring at you."

When Lobotomy Practice ends medically:
	say "The doctor says, 'I[']m afraid I[']m going to have to give you a frontal lobotomy!' he sticks you with his hypo and you pass out. When you awaken, you feel somewhat indifferent to your surroundings. You feel like wandering...";
	adjust locations of key people;
	lobotomize the player.
	
Every turn when the player can see the MadDoctor during Lobotomy Practice:
	if the time since Lobotomy Practice began is at least 1 minute:
		let rando be a random number between 1 and 20;
		say "The doctor says, ";
		if rando is at most 6:
			say "'You are not being a good little patient! Now return to your cell, or you will need a lobotomy!'";
		otherwise if rando is at most 12:
			say "'I grow tired of dealing with you inferiors!'";
		otherwise:
			say "'What are you doing here? Go where you belong!'".

Plughing is an action applying to nothing.
Understand "plugh" as plughing.

Carry out plughing:
	if the player is lobotomized:
		now the player is not lobotomized;
		say "You get better.";
	otherwise:
		say "Sorry, that doesn't work right now."

Test violent with "n / attack doctor / look / s / z".
Test medical with "n / z / z / look / s / z".

Lobotomized Wandering is a scene. Lobotomized Wandering begins when the player is lobotomized. Lobotomized Wandering ends when the player is not lobotomized.

When Lobotomized Wandering begins:
	say "<BEGIN>[line break]".

Every turn during Lobotomized Wandering :
	meander the player.

[When Lobotomy Practice ends violently]
Instead of attacking the MadDoctor:
	say "The doctor sticks you with his hypo. 'I[']m afraid I[']m going to have to give you a frontal lobotomy!' he says and you pass out.";
	adjust locations of key people;
	the lobotomy takes effect in zero minutes from now.

At the time when lobotomy takes effect: [only true in later check]
	lobotomize the player.

When Lobotomized Wandering begins:
	say "When you awaken, you feel somewhat indifferent to your surroundings. You feel like wandering..."

To adjust locations of key people:
	move the MadDoctor to the Office;
	move the player to Padded Room, without printing a room description.

Some debugging bits are left in to show where the scene change happens and when the meander code is checked, and there are several changes from your original code, so it’s not a straight copy-and-paste.

2 Likes

It does, except that Lobotomized Wandering needs to be a recurring scene.

The solution I came up with checks whether Lobotomy Practice ended violently, and uses a let variable to control wandering:

To meander the player:
	let rando be a random number between 1 and 20;
	let canto be 1;
	if Lobotomy Practice ended violently:
		unless the time since Lobotomy Practice ended is at least 1 minute:
			now canto is 0;
	if canto is 1:
		if rando is at most 5:
			say ">north[command clarification break]";
			try going north;
		otherwise if rando is at most 10:
			say ">east[command clarification break]";
			try going east;
		otherwise if random is at most 15:
			say ">south[command clarification break]";
			try going south;
		otherwise:
			say ">west[command clarification break]";
			try going west.

Great!

FYI for you and others happening across this thread: