beginner questions/programming

Copy and past doesn’t translate well into inform because it replaces tabs with spaces. Sorry.

No need for an apology; you’ve both been of imeasurable help to me and it’s very much appreciated. :slight_smile:

I’ve edited my post because I’ve slightly improved the code since before. It now reads thus:

After printing the name of the brown cotton coat while taking inventory: If the number of things in the deep pocket > 0: Say "[line break] the brown cotton coat's deep pocket contains:"; Let L be the list of things inside the deep pocket; Repeat with n running through L: Say "[line break] [a n]".

Which produces this result:

i
You are carrying:
a brown cotton coat
the brown cotton coat’s deep pocket contains:
a compass
a frost projector (being worn)
a handkerchief

(Somehow changing the last little bit [A n] to [a n] corrected the problem of the coat being described as “An brown cotton coat”)

Still no idea on how to shift “(being worn)” to the end of the coat’s description where it belongs. I’ve also tried using “Instead of printing the name of the brown cotton coat …” but Inform 7 didn’t like that. :frowning: Is there a way to re-word the rule so that it takes effect after the words “(being worn)” are printed for the coat?

Another approach would be to implement the coat itself as a container. The drawback is that your player can’t open the coat and the pockets separately, but unless you need this capability, you are better off faking the existence of the pocket. That way you don’t have to write so much code just to get back to the standard behavior.

A coat is a kind of container. A coat is wearable. A coat is usually openable and closed.

The player is wearing a brown cotton coat. The brown cotton coat is a coat. The brown cotton coat contains a compass and a frost projector.

Understand "pocket/pockets" as the brown cotton coat.

Instead of searching the closed brown cotton coat:
        try opening the noun.
	
Instead of examining the brown cotton coat:
        say "Lightweight and mud-colored, the coat has several deep pockets[if the noun is open], in which [is-are a list of things inside the noun][end if]."
	
After printing the name of a closed coat:
        omit contents in listing.

After opening the brown cotton coat:
        say "You search through the coat pockets, turning up [a list of things inside the noun]."

After closing the brown cotton coat:
        say "You close the pocket flaps."

Rule for printing the name of the brown cotton coat while taking inventory:
if yourself is wearing the brown cotton coat, say “(being worn)[line break]”;
if the number of things in the deep pocket > 0:
let L be the list of things inside the deep pocket;
repeat with n running through L:
say " [n][line break]" instead.

Putting the instead will stop it from printing again at the end.

It was interesting seeing that; I didn’t know that the “instead” command could be put at the end of a sentence (I have a lot to learn about the syntax of Inform 7).

However it didn’t work, this was the result:

You are carrying:
a (being worn)
compass
(being worn)
a handkerchief

The coat’s name is missing, along with the frost projector’s name and the “(being worn)” generated by Inform 7 is still there regardless.

I replaced “rule for” with “After” to bring the coat’s name in, but that “(being worn)” is still confounding me. :frowning:

Yes that approach occured to me early on as well. Strictly speaking I guess it’s not necessary to have the open/close feature, except that the player here will be gathering a lot of objects and it would have been convenient to shorten the inventory listing by closing the pocket. It’s dissapointing that such a limitation exists when you’d think that clothing with pockets would be a very common feature in interactive fiction. :frowning:

Thanks guys. :slight_smile:

Clothing is fairly common; this specific inventory format is not something I’ve seen asked for much, though.

Using the “rule for printing the name” hook works in many respects, but it has a few problems. The “(being worn)” tag shows up where it does because, from Inform’s point of view, all that other stuff you’ve printed about the coat is still part of the coat’s name. You can suppress it by hand using “omit contents in listing”, like this:

After printing the name of the brown cotton coat while taking inventory: if the brown cotton coat's pocket is open and the brown cotton coat's pocket contains something: say ", [if the brown cotton coat is worn]worn and [end if]containing in the pocket: "; repeat with item running through things in the brown cotton coat's pocket: say "[line break] [a item]"; omit contents in listing.

