New User (from Quest) needing help with If/When for setting numeric variables

Heya all,

I’ve been fiddling with a bit trying to get numeric variables to work in Inform 7 And can’t find exactly where this is covered in the built-in documentation, but because it’s so fundamental figured it’s easily answered on a forum.

I’ve got a value, Energy, that I intend to use to dictate events (If Stamina = x).
Energy starts off at 1 and can be increased or decreased through various actions, which then unlock responses and events.

In my code I have

Energy is a number that varies
Energy is initially 1

These two work, I think.

Where I’m struggling is that I want:

If Energy is less than 1, Energy is 1.

or

If Energy is less than 1:
set Energy to 1

So that Energy cannot be reduced infinitely. Any time Energy is less than 1, it becomes 1.

I’ve tried a few dozen combinations of language and arrangements and I’ve been combing the documentation but can’t figure out how to do this. Any suggestions?

Thanks, Lilt

While Inform looks like it knows all kinds of English, particular phrases are required to do particular things. And ‘set (something to something)’ isn’t actually part of its vocab.

This first bit is okay:

Energy is a number that varies.
Energy is initially 1.

… though we can do a little refinement here. When you use the phrase ‘Energy is initially 1’, that both tells Inform that Energy is a number variable, and that it starts with a value of 1. In other words, when you use the ‘initially’ phrase like this, you don’t need the preceding line ‘Energy is a number that varies’ part as well.

So at the point you’re struggling, this is where you need to know the way Inform changes variables. And that is with the ‘now’ phrase. Inform doesn’t know the phrase ‘set (anything)’, unless you create it yourself. The way to change a variable with ‘now’ is like this is:

if energy is less than 1:
	now energy is 1;

Maybe have a look at 2.2 in the documentation, ‘Making rules’, as well.

-Wade

4 Likes

Thanks! I’ve got the system mostly working now.

Energy is initially 1.
Every turn:
if Energy is less than 1:
now Energy is 1;

Though I’ve noticed something unusual when testing.

Every turn:
if player is not wearing Battery Drain:
now Energy is Energy + 2;
else if player is wearing Battery Drain:
now Energy is Energy - 2;

This system seems to draing Energy in a way the first block can’t keep up. I get -1 Energy.

Though I may have to rework this system as I want the player to be able to wear four objects that provide a solid numerical boost to Energy rather than an infinite upwards clock, much like how armour gives a solid +1 or +2 in RPGs.

What’s going on here is that your second Every Turn rule is getting evaluated after the first – so at the end of each turn, the energy is getting corrected up to 1 if it’s 0 or negative, and then if the player’s wearing the battery drain, it’s getting adjusted down by 2, which gets you to -1. The usual rule is that the order of operations runs from more specific to more general, so for example an Every Turn rule with a condition in the header will be evaluated before one without, but the specifics are quite complex (only click that link if you really want to dive into a bunch of mostly-irrelevant detail).

There are a couple of things you could do to fix this. The simplest is to combine the two rules into a single Every Turn rule, so you can manually put things in the correct order:

Every turn:
    If player is not wearing Battery Drain:
         Now Energy is Energy + 2;
    If player is wearing Battery Drain:
         Now Energy is Energy - 2;
    If Energy is less than 1:
        Now Energy is 1.

The other approach is to tell Inform the precise order you want the rules to fire, which is a little more complex but is a good trick to learn because you’ll sometimes run into situations where you can’t easily combine rules as in the first approach. This way of doing things just requires naming the rules - here’s what that looks like:

Every turn (this is the battery drain rule):
    If player is not wearing Battery Drain:
         Now Energy is Energy + 2;
    If player is wearing Battery Drain:
         Now Energy is Energy - 2;

Every turn (this is the no negative energy rule):
    If Energy is less than 1:
        Now Energy is 1.

The no negative energy rule is listed after the battery drain rule in the every turn rulebook.

Hope this is helpful! If any of it’s confusing, the relevant documentation here is Chapter 19 of Writing with Inform, especially 19.4 on Listing Rules Explicitly.

2 Likes

When I was at your stage of learning, one issue initially caused me a lot of confusion, which cleared up when the following penny dropped: there are basically two totally different kinds of Inform 7 statement, those that work inside rules, and those that work at the top level and basically happen right at the start of the game (these could be rule declarations like where you declare your every turn rule, or your variables, or they could be something else like an Understand statement).

This was an example of such confusion. To set a variable outside a rule (i.e. right at the start, you can do something like “Energy is initially 1”, but inside a rule, it has to be something like “now energy is 1”.

“Understand” is another similar example that often causes confusion in the same way. It works at the top level, but not in rules (so if you want to dynamically change the way the parser understands things, you need something like “Understand X as Y when condition Z is true.”).

3 Likes

Thanks for the help!

Yeah, Inform 7 is a very strange way of coding and I’m still getting accustomed to it. Many of the rules are quite strange and need some getting used to, but I’m steadily getting to the point I can do most of the basic things I need.

That advice for understanding x as y when condition z is true seems very useful, I’ll definitely keep that in mind.

1 Like