Creating properties for new kind, but they apply to 'object'

Hi. I’m writing an Inform 7 game with a Photopia- or Bioware-esque dialogue system. In the source text, I defines ‘dialogue branch’ as a new kind of object like so:

[code]A dialogue branch is a kind of object.

A dialogue branch has a truth state called enabled. Enabled is usually true. [If a branch is not enabled, it doesn’t show up as a possible choice in the command prompt.]

A dialogue branch has some text called the prompt. The prompt of a dialogue branch is usually “[bold type]Error:[roman type] [The item described] has no prompt.” [The prompt is the text that labels the option to choose the branch.]

A dialogue branch has some text called the description. [The description is the text displayed when the branch is chosen.]

A dialogue branch has a list of dialogue branches called the choices. [These are the child branches of the branch.]

A person has a dialogue branch called the home dialogue branch. [This flag indicates the default branch when you TALK TO someone.]

The null dialogue branch is a dialogue branch. The home dialogue branch of a person is usually the null dialogue branch. [A placeholder to prevent runtime errors due to not defining dialogue for someone.] The description of the null dialogue branch is “[bold type]Error:[roman type] Attempted to read out null dialogue branch.”[/code]
(The dialogue branch is laid out this way so that I can easily define whole dialogue trees using a table.)

This code, if pasted into a blank project, compiles into what we would expect: it creates a new kind of object, ‘dialogue branch,’ with various properties. But when I compile my full Inform 7 project, a game is created in which ‘enabled,’ ‘prompt,’ ‘description,’ and ‘choices’ are properties of the ‘object’ kind itself, not just the ‘dialogue branch’ object:

screen-1.JPG
This can be verified in-game with the ‘showme’ command, which shows that yes, every single object in the game world has an ‘enabled,’ a ‘prompt,’ a ‘description,’ and a list of ‘choices.’

You’ll also notice the orange arrows in the screenshot, which normally lead back to the definition of the kind in the source text - strange, because ‘object’ is defined in the Standard Rules, not in my project. Similar orange arrows show up in the Index for every single kind of value other than ‘command parser error.’ All of the orange arrows, including the ones in the screenshot, point to the last header in my project, which is a header, not any kind of code.

There are no lines of code saying “Some objects are defined by…” or “All objects are dialogue branches” or any nonsense like that, so as far as I know this shouldn’t be possible. I can only conclude that there’s some part of my source text that interacts strangely with the compiler, causing it to muddle up my source text and the Standard Rules. While the additional properties on everything don’t actually interfere with the working of my game, I’m worried that it may lead to excessive memory use, and that it may be a symptom of other weird things that are happening with the compiler.

I’ve uploaded a mirror of my project on Google Drive here. (Contains mildly graphic descriptions of a dying man.) Any advice or insight on this problem would be appreciated.

Are you using Inform 6G60? I notice you have a lot of “consider” phrases, which have been deprecated in the latest release. And when I try to compile in 6G60, I get a lot of errors; there was a floating “otherwise,” and when I fixed that you’d defined “singing” as a new action (which might mean you’re working in a post-6G60 version, after singing was removed?), and then when I fixed that I encountered a problem with ‘Understand “man” or “guy” or “dude” as a male person’.

So at this point I think I have to say, make sure that the source code you’re uploading is actually compiling in some version of Inform, and if you could say which version you’re working in that would be very helpful.

I’m using the version listed on the Inform website’s download page right now, which is 6M62, dated 23rd June 2016. I’m compiling on the Windows version, and it works fine.

I’ve zipped a new version which can be found here, if that’s any help. It’s the same source text, I’ve just cleaned it up a bit and confirmed that it will compile correctly on my machine.

Oh, my bad–I didn’t have the latest version of Menus. Sorry about that. (I didn’t see the inclusion the first time.)

Or rather, the impossibly obscure file handling of older versions of Inform has lodged an outdated version of Menus somewhere where I can’t find it on my hard drive. So tiresome. I’ll try to expunge it and see if I can get anywhere.

No worries. As I said, this isn’t a critical problem – my game’s not crashing or anything like that, it’s just weird and unintended behind-the-scenes behavior. Still, I’d be grateful if you could dig up anything to resolve it.