I should add, though, that the things that are in the pocket will be listed differently than the things out of the pocket, because our “[a item]”-style list doesn’t include inventory information such as “(providing light)” or “(closed)”. We could get around that by writing

After printing the name of the brown cotton coat while taking inventory: if the brown cotton coat's pocket is open and the brown cotton coat's pocket contains something: say ", [if the brown cotton coat is worn]worn and [end if]containing in the pocket: [line break]"; list the contents of the brown cotton coat's pocket, with newlines, indented, giving inventory information, including contents, with extra indentation; omit contents in listing.

But the problem here is that the formatting doesn’t work right because we’ve called the listmaker while we were already in the middle of an existing list, so it loses track of how much it needs to indent. It’s possible to fix that too, but it would require considerably more fiddly hackery.

Here are some other suggestions, from easiest to trickiest:

  1. put the pocket contents all in-line:

After printing the name of the brown cotton coat while taking inventory: if the brown cotton coat's pocket is open and the brown cotton coat's pocket contains something: say ", [if the brown cotton coat is worn]worn, [end if]with [a list of things in the brown cotton coat's pocket] in the pocket"; omit contents in listing.

  1. generate a second segment to the inventory list, like this:

After taking inventory: if the player encloses the brown cotton coat and the brown cotton coat's pocket contains something and the brown cotton coat's pocket is open: say "In the pocket of the brown cotton coat: [line break]"; list the contents of the brown cotton coat's pocket, with newlines, indented, giving inventory information, including contents, with extra indentation.

which would produce output like

with the whole pocket segment vanishing if the pocket is closed.

  1. Use the hack of making the coat itself “openable” and then disguising the fact, as suggested up-thread.

  2. Go to a more natural-English inventory listing, and use Jon Ingold’s Written Inventory extension to customize your inventory output just about however you like.

  3. Write your own custom inventory output code.

If you end up wanting your own inventory-fiddling code, Emily’s recommendation of Jon Ingold’s Written Inventory extension is a good one. If you need further hacking (as I did), you might find my Fragile Shells source (ifarchive.org/if-archive/games/s … Shells.txt) helpful. Look for “Chapter 4 - Updated Inventory”.

Thanks everyone, particlarly Emily for such a detailed explanation. Much appreciated and sorry it’s taken so long for me to get back to you:

  1. I began working on the suggestions and lost track of time,
  2. It took me a while to locate this thread again

My first project is taking shape, slowly but surely, and as intended I’m learning things along the way.

Still running over some bumps with the syntax and vocabulary however. I have one particular rule that I need to create, and it has baffled me for months even though it ought to be very simple. I’ve put it aside and worked on other things (making considerable progress), then come back to it and tried again, re-visited Inform7’s inbuilt documentation, and tried every variation that I can think of.

I know I’m going to feel like an idiot when I see the answer, but how do I achieve this?

I have a fire extinguisher case with a glass front. Player has to find an object suitable to break or cut the glass case to reach the extinguisher. Obviously I don’t want the player taking anything in or out of the case while the glass is in the way.

The code I’ve tried
First part works fine:

[code]Glass is a kind of thing. Glass can be intact, shattered or cut.

A small metal case is in the Kitchen. The small metal case is fixed in place. The case glass is part of the small metal case. The case glass is glass and intact.

A fire extinguisher is inside the small metal case.[/code]
Below is the code that I’ve been unable to get to work:

Instead of taking a thing out of the small metal case when the case glass is intact: say "The glass front of the case prevents you reaching inside." Instead of putting a thing inside the small metal case when the case glass is intact: say "The glass front of the case prevents you reaching inside."

This is the error, every single time:
You wrote ‘Instead of taking a thing out of the small metal case when the case glass is intact’ , which seems to introduce a rule taking effect only if the action is ‘taking a thing out of the small metal case when the case glass is intact’. The part after ‘when’ (or ‘while’) was fine, but the earlier words did not make sense as a description of an action. I am unable to place this rule into any rulebook.

