The Foxaroo tinkering around with Inform7

It is with great sadness that I type what will probably be my last post on this forum.

On the previous page of this thread you’ll note in my post in June of last year that I had lost my job. It took me 6 months to find a new one, and what I’m in now is an even more demanding role than before.

Realistically I’m just not going to have time to progress with my interest in Interactive Fiction. Being a very slow-learning dyslexic individual I need a lot of time to skill up.

It’s taken me a while to accept this situation. I adore the versatility of Inform and would have loved to go much further with it (if only it had been around when I was in high school back in the 1980’s). Let’s home there’s still I.F. fans around when I retire.

Bye all. :slight_smile:

I expect that it’s unusual to share a piece of art on a programming forum, but I felt very defeatist with my last comment, having to abandon my keen interest in Inform7.

The below image illustrates why I could no longer keep it going, along with many of my other hobbies.

(Not my own artwork - I commissioned this)

Enough said.

Eight years it’s been since I was here.

The job that I commenced in 2014 was insane for the amount of work they expected their staff to do, and I watched a lot of other staff come & go during the seven years I was there.

Now I’ve at long last moved to a better job and am slowly taking a renewed interest in prior hobbies, including Inform.

Just recently I’ve realised that my learning difficulties (dyslexia) are only part of the problem. The documentation supplied with Inform7 is lacking in that it doesn’t provide syntax and parameter references for Inform7’s commands, which is how I’ve learned languages in the past.

Is there a supplementary guide or glossary available for Inform7?

4 Likes

The Project Index available in the IDE is as close as it gets. It’s not the sort of reference you’re talking about, but you might find Inform 7 for Programmers useful. It’s for 6G60 and there were substantial changes in the subsequent release, 6L02, so some bits are outdated.

The good news is that the forthcoming release (the compiler is already here; the IDE’s are expected soon) is open source and there’s detailed documentation about the compiler and tools. So it’s much, much more possible for a third party to write reference material on I7 finally.

Congrats on your new job, and welcome back to I7 and the forum.

4 Likes

Thanks, and thanks especially for the The Inform 7 Programmer’s Manual. That’s more helpful to me than it might have appeared. :slight_smile:

1 Like

See the I7 Documentation and Resources sticky post for some other things of potential interest, but there’s nothing better in this vein than I7 for Programmers.

3 Likes

Is the extension “Hidden Items” by Krister Fundin still available for download anywhere?

During the eight years in which I was absent I’ve moved onto a new computer and lost my extensions from the previous installation of Inform. For my current project I need to make doors appear and vanish.

It doesn’t seem to be online at the Friends of I7 Github repository.

Here’s a version I found on my hard drive:
Hidden Items.i7x (2.8 KB)

These other extensions might also cover your use case:

Disappearing Doors by Andrew Plotkin: extensions/Disappearing Doors-v1.i7x at 9b3ca7a4deb57157af4c60dc643bb954b324ca00 · i7/extensions · GitHub

Version 2 of Secret Doors by Gavin Lambert: extensions/Secret Doors-v2.i7x at 9b3ca7a4deb57157af4c60dc643bb954b324ca00 · i7/extensions · GitHub

If you’re using the 9.3 / 6M62 version of I7, you might have to get these from the corresponding branch of the repository.

3 Likes

That’s awesome! Thank you very much for providing all of this. I’m going to be studying it all over the coming weekend. :slight_smile:

1 Like

You’re not the first to have the issues with the missing Inform 7 documentation; it caused me to suspend Inform 7 work for about 4 years.

Right now, I’m mostly trying to port extensions to the newest release, and push bugfixes upstream for the newest release, but I’m one of several people who will probably try to write new reference material on I7. Zed is another.

For reference, Hidden Items.i74 is in the I7 extensions “archive” repository, which was frozen in 2014, and so mostly has stuff which broke a long time ago: GitHub - i7/archive: A mirror of the Inform 7 extensions website, but with a history of changes!

1 Like

I managed to get “Hidden Items” by Krister Fundin working after a minor change to one of the lines in the extension. Out of curiosity I tried the others but sadly none proved functional (a pity; I like to have options and alternatives).

Then, unrelated, I ran into something very odd. Not crucial to my project, but again I’m curious as to why this is happening. I wanted to test Hidden Items by making a door appear and vanish when a wand is waved, but my code only responds to the first wand created in the source.

Below is the code trimmed down to the applicable lines.

Include Hidden Items by Krister Fundin. [Required to make doors appear & vanish.]

The Construct is a room.  Office Working Area is a room.  Fantasy Testing Foyer is a room.

The Emerald Door is north of Office Working Area and south of Fantasy Testing Foyer. The Emerald Door is a closed door.

