Incrementing variables in an action

Hello! I’m creating an inform 7 game based off being a phone that can do things like vibrate, notify, and search. Currently I’m experiencing problems getting the values I want from notifying and vibrating about nouns in the room.

vibrating is an action applying to one thing.
Understand “vibrate at [something]” as vibrating.
Understand “vibrate about [something]” as vibrating.

Instead of notifying:
if the noun is gum,
say “Kyle hates gum and vomits. That was drastic. Perhaps you won’t point this out next time.”;
decrease Upgrade Desire by 5;
now notifyFirst is true;
if the noun is magazines,
say “Kyle loves magainzes! How did you know?”;
now Kyle has the magazines;
now notifyFirst is true;
if the noun is chips,
say “Kyle likes chips usually, but doesn’t really want any right now.”;
now notifyFirst is true;
if the noun is pizza,
say “You: There is pizza on the floor! It’s made of cheese, sauce, and some toppings! Would you like to order?[line break] Kyle: Dude, that’s sick! But does REALLY know about the sauce?”;
increment the smooglecount;
if the noun is beer,
say “You: Beer is widely consumed! You seem to like it! Order more?[line break] Charlie: I don’t know if your phone should be supporting drinking like that…”;
increment the smooglecount;
if the noun is trash,
say “You: Trash is unwanted. Kind of like you! Kyle: Wow. Rude.”;
decrease upgrade desire by 2;
increment the smooglecount;
if the noun is cheese,
say “You: Cheese is a food made from the pressed curds of milk. Charlie: LAME”;
decrease upgrade desire by 5;
increment the smooglecount;
if the noun is sauce,
say “You: YOUR GIRL [bold type]KNOWS[roman type] I’VE GOT THE SAUCE[line break]Kyle: THAT’S FUCKING HILARIOUS.”;
increase upgrade desire by 2;
increment the smooglecount;
if the noun is toppings,
say “You: Pepperoni! Mushrooms! Avocado! Asparagus! Anchovies! Olives! Pineapple! Ham! Sausa–[line break]Kyle: ALRIGHT ALRIGHT ALRIGHT PRIXEL STOP”;
decrease upgrade desire by 5;
increment the smooglecount;
if smooglecount is greater than 4,
say “Charlie: Well, that’s all cool, but it’s no iPear. I’m gonna go to the kitchen.[line break]You notice Charlie is walking right into a pile of beers. Give him a buzz![line break]”;
say “Smooglecount is [smooglecount]”;
say “Upgrade Desire is [upgrade desire]”;
now Charliescene is true;
if smooglecount is greater than 7,
say “Charlie walks into the beers and trips, rolling his ankle and falling into a door. Charlie: SON OF A BITCH. Your damn phone got me all distracted dude. You know, for a phone that knows so much about what’s going on around it you’d think it could warn a brotha too.”;
decrease upgrade desire by 5;
now Charliescene is true;

Entering “notify about gum / notify about pizza” into the console yields this output:

notify about gum
Kyle hates gum and vomits. That was drastic. Perhaps you won’t point this out next time.
Charlie: Well, that’s all cool, but it’s no iPear. I’m gonna go to the kitchen.
You notice Charlie is walking right into a pile of beers. Give him a buzz!
Smooglecount is 6Upgrade Desire is 85
Kyle purchases his goods - including you - and delightfully walked out the door. You overheard, however, that after a year he will have the opportunity to upgrade you or get a new phone. However, that won’t matter! He loves you!
End of Prologue.

notify about pizza
You: There is pizza on the floor! It’s made of cheese, sauce, and some toppings! Would you like to order?
Kyle: Dude, that’s sick! But does REALLY know about the sauce?
Charlie: Well, that’s all cool, but it’s no iPear. I’m gonna go to the kitchen.
You notice Charlie is walking right into a pile of beers. Give him a buzz!
Smooglecount is 12
Upgrade Desire is 65
Charlie walks into the beers and trips, rolling his ankle and falling into a door. Charlie: SON OF A BITCH. Your damn phone got me all distracted dude. You know, for a phone that knows so much about what’s going on around it you’d think it could warn a brotha too.

Any thoughts? I’m certain that the values are all being incremented, but why does it go through and check each noun? I thought it was only supposed to check the noun that you are using in an if statement?

Thanks!

My first thought is you might separate all this into check/carry out/report rules instead of trying to accomplish everything in one very complicated and hard to troubleshoot instead rule.

