Changing the description of the player

I’m writing a story in the third person. I want to change the description of the player mid-game. Initially, I want the player to be unknown/unnamed. Then, at some point, the player’s background is revealed and the player now has a name.

Here is how I’ve attempted to implement this:

Yourself can be anonymous or named.

When play begins:
	now the story viewpoint is third person singular;
	now the story tense is present tense;
	now yourself is female;
	now yourself is anonymous.

To say BackgroundReveal:
        say "... player background stuff ...".
        yourself is named.

The description of yourself is "[if yourself is named]Olivia Yeung, an antiques shop owner.[else]A mysterious woman dressed all in black.[end if]".

In the last line above, I’ve also tried [if player is named] and just [if named], but the end result (mentioned below) is the same.

At the point in the story when the player’s background is revealed, I have a line of code that looks like:

say "[BackgroundReveal]"

To test this I’ve tried the following.

  1. At the very start of the game, “x self” gives me the anonymous response.
  2. I navigate to a point where [BackgroundReveal] is printed.
  3. I try “x self” again. But it still gives me the anonymous response.

Can anyone see what I’m doing wrong here?


Looks like two-and-a-half things which cancelled themselves out in a way that allowed your source to compile but produced the wrong behavior.

In this:

To say BackgroundReveal:
        say "... player background stuff ...".
        yourself is named.

the period at the end of the second line terminates the code block. So the last line isn’t treated as part of the “To say” phrase, but as a separate assertion.

Also, if it were in a code block, you’d need to say “now yourself is named.” But since it’s a separate assertion, it compiles without “now” (and wouldn’t compile with “now”). So this declares “yourself” to be named at compile time.

The half-a-thing is that you can set initial values at compile time in an assertion, and you don’t need to do it in a “When play begins” rule. I think all of the things you’re doing in that rule could be declared on their own (just write them as stand-alone sentences without “now”).

So what’s going on is:
yourself is initially set to “named” before anything runs;
when play begins, the “when play begins” rule sets yourself to “anonymous”;
when you trigger BackgroundReveal, the only line that is part of the code block is the “say” phrase, so yourself doesn’t get set to “named.”

The quickest fix is to put in that semicolon and “now”:

To say BackgroundReveal:
        say "... player background stuff ...";
        now yourself is named.

Another point is that you can do “BackgroundReveal” in a phrase that isn’t a “to say”, like To reveal background: which you could call by saying reveal background in another code line. This is a bit more reliable than having state changes in a “say” phrase, since sometimes text substitutions get looked at even when they’re not printing, and that triggers any state changes that are supposed to happen when the substitution does get printed.

1 Like

Thank you for the detailed response! That really clarifies a lot of things for me.

What if I also wanted to include a new “understand” rule once the player’s name has been revealed?

To say BackgroundReveal:
      say "... player background stuff ...";
      now yourself is named;
      now understand "Olivia" as yourself.

The above doesn’t work, nor does it work if I remove the “now” in the last line.

Understand "Olivia" as yourself when yourself is named.
1 Like

Yes, “Understand” lines can’t be changed at runtime with “now” or something, so you have to include a “when…” clause, and then make the thing after the “when” true.

Great, thank you!

One more question… I was under the impression that the tab is important for defining scope. The examples I’ve read made Inform look like python to me, where the indent-level determines to which code block a line belongs.

However, in the code in my OP, is the tab before “yourself is named” effectively “ignored” since the statement is treated as an assertion outside the “To say” block?

I guess the essence of my question is, when are tabs required and when are they treated as any other whitespace?

I followed your advice and moved everything to stand-alone statements without the “now”. You’re right that this worked, in most cases. I got a compile error on the story viewpoint and story tense statements, so the code block looks like this now:

Yourself is female and anonymous.
When play begins:
	now the story viewpoint is third person singular;
	now the story tense is present tense.

As a follow-up, how do I know, when assigning a variable, whether the assignment statement should should begin with “now” or not? I find myself guessing at that a lot and just trying out both.

Basically (and as I understand it, I could have lots of details wrong), first the Inform compiler breaks the code up into blocks, then it looks at the indentation. A code block will break either when there is a period outside quotation marks, or a full blank line after the code block. In your case it broke because of the period.

Within a code block, if there’s more than one level of indentation, you need to have the tab stops lined up properly. But if you have a one-line code block, it can be indented as much as you like or even put on the same line as other code after a period, as in:

Before waiting, say "You're going to wait." After waiting, say "You have waited."

(For one-line rules like this, you can use a comma after the rule header and write them inline instead of using a colon and putting the code on the next line.)

This is why your original code compiled; the “yourself is named.” line was treated as a standalone assertion which was allowed to be indented.

The same thing seems to hold whenever the code block doesn’t have any nesting dependent stuff that would require mutliple levels of indentation; this ee cummingsish rule compiles:

	Before waiting:
say "You're going to wait.";
					say "Anytime now.";
		say "Yup."

and works just like

Before waiting:
	say "You're going to wait.";
	say "Anytime now.";
	say "Yup."

But again, if you need more than one level of indentation (which basically means, if your rule/phrase has a colon after the header line) it has to be aligned properly, so this has to be just so:

Before waiting:
	if yourself is named:
		say "Olivia the antiques shop owner is going to wait.";
		say "She's going to wait."

(Actually, on a test, if you indent the first line and leave the others where they are, it’ll still compile. But this would be a bad idea!)

Yeah, I was just wrong about those two, per the examples given in §14.1 of the documentation! Sorry about that.

If you’re doing something within a rule or phrase that will be executed while the game/story is running, use “now.” If it’s a standalone assertion that defines the initial conditions of the world, then you don’t use “now.” The assertions are discussed a bit in §2.1 of the documentation.

1 Like

Thank you Matt for these explanations! I really appreciate all of your time and help.

Also, “ee cummingsish” is such a great word that it needs to be added to the Oxford English Dictionary :laughing: