The Foxaroo tinkering around with Inform7

I may be misunderstanding what you’re trying to do, but isn’t the cleanest way just not to advance time when the player takes an action you want to be free?

Looking is taking a free action.
Taking inventory is taking a free action.

The advance time rule does nothing when taking a free action.

Edit: Oh, sorry, I realize now that you’re doing something complicated with multiplayer. Forget I spoke.

That’s brilliant! I would never have thought to use the “Report” rulebook. I expected it was just for printing the results of an action.

What does “Last Report” do? I’ve re-read Chapter 12.9 and can’t see this mentioned here, and I’ve string searched “Last Report” but apparently it’s not worded as such anywhere in the I7 Documentation.

That worked like a charm too, thanks. Although I’m not familiar with the double hyphen “–” syntax, and I was unable to find it in the documentation. I can see what how it works, I’d just like to read up and fully understand its uses. Is this covered in a specific chapter?

All of it is now working correctly. Something annoying happened though; the bug associated with looking for the first time went away on its own before I’d even implemented your fix. The first modification I made was your improved If-otherwise block to remove the extra player-change. Soon as that was in place I was no longer having a false free-turn moment after startup. Regardless I’ve implemented your new line.

Thanks, I’m glad it was helpful! :slight_smile:

Your expectation was totally sensible, and in general, it is a good idea and good practice to roughly stick to the guidelines described in chapters 7 and 12 of the manual (Basic Actions and Advanced Actions).
But in principle at least, you can put nearly anything in those rules at any time, if you just keep in mind the order and conditions in which they are executed. So sometimes a small tweaking of the rules in an unusual place can be useful.

The “Last” tells Inform to put this rule at the last place in the collection of Report rules, to make sure that it runs last. It’s not specific to Report, it can be used with other rulebooks as well. See 19.7. The preamble of a rule.

That syntax is documented at 11.8. Otherwise.

That’s strange, because when I comment out the “After looking for the first time” rule, I get the following output at the start of the game (Tom gets a free turn instead of the game changing to Harry directly):

Office Working Area
A nice room.

You can see an Emerald Door, Dick, Harry and Mary here.

Current player is Tom >z

Time passes.

Tom continues his turn.

Current player is Tom >z

Time passes.

Current player is Harry >

With the “After looking” rule in place, it is as it should be:

Office Working Area
A nice room.

You can see an Emerald Door, Dick, Harry and Mary here.

Current player is Tom >z

Time passes.

Current player is Harry >

Yes, that’s what had been happening with me, and what I expected to keep happening until I implemented your improvement. Having the bug go away on its own was unnerving. I’ll be keeping an eye on it

Thanks again, and for all the documentation references.

Just a curiosity question here about Inform7’s syntax for comparisons. Can you not use “equals” or “is equal to?” My code here works, I just don’t like the peculiar wording. IE having to write that [one value] is [another value] instead of [one value] equals [another value] or is equal to.

(Middle of the three comparisons).

		Roll the Dice for the Antagonist;
		if the Dice_roll of the player is less than the Dice_roll of the Antagonist:
			say "You narrowly dodge [The Antagonist]'s attack, avoiding taking damage.";
		if the Dice_roll of the player is the Dice_roll of the Antagonist:
			say "Moving quickly you dodge [The Antagonist]'s attack.  Though the outcome there would have been a draw anyway.";
		if the Dice_roll of the player greater than the Dice_roll of the Antagonist:
			say "You easily dodge [The Antagonist]'s attack, however you had the advantage there and could have struck a blow.";

I don’t think there is a directly built-in way. However, in the Standard Rules there is this sentence:

The verb to be means the equality relation.

We can define our own additional verb constructions accordingly:

The verb to be equal to means the equality relation.

The verb to equal means the equality relation.

Then we can use them in our code:

if 23 is equal to 17 + 6, say "23 is equal to 17 + 6.";
if 23 equals 17 + 6, say "23 equals 17 + 6.";
if 23 does not equal 17 + 7, say "23 does not equal 17 + 7.";
[and so on]

I don’t know if there are any pitfalls or unintended side effects, but it seems to work as expected.

3 Likes

A somewhat cruder alternative is:

To decide whether (N - a value) is/-- equals/equal to/-- (M - a value):
	if N is M:
		decide yes;
1 Like