Well, I’m stumped. I tested that if you just carve out the dialogue system section with enough to make it compile, it doesn’t happen:

[spoiler][code]Definition: a person is other if it is not the player.

This is the rest of the turn rule:
abide by the every turn stage rule;
abide by the timed events rule;
abide by the advance time rule;
abide by the update chronological records rule;
abide by the adjust light rule;
abide by the note object acquisitions rule;
abide by the notify score changes rule;
follow the scene changing rules.

The conversational partner is a thing that varies.

Part 2.3.1 - Dialogue System

Chapter 2.3.1.1 - Dialogue Branches

A dialogue branch is a kind of thing.

A dialogue branch has a truth state called enabled. Enabled is usually true. [If a branch is not enabled, it doesn’t show up as a possible choice in the command prompt.]

A dialogue branch has some text called the prompt. The prompt of a dialogue branch is usually “[bold type]Error:[roman type] [Printed name] has no prompt.” [The prompt is the text that labels the option to choose the branch.]

A dialogue branch has some text called the description. [The description is the text displayed when the branch is chosen.]

A dialogue branch has a list of dialogue branches called the choices. [These are the child branches of the branch.]

A person has a dialogue branch called the home dialogue branch. [This flag indicates the default branch when you TALK TO someone.]

The null dialogue branch is a dialogue branch. The home dialogue branch of a person is usually the null dialogue branch. [A placeholder to prevent runtime errors due to not defining dialogue for someone.] The description of the null dialogue branch is “[bold type]Error:[roman type] Attempted to read out null dialogue branch.”

[If a branch has no children, it will end the dialogue upon being read out.]

Chapter 2.3.1.2 - Tearing Out Inform Dialogue

Understand the commands “ask” and “tell” and “say” and “answer” as something new.

To say use-talk-to:
say “(Use the command TALK TO or T to converse with other characters.)[run paragraph on]”

Understand “ask [text]” or “tell [text]” or “answer [text]” or “say [text]” as a mistake ("[use-talk-to][line break]").
Understand “ok” or “okay” or “nod” as a mistake ("[use-talk-to][line break]").
Understand “shake head” as a mistake ("[use-talk-to][line break]").

Instead of asking someone to try doing something, say “[use-talk-to][line break]”.
Instead of answering someone that something, say “[use-talk-to][line break]”.
Instead of saying yes or saying no or saying sorry, say “[use-talk-to][line break]”.

Chapter 2.3.1.3 - Engaged in Dialogue

Yourself can be free to act or engaged in dialogue. Yourself is free to act.

The available dialogue choices is a list of dialogue branches that varies.

Reading out something is an activity on dialogue branches.

To read out (current branch - a dialogue branch):
carry out the reading out activity with the current branch.

Rule for reading out a dialogue branch (called the current branch):
say “[description of the current branch][if the description of the current branch is not empty][line break]”;
if the number of entries in the choices of the current branch is 0, end the dialogue;
otherwise:
change the available dialogue choices to have 0 entries;
repeat with current child running through the choices of current branch:
if the enabled of current child is true, add current child to the available dialogue choices.

To say dialogue-cmd-prompt:
if the number of entries in the available dialogue choices is 0:
say “[bold type]Error:[roman type] Attempted to print the dialogue command prompt with no available choices. Now ending the dialogue…[line break]”;
end the dialogue;
otherwise:
repeat with N running from 1 to the number of entries in the available dialogue choices:
say “[N]) [prompt of entry N in the available dialogue choices][line break]”;
say “[line break]>”.

To start a dialogue with (provided partner - a thing):
if the home dialogue branch of the provided partner is not the null dialogue branch:
now the conversational partner is the provided partner;
if the number of characters in “Talking to [the conversational partner]” is greater than 14, now right alignment depth is the number of characters in “Talking to [the conversational partner]”;
now the command prompt is “[dialogue-cmd-prompt]”;
read out the home dialogue branch of the conversational partner;
now the player is engaged in dialogue;
otherwise:
say “[bold type]Error:[roman type] Attempted to start a dialogue with [the provided partner] but no home dialogue branch was defined for [them].”

