Hey everyone, I’m making my very first game with Inform 7, and I’m having trouble with what is probably a simple issue.
I have a situation where I want a locked door to link two rooms, but I want the “door” to be a feature in the scenery that the player needs a weapon to break open. This is what I came up with, but it doesn’t work:
The bricks is a door. The bricks is scenery. The bricks is lockable and locked. The bricks is east of the Cellar and west of the Cave.
Instead of attacking the bricks:
[if the player has nothing] say “You have no weapon.”[end if];
[if the player has a weapon] say “You break through the bricks.”;
now the bricks is unlocked[end if].[/code]
When I test this without having a weapon, the game displays both messages and unlocks the door anyway.
Any help would be much appreciated!
Looks like a punctuation problem. You need to remove the brackets from around the [if] bits. With brackets, that stuff is a comment, and will do nothing. You’ll also need to add a couple of colons and maybe another indent or two. My I7 is too rusty for me to give you a code example.
The first thing is that anything that you put in brackets outside of quotation marks gets treated like a comment–that is to say ignored. So none of that stuff is doing anything!
The second thing is that, if you want to stop executing a rule in the middle, you have to tell inform to do so; usually by a phrase like “stop the action” or sometimes “instead” or “continue the action” or “rule succeeds.” (Exactly which you want will depend on how you want other rulebooks to behave – you might want to look at the documentation chapter on Rulebooks for more on this.) So you’d need something like that…
…or in this case it’d be simple just to use an “otherwise” and rewrite the rule, like this:
Instead of attacking the bricks:
if the player carries a weapon:
let smasher be a random weapon carried by the player;
say "You break through the bricks with [the smasher].";
now the bricks is open;
say "You have no weapon."
I did something to let the game use the weapon’s name in the message, just to show how you might do that (and note that the bit in the square brackets doesn’t get treated as a comment because it’s in quotes). Also, you probably want to make the bricks open rather than unlocked–if you make them unlocked the player still has to open the bricks, and can shut them again, which is not what you intend I suspect. (In fact for this reason you should probably make the bricks not openable.)
But! There’s an even Informier way to do it:
[code]Instead of attacking the bricks: say “You have no weapon.”
Instead of attacking the bricks when the player carries a weapon (called smasher):
say “You break through the bricks with [the smasher].”;
now the bricks is open.[/code]
Inform will first check to see if the more specific rule applies, and if it does, will run it. (And since it’s an “instead” rule, it won’t run any of other usual rules for attacking.) If the player doesn’t carry a weapon, that rule doesn’t apply, and Inform will run the other rule.
Hope this helps!
Thanks so much for the responses! I feel silly for using the brackets like that. I plugged in the second code example and it worked perfectly with some additional lines to classify the weapon as a thing. Maybe the additional lines aren’t necessary, but inelegant or not, it now functions! Very much appreciated. That just saved me hours!
I have another almost certainly amateur question, so I’ll just ask it in here rather than making a new thread.
In my game I have one room that is very hot. I want the player to die and the game to end if the player stays in this room for five turns. I think I can achieve this by having a recurring scene start when the player enters the room, then having the scene end when the player leaves the room. Each turn during the scene would display a different message, and the fifth turn would result in a game over.
However, I can’t figure out how to get a different message to display each turn. So far I’ve got something like this:
[code]Heatdeath is a recurring scene. Heatdeath begins when player is in the Boiler. Heatdeath ends when player is not in the Boiler.
When Heatdeath begins:
say “It is hot.”[/code]
This works, but everything I’ve tried to add descriptions for each turn causes an error. I tried making a table. I tried scrapping the scene and using time-based events. After a few hours I decided I should ask for help instead!
You could write a rule for “instead of doing anything when the location is the Boiler for five turns”. That will fire on the fifth consecutive action in that room.
Thanks so much! I had to modify it a little, but it works.
Every turn: if player is in the Boiler for one turns
Every turn: if player is in the Boiler for two turns
Every turn: if player is in the Boiler for three turns
Every turn: if player is in the Boiler for four turns
Every turn: if player is in the Boiler for five turns
This way it seems that the player can still move around and execute other actions. “Instead of doing anything” appeared to override all other actions. This method is much easier than trying to write a scene like I had been doing!
It might be easier to dispense with the scene, and instead just track the player’s heat level in a variable or an attribute of the player, something like this (off the top of my head; I don’t actually have Inform 7 installed on this laptop to test this):
The current heat level is a number that varies. The current heat level is 0.
Definition: A room is hot rather than cold if it is The Boiler. [tweak this if you have more hot rooms]
Every turn when the location is hot:
increment the current heat level;
if the current heat level is 1, say "It sure is hot in here.";
if the current heat level is 2, say "You're feeling kind of uncomfortable in this heat.";
if the current heat level is 3, say "You're feeling [italic type]really[roman type] uncomfortable in this heat!";
if the current heat level is 4, say "It's too hot! You [bold type]need[roman type] to get out of here [bold type]now[roman type]!";
if the current heat level is 5 or greater, end the story saying "You die of heatstroke."
Carry out going to a cold room: now the current heat level is 0.
Report going from a hot room to a cold room: say "Phew! It's so much cooler out here."
Thanks for the example code! I think I’ll stick with what I have now with the “Every turn” set-up, just because I don’t have to introduce any new mechanics like heat level with that, but it’s still helpful to learn how to use varying numbers.
Yet another silly issue…
In one room in my game, there’s a monster that’s designated as scenery. The player has a blade in their inventory and that’s it. When you type the single word “attack” as a command, the game says:
Violence isn’t the answer to this one.
So I have two questions here. Is there any way to make the player automatically attack the monster when only “attack” is typed? I figured out that the code “Instead of attacking in the Room, try attacking the Monster” does attack the monster, but the game still displays “(the blade)” as a response even when the monster is being attacked.
My second question is, can I change the automatic “Violence isn’t the answer to this one” response? I’ve tried installing the Default Messages extension to tinker with it that way, but for some reason my computer won’t install it. Even the pre-installed extensions like Basic Help Menu, Basic Screen Effects, etc., are greyed out in my drop-down menu. So… can I just edit this one line by changing the rule in this particular game’s source code?
does the player mean attacking the monster:
it is very likely
Someone else will have to address your second query as I’ve yet to be able to change default responses in the new build of inform.
I only just figured out how for my most recent game. It’s in the documentation that came with the latest build under chapter 14 - Adaptive Text and Responses. You’ll have to type RESPONSES in a test game to get it to print out all of the default responses. I copied it to a txt file and saved it to my computer to make it easier to reference.
You want a “Does the player mean…” rule.
And which version of I7 are you using? In 6L02 onward the “library messages” system has been placed by “responses”, so the procedure for changing the message will be different.
“Does the player mean” worked perfectly! These things seem more intuitive in retrospect, but I feel like I never would’ve figured it out on my own. I was going in the totally wrong direction. Thank you!
My “About Inform” window says that my version is Inform (1.52/6.33/6L38).
Oh, and I did figure out how to change this default response:
Rule for printing a parser error when the latest parser error is the can't see any such thing error (this is the don't know that word rule):
say "[if location is a dark room]It is too dark to see anything properly.[otherwise]That would not help you."
But this approach doesn’t seem to work for the Violence message. Under RESPONSES I found:
block attacking rule response (A): "Violence [aren't] the answer to this one."
I’ve tried to plug this into the code above in a few different ways and it won’t cooperate.
The way to do it would be:
The block attacking rule response (A) is "You don't think attacking [the noun] will help."
It worked! It was so simple! Thank you so much!