When play begins:
	now the command prompt is "Current player is [player] >";
	now the left hand status line is "Current player: [player]".
	
After reading a command: say conditional paragraph break.

Tom, Dick, Harry and Mary are people in the Office Working Area.  Tom, Dick and Harry are men.  Mary is a woman.  Player_marker is a person in The Construct.  The player is Tom.  Understand "Tom" as Tom.    Tom carries an ebony wand.  Dick carries an crystal wand.  Harry carries a marble wand.  Mary carries a sapphire wand.    [*** This is temporary for testing ***]

Rule for printing the name of Tom: say "Tom".
Rule for printing the name of Dick: say "Dick".
Rule for printing the name of Harry: say "Harry".
Rule for printing the name of Mary: say "Mary".

Every turn:
	if the player is Mary, now the player is Player_marker;
	if the player is Harry, now the player is Mary;
	if the player is Dick, now the player is Harry;
	if the player is Tom, now the player is Dick;
	if the player is Player_marker, now the player is Tom. [This is needed to avoid the game engine skipping the last player.]

Instead of waving any wand:
	if the player is in Office Working Area:
		if The Emerald Door is hidden:
			reveal The Emerald Door; [NOTE: This command requires the extension Hidden Items by Krister Fundin.]
			say "The Emerald Door becomes visible. [line break]";
			rule succeeds;
		otherwise:
			hide The Emerald Door; [NOTE: This command requires the extension Hidden Items by Krister Fundin.]
			say "The Emerald Door has vanished!";
			rule succeeds;
	otherwise:
		say "Nothing happens.";
		stop the action.

Peculiarly, the action is only triggered by the wand that is created first. In this case the ebony wand.
Alternatively, if I arrange as thus:

Dick carries an crystal wand.  Tom carries an ebony wand.  Harry carries a marble wand.  Mary carries a sapphire wand.

Then the action is only triggered by the crystal wand. Nor does it matter whom uses the wand; I’ve had the characters drop and take different wands but whomever uses the first created wand is the only one triggering the action.

Like I said; not crucial to my project, but I’m very curious as to why this would happen?

Ah, right. Just for reference and third parties reading along, the extension has this line:
change the original location of T to the holder of T;
The “change ... to” syntax was deprecated a while ago, it’s now “now ... is”:
now the original location of T is the holder of T;

Do they not work for your use case, or are you getting errors using them? I’m asking because both (“Disappearing Doors” and “Secret Doors”) are working fine on my install here (Inform 7 6M62 on Windows), using the respective examples included.

That happens because Inform doesn’t understand, from declaring “Tom carries an ebony wand. Dick carries an crystal wand.” (etc.), that a wand is supposed to be a kind of thing. It just creates objects which happen to be called “ebony wand”, “crystal wand”, and so on.

Because of that, Inform does not know that the line “Instead of waving any wand:” should apply to each wand, and treats it as referring to “a wand” or “the wand”, and decides that this refers to the first one mentioned in the source.
(I guess other people could explain it more deeply, because how Inform understands “any/some/a/the/anything/something/…” is complicated and I don’t know all the details. But I think what I wrote is the basic explanation.)

So, we need to tell it:

A wand is a kind of thing.
The ebony wand is a wand.
The crystal wand is a wand.
[etc.]

Interestingly, now the line “Instead of waving any wand:” does not compile any more. But if we change it to: “Instead of waving a wand:”, it works as intended.

2 Likes

This feels like a bug, actually. I can’t think of a documented use of “any” that the compiler might be using in this case.

1 Like

This is the key. Inform doesn’t know that those objects are all supposed to be instances of a specific type—presumably a “wand holder” or a “receipt for a wand” or a “book titled ‘How to Use a Wand’” shouldn’t be included in this rule, after all, but Inform doesn’t know enough English to make this distinction on its own. So you have to tell it explicitly (“the ebony wand is a wand” or “X carries a wand called an ebony wand”).

Though, as zarf says, it’s unclear why the “any” is accepted.

That’s an excellent explanation. Thank you so much for that. I’m still grappling with a lot of Inform7 concepts at the novice level (being dyslexic doesn’t help). One thing that surprised me with this is that you are able to use the same word for the “kind of thing” and the object. IE “wand is a wand.” I’d expected that the compiler would be unable to differentiate between the two. Very clever application, Inform. :smiley:

Yes indeed you are correct. As soon as I implemented StJohnLimbo’s corrections to my code the word “any” immediately began producing an error message, so I changed it to “Instead of waving a wand” and the code now compiles & runs.

Hmm, those reports read as if Inform encountered references to Github elements. That would occur if HTML files instead of the raw extension text files were downloaded.