Sorry to take so long to get back to you. Work + coming down with a cold.

Thanks. This does indeed make re-reading the code easier to comprehend. I’ll be using that in all my future projects too. It ought to be part of the standard rules.

I have two questions about controlling things in Inform 7. Strictly speaking I can still complete my project without knowing, but these are features I’d like to be able to add to my game.

  1. Can you override the game engine from automatically picking up an object when the action requires that the object be carried? For example I’ve just written the code for when the player lights their light source, and I’d like to display the message “You must be holding the [noun] in order to light it.”. I’ve tried using “Before Lighting” and “Check Lighting” as well as putting a condition into “Carry out Lighting” but the game picking up the object still takes place before any of my code executes “(First taking the [noun]).”

  2. Can you nominate your own description when the player is in a dark location? Inform 7’s default when the player enters a dark room is “It is pitch dark, and you can’t see a thing.” I’d like to display a different description depending on which realm (region) the player is in:
    Fantasy - “It is pitch black. You are likely to be eaten by a grue.” (The iconic Zork phrase).
    Detective - “’ ’ ’ ’ ’ ’ . You are likely to be mugged.”
    Sci-fi - " ’ ’ ’ . You are likely to be attacked by a horta." (Star Trek monster).
    Anthropomorphic - " ’ ’ ’ ’ ’ '. You are likely to be maimed, and mauled, and devoured." (Zootopia opening scene).

For the second one, you’ll want a “rule for printing the name of a dark room” and/or a “rule for printing the description of a dark room”.

There are five activities for darkness: printing the name of a dark room, printing the description of a dark room, printing the announcement of darkness, printing the announcement of light, and printing a refusal to act in the dark. Most authors never need to care about any of them, and honestly having them be full activities might be overkill. But that’s the way it’s set up right now.

1 Like

For the first one, you’ll need a rule for implicit taking. I’m assuming you have something like a light source defined in your code? This approach should work:


The sewer is a room.

A light source is a kind of thing.

The lantern is a light source in the sewer.  It is wearable.

Rule for implicitly taking a light source when lighting:
	Say "You need to carry [the noun] to light it." instead.

Understand the command "light" as something new.   Understand "light [light source]" as lighting.  Lighting is an action applying to one carried thing.

Carry out lighting:
	Say "Blarg."

(I have the lantern as wearable so you can confirm WEAR LANTERN will implicitly take it, but LIGHT LANTERN won’t).

1 Like

And for the first one, look at the example “Lollipop Guild” to see how implicit taking can be changed. You need to disable the rules that require you to be holding a thing in order to light it—either in one specific circumstance, or in general.

Is this a custom action you’ve defined? By default, “light [something]” is the burning action, which does nothing unless overridden with Instead rules.

EDIT: Alas, not fast enough.

2 Likes

Thanks Daniel,

Yes, what I’m doing is unusual and there wouldn’t normally be a need to change the darkness description. Nevertheless it’s fun to give my adventure a bit more flavour.

Worked like a charm:

Rule for printing the description of a dark room: Say "It is pitch black.  You are likely to be [if the player is in Fantasy Area]eaten by a grue[End if][if the player is in Sci-fi Area]attacked by a horta[End if][if the player is in Anthromorphic Area]maimed, and mauled, and devoured[End if][if the player is in Detective Area]mugged[End if]." instead.

Mike Russo,

Thanks for the advice about implicitly taking. I’ve had a quick read of the chapters where that is mentioned and will tackle the problem tonight and then get back to you.

Oh, yes, it’s absolutely good to have a way to customize these things! They’re great for giving a game its individual flavor.

I just think activities are overkill, because you could just as easily make it a single piece of text that could be replaced (a “response”).

1 Like

Mike Russo,

Thanks for your advice.

Seeing that in my current adventure I don’t need the player to automatically take anything (quite the opposite in this case), I went with a blanket rule:

Rule for implicitly taking something (called target): 
	say "You need to be holding the [target] first."; 
	stop the action.

Out of curiosity I experimented to see if the rule can be limited to a specific thing type, and it worked too. Good to know for future projects.

Rule for implicitly taking a light-source (called target): 
	say "You need to be holding the [target] first."; 
	stop the action.

Thanks for your help. :slight_smile:

2 Likes