To start a dialogue with (provided partner - a thing) using dialogue (chatter - a dialogue branch):
now the conversational partner is the provided partner;
if the number of characters in “Talking to [the conversational partner]” is greater than 14, now right alignment depth is the number of characters in “Talking to [the conversational partner]”;
now the command prompt is “[dialogue-cmd-prompt]”;
read out the chatter;
now the player is engaged in dialogue.

To end the dialogue:
now right alignment depth is 14;
now the command prompt is “>”;
now the player is free to act;
follow the rest of the turn rule.

After reading a command when the player is engaged in dialogue:
if the player’s command includes “[number]”:
let N be the number understood;
if N > 0 and N <= the number of entries in the available dialogue choices:
read out entry N in the available dialogue choices;
reject the player’s command;
stop;
say “Please choose a response from the list by typing the corresponding number.”;
reject the player’s command.

Chapter 2.3.1.4 - Talking To

Talking to is an action applying to one visible thing.
Understand “talk to/with [something]” as talking to.
Understand “speak to/with [something]” as talking to.
Understand “t [something]” as talking to.

Check talking to something that is not a person (this is the can’t talk to inanimate objects rule): say “You doubt that would make for engaging conversation.” instead.

Check talking to the player (this is the can’t talk to yourself rule): say “You aren’t that far gone, Marid.” instead.

Check talking to an other person when the home dialogue branch of the noun is the null dialogue branch (this is the can’t talk to someone with no dialogue rule): say “[The noun] [have] nothing to say to you.” instead.

Carry out talking to something: start a dialogue with the noun.

Lab is a room.

Include Menus by Emily Short.
Include Basic Screen Effects by Emily Short.[/code][/spoiler]

but I personally can’t see what’s causing it. I’d file this as a bug (you can point to the page on the Google Drive that contains your source code instead of pasting it all in). Or maybe someone more knowledgeable will be able to dig it up.

There’s probably some declaration somewhere in the code which makes the system think that all objects are dialogue branches (as well as vice versa). But I don’t know what to look for.

If you can trim out as much of the game code as possible, while still demonstrating the problem, that will help a lot.

(Oh wow. What it must be like to be Zarf.)

I’ve done some trimming and think I’ve managed to pinpoint the cause of the problem. Unbelievably enough, it seems to be the headers in the source text that’s messing with the compiler. Consider this example game:

[code]“The Weight of a Snowflake” by Chin Kee Yong

The Snowfield is a room.

A special snowflake is a kind of object. A special snowflake has some text called the text that should be unique to special snowflakes.

Some special snowflakes are defined by the Table of Test Dialogue.

Table of Test Dialogue
special snowflake text that should be unique to special snowflakes
red snowflake “This snowflake is red”
blue snowflake “This snowflake is blue”[/code]
This compiles perfectly. But add even a single header anywhere in the source text:

Chapter 1 - In which snowflakes receive their definition

And suddenly the problem emerges. The orange arrows appear in force, and Inform grants the “text that should be unique to special snowflakes” property to all objects regardless of kind.

The table is what’s granting the property to all objects. If the table is omitted from the source text, the new text property is indeed restricted to special snowflakes. The larger problem seems to be the header and the way it confuses the compiler. I’m guessing that Inform 7 isn’t translating tables and headers properly, causing unseen errors when the Inform 6 backend handles the source text.

Like being most other people, except you spend more time tracking down IF tool bugs.

Your trimmed-down sample is very helpful! Thanks.

I note that the first form doesn’t compile perfectly. The “object” kind in the index doesn’t have the misplaced-arrow problem, but it does incorrectly list “text that should be unique…” as an associated property.

1 Like

I am going to file this bug; I want to simplify the test case even further.

The problem is entirely in the I7 compiler. It’s generating all the low-level data tables as if the property really is defined for the “object” kind.

EDIT-ADD: I suspect the problem is the assumptions it makes based on table column types. Those have always been hard to understand.

Filed: inform7.com/mantis/view.php?id=1965

There’s a sim.

(And nice job tracking this down!)

Oops, I didn’t catch that. I was too fixated on the novelty of a header causing problems, I think.

Matt W and Zarf, thanks for all your help! (And if you ever encounter trouble with other people in your head let me know.)