Using Inform 7 Inherited Properties in Conditional Statements

I am trying to work with Inform 7’s inheritence where a child thing inherits properties from a parent thing and the child thing’s properties are used in a conditional statement.

I have got a room and in that room I have a table and on that table I have a fuse tester.

Workshop is a room. "An empty room except for a table in the center. On the table is a fuse tester.[if the fuse tester contains the orrery fuse] The orrery fuse in the fuse tester.[else if the fuse tester contains the time machine fuse] The time machine fuse is in the fuse tester.[otherwise] The fuse tester is empty.[end if]"

The table is a supporter.
The table is in the Workshop.
The table is undescribed.

The fuse tester is a container.
The description of the fuse tester is "A simple box with a slot for a fuse and a small bulb.[if the fuse tester contains the orrery fuse] The orrery fuse is in the slot.[else if the fuse tester contains the time machine fuse] The time machine fuse is in the slot.[otherwise] The slot is empty.[end if] The bulb is currently [if the fuse tester is switched on]lit.[otherwise]unlit."
The fuse tester can be switched on or switched off. The fuse tester is switched off.
The fuse tester is on the table.
The fuse tester is fixed in place.
The fuse tester is undescribed.
The examine containers rule does nothing when examining the fuse tester.

Before inserting a breaker into the fuse tester:
	if the fuse tester contains a breaker:
		say "You will need to remove the other fuse from the tester first.";
		stop the action;
	otherwise:
		continue the action.

I want to have two fuses to test but since each fuse is either working or not working, I created a parent thing for them to inherit from.

A breaker is a kind of thing.
The breaker is either working or not working. A breaker is usually working.

The orrery fuse is a breaker. "pristine".
The orrery fuse is working.
The description of the orrery fuse is "The [noun] looks [initial appearance]."

The time machine fuse is a breaker. "burnt".
The time machine fuse is not working.
The description of the time machine fuse is "The [noun] looks [initial appearance]."

Then I have a conditional statement to determine if the fuse tester should be switched on or off depending on whether the fuse is working or not working (The fuse tester’s description shows the bulb as “lit” for a working fuse; “unlit” for a not working fuse).

After inserting a breaker into the fuse tester:
	if the breaker is working: 
		now the fuse tester is switched on;
	otherwise: 
		now the fuse tester is switched off; 
	continue the action.

With the “if the breaker is working:” line, every fuse that I put into the fuse tester registers as working, the fuse tester is always switched on, and the bulb is always lit.

If I change that line to read “if the fuse is working:”, every fuse I put into the fuse tester registers as not working, the fuse tester is never switched on, and the bulb is never lit.

The complete code is below for anyone who wants to run it. Three things about this code that I have not mentioned:

  1. There is a debug-mode variable that is set to true. This is so some ALL-CAPS DEBUG TEXT will be printed (set debug-mode to false to hide)
  2. The handlers “Before removing a fuse from the fuse tester:” and “After taking a breaker:” are there to handle both the > take orrery fuse from tester. and > take orrery fuse. commands (each resolves to a different action)
  3. There is a test case called “fuses” at the end of the code below that can be used to test the implementation (type > test fuses to run)

I have been working on this off-and-on for the past few days, searching through the documentation and the forums to see what I am missing. At this point I think a second set of eyes could help (it is probably something simple, something I am missing about Inform 7).

Thanks in advance.

=== Complete Code Listing Below ===

"fuse-test" by Bill Maya

When play begins:
	now the player is carrying the orrery fuse;
	now the player is carrying the time machine fuse.
	
debug-mode is a truth state which varies.
debug-mode is true.

Workshop is a room. "An empty room except for a table in the center. On the table is a fuse tester.[if the fuse tester contains the orrery fuse] The orrery fuse in the fuse tester.[else if the fuse tester contains the time machine fuse] The time machine fuse is in the fuse tester.[otherwise] The fuse tester is empty.[end if]"

The table is a supporter.
The table is in the Workshop.
The table is undescribed.

