A few beginner's questions

Hi,

I come from a gamedev and coding background and have been wanting to get into Inform 7 for a long time, but I’m having problems getting into Natural Inform. I’ve tried to go through documentations and code examples, but I just can’t seem to discern a basic logic behind the syntax - especially when it comes to defining new actions and responses - beyond creating rooms and items.

I think it’d make things easier if I could get some help with code for my most immediate needs, so I was hoping that someone here could maybe help with that.

These are the things I’m trying to accomplish in order of significance:

  • Give all living creatures - including the character - a health status in the range of dead, weak, alive, strong and invincible. If a character is dead then interacting with it won’t produce responses indicating that it’s alive, such as “I don’t think X would like that” in response to trying to pick the person up.
  • Allow the player to change characters from dead to any other status using certain items.
  • Allow the player to bury and dig up dead characters if they have a shovel.
  • Allow the player to bury and dig up any item if they have a shovel.
  • Classify certain items as weapons, and give those weapons a power status in the range of none, weak, normal, strong and max.
  • Allow the player to attempt to kill any living creature using any weapon, where the weapon’s power status is matched against the character’s health status, and the player’s weapon needs to be one level higher than the creature’s health in order to be effective.
  • Give all living creatures a defense status in the range of none and max, where if a character is attacked by the player, it will kill the player in return if its defense status is set to max rather than none.

I don’t know if I’m asking too much, but anything on this list that I could get help with would be greatly appreciated.

Thanks for reading!

These one is straightforward:

A person can be dead, weak, alive, strong, or invincible (this is its health status property). A person is usually alive.

See §4.10 of Writing with Inform.

Some of the other things depend on existing rules and actions. For instance, if you’ve defined an action for pointing a thing at something, you can write:

Carry out pointing the wand of resurrection at a dead person: now the second noun is weak.

The second noun being the second noun involved in the action, that is, the dead person. You’d also need another rule to print a message about this, and rules to take care of other cases (if the person isn’t dead, if you’re pointing something that’s not the wand, etc.)

Similarly, you can special-case a lot of the rules and/or messages for other actions to check whether the person you’re dealing with is dead.

I guess you specifically asked about creating actions, so the part where I said “Just create this action” was probably not that helpful. Here’s an example of how you could create the action you need, and write rules for the various cases. When you see “instead” in a Check rule (or most other rules), it tells Inform to just stop processing the action right there without proceeding through Carry Out and Report stages.

[code]A person can be dead, weak, alive, strong, or invincible (this is its health status property). A person is usually alive.

Pointing it at is an action applying to one carried thing and one thing. Understand “point [something] at [something]” as pointing it at.

Check pointing something at something when the noun is not the wand of resurrection: say “Not much point in pointing that at anything.” instead.

Check pointing the wand of resurrection at something when the second noun is not a person: say “You cannot resurrect what was never alive.” instead.

Check pointing the wand of resurrection at a person when the second noun is not dead: say “[The second noun] says ‘I aten’t dead.’” instead.

Carry out pointing the wand of resurrection at a dead person: now the second noun is weak.

Report pointing the wand of resurrection at a person: say “[The second noun] groans and stirs to life, literally.” [we don’t want to say “at a dead person” because the second noun isn’t dead anymore!]

Morgue is a room.

The player carries a wand of resurrection. The description of the wand of resurrection is “This wand, carved with arcane symbols, resurrects dead people. (The arcane symbols spell out ‘Does exactly what it says on the tin.’)”

Linda is an alive woman in the morgue. Inky, Blinky, Pinky, and Clyde are dead men in the morgue.

The player carries a pointless sphere. The description of the pointless sphere is “Because it is round, it has no point.”[/code]

Thanks, I really appeciate the help. That got me a long way, and helped clarify a lot of questions that I’ve been having.

I’ve come across somewhat of a problem though. I have a dead character who is stuck in a downed space ship. I’m trying to allow the player to pull him out, but this is the result:

Crash Site 
The crash has churned up the stone-desert ground and glass and debris is strewn all over. 

The mangled wreckage of your ship looms over you. 

>look at ship 
The ship is wrecked, but it looks like most of the damage is non-critical. 

In the ship is Malone. 

>take malone 
You pull Malone out. 

>look 
Crash Site 
The crash has churned up the stone-desert ground and glass and debris is strewn all over. 

Malone is on the ground. 

The mangled wreckage of your ship looms over you. 

>take malone 
You pull Malone out. 

This is the code:

A person can be dead, weak, alive, strong or invincible. A person is usually alive. 
A person can be lightweight, mediumweight or heavyweight. A person is usually mediumweight. 

Instead of taking a dead person: 
	If dead person is inside an object: 
		If a dead person is mediumweight: 
			say "You pull [noun] out."; 
			move noun to crash site; 
		otherwise: 
			say "[noun] is too heavy."; 
	otherwise: 
		say "No."; 