The reason it’s not stopping is you’ve written it as one huge instead rule without telling it to stop (there’s more to it, but essentially…) Usually, you can bail out of a rule with “rule succeeds” or “stop the action”, but that’s why it’s generally not a good idea to rely solely on instead rules for everything. While inside of an instead rule, the parser won’t observe any standard or competing rules (like "Is it too dark to do this? Can the player actually reach this thing?) and carries out your instructions explicitly whether they make game world sense or not.

[code]Check notifying about gum:
if notifyFirst is true:
say “You’ve already done that.” instead. [if that’s what this is for]

Carry out notifying about gum:
decrease Upgrade Desire by 5;
now notifyFirst is true;

Report notifying about gum:
say “Kyle hates gum and vomits. That was drastic. Perhaps you won’t point this out next time.”;

[/code]

One hurdle I took a bit to understand is writing these rules are additive to Inform’s rulebooks, and as long as you’ve added it to the correct phase of the turn, you needn’t worry in most cases about what order they are in. An instead rule, conversely goes straight through and does everything immediately in order without stopping unless you tell it to.

Check rules are for situations that can interrupt an action, like “If the player doesn’t have the blue key, they can’t go through the blue door; print this message instead and don’t allow it.” This gets filed with every other normal check rule that includes “Is the player actually able to reach the door?”

Carry out means the action is going to succeed, now you just need to move the pieces. “When the player goes through the blue door, they are sprayed with blue paint and are now ‘blue’.” In the case of a door, Inform handles moving the player since there are already built in rules about “going” and you needn’t move the player.

Report adds a custom message to the action. “Tell the player they are now covered in paint.” This doesn’t interfere with any other reporting that Inform usually does that normally says “You go through the door.” (or whatever the standard report is.

After rules run before report and will cut them off. Say if the player is carrying an umbrella to avoid the paint and you want a different result in this case. “After going through the blue door when the player is blue: if the player carries the umbrella: say “You are sprayed with blue paint and quickly open the umbrella to avoid it.”; now the player is not blue.”

(This is all pseudocode, but hopefully, it makes sense.)

I’ve managed to make it worse!

I don’t think this is how you intended it to be used (I wasn’t getting output from the pseudocode, as expected, so I did this based on documentation, but this is what I did:

Check notifying:
if the noun is magazines,
if notifyFirst is true,
say “You’ve already done this!” instead;

Carry out notifying:
if the noun is magazines,
increase Upgrade Desire by 2;
now Kyle has the magazines;
now notifyFirst is true;

Report notifying:
if the noun is magazines,
say “Kyle loves magainzes! How did you know?”;

Check notifying:
if the noun is chips,
if notifyFirst is true,
say “You’ve already done this!” instead;

Carry out notifying:
if the noun is chips,
now notifyFirst is true;

Report notifying:
if the noun is chips,
say “Kyle likes chips usually, but doesn’t really want any right now.”;

Check notifying:
if the noun is pizza,
if notifyFirst is true,
say “You’ve already done this!” instead;

Carry out notifying:
if the noun is pizza,
increment the smooglecount;

Report notifying:
if the noun is pizza,
say “You: There is pizza on the floor! It’s made of cheese, sauce, and some toppings! Would you like to order?[line break] Kyle: Dude, that’s sick! But does REALLY know about the sauce?”;

Check notifying:
if the noun is beer,
if notifyFirst is true,
say “You’ve already done this!” instead;

Carry out notifying:
if the noun is beer,
increment the smooglecount;
decrease Upgrade Desire by 2;

Report notifying:
if the noun is beer,
say “You: Beer is widely consumed! You seem to like it! Order more?[line break] Charlie: I don’t know if your phone should be supporting drinking like that…”;

Check notifying:
if the noun is trash,
if notifyFirst is true,
say “You’ve already done this!” instead;

Carry out notifying:
if the noun is trash,
decrease upgrade desire by 2;
increment the smooglecount;

Report notifying:
if the noun is trash,
say “You: Trash is unwanted. Kind of like you! Kyle: Wow. Rude.”;

Check notifying:
if the noun is cheese,
if notifyFirst is true,
say “You’ve already done this!” instead;

Carry out notifying:
if the noun is cheese,
decrease upgrade desire by 2;
increment the smooglecount

Report notifying:
if the noun is cheese,
say “You: Cheese is a food made from the pressed curds of milk. Charlie: LAME”;

Check notifying:
if the noun is sauce,
if notifyFirst is true,
say “You’ve already done this!” instead;

Carry out notifying:
if the noun is sauce,
increase upgrade desire by 2;
increment the smooglecount;

Report notifying:
if the noun is sauce,
say “You: YOUR GIRL [bold type]KNOWS[roman type] I’VE GOT THE SAUCE[line break]Kyle: THAT’S FUCKING HILARIOUS.”;

Check notifying:
if the noun is toppings,
if notifyFirst is true,
say “You’ve already done this!” instead;
Carry out notifying:
if the noun is toppings,
decrease upgrade desire by 2;
increment the smooglecount;
Report notifying:
if the noun is toppings,
say “You: Pepperoni! Mushrooms! Avocado! Asparagus! Anchovies! Olives! Pineapple! Ham! Sausa–[line break]Kyle: ALRIGHT ALRIGHT ALRIGHT PRIXEL STOP”;

The result was:

notify about magazines
Kyle loves magainzes! How did you know?
Upgrade Desire is now 100
Kyle purchases his goods - including you - and delightfully walked out the door. You overheard, however, that after a year he will have the opportunity to upgrade you or get a new phone. However, that won’t matter! He loves you!
End of Prologue.

Charlie’s House
Across the floor lies muck; a heaping load of it. Nothing but clothes, pizza boxes, beer, all the like. However, you love Charlie anyway. After all, would it really be Charlie without this stuff!?

You can see Kyle, pizza, beer and trash here.

You have come to see your best friend, Charlie, to show him your new ware. Charlie is a phone enthusiast, so Kyle knew if ANYONE would appreciate it, he came to the right place. Time to show Charlie what you’re made of, now that competition is out there!
Charlie: Dude, your phone is so killer! I hear it has hella useful stuff bro, but can it change your way of life like the iPear can?!
Kyle: Haha, I wouldn’t go that far, but I suppose we do have to see if it really CAN do anything special. "Okay Prixel: What can you tell me about the stuff on the floor?

notify about beer
Upgrade Desire is now 98
You: Beer is widely consumed! You seem to like it! Order more?
Charlie: I don’t know if your phone should be supporting drinking like that…

notify about pizza
You’ve already done this!

What is the problem with the output? It seems to be behaving according to schedule. When you “notify about beer”, a check rule flips notifyFirst to true. Then when you “notify about pizza”, another check rule sees that notifyFirst is true, and prints the “you’ve already done this” response.

If you only want that response to print when the player tries notifying about the same thing a second time, then you’ll need a separate truth value for each thing that can be notified about.

In general, your code would be clearer if your wrote your rules as “Check notifying when the noun is cheese:” (or just “Check notifying cheese:”) rather than doing everything with “if” clauses.

Also, when the rule is doing the same thing regardless of what the noun is, you don’t have to condition over the nouns. In the code as you’ve written it, all the Check rules could be replaced with one rule: Check notifying when notifyFirst is true: say "You've already done this!" instead.

If you replace notifyFirst with a set of truth states, one for each notifiable thing, you will still be able to do this in one rule, provided you make the truth state a property of the thing. I haven’t tested this:

A thing has a truth state called the notifyFirst. The notifyFirst of a thing is usually false.

Check notifying when the notifyFirst of the noun is true:
   say "You've already done this!" instead.

Carry out notifying something:
   now the notifyFirst of the noun is true.

Carry out notifying cheese: (etc...)

Also, you can make sure the notify action can’t happen unless the noun is in scope (meaning in interactable range) by modifying your action.

Notifying is an action applying to one touchable thing.
Notifying is an action applying to one visible thing and requiring light.

Be aware “visible” has a specific meaning that can feel weirdly counter-intuitive in Inform. Someone will jump in if I’m wrong, but “visibility” refers to scope and doesn’t necessarily mean the player can “see” the item. I think an item can be internally marked “visible” in a dark room, but the parser can still disallow actions that “require light” - “It’s too dark to see that!”

Indeed, “visible” means the player can perceive it in some way. Something in your hand in a dark room is still “visible” because you can feel it. “Requiring light” means you can’t e.g. read a book even if it’s in your hand in the dark. Chalk it up to English not having a good word for “able to be perceived by any sense”.

Also, “applying to one thing” by default means “one touchable thing”. This is imo a design flaw in Inform, that “one thing” is more specific than “one visible thing”, but it’s far too late to change now.

If I understand the question, I see two ways to fix this.

  1. put the word instead at the end of each if statement. That will stop the action after the first condition is met.

  2. Put the word otherwise before all but the first if statement. This makes the options mutually exclusive.

I think you can do both, if you like belts and suspenders…

I think you’re making things overly complicated.

What I’d do in your case is make the action as generic as possible, and then pass all the arguments to the objects themselves. For instance:


CHAPTER - NOTIFYING

A thing can be smoogly [no idea what "smoogle" is, so I'm winging it here].
A thing has a number called the upgrade value.
A thing has some text called the notify response.
A thing has a truth state called the notifyFirst. The notifyFirst of a thing is usually false.

Check notifying:
    if the notifyFirst of the noun is true, say "You've already done this." instead.

Carry out notifying something:
    increase upgrade desire by the upgrade value of the noun;
    if the noun is smoogly:
        increment smooglecount;
    now the notifyFirst of the noun is true.

Report notifying something:
    say the notify response of the noun;
    say line break.

CHAPTER - THINGS

SECTION - MAGAZINES

The magazines is a thing.
The upgrade value of the magazines is 2.
The notify response of the magazines is "Kyle loves magazines! How did you know?".
After notifying the magazines:
    now Kyle is carrying the magazines;
    continue the action.

SECTION - BEER

The beer is a thing. The beer is smoogly.
The upgrade value of the beer is -2.
The notify response of the beer is "You: Beer is widely consumed...."

And so on.