In place of “a thing” I’ve tried “anything”, “any object”, “(whatever - a thing)” and some others I’ve forgotten now.

In place of “out of the small metal case” I’ve tried “from the small metal case” and “from out of the small metal case” and “remove a thing from the small metal case.”

I know this is going to turn out to be something embarrasingly simple. :unamused:

This looks a lot less embarrassingly simple than you think. The action you want for “taking it out of” is “removing it from,” I think, but if you look up “removing it from” in the index (under the Actions tab) it warns you not to write rules about it – you can only remove things from things by TAKING them, and the removing action is used to provide error messages. So for the first rule, what you want I think is something like:

nstead of taking a thing when the small metal case encloses the noun and the case glass is intact: say "The glass front of the case prevents you reaching inside."

(I originally had “when the noun is in the small metal case” but I wanted to catch cases where you had something that was in a container that in turn is in the case, or something like that. Haven’t tested those cases.)

For the other rule, the name of that action is “inserting it into” – this is one that trips me up a lot – so you can write

Instead of inserting a thing into the small metal case when the case glass is intact: say "The glass front of the case prevents you reaching inside."

Haven’t tested these too much but at least they work in the basic cases!

Thank you Matt w, most appreciated and yes you’re right; I don’t feel foolish at all after seeing that. I haven’t yet encountered the phrase “encloses the noun” in the instructional documentation and I wouldn’t have figured that out on my own any time soon. Cheers! :slight_smile:

I’ve tested both the taking and the inserting, and each one works!

Merry Christmass everyone - have you noticed that today, the 25th Dec when Inform7 reports an error it displays a broken christmas decoration? :open_mouth:

Well, the “encloses” part isn’t really necessary – you could write “Instead of taking a thing when the noun is in the small metal case and the case glass is intact:” and it would probably work for your case. “Encloses” just takes care of things that are parts of things in the case, or in things that are in turn in the case, if you want to implement them. “Encloses” is discussed in section 3.25 of the Inform docs.

Merry Christmas to you too! It’s not December 25th in the States yet, but I’ll be sure to give myself a compiler error tomorrow.

I’ve been coding tonight (Dec 25th) as well… and Inform 7 rewards you with a giant, shiny red bauble (unbroken) if your code compiles correctly! :smiley:

Hurrah for the Christmas I7 elves!

FWIW the glass case is a textbook example of a situation where you could use the built-in transparent property. If you make the container closed and transparent, the player can automatically see what’s inside but can’t do anything to them that would require touching them. This has the added bonus of taking care of any other commands you might want to limit (touching, pushing etc). When the glass is broken make the container open and the player can interact with the things inside.

Ah, I had thought of that but decided it might be duplication of effort, since you probably want to write special rules (or parser error messages?) for reaching inside the case anyway. But preventing pushing and touching is a good idea anyway.

