How to use if/else statements with secret room exits?

My question is:

The player is in the Starting Room. They can only go north to the lab. So they do. They enter the lab. The player has a set of blueprints for the lab. If they read the blueprints, a secret passage opens to the north. But if they read the blueprints twice or more, I want a message to say “You already read the blueprints and you can’t open an already opened secret passage twice.”

  1. I cannot get the game to print this message. There is something wrong with my if/else statement in To say blueprints_desc.

  2. The statement “else if north from the lab is Secret_Room” is wrong. For the life of me, I CANNOT find one example in the Recipe Book that contains that statement. I have looked 500 times. I know I saw that statement somewhere before because at one point in my debugging I had that statement right and now I can’t find it again in the Recipe Book.

  3. So what is the correct statement? And if you can find the correct statement, it still won’t print out “You already triggered the secret passage once already.”

  4. As I type this, a box has opened to my right. It contains similar topics to mine about exits and if/else statements. But I click on these topics and nothing happens. I don’t want to repeat a topic, but nothing happens when I try to see them.

  5. Thank you for all your help.

Starting_Room is a room.  The description of Starting_Room is "The player starts here."  North of Starting_Room is the Lab.

Lab is a room.  The description of Lab is "This is a lab."  South of Lab is Starting_Room.

Some blueprints are a thing.  The player carries blueprints.  Blueprints are portable.  The description of blueprints is "[blueprints_desc}".

To say blueprints_desc:
	if location is not Lab:
		say "You are not in the lab, and the blueprints only talk about things in the lab.";
	else if north from the lab is nowhere:
		say "You discover a secret passage to the north!";
		change the north exit of Lab to Secret_Room;
		change the south exit of Secret_Room to Lab;
	else if north from the lab is Secret_Room:
		say "You already discovered the Secret Room and you can't discover it twice.  Nothing happens."
		
Secret_Room is a room.  The description of Secret_Room is "The room is secret."  South of Secret_Room is nowhere.

Okay, there are four problems in the source. Three are just syntax, and one is a pretty subtle programming issue with Inform.

Syntax:

You have
else if north from the lab is nowhere

A way to check for the absence of a room in a direction is like this:
else if the room north of lab is nothing:

Then your next else statement needs a similar treatment:
else if the room north of lab is Secret_Room:

You’ve got a brackets typo in
[blueprints_desc}

That needs a closing square bracket, not a curly.

Once all that was working, the problem was that as soon as I looked at the blueprints in the lab, the secret passage became open but the game also said ‘You can’t open the secret door twice.’ The first ‘You discover a secret passage’ message never appeared.

This is the subtle catch. In Inform, it’s dangerous to run code that changes variables or the world state as part of a text expansion. This is because, in preparing to expand the text, Inform runs it once behind the scenes (running all the code inside but without printing it), then it runs it again, printing the output. So all the non-text-printing code runs twice

‘blueprings_desc’ is a text subsitution worked out during play, whenever you display it, by the phrase ‘To say blueprints_desc’. And as soon as the player examines the blueprints, everything in To say blueprints_desc runs twice in a row, first without printing the output, then with printing it. So on the first run, the passage is found and the exits are changed, but no text is printed. Then Inform does the printing version, at which point the exit already exists so we go straight to the ‘You already discovered the Secret Room’ text.

People have usually made a lot more game by the time they encounter this subtlety, so consider yourself lucky or unlucky as you see fit!

How to avoid this happening: the first and best is, don’t change the world state or variables in code that’s running during a text substution. It’s always possible to do things another way.

In the case of these blueprints, what you can do (which is what I would do and do all the time) is turn the whole thing into a rule and skip the text substitution. There are, surprisingly, many ways to do this, and all have their annoyances.

Here’s how I’ve done it:

Check examining the blueprints:
	if location is not Lab:
		say "You are not in the lab, and the blueprints only talk about things in the lab.";
	else if the room north of lab is nothing:
		say "You discover a secret passage to the north!";
		change the north exit of Lab to Secret_Room;
		change the south exit of Secret_Room to Lab;
	else if the room north of lab is Secret_Room:
		say "You already discovered the Secret Room and you can't discover it twice.  Nothing happens.";
	rule succeeds;

I need to end the rule with ‘rule succeeds’ to stop the examining action reaching later stages. If it reaches the carry out stage, it will also print ‘You see nothing special about the blueprints’, because we have set no description text on them, and we don’t want it to say that.

If I began the rule
After examining the blueprints:
we have the exact same problem.

So you can write a ‘Check’ rule like I have, stopping it with rule succeeds. Or an ‘Instead’ rule. But sensing you’re learning, I don’t like to overrecommend Instead rules to learners because they tend to end up overusing them inappropriately too early.

  • Another way (this is advanced and possibly overkill, but then again it may just be some people’s preferred way - and it’s the most adherent to Inform’s preferred programming style) is to use a Carry out or After rule for the examining the blueprints code, but then disable the other rule that prints ‘You see nothing special’ just in the case of the blueprints. Which would be:

The examine undescribed things rule does nothing when examining the blueprints.

-Wade

4 Likes

Yes, I think that will do it. Thank you for all your help!