Trying to make a scene "say" something the first time you enter a room during a scene

The story I am writing is broken down into nights. Each night is a scene. Now on the first night I can get the program to put out a “say” when you enter a room for the first time and that time only. That’s easy. Each scene starts the player off in the bedroom room which is next to the kitchen. The kitchen is the only room you can get to from the bedroom so you have to go into the kitchen at the beginning of each scene. I want, at least for the first two scenes, for something different to be said upon the first time entering the kitchen ((or any area)) I can do it on the first scene when the game begins but can’t seem to trigger it on the second scene. Now I know the first scene ended and the second began. I have it set up like so.

When First Night Begins:
Now the player is in The Cottage Bedroom;
Now the stranger is in The shore;
Now Otis is in The Cottage Kitchen.

When First Night Ends:
Remove Otis From Play.

When Second Night begins:
say “You awake in the mid evening the next day. Tonight is your shift to take care of the lighthouse. You immediately notice Otis is not in his bed. That’s odd considering how he always sleeps on his nights off, as do you. You can’t help but feel a little uneasy.”;
Now the player is in The Cottage Bedroom;
Now the stranger is in The Cottage Kitchen.

Lastly I have this.
After entering The Cottage Kitchen for the first time during Second Night:
say “As you emerge from your quarters you see not Otis, but the stranger standing there. He eyes you in a way that makes you feel uncomfortable as if there were some malice behind his gaze. Upon asking him why he hasn’t left the island yet as he said he would, he claims that he discovered a hole in the bottom of his rowboat, rendering it useless.”;
Continue the action.

Is this because Inform can’t detect going into a room for the first time in individual scenes?

Firstly, it helps if you remember to use the three backticks around any code. Or click that little </> icon. It can also help if you can extract a sufficient snippet to be complete on its own, to make it easier for both yourself and others to play around with the code and test things – I use a separate “testbed” project so that I can try out things in isolation, both to test forum thread posts and to sanity check my own code. :grin:

Secondly, entering The Cottage Kitchen is quite likely the wrong action – that only triggers if that is the actual action – merely going to the kitchen via a regular exit does not count as entering, it is going to the Cottage Kitchen. (Entering is for movement within a room, like entering a car or a box, not for movement between different rooms.)

Thirdly, unfortunately the for the first time etc only keep track of the action itself, not any additional conditions. The additional conditions (here, only during the Second Night) will still prevent the rest of the rule from running, but if the action itself happened during the First Night then that still counts, so on the Second Night then for the first time won’t be true. (You can test that by setting things up so that you never go to the kitchen on the first night – then your rule does get triggered the first time you go there on the second night.)

You will have to use something else to keep track of that. Probably the easiest method in this case is simply to use the standard visited flag:

When Second Night begins:
	now The Cottage Kitchen is unvisited;

After going to unvisited The Cottage Kitchen during Second Night:
	say "...."
1 Like

Hmm, actually, playing around some more, it looks like for the first time does take into account the when/while conditions, just not the during conditions. So this also works (but I’d still probably recommend doing it the other way):

After going to The Cottage Kitchen when Second Night is happening for the first time:

(Someone with an account should probably put that on the I7 bug tracker, if that’s still tracking bugs. I can provide more technical detail about what it’s doing wrong in the I6 code if needed.)

1 Like

Awesome. I will try all that tomorrow. I am still having trouble with the specific wording for things and that trips me up a bit. I might just print out a lot of common words and how they are used and have that with me when I program. Thanks!

Well, that particular change looks like a bug – during is the recommended way to do it normally, it’s just that for the nth time overlooks that.

But the is happening rewording you can find in 10.4. During scenes.

(If you’re really curious, you can find almost anything that Inform understands in the Index -> Phrasebook, including things added by extensions. But even though it’s categorised, there’s so much there that it can be hard to find specific things. Oddly enough, is happening doesn’t appear there, although has happened does. You can find happening in the Lexicon section though.)

It’s not overlooking that, it’s just evaluating it differently from how the OP intends. Inform is reading it as “if the first time you go to the kitchen, it’s during the second night.” Consider:

Lab is room.
The Kitchen is north of the Lab.
The Den is south of the Lab.

First night is a scene. First night begins when play begins.

After going to the Kitchen for the first time:
	say "Wow! A Kitchen!".
Second night is a scene. Second night begins when the player is in the lab for the second time. First night ends when second night begins.

After going to the Kitchen for the first time during the Second night:
	say "Seems like we've been here before.".
test me1 with "scenes / n / s / n".

test me2 with "scenes / s / n / n".