(What I mean is, if I comment out my instead rules and add this code:

[code]The small metal case is transparent and closed.

Instead of attacking the case glass:
say “Crash!”;
now the case glass is shattered;
now the small metal case is open.
[/code]

then I get this response:

where the first two responses are annoying. In fact, even if we add the “Instead” clauses back in we get this, because taking the extinguisher fails the basic accessibility rule before the “Instead” rule fires, so getting a nice message back in this case is going to require something more.

BTW, some unrelated user-friendly things – it’d probably be a good idea to understand “front” as the case glass and to redirect attacking the small metal case to attacking the case glass.

[Awesomeness: When testing this I got the following parser error:

with the special Dec. 25 broken ornament over it! Cool.]

Fair point. Fortunately “something more” in this case is just using a before rule, which fires before the basic accessibility rule. Or if you want to use accessibility rules (this might actually be the cleanest solution):

[code]A reaching inside rule for the metal case:
say “The glass front of the case prevents you reaching inside.”;
rule fails.

A reaching inside rule for the metal case when the case glass is shattered:
rule succeeds.[/code]

Oh, duh, thanks.

Looks neat – I’d forgotten about the reaching inside rules. The original author probably wants to code the first rule as “when the case glass is intact” and the second as the general rule, since I suspect you can reach inside the case when the glass is cut. In this case I guess we can write “allow access/deny access” instead of “rule succeeds/rule fails”?

Thanks Guys and Gals.

Is there a way to substitute “break” / “breaking” instead of “attack” / “attacking” the case glass?

It would be the more obvious verb for the player to figure out, but it seems that breaking is a word already in Inform7’s vocabulary, and it seems reluctant to alow a rule to override it. “Attacking” works just fine, but “breaking” produces the error:

You wrote 'Instead of breaking the case glass'  , which seems to introduce a rule taking effect only if the action is 'breaking the case glass'. But that did not make sense as a description of an action. I am unable to place this rule into any rulebook.

BTW I’ll be travelling from the 8th Feb to the 16th March and probably out of touch during that time. When I return I’ll commence a thread specifically for the project that I’ve been working on all this time - it’s taking me too long to suss out Inform7’s little quirks on my own. I’ve appreciated the friendly and generous assitance you people have given me, and hopefully it will be fun to involve you in the project more directly. (Albeit with the consequence of the end result not being the surprise that I’d planned, but what the hey. :slight_smile: )

Actually it’s the opposite: breaking is a word that Inform doesn’t know and therefore doesn’t know what to do with it.

If you want only the command BREAK GLASS to work you have to make your own breaking action, but I wouldn’t do that: the attacking action already includes BREAK as a synonym, along with many others, so the BREAK GLASS command already works. If you make a new breaking action and the player types HIT GLASS or SMASH GLASS or something else they get the rather misleading “Violence is not the answer” response.

To elaborate a little, and hopefully accurately, there are two kinds of vocabulary here: The words that show up in your source code and the words that the player types. (The TL;DR is that “break glass” should work already; let us know if it doesn’t.)

In the source code, you have (for instance) names of actions, like “attacking.” If you wanted to use “breaking” in the source code you’d have to define a new action by saying something like “Breaking is an action applying to one thing” and then defining rules for it. But you don’t need to, because…

It doesn’t matter to the player whether your source code calls the action “attacking” or “breaking.” The player never has to directly deal with the words that appear in your source code, or the names of your actions. The words that the player types get translated into actions by the parser. Understand statements tell the parser how to do this translation. That’s why you often see code like this:

Twirling is an action applying to one thing. Understand "twirl [something]" as twirling.

If not for the “understand” statement, the parser wouldn’t know that the command “TWIRL MUSTACHE” was meant to be translated into the action of twirling the mustache, and twirling would never happen.

In this case, as Juhana points out, “BREAK [something]” is already built in as a synonym for “ATTACK [something].” So your game will automatically understand “BREAK GLASS” as attacking the glass, unless you tell it not to. So you’re set.

(Specifically, this is the relevant part of the standard rules:

Understand "attack [something]" as attacking. Understand the commands "break", "smash", "hit", "fight", "torture", "wreck", "crack", "destroy", "murder", "kill", "punch" and "thump" as "attack".

The “Understand the commands…” part means that those words get mapped onto “attack” with all the attendant syntax. I suppose Graham could’ve put in

Understand "break [something] as attacking. Understand "smash [something] as attacking. [etc.]

but it would obviously have been more tedious, and maybe there’s a difference I’m not picking up.)

Well said!

The difference is that “Understand the command…” makes the words themselves synonymous, regardless of the action. So if you created your own “attacking it with” action you could just define one grammar line, “Understand “attack [something] with [something]” as attacking it with”, and all the other verbs would automatically work with this new action as well.