The fuse tester is a container.
The description of the fuse tester is "A simple box with a slot for a fuse and a small bulb.[if the fuse tester contains the orrery fuse] The orrery fuse is in the slot.[else if the fuse tester contains the time machine fuse] The time machine fuse is in the slot.[otherwise] The slot is empty.[end if] The bulb is currently [if the fuse tester is switched on]lit.[otherwise]unlit."
The fuse tester can be switched on or switched off. The fuse tester is switched off.
The fuse tester is on the table.
The fuse tester is fixed in place.
The fuse tester is undescribed.
The examine containers rule does nothing when examining the fuse tester.

Before inserting a breaker into the fuse tester:
	if the fuse tester contains a breaker:
		say "You will need to remove the other fuse from the tester first.";
		stop the action;
	otherwise:
		continue the action.

A breaker is a kind of thing.
The breaker is either working or not working. A breaker is usually working.

The orrery fuse is a breaker. "pristine".
The orrery fuse is working.
The description of the orrery fuse is "The [noun] looks [initial appearance]."

The time machine fuse is a breaker. "burnt".
The time machine fuse is not working.
The description of the time machine fuse is "The [noun] looks [initial appearance]."
		
After inserting a breaker into the fuse tester:
	if debug-mode is true, say "BREAKER INSERTED[line break]";
	if the breaker [fuse] is working: [Always hits this branch if this line is "if the breaker is working:" Result is that time machine fuse will light bulb.]
		if debug-mode is true, say "FUSE WORKING";
		now the fuse tester is switched on;
	otherwise: [Always hits this branch if the above line is "if the fuse is working:" Result is orrery fuse will not light bulb]
		if debug-mode is true, say "FUSE BROKEN";
		now the fuse tester is switched off; 
	continue the action.

Before removing a fuse from the fuse tester: [Handles > take orrery fuse from tester => [removing the orrery fuse from the fuse tester] action]
	try taking the fuse.

After taking a breaker: [Handles > take orrery fuse => [taking the orrery fuse] action]
	if debug-mode is true, say "BREAKER TAKEN";
	now the fuse tester is switched off;
	continue the action.

Test fuses with "x tester / put orrery fuse in tester / x tester / take orrery fuse from tester / x tester / put time machine fuse in tester / x tester / take time machine fuse from tester / x tester."

I haven’t tested this, but pretty sure the issue is in this code, because you’re being ambiguous about which breaker is being talked about - “a breaker” doesn’t give Inform enough to go on so I think it’s defaulting to the first-listed breaker in your code. Try this instead:


After inserting a breaker (called the foo) into the fuse tester:
	if the foo is working: 
		now the fuse tester is switched on;
	otherwise: 
		now the fuse tester is switched off; 
	continue the action.

(Also not sure you really need the “continue the action” here).

EDIT: also the “working” / “not working” property descriptions might be causing some problems, since as I understand it Inform automatically creates and understands a “not X” property whenever you create a property X. So again this can lead to confusion - might be better to say a breaker can either be working or broken (or burnt-out or what have you).

yup, it’s something simple that trips everyone up.

You have:

After inserting a breaker into the fuse tester:
	if the breaker [fuse] is working:

Either of these would work:

After inserting a breaker (called fuse) into the fuse tester:
	if the fuse is working:
After inserting a breaker into the fuse tester:
	if the noun is working:
1 Like

The shorthand rule to remember in I7 is: if you’ve defined KIND as a kind, never write “the KIND”. It’s fine to talk about “a breaker”, or maybe “a random breaker”. But when you see “the” before a kind name, the compiler is going to get confused.

2 Likes

@Zed & @DeusIrae Your suggestions to change the “After inserting” rule so the breaker is disambiguated worked. Thank you both.

After inserting a breaker (called fuse) into the fuse tester:
	if the fuse is working: 
		now the fuse tester is switched on;
	otherwise: 
		now the fuse tester is switched off; 
	continue the action.

I added the “continue the action.” so I could get automatic confirmation of putting the fuse in the tester.

Without that line the reply is suppressed.

1 Like