There doesn’t seem to be a way of changing this particular evaluation using parentheses. Changing the order works as you’ve seen, but the compiler’s parser only understands the “is happening” wording in this case. This is probably less of a bug and more a feature request with regard to optional wording in the use of “during” with multiple conditions.

No, I meant what I said – I was looking at the generated I6 code. It handles the during condition in a completely different way from the when condition, which is usually fine – but not when combined with a for the first time or similar condition.

The order is irrelevant, it’s just because when is handled differently that the alternate variant works as expected.

Essentially I7 is reading After going to The Cottage Kitchen for the first time during Second Night equivalently to:

After going to The Cottage Kitchen for the first time:
	if Second Night is happening:
		say "stuff"

i.e. the rule as a whole runs regardless of the scene (satisfying “first time”), but then simply does nothing if the wrong scene is active.

(This is still a bit of a simplification and there’s a little bit more to it than this, but it’s sufficiently accurate to get the idea.)

Surely that’s exactly what BadParser said?

Inform is reading it as “if the first time you go to the kitchen, it’s during the second night.”

(I agree that the order of the clauses is irrelevant.)

The rule is indeed generated differently, but the compiler is generating it correctly based on how it parses the condition.

1 Like

Perhaps, but I can’t personally parse what they said, so I’m not sure :slight_smile:

I disagree. If you look at the difference in the generated I6 code with the during scene version and the when scene is happening version, you should see what I meant. Besides, it makes zero sense to deliberately ask for what the compiler is actually generating – it’s an oversight, not an intended case.

1 Like

I’m looking at a test case with several variations of that rule, and I don’t see a bug.

After jumping during Night:
	say "Jumping and... (A) It's night.";
	continue the action;

After jumping for the first time during Night:
	say "Jumping and... (B) It's night AND you jumped for the first time.";
	continue the action;

After jumping when (Night is happening for the first time):
	say "Jumping and... (C) This is the first happening of Night.";
	continue the action;

After jumping when Night is happening for the first time:
	say "Jumping and... (D) This is the first time you jumped at night.";
	continue the action;

(Not including the I6 code here because it’s long.) (I changed the action to Jumping to make it easier to read and test.)

Each of these produces a recognizable, if perhaps strained, interpretation of the condition. The compiler’s interpretation is then implemented correctly.

When looking at the I6 code, it’s helpful to remember that the rule only counts as run when it reaches the if (debug_rules) DB_Rule(...) line. That’s when the “Rule… applies” message appears in RULES debug mode.

Note that parentheses do have an effect in case C, although it’s not the effect the original poster wanted.

It’s whether the condition is tested inside PAPR_n/TestSinglePastState or outside of it that matters, as that’s what causes the counting of first time. (On an unrelated note, the way that it has two different kinds of code generation for very similar things seems a bit peculiar as well.)

I can see what you’re saying, but my main point is that cases B and C don’t seem like they would ever actually be useful (especially C, as it’s very hard to trigger), and yet the phrasing in B is a more natural way to say what D actually does. So my argument is that B should trigger the same code generation as D. (And if you really wanted the behaviour that B currently provides for some reason, you could just put the scene test inside the rule body as I posted above.)

I agree. There’s plenty of room to improve the way the compiler disambiguates these things.

There’s another whole category of ambiguities of the form “if the player is drunk for the first time.” This seems straightforward until you have a game with several playable characters – so the player variable can refer to different people. Then you realize that “if the player is drunk for the first time” is interpreted differently from “if Steve is drunk for the first time” even when player == Steve, which violates a whole lot of common-sense assumptions about how variables work. (“Referential transparency”.) But the other interpretation isn’t obviously right either!

Anyhow, it’s tricky to say what will be useful to authors. I can think of straightforward uses of C. (Night is a recurring scene, so some rules apply at night, but other rules apply “if Night is happening for the first time”, “if Night is happening for the second time”, etc. Yes, I’d use a night-counter variable, but not everybody would.)

Yeah, that’s a tricky one. I can see both being useful for different cases. But it’s understandable, due to the way that the tracking works under the hood.

In English, yes. In the game, no. See, Night is happening for the first time will only be true for one turn, so the only place it could ever have a guaranteed effect is in an every turn rule (otherwise it will most likely just never run, if the player does a different action that turn), in which case you might as well just do it in the when Night begins rule instead. And Night is happening for the second time means the second turn during the first instance of Night, not the second time that the whole Night scene occurs.

Nope. It’s true for the first entire span of time that Night is happening. That is, from the first time Night starts to the first time Night ends.

Huh. That’s correct, but not what I was expecting. (Is it only actions that get “cleared” after one turn, then? Maybe that’s why they’re tracked separately despite being otherwise very similar.) I guess case C makes slightly more sense after all.