Noob Help

Hi there, I’ve started using Inform 7 for about 3 days now, and I’ve had a few problems along the way but I have been able to solve them with the help of my friends. However I have now encountered an ‘otherwise:’ issue which doesn’t make sense to me. The code is quite simple. I want to make it so that when the enemy is dead, the player can go north, but if the enemy is alive, the player cannot move elsewhere and is stuck until they beat the enemy. Here is my code.

The Luxuria Castle is a room. The Luxuria Castle is northwest of the Desolate Path. "You arrive at a strange castle worshipping the Sin called Lust. [line break] A provocative voice lures you in...". The Dead Man is in the Luxuria Castle. The Dead Man is a container. The Dead Man contains the Note. The Note is a thing. The description is "BEWARE!!! TAKE THE ORB FROM THE CASTLE CHAMBERS AND GET OUT BEFORE THE S-. It appears he was killed before he could finish his note. [line break] The voice you heard earlier is getting closer and closer, until you can see the Succubus. She stands in front of you with a dagger poised in her hand, ready to strike. She smiles seductively as she licks the dagger and beckons you to come closer.". The Succubus is a person in the Luxuria Castle.

A person has a number called maximum hit points. A person has a number called current hit points.

The maximum hit points of the player is 100. The maximum hit points of the Succubus is 95.

The current hit points of the player is 100. The current hit points of the Succubus is 95. 

Instead of attacking The Succubus:
	let the damage be a random number between 20 and 40;
	say "You attack the Succubus, hitting it for [damage] damage!";
	say "Succubus health: [current hit points of Succubus]";
	decrease the current hit points of The Succubus by the damage;
	if the current hit points of The Succubus is less than 0:
		say "[line break]The Succubus has been slain, and is banished back to the Underworld!";
		now The Succubus is dead;
		stop the action;
		[break]
	let the enemy damage be a random number between 15 and 20;
	say "[line break]The Succubus attacks you, damaging you for [enemy damage] health!";
	decrease the current hit points of the player by the enemy damage;
	if the current hit points of the player is less than 0:
		say "[line break]You have been killed by The Succubus!";
		end the story.

When play begins:
	now the left hand status line is "Health: [current hit points of player]";

The Lust Chamber is a room. The Lust Chamber is north of Luxuria Castle. The Lux Pedestal is in the Lust Chamber. The Lux Pedestal is a container. The Lux Pedestal contains the Orb of Lust. The Orb of Lust is a thing. The description is "Upon examining the orb, you can hear spirits whispering desires through it, and screams of pain as the spirits are those which were slain by the Succubus.". The Lux Pedestal is fixed in place.
Check going north in the Luxuria Castle:
	if The Succubus is dead:
		say, "Now that the Succubus has been slain, you can now proceed through north of the Luxuria Castle.".
	otherwise:
		say, "The Succubus blocks your path, you must fight it".

For some reason, the problem tells me it lies in the otherwise^.
If you can help, thank you very much!

I posted a response in your other post but it’s just the period in the if part is ending the phrase before the otherwise. Just change it to a semicolon.

Check going north in the Luxuria Castle: if The Succubus is dead: say, "Now that the Succubus has been slain, you can now proceed through north of the Luxuria Castle."; otherwise: say, "The Succubus blocks your path, you must fight it".

Also, it doesn’t look like the player is actually blocked from going north when the succubus is alive as you’ve written it, they just get the message that it’s alive instead of the one that it’s dead. You need to add “instead” to the end of the last say to actually block going north.

Thank you all for helping me ( I really appreciate it!) but now it isn’t so much of a problem, but more like how to make it more efficient. I want to make it so that when the player takes one item from a container of 5 items they cannot take another one. So far I don’t know how to program as such but here is the code:

The War Chest is in the Ira Castle. The War Chest is a container. The War Chest contains The Mace, The Dagger, The Staff, The Trident and The Heavy Sword.

Instead of taking The Mace when The Dagger is in the inventory:
say “You can only take one weapon with you.”.

Instead of taking The Mace when The Heavy Sword is in the inventory:
say “You can only take one weapon with you.”.

Instead of taking The Mace when The Trident is in the inventory:
say “You can only take one weapon with you.”.

Instead of taking The Mace when The Staff is in the inventory:
say “You can only take one weapon with you.”.

Instead of taking The Mace when The Dagger is in the inventory:
say “You can only take one weapon with you.”.

Do I need to write it like this for every single variation? Or is there a more efficient way to do it? Thanks :smiley:

A weapon is a kind of thing. Instead of taking a weapon when the player encloses a weapon: say "You can only carry one weapon at a time."

Cellar 1 is a room. Cellar 1 is north of the Colosseum. “Upon entering the cellar, you can smell freedom behind the door.”. Freedom is north of Cellar 1. The Chains is scenery in Cellar 1. “The Chains block you from exiting.”.
Check going north in Cellar 1:
if the player holds The Thresh Key:
say “The key fits into the lock and the chains fall from the door.”;
end the story.
otherwise:
say “You need a key to unlock the chains, perhaps it is somewhere else in the castle” instead.

This is quite strange but the otherwise is wrong

Cellar 1 is a room. Cellar 1 is north of the Colosseum. "Upon entering the cellar, you can smell freedom behind the door.". Freedom is north of Cellar 1. The Chains is scenery in Cellar 1. "The Chains block you from exiting.".
Check going north in Cellar 1:
if the player holds The Thresh Key:
    say "The key fits into the lock and the chains fall from the door.";
    end the story. [ should be a ; ]
otherwise:
    say "You need a key to unlock the chains, perhaps it is somewhere else in the castle" instead.

The period strikes again.

I’m really sorry but once again, I have another problem :stuck_out_tongue:. I want the player to be able to go north when they have collected all 3 orbs, but I don’t know how to code that as something like: If the player has (all three orbs) then do this etc.

Here’s the code:

The Door of Death is a lighted room. The Door of Death is west of the Desolate Path. "You find yourself at the entrance of a large basalt door. Skull motifs decorate the framework of the door and a grim aura fills your heart with despair. Where the keyhole should be is instead 3 circular holders, possibly to hold 3 orbs of some sort. On each holder, there are latin words engraved at the bottom:

Orb of Luxuria

Orb of Invidia

Orb of Ira

It seems you have to collect these orbs to unlock the door.".

Check going north in The Door of Death:
if the player holds The Orb of Envy and The Orb of Lust and The Orb of Wrath:
say “You have finally escaped Sheol and are now safe in Heaven.”;
end the story;
otherwise:
say “You do not have all the orbs yet, come back and when you have them.” instead.

Soul Rest is north of The Door of Death. Soul Rest is a lighted room

Thank you very much for helping!!!

Simplest fix:

	if the player holds The Orb of Envy and the player holds The Orb of Lust and the player holds The Orb of Wrath:
		say "You have finally escaped Sheol and are now safe in Heaven."; 
		end the story;
	otherwise:
		say "You do not have all the orbs yet, come back and when you have them." instead.

I put this code into Inform7, but I still got the same problem. The program says:

Problem. The phrase or rule definition ‘if the player holds The Orb of Envy and the player holds The Orb of Lust and the player holds The Orb of Wrath’ is written using the ‘colon and indentation’ syntax for its 'if’s, 'repeat’s and 'while’s, where blocks of phrases grouped together are indented one tab step inward from the ‘if …:’ or similar phrase to which they belong. But the tabs here seem to be misaligned, and I can’t determine the structure. The first phrase going awry in the definition seems to be ‘say “You have finally escaped Sheol and are now safe in Heaven.”’ , in case that helps.

This sometimes happens even when the code looks about right, to the eye, if rows of spaces have been used to indent phrases instead of tabs.

(The way this sentence starts makes me think it might have been intended as part of a rule rather than being a statement about the the way things are at the beginning of play. For example, 'If the player is in the Penalty Zone, say “An alarm sounds.” is not allowed: it has to be put in the form of a rule showing Inform what circumstances apply - for example 'Every turn: if the player is in the Penalty Zone, say “An alarm sounds.”)

Because of this problem, the source could not be translated into a working game. (Correct the source text to remove the difficulty and click on Go once again.)

Your tabs must not line up properly. Check each line for the proper amount of tap character, no extra spaces, no blank lines, colons and semicolons where needed.

Inform is a computer programming language. Like other programming languages, it is fussy about syntax and formatting. Correct indentation and the use of semicolons are the basic building blocks of good Informese, but there are other areas as well that are potential trouble spots for the newcomer.

When copying your code into this forum, it will help if you select the text of the code after pasting it and use the Code button at the top of the forum’s input window. If you don’t do this, we can’t tell what indentation you used.

You still need the check going… line of what you initially wrote:

Check going north in The Door of Death:
	if the player holds The Orb of Envy and the player holds The Orb of Lust and the player holds The Orb of Wrath:
		say "You have finally escaped Sheol and are now safe in Heaven."; 
		end the story;
	otherwise:
		say "You do not have all the orbs yet, come back and when you have them." instead.

PS: You will probably find doing it this way gets excessive on the typing and line size. A pattern like this may eliminate some of the clutter:

sheol-key-item is a kind of thing.
The Orb of Wrath is a sheol-keyitem.
The Orb of Envy is a sheol-keyitem.
The Orb of Lust is a sheol-keyitem.
Definition: the player is possessing-all-sheol-keys if the number of sheol-keyitems held by the player is 3.

Then you would rewrite that rule to be simply:

Check going north in The Door of Death:
	if the player is possessing-all-sheol-keys:
		say "You have finally escaped Sheol and are now safe in Heaven."; 
		end the story;
	otherwise:
		say "You do not have all the orbs yet, come back and when you have them." instead.

The above code puts the orbs and an adjective definition in a neat package so you could easily modify it later if you change the story and add more required orbs (maybe you later decide you want the player to find all seven deadly sin orbs then you’d just add the four missing sin orbs in the same pattern as the other three then change that 3 at the end to a 7). The Check going … rule will not need any changes. So if you had several rules checking if the player is possessing-all-sheol-keys they would not need any additional adjustment once the first section was changed to have seven deadly sin orbs.

You can duplicate the pattern to make new groups of key items for other parts of your game but you have to have replace sheol-keyitem and possesses-all-sheol-keys with appropriate new names for the new group (and different names for the items themselves).

If you create the orbs as their own kind (named, say, Sheol key), Inform lets you check containment directly:

Check going north in The Door of Death: if the player holds all Sheol keys: say "You have finally escaped Sheol and are now safe in Heaven."; end the story; otherwise: say "You do not have all the orbs yet, come back and when you have them." instead.

I can see how this would work, but frustratingly after following your code it still says there are problems:

Code:

Soul Rest is north of The Door of Death. Soul Rest is a lighted room.
Sheol Key is a kind of thing.
The Orb of Wrath is a Sheol Key.
The Orb of Envy is a Sheol Key.
The Orb of Lust is a Sheol Key.

Definition: The player is possessing-all-sheol-keys if the number of Sheol Key held by the player is 3.

Check going north in The Door of Death:
if the player is possessing-all-sheol-keys:
say “You have finally escaped Sheol and are now safe in Heaven.”;
end the story;
otherwise:
say “You do not have all the orbs yet, come back when you have them.” instead.

Try using “to decide on” instead of a definition like that. Try this:

To decide on whether the player is possessing-all-sheol-keys:
  decide on whether or not the number of Sheol Key held by the player is 3.

I think checking if “something is (adjective)” is not a valid condition, you can only use them to restrict the set of things a token matches (e.g. Before examining a possessing-all-sheol-keys actor…).

PS: This example uses “holds all” as suggested above. There is no longer any magic number to change. Scatter FooKeyItems in room definitions to your heart’s content. :wink:

I got the syntax slightly off with the definition (must be a kind rather than a specific instance) but otherwise it works just fine:

"test" by Brian Jack

FooKeyItem is a kind of thing.
Foo1 is a FooKeyItem.
Foo2 is a FooKeyItem.
Foo3 is a FooKeyItem.
definition: a person is FooKeyed if he holds all FooKeyItems. [I messed the syntax initially but this does indeed work]
Obligatory Test Room is a room.

OtherRoom is north of Obligatory Test Room.

Check going north from Obligatory Test Room:
	if player is FooKeyed: [<-- "something is <adjective>" is a perfectly fine condition I use it all the time]
		say "The way magically lets you pass.";
	otherwise:
		say "The way is magically blocked.";
		stop the action.

test me with "n / purloin Foo1 / purloin Foo2 / purloin Foo3 / n".

test
An Interactive Fiction by Brian Jack
Release 1 / Serial number 151113 / Inform 7 build 6L38 (I6/v6.33 lib 6/12N) SD

Obligatory Test Room

test me
(Testing.)

[1] n
The way is magically blocked.

[2] purloin foo1
[Purloined.]

[3] purloin foo2
[Purloined.]

[4] purloin foo3
[Purloined.]

[5] n
The way magically lets you pass.

OtherRoom

Ah, I see, the issue is not the condition but that “the player” was used instead of “a person” in the definition. So adjectives have to modify whole kinds, and “to decide on” is for specific conditions. Good to know!

In general definitions work good for these kinds of one-liner type expressions that can be expressed as adjectives. More complicated evaluations needing loops or nested if/otherwise would be better as deciders. Though a decider in this case would also work (and allow specifically testing for only the player’s possession of key items) being that specific will actually cause more work down the line if you ever want to use actors in your game then you wind up having to modify all the cases where you tested things on the player specifically, changing them all to test on people (or actors as appropriate) instead.

The FooKeyed adjective will work even if it is an actor going north (“bob, go north”) though you’d have to change the check rule to handle actors:

check an actor going north from Obligatory Test Room:
  if the actor is FooKeyed:
    say "[if the actor is the player]you[otherwise][the actor][end if] are magically teleported beyond.";
  otherwise:
    say "The way is magically blocked and [if the actor is the player]you[otherwise][the actor][end if] cannot pass.";
    stop the action.

With a Bob person in the room holding the keys he would be able to go north (assuming appropriate persuasion rules and a way for him to get the keys).

The adjective form also allows use of an instead rule with something like: ‘instead of a FooKeyed actor going north from Obligatory Test Room:’. Using instead like this uses the method of having the action normally fail in all cases except for any instead rule that provides an exception where it may succeed. Indeed, several actions that are normally blocked by the standard rules (such as attacking) can be made to work with precisely this pattern. For instance this pseudocode:

Bullseye is a thing in Obligatory Test Room.
definition: a person is fightable if he carriers the bullseye.

instead of an actor attacking a fightable person:
  say "[if the actor is the player]you[otherwise][the actor][end if] tackle [the noun] and take their bullseye.";
  now the actor carries the bullseye.
  rule succeeds.

Will allow attacking in this exceptional case and all others get the normal blocking (“Violence is not the answer here.”). Yielding a sort of mini capture-the-flag scenario.

Adjectives can modify either kinds or specific objects. However, “the player” is not a specific object. It’s a global variable.