FYI - I just found a weakness in Krister Fundin’s “Hidden Items”. It cannot be applied to one-sided doors.

**Chapter 3.12. Doors**

In real life, most doors are two-sided, and can be used from either of the rooms which they join, but this is not always convenient for interactive fiction. Here is a one-sided door:

The blue door is a door. It is south of Notting Hill. Through it is the Flat Landing.

If you attempt to turn the blue door into a hidden door, you receive the below error:

Run-Time ProblemAttempt to remove a door from play (P44) 
 
Most problems are detected when Inform translates the source text, but this is one of the exceptions, a "run-time problem" which emerges only during play.

--------------------------------------------------------------------------------

Doors are part of the fixed geography of the model world, and are tied in to the map, so it is illegal to remove them from play. (Of course rules can be used to simulate the absence of a door, or to change its behaviour almost completely.)

I looked inside the extension and found that it the hidden effect was designed to apply to both rooms in which a door is connected, and thus it is unable to cope with a door that is missing one side.

My plan had been to make my doors one-sided for expedience. I can get around it by adding code to hide the doors again once the player walks through them.

Just thought this was interesting to note.

Doors and backdrops’ implementation are a holdover of I6’s concept of “floating objects”. Hidden Items’ implementation depends on floating objects, but I7’s Standard Rules and Kits really don’t intend that the author manipulate them directly.

In I6, almost anything can be made a floating object, but in I7 this is strictly and only used for backdrops and two-sided doors. […] the scheme is not logically defensible, and this is why we do not allow the user to create new categories of floating objects in I7.

The last code line in Hidden Items is remove T from play. That (deprecated, as it happens) I7 phrase invokes the I6 routine RemoveFromPlay and that checks if you’re trying to remove a door and generates the runtime error.

If you were to change that last line to surreptitiously remove T from play, you would do an end-run around I7’s remove <thing> from play’s checks: Hidden Items defines that phrase to directly use the I6 statement remove <object>. I’m not saying it’s a good idea, and I’m not sure what side effects it might have with other things, but at least superficially it makes the one-sided door case work without run-time error.

For most things, you’d be better off skipping Hidden Items and just leaving things off-stage and teleporting them in when revealed. For doors, you might check out @HanonO 's Easy Doors which creates fake, highly manipulable things that call themselves doors that are good enough for many purposes.

2 Likes

I’ve run into difficulty with my first intermediate use of a table in Inform 7. I wanted to create an achievement system, as many modern games do these days. The first of my four players to complete any particular puzzle has their name recorded in the table (after of course checking to see if there is already a name there).

At the moment I’m having difficulty with the syntax.

Here’s the table, basically (Just one row at the moment, I’ll be adding the others later):

Table 2 - List of Achievements
Deed	The_Player	Achievement_Text
"BREACH"	a text	"*Into the breech!*"

The code runs OK when I use a literal text for the search:

To Award Achievement (Medal - text):
	if there is no The_Player corresponding to a Deed of Medal in the Table of List of Achievements:
		choose row with a Deed of "BREACH" in the Table of List of Achievements;
		say "ACHIVEMENT EARNED[Line break]=================[Line break][Achievement_Text entry][Paragraph break]".

But when I try to swap the literal text of “BREACH” with the variable name Medal, I receive a run time error.
*** Run-time problem P21: Attempt to look up a non-existent correspondence in the table 'Table 2 - List of Achievements'.

This is despite the fact that the variable succeeds within the IF statement immediately above.

I’ve tried to follow the guidelines laid out in Chapter 16.5 of the documentation. What would be causing this problem?

It works fine for me. Did you accidentally type “breech” instead of “breach”, perhaps? (I notice you’ve done that in the Achievement_Text.)

Medal room is a room. 

Table 2 - List of Achievements
Deed	The_Player	Achievement_Text
"BREACH"	a text	"*Into the breach!*"

To Award Achievement (Medal - a text):
	if there is no The_Player corresponding to a Deed of Medal in the Table of List of Achievements:
		choose row with a Deed of medal in the Table of List of Achievements;
		say "ACHIVEMENT EARNED[Line break]=================[Line break][Achievement_Text entry][Paragraph break]".
		
When play begins: award achievement "BREACH".
3 Likes

Yes that was it. Being dyslexic it’s a mistake I’m prone to.

Sorry for the late reply - it’s been a busy week.