Instead of attacking a dead person: 
	say "You can't kill that which is already dead."; 

Crash Site is a room. "The crash has churned up the stone-desert ground and glass and debris is strewn all over." 

A ship is here. It is fixed in place. "The mangled wreckage of your ship looms over you." The description is "The ship is wrecked, but it looks like most of the damage is non-critical." 

Malone is a man in the ship. He is dead. He is fixed in place. "[if malone is in ship]Malone’s body is still in the co-pilot seat[otherwise]Malone is on the ground." The description is "You think about burying him, but you don’t have a shovel, or anything to dig with." 

My questions are:

  • Why is it that I can pull Malone out multiple times, even though he’s not in the ship anymore?
  • Why can’t I write “If a dead person is mediumweight or lightweight:”?
  • Why can’t I write “move noun to current room” instead of “move noun to crash site”?

Thanks in advance.

“Object” is at the top of Inform’s kind hierarchy. Everything is an object; in particular, rooms are objects, and that’s what’s going wrong with your code. If you change the condition to

       If dead person is inside a container:

then it will work. (Objects are divided into the kinds “thing”, “room”, “direction” and “region”. “Container” is a subkind of “thing”.)

(You haven’t explicitly declared Ship to be a container, but Inform deduces that it is one when you declare Malone to be in it.)

To your second question: Inform just doesn’t understand that use of “or”. It expects “or” to separate two separate conditions, not two adjectives within one condition. So you need to spell it out as

		If dead person is mediumweight or dead person is lightweight: 

Third question: You just want “the location” rather than “the current room”.

Here is one way to write the rule in your example:

Instead of taking a dead person (called the corpse): if the corpse is inside a container: if the corpse is mediumweight or the corpse is lightweight: say "You pull [the corpse] out."; move the corpse to location; otherwise: say "[The corpse] is too heavy."; otherwise: say "No."

“The corpse” here is a variable, and writing it like this makes sure that we are always referring to the exact same thing, and also relieves the game from having to repeatedly search for a present dead person every time one is mentioned.

Another thing to consider is that it usually better to have several more specific rules, which in this case would mean changing the rule to “Instead of taking a dead person (called the corpse) which is inside a container,” and then writing another one, “Instead of taking a dead person,” which applies when trying to pick up dead people from the ground.

EDIT: Sorry for missing jrb’s reply above.

Actually I think the later bits appeared after you’d posted. I have a bad habit of retro-editing my posts.

Something that maybe hasn’t explicitly been said above, but you need to watch out for things like “if dead person is in a container.” Inform will interpret this as “if a dead person is in a container,” that is, if any dead person is in a container. Ditto for “if the dead person is in a container.”

This leads to a lot of traps because in English it’s natural to say “Instead of taking a dead person: if the dead person is in a container” etc. etc. and understand that when we say “the dead person” we mean the dead person we were just talking about, anaphorically. But the Inform compiler can’t make that connection!

“Called” parentheticals like Angstsmurf’s “Instead of taking a dead person (called the corpse):” create a temporary variable and set it to the particular dead person in question. Also, if you want to refer to the first object of the action without giving it a name, you can use “the noun” (as in some of the rules I had above–and as you already had in your rule).

Just make sure you specify the object the player is handling, instead of “any dead body” in the game.

[code]
The can’t take other people rule does nothing when the item described is dead.

Check taking a dead person (called corpse) (this is the pull bodies from wreckage rule):
If corpse is inside an object:
If corpse is mediumweight:
say “You pull [Corpse] out.”;
move corpse to the location;
stop the action; [you don’t want the rule to continue to the “carry out taking” phase]
otherwise:
say “[Corpse] is too heavy.” instead;
otherwise:
say “No. You have no reason to move casualties very far from where they landed because you’d be tampering with crash site evidence.” instead; [/code]
Note I changed this to a check rule, bailing out with “instead” at the end of lines that fail the check. I also named this rule so you could refer to it as I did the “can’t take other people” rule.

The reason for this is when you use INSTEAD the parser goes hands off and doesn’t run any other rules - for example, suppose there is a heavy ladder in the game which you’ve written rules to disallow the player from manipulating other items while they are holding it, or if the room is too dark to see … An INSTEAD rule will skip all the other intervening check rules and you might wind up in a situation where the player seemingly grew temporary extra hands because the parser wasn’t able to interrupt with the ladder-check rules. Or if you don’t want them to see the body until the lights are on, the Instead rule would let them do the body pick-up and drop without even being able to see it, ruining a reveal.

This may not apply in this specific situation, but it’s a good idea to understand that INSTEAD rules are primarily for situations you want to completely disallow without the parser bothering to check anything else, and in most cases shouldn’t include world-manipulation that the parser would normally handle.

Instead of eating something: say "But you have no mouth. You aren't able to scream, either."