The .i7x files are just plain text files which can be opened in any editor. They start with “Version 1 of Disappearing Doors by Andrew Plotkin begins here.” and so on.

There are mainly two options to get them:

a) Go to extensions/Disappearing Doors.i7x at 9.3 · i7/extensions · GitHub and extensions/Secret Doors.i7x at 9.3 · i7/extensions · GitHub

and click on the “Raw” button to show the raw text files, and then save/download them with the browser via CTRL+S.

or

b) clone the whole repository to a location on your hard drive, and then (using the 9.3 branch for 6M62) navigate to the subdirectories and install the .i7x files from there. You can also download the branch as a zip file by going here: GitHub - i7/extensions at 9.3 and clicking on “Code” → “Download ZIP”.

Just for checking and comparing, the files should be like this before installing:
Disappearing Doors.i7x (5.2 KB)
and
Secret Doors.i7x (6.6 KB)

1 Like

Hey thanks! I followed your instructions and both extensions are accepted by the compiler now.

Sorry for the delay; I got them to work at least a week ago but have been experimenting with them and forgot to comment here.

2 Likes

Another very interesting problem already. Is there a way to differentiate between when the player uses the “Look” command, and when the game engine is doing so?

The reason being that in my project, where four players are taking turns one after another, I’d like to not penalise them a turn if they want to see the room description again, or take inventory, or use a help command.

Free_turn is a truth state that varies.  Free_turn is initially false.

Office Working Area is a room.  Fantasy Testing Foyer is a room.

The Emerald Door is north of Office Working Area and south of Fantasy Testing Foyer. The Emerald Door is a closed door.

When play begins:
	now the command prompt is "Current player is [player] >";
	now the left hand status line is "Current player: [player]".
	
After reading a command: say conditional paragraph break.

Tom, Dick, Harry and Mary are people in the Office Working Area.  Tom, Dick and Harry are men.  Mary is a woman.  There is a person called Player_marker.  The player is Tom.  Understand "Tom" as Tom.

Rule for printing the name of Tom: say "Tom".
Rule for printing the name of Dick: say "Dick".
Rule for printing the name of Harry: say "Harry".
Rule for printing the name of Mary: say "Mary".

Every turn:
	If Free_turn is false:
		if the player is Dick, now the player is Player_marker;
		if the player is Mary, now the player is Dick;
		if the player is Harry, now the player is Mary;
		if the player is Tom, now the player is Harry;
		if the player is Player_marker, now the player is Tom; [This is needed to avoid the game engine skipping the last player.]
	Otherwise:
		say "[player] continues [if player is male]his[else]her[End if] turn.";
		Now Free_turn is false.

Understand "Help" as summoning help. Summoning help is an action applying to nothing. 

Carry out summoning help: Say "(Help text will go here)".

Looking is Free Turn Granting.  Taking Inventory is Free Turn Granting.  Summoning help is Free Turn Granting.

After Free Turn Granting: Now Free_turn is true.

It seemed simple enough; classify each of these actions so that they flip a truth state, and then use that variable to skip the player change.

However the game engine performs a look of the initial room at start up, and then again each time a player enters a room. This trips the truth state into falsely granting a free turn.

I’ve been mucking around with phrases such as “After entering a room: Now Free_turn is false.”, but this didn’t work, which I assume because the game engine looking comes after moving the player to the new room. In any case it wouldn’t have solved the problem of the truth state being tripped when the game begins.

Any ideas?

There are probably various ways to go about this.

One way to do it with your current code would be to add this:

After looking for the first time:
	now Free_turn is false.

Last report going:
	now Free_turn is false.

The first rule takes care of the implicit looking on the very first turn, and the second rule is applied after the looking that happens as part of the going between rooms.

There might be hidden pitfalls, but it seemed to work as desired when I tested it.

For a slightly different approach, also check out example 409 (Timeless) in the Recipe Book, section 4.1. The Passage Of Time.

Side note:
In your current implementation, a runtime error can happen when the player changes to the virtual Player_marker person, who is off-stage. I encountered:

Run-time problem P45: Attempt to change the player to a person off-stage.

The player must always be on-stage, more or less by definition, so cannot be changed to someone who is currently off-stage.

In order to avoid the need for the extra player-change (i.e., to avoid the skipping you mention in your comment), I’d turn that part of the code into an “otherwise if” structure or equivalently into the “if … is:” structure, so that only one branch is executed, like this:

Every turn:
	If Free_turn is false:
		if the player is:
			-- Dick: now the player is Tom;
			-- Mary: now the player is Dick;
			-- Harry: now the player is Mary;
			-- Tom: now the player is Harry;
	Otherwise:
		say "[player] continues [if player is male]his[else]her[End if] turn.";
		Now Free_turn is false.