Stuck implementing a table with consult about

I’ve been coding away on my first piece of IF using Inform7 slowly wading through syntax errors etc, but now I am really stuck. I’m trying to implement a detective’s notebook (similar to what is found in Chris Huang’s “An Act of Murder”) that automatically records relevant evidence or clues for the player along with the current time and can be read or consulted later on.

The usage I intended is as follows:

[Items are added to the notebook in the game via code such as:
          Note "Matchbook" with "Has Tony's phone number CH 2481.";

 The player can use the commands:
          > examine notebook
          > consult notebook about Matchbook
          > read about Matchbook in notebook
          > look up Matchbook in notebook
] 

I got the basics working with the ability to add items to the notebook during the game and the ability to read the notebook as follows:

Table of Notes
timestamp	item	detail
a time	some text	some text
with 50 blank rows

[ Items in the notebook will be stored by unique item and only recorded once.
  This makes it easier to have multiple sources giving the same clue.   
  First time, alert the reader that player he has found a clue. ]
To note (t - some text) with (d - some text):
	if the number of blank rows in the Table of Notes is 0:
		say ">>Warning: the notebook is now full.  (Please file a bug report.)";
		rule succeeds;
	[ Note: Check to see if the clue is already in the notebook, if so, disregard. ]   
	if there is an item of t in the Table of Notes:
		rule succeeds; 
	else:
		if the number of filled rows in the Table of Notes is 0:
			say "You decide to take a note of this in your notebook.";
		increase score by 1; 
		choose a blank row in the Table of Notes;
		change timestamp entry to the time of day;
		change item entry to t;
		change detail entry to d.

[ Examine or Read notebook willl display a list of times, items, but omits detail  ]
Instead of examining notebook:
	if the number of filled rows in the Table of Notes is 0:
		say "Alas your notebook is empty.  You still need to find some clues.";
	else:
		say "The notebook contains [the number of filled rows in the Table of Notes] entries:[line break]";
		repeat through the Table of Notes:
			say "  [timestamp entry] - [detail entry][line break]".

So far this all works fine. But when I try to implement a mechanism for the player to type something like

Consult notebook about matchbook

I tried writing the code below which doesn’t compile because of the use of something in the second and third lines. (It does work properly if I substitute a literal value such as “Matchbook”.

Instead of consulting notebook about something:
	if there is a detail corresponding to an item of something in the Table of Notes:
		choose row with a item of something in the Table of Notes; 
		say "[item entry] - [Detail entry][line break]";
	else: 
		[ enable user to look up by time, just in case ]
		if there is a timestamp of something in the Table of Notes:
			choose row with a timestamp of something in the Table of Notes;
			say "[timestamp entry] - [item entry] - [Detail entry][line break]";
		else:
		[ This never matches! ]
			say "There's nothing that matches that item exactly."

I’m really stumped. I have read the built-in docs, the programmer’s guide to Inform7, Jim Aikin’s Guide and Aaron Reed’s book. I have tried half a dozen ways over several hours and I either have compiler errors on the syntax or runtime errors. In Jim Aikin’s book there’s an example of an Encyclopedia that uses Topic as the type in the table. I tried that but then I couldn’t figure out how add new items to the table without getting a runtime error on a statement like:

    Note "Matchbook" with "Has Tony's phone number CH 2481.";

If anyone can provide some tips here (or ideally working code!) that is much appreciated.

thanks in advance
–Zack
z-machine-matter.com

This doesn’t look right. I don’t think you can use “something” as a variable. You probably want “the topic understood,” but you may need an intermediate step to strip the topic down to the keyword.

Have a look at the section of Writing with Inform about Topic Columns.
inform7.com/learn/man/doc253.html

I’m not sure if this has changed, or it’s just listed somewhere else but there’s also an example somewhere about looping over all rows of a table to see if each item matches the topic understood. Using tokens in a topic column is probably what you want, though.

Thanks. Yes, I know the code is not right. I have tried declaring the item column as a topic column as shown in the docs you mentioned and also in Jim Aiken’s Handbook. e.g.

Table of Notes
timestamp	topic	detail
a time	some topic	some text
with 50 blank rows

and then changing all the references to item to be topic. But then when I try to put something into the notebook as follows:

Note "Matchbook" with "Brass lantern...";
I get a runtime error because “Matchbook” is text, not a topic.

So yes, I understand the problem, I just don’t know an alternative way to implement this using a topic column. That’s why I posted my question.
–Zack

Well, I’m stumped. I don’t know why it’s allowed to write “if [snippet] includes [text]”, even though it appears that it’s impossible for those two things to ever match. For reference, here’s a compilable example that I was trying:

[spoiler][code]Study is a room. The player carries a notebook.

Table of Notes
timestamp item detail
a time some text some text
with 50 blank rows

[ Items in the notebook will be stored by unique item and only recorded once.
This makes it easier to have multiple sources giving the same clue.
First time, alert the reader that player he has found a clue. ]
To note (t - some text) with (d - some text):
if the number of blank rows in the Table of Notes is 0:
say “>>Warning: the notebook is now full. (Please file a bug report.)”;
rule succeeds;
[ Note: Check to see if the clue is already in the notebook, if so, disregard. ]
if there is an item of t in the Table of Notes:
rule succeeds;
else:
if the number of filled rows in the Table of Notes is 0:
say “You decide to take a note of this in your notebook.”;
increase score by 1;
choose a blank row in the Table of Notes;
change timestamp entry to the time of day;
change item entry to t;
change detail entry to d.

[ Examine or Read notebook willl display a list of times, items, but omits detail ]
Instead of examining notebook:
if the number of filled rows in the Table of Notes is 0:
say “Alas your notebook is empty. You still need to find some clues.”;
else:
say “The notebook contains [the number of filled rows in the Table of Notes] entries:[line break]”;
repeat through the Table of Notes:
say " [timestamp entry] - [item entry] - [detail entry][line break]".

Instead of consulting notebook about something:
Repeat through Table of Notes:
if the topic understood includes item entry:
say “[item entry] - [Detail entry][line break]” instead;
[
[ enable user to look up by time, just in case ]
[ Every wording I can think of for this produces an error: ]
if the player’s command includes timestamp entry:
say “[timestamp entry] - [item entry] - [Detail entry][line break]” instead;
]
[ This never matches! ]
say “There’s nothing that matches that item exactly.”

When play begins:
Note “matchbook” with “Has Tony’s phone number CH 2481.”;

test me with “look up matchbook in notebook”[/code][/spoiler]

And here’s the relevant lines, unspoilered:

Instead of consulting notebook about something: Repeat through Table of Notes: if the topic understood includes item entry: say "[item entry] - [Detail entry][line break]" instead;

I would love it if someone could explain why this doesn’t work, or how to make it work, or how to write a “topic literal” in order to add it to a table.

In the meantime, I thought of a couple alternatives.

Here’s the first. Instead of trying to use texts or topics, create a kind of thing called a subject. That’s how Epistemology does it, and Conversation Framework uses that to create new “quizzing it about” and “informing it about” actions to replace the topic-based ask/tell actions. I used the same approach here to replace consulting it about, but I’ve also created a special verb for looking up times.

[spoiler][code]Study is a room. The player carries a notebook.

a subject is a kind of thing. [borrowed from Epistemology]

matchbook is a subject. [if there were an actual matchbook in the game, you wouldn’t need this line]

looking it up in is an action applying to one visible thing and one thing.
Understand “look up [any thing] in [something]” as looking it up in.
Understand “consult [something] on/about [any thing]” as looking it up in (with nouns reversed).
Understand “read about [any thing] in [something]” as looking it up in.
Understand “read [any thing] in [something]” as looking it up in.

check looking something up in when the second noun is not the notebook:
say “You can only look things up in your notebook.” instead

check looking something up in the notebook:
unless there is an item of the noun in table of notes:
say “There is nothing that matches that item exactly.” instead

carry out looking something up in:
choose row with an item of the noun in table of notes;
say “[item entry] - [Detail entry][line break]”;

chronologically-seeking it in is an action applying to one time and one thing.
Understand “look up [time] in [something]” as chronologically-seeking it in.
Understand “consult [something] on/about [time]” as chronologically-seeking it in (with nouns reversed).
Understand “read about [time] in [something]” as chronologically-seeking it in.
Understand “read [time] in [something]” as chronologically-seeking it in.

check chronologically-seeking when the second noun is not the notebook:
say “You can only look notes up in the notebook.” instead

check chronologically-seeking when the second noun is the notebook:
unless there is a timestamp of the time understood in the table of notes:
say “There is no note for that time.” instead

check consulting the notebook about something:
say “There is nothing that matches that subject exactly.” instead

carry out chronologically-seeking:
choose row with a timestamp of the time understood in table of notes;
say “[timestamp entry] - [item entry] - [Detail entry][line break]”;

Table of Notes
timestamp item detail
a time a thing some text
with 50 blank rows

[ Items in the notebook will be stored by unique item and only recorded once.
This makes it easier to have multiple sources giving the same clue.
First time, alert the reader that player he has found a clue. ]
To note (d - some text) about (t - a thing):
if the number of blank rows in the Table of Notes is 0:
say “>>Warning: the notebook is now full. (Please file a bug report.)”;
rule succeeds;
[ Note: Check to see if the clue is already in the notebook, if so, disregard. ]
if there is an item of t in the Table of Notes:
rule succeeds;
else:
if the number of filled rows in the Table of Notes is 0:
say “You decide to take a note of this in your notebook.”;
increase score by 1;
choose a blank row in the Table of Notes;
change timestamp entry to the time of day;
change item entry to t;
change detail entry to d.

[ Examine or Read notebook willl display a list of times, items, but omits detail ]
Instead of examining notebook:
if the number of filled rows in the Table of Notes is 0:
say “Alas your notebook is empty. You still need to find some clues.”;
else:
say “The notebook contains [the number of filled rows in the Table of Notes] entries:[line break]”;
repeat through the Table of Notes:
say " [timestamp entry] - [item entry] - [detail entry][line break]".

When play begins:
Note “Has Tony’s phone number CH 2481.” about matchbook;

test me with “read notebook/look up matchbook in notebook/look up 9:00 in notebook”[/code][/spoiler]

Another alternative would be to use a topic-based table, but instead of adding rows as you need them, create a “recorded” or “known” column in the table that hides entries when they’re not yet known. You might even be able to get away with using the timestamp column - set all timestamps blank, and then set them to the time of discovery when they’re activated.

A similar approach would be to have two tables, one complete and one empty, and you would copy entries from the complete table when they’re added to the notebook.

Thanks again for looking into this with me. I decided to try to code the Table of Notes as a static table with a topic column, as you suggested. It is pre-filled with all of the relevant topics and clues and I set the timestamp with a default value of 1:00 pm to indicate a clue is not yet discovered. Then as the user uncovers clues, I call a subroutine called Note passing the topic & text. If it’s found in the table, I set the time to the actual time, which will be much later, to make the clue visible in the notebook.

Unfortunately, I have run into equally vexing problems with this approach.

  1. I can’t find the clues in the table to make them visible
  2. I can’t print the topics in the table

I think the error is related to the fact that I’m trying to pass a string argument into a Note subroutine and look it up as a topic. But after 5+ hours and many code variations, I can’t for the life of me figure out the right way to do this. But it’s clear that the string is not being passed properly; “topic understood” is not valid in the Note subroutine. Here’s the code in a shortened form:

[ I'm stuffing one clue in the table to be visible during testing ]
number of found clues is a number that varies.
When play begins: now number of found clues is 1. 

[ Static table with 1 found clue to start; unfound clues have timestamp 1:00 pm]
Table of Notes
timestamp	topic	detail
1:00 pm	"Matches/Matchbook"	"From the Brass Lantern Tony -- CH 2481."
1:00 pm	"Alan Hugo's Motive"	"Financial problems...?"
1:00 pm	"News report"	"Klaus Fuchs worked at Los Alamos Laboratory..."
1:00 pm	"news/newspaper"	"Alan Hugo also worked at Los Alamos."
9:30 pm	"fish"	"This is a red herring."

[ This gets called later with a topic and string, e.g.
      Note "Matches" with "From the Brass Lantern Tony -- CH 2481.";
  How do you pass a string in to a subroutine to treat it like a topic? 
]
To note (topic - some topic) with (dd - some text):
	[ Topic understood appears to be nil -- runtime P39 if I try to print it ]
	[ say ">>Topic understood is: [topic understood] [line break]"; ]
	[ This next condition never matches --  ]
 	if the topic understood is a topic listed in the Table of Notes:	
		if the number of found clues is 0:
			say "You decide to take a note of this in your notebook.";  
		increase score by 1; 
		increase number of found clues by 1;   
		change timestamp entry to the time of day;
	else:
		say ">>Warning: Clue not found: [dd][line break]". 
                [ How do I print the topic to help with debugging?]

[ Examine or Read notebook willl display a list of times, topics  ]
Instead of examining notebook:
	if the number of found clues is 0:
		say "Alas your notebook is empty.  You still need to find some clues.";
	else:
		say "Notebook has [the number of found clues] entries:[line break]";
		repeat through the Table of Notes:
			if timestamp entry is not 1:00 pm:
				say "  [timestamp entry] - [detail entry][line break]".  
				[How do you print the topic entry which is what I want? ]

[ From Jim Aiken's Handbook using Topic tables  ]
Instead of consulting the notebook about something:
	if the topic understood is a topic listed in the Table of Notes:
		if timestamp entry is not 1:00 pm:
			say "You read the entry on [the topic understood]:[line break]";
			say "[detail entry][line break]";
		else:
			say "Nothing visible in the notebook on [the topic understood].";
			[ This is just for debugging purposes.  ]
	else:
		say "There's nothing in the notebook on [the topic understood]."

I can print the notebook and consult the notebook on topics, but when I try to make a clue visible, it does not seem to be able to find the entry in the table; it always tells me the clue was not found.

   [ This always results in "Warning>> Clue not found: " ]
   note "Matchbook" with "From the Brass Lantern Tony -- CH 2481.";

If anyone can help me figure out a solution here, I would be tremendously grateful. I’m about ready to tear my hair out on this one.

Inform7 seems like a great language, but I am frustrated beyond belief that something so simple should take so many hours of trial and error. Nor can I find any documentation that says how to do something fairly basic like print a topic or do some kind of typecast operation to convert a topic to text or vice verse.

–Zack

As usual I’m not positive about this. But I think the basic problem with the last attempt is that the relation of being listed in a table only matches a so called snippet with a topic (the topic understood actually stores a snippet). Neither snippets nor topics are text. So what you want is a note-phrase that passes text to a subroutine that should treat it as a snippet. I’m not sure if that is possible.
Apparently snippets are meant to point to one or more words in the player’s commands.
If you defined a noting action (rather than a note-phrase) applying to one topic, the topic understood would store a snippet that could be tested for being listed in the Table of Notes.
However, it also works if the source text rather than the player calls the action in question.

How well the following suits your needs I can’t tell, of course; but it seems to do more or less what you want:

"More clues" by Zack

The Venue  is a room.
The player carries a notebook.
A newspaper is a thing in the Venue.

[ I'm stuffing one clue in the table to be visible during testing ]
number of found clues is a number that varies.
When play begins: now number of found clues is 1. 

[ Static table with 1 found clue to start; unfound clues have timestamp 1:00 pm]
Table of Notes
timestamp	topic	detail
1:00 pm	"Matches/Matchbook"	"From the Brass Lantern Tony -- CH 2481."
1:00 pm	"Alan Hugo's Motive"	"Financial problems...?"
1:00 pm	"News report"	"Klaus Fuchs worked at Los Alamos Laboratory..."
1:00 pm	"news/newspaper"	"Alan Hugo also worked at Los Alamos."
9:30 pm	"fish"	"This is a red herring."

Instead of reading the newspaper:
	try noting "newspaper".

[ This gets called later with a topic and string, e.g.
      Note "Matches" with "From the Brass Lantern Tony -- CH 2481.";
  How do you pass a string in to a subroutine to treat it like a topic? 
]
Noting is an action applying to one topic.
Understand "note [text]" as noting.

Carry out noting:
   [ Topic understood appears to be nil -- runtime P39 if I try to print it ]
   [ say ">>Topic understood is: [topic understood] [line break]"; ]
   [ This next condition never matches --  ]
	if the topic understood is a topic listed in the Table of Notes:
		if the number of found clues is 0:
			say "You decide to take a note of this in your notebook.";  
		increase score by 1; 
		increase number of found clues by 1;   
		change timestamp entry to the time of day;
		rule succeeds;
	else:
		say ">>Warning: Clue not found about [topic understood][line break]".                [ How do I print the topic to help with debugging?]

[ Examine or Read notebook willl display a list of times, topics  ]
Instead of examining notebook:
	if the number of found clues is 0:
		say "Alas your notebook is empty.  You still need to find some clues.";
	else:
		say "Notebook has [the number of found clues] entries:[line break]";
		repeat through the Table of Notes:
			if timestamp entry is not 1:00 pm:
  				say "  [timestamp entry] - [detail entry][line break]".  
            [How do you print the topic entry which is what I want? ]

[ From Jim Aiken's Handbook using Topic tables  ]
Instead of consulting the notebook about something:
	if the topic understood is a topic listed in the Table of Notes:
		if timestamp entry is not 1:00 pm:
			say "You read the entry on [the topic understood]:[line break]";
			say "[detail entry][line break]";
		else:
			say "Nothing visible in the notebook on [the topic understood].";
         [ This is just for debugging purposes.  ]
	else:
		say "There's nothing in the notebook on [the topic understood]."

Some aspects of Inform are very hard to find out about in the documentation – great as it is.

Felix,
thank you this is very helpful. There’s only one issue that puzzles me is how to print the topic when examining the notebook. Right now I can print the [detail entry] ok, but what I really want is the [topic entry] or [topic understood]. I sort of understand why Inform doesn’t want to print it, since a topic is more complex than a string.

Instead of examining notebook: if the number of found clues is 0: say "Alas your notebook is empty. You still need to find some clues."; else: sort the Table of Notes in timestamp order; say "The notebook has [the number of found clues] entries:[line break]"; repeat through the Table of Notes: if timestamp entry is not 1:00 pm: [ topic understood is nil - causes runtime error p39] say " [timestamp entry] - [topic understood][line break]". [How do you print the topic entry? ]
So in order to just get on with the rest of my coding, I’ve added an extra column called key which is plain text equivalent to the topic. No doubt there’s a better way to do this, but for now I guess it is not the worst thing in the world.

Thanks everyone for your help. Much appreciated.
The world somehow seems sunnier today. :wink:
–Zack

There’s some other old posts that might be helpful here. (I don’t have any firsthand experience with any of this, but I remembered some of the posts and looked them up).

This topic discusses why you can’t just print the topic – it’s a function, which I think means it could potentially include things like “paper/newspaper,” and you can’t print that. It sounds like the preferred solution is what you’re going to do – include an extra text column that repeats the topic.

Here’s a cool kludge for turning text into a snippet, if you want to do that.

I’m probably not going to be a bit of help here. I’ve never mastered the use of tables in I7. Tables strike me as one of the most awkward implementations I’ve ever seen. I sincerely hope that Graham Nelson reads this entire thread and takes it under consultation.

That said, you may be on the right track in making the entries in the notebook subjects rather than raw text. A subject is just an object (and there’s a sentence that would make a grammarian shudder). The subject will have a name (which you can print), vocabulary (so the player can use the write about and look up actions flexibly), and a text (the text of the noted clue). You might not need multiple columns in a table, just one column that either does or doesn’t have a subject entry in it.

Come to that, I’m not sure you need a table at all. Just give each subject a number (the notebook-order number) and set it to -1 as a default. When a subject is entered in the notebook, change its notebook-order number. When the player tries to look up something or write something in the notebook, all you have to do is check whether the notebook-order of the subject is -1. Each time a new subject is entered in the notebook, give it a notebook-order value that is one higher than the previous one (which you would have to check on the fly).

That would be how I would try designing it, anyhow. If I have time tonight, I’ll try roughing it out.

–JA

I don’t think the problem is with tables per se–to my mind, they’re pretty darn straightforward, as evidenced by how easily newcomers learn to use (and probably overuse) them. I’m guessing that the difficulty you’re referring to comes with matching the melange of different types that all look like text (topic, snippet, text, indexed text, etc.) This often happens in tables because the manual suggests topic columns as a good way to organize data. And they would be, except for all the contortions an author can be forced into in using them (as illustrated by the progression of this thread).

The profusion of “textual” types is what really could use an overhaul, in my opinion. Unfortunately, there’s a sense in which that overhaul would mean redesigning much of the system…

Given which, maybe the most practical solution is better documentation that gives users better insight into exactly what the data structures are, why they’re incompatible, and how to effectively typecast between them.

–Erik

Well, yeah, that too. But I tend to fumble around with tables, because I’ve never properly grasped the syntax with which one would look up an item in a table and then use it.

Here’s another way of creating a notebook that can record the detective’s clues. I avoided using tables. This may or may not meet the design criteria. Also, it relies on the author to make sure that every suspicious item has a clue as part of it.

You have to be in the presence of an in-game object to jot down the clue. This may be limiting.

This doesn’t give the player the option of jotting down their own clue information. If you want to do that, you could try adapting my Notepad extension.

[code]The Kitchen is a room. “If nothing else, the food in this kitchen is a crime.”

A table is in the Kitchen.

Section - Items

A clue is a kind of thing. A clue is always privately-named. A clue has a number called the note-number. The note-number of a clue is usually -1.

A suspicious item is a kind of thing.

On the table are a carving knife, a mackerel, and a lemon merengue pie. The pie is edible. The knife is a suspicious item. The mackerel is a suspicious item. The pie is a suspicious item. Understand “fish” as the mackerel. The description of the knife is “It looks quite sharp.” The description of the mackerel is “Quite dead, and not holy at all.” The description of the pie is “Clearly toxic.”

The player carries a notebook. Understand “clues” and “notes” as the notebook.

The knife-clue is a clue. The knife-clue is part of the carving knife. The description is “carving knife: Could have been used to stab Professor Plum”.

The fish-clue is a clue. The fish-clue is part of the mackerel. The description is “mackerel: Could have been used to bludgeon Miss Scarlet”.

The pie-clue is a clue. The pie-clue is part of the lemon merengue pie. The description is “lemon merengue pie: Could have been used to poison Colonel Mustard”.

Section - Actions

Note-taking is an action applying to one visible thing and one thing. Understand “write about [any thing] in [something]” as note-taking.

Check note-taking:
if the second noun is not the notebook:
say “You can’t write in [the second noun].” instead;
otherwise if the noun is not a suspicious item:
say “You can’t write that up in the notebook.” instead;
otherwise:
let C be an object;
repeat with found-it running through clues:
if found-it is part of the noun:
now C is found-it;
if the note-number of C is not -1:
say “You’ve already written your notes about [the noun] in the notebook.” instead.

Carry out note-taking:
let N be a number;
let N be 1;
let S be an object;
repeat with recorded running through clues:
if the note-number of recorded is not -1:
increase N by 1;
if recorded is part of the noun:
let S be recorded;
now the note-number of S is N;
say “You write: ‘[description of S]’ in your trusty notebook.”

Understand the command “read” as something new.

Clue-consulting is an action applying to one thing and one visible thing. Understand “consult [something] about [something]” as clue-consulting. Understand “look up [any thing] in [something]” as clue-consulting (with nouns reversed). Understand “read about [any thing] in [something]” as clue-consulting (with nouns reversed).

Check clue-consulting:
if the noun is not the notebook:
say “You can’t look up anything in [the noun].” instead;
otherwise if the second noun is not a suspicious item:
say “You haven’t written anything about [the second noun] in your notebook.” instead;
otherwise:
let found-it be a truth state;
let found-it be false;
repeat with recorded running through clues:
if recorded is part of the second noun and the note-number of recorded is not -1:
now found-it is true;
if found-it is false:
say “You haven’t written anything about [the second noun] in your notebook.” instead.

Carry out clue-consulting:
say “Consulting your notebook, you find the following entry for [the second noun]: [run paragraph on]”;
let C be an object;
repeat with recorded running through clues:
if recorded is part of the second noun:
now C is recorded;
say “‘[description of C].’”

Reading is an action applying to one thing and requiring light. Understand “read [something]” and “consult [something]” as reading.

Instead of reading something:
say “Nothing is written on [the noun].”

Instead of reading the notebook:
let N be a number;
let N be 0;
repeat with recorded running through clues:
if the note-number of recorded is not -1:
increase N by 1;
if N is 0:
say “Nothing has yet been recorded in the notebook.”;
otherwise:
say “In the notebook you find the following entries: [line break]”;
repeat with recorded running through clues:
if the note-number of recorded is not -1:
say “[description of recorded].[line break]”.[/code]

Hope that helps!

–JA

On further investigation, that code didn’t work as desired, because I forgot a couple of “[any thing]” specifications. It should be all better now.

–JA

I, for one, certainly find it quite confusing.

And I’d love that.

I found a discussion of some of it in Inform 7 for Programmers, which did explain things. But I would very much like to see such things explained in the official documentation, too. After all Ron’s tutorial is explicitly aimed at people with programming experience whereas Inform 7 strives to be accessible also to people with none.

Jim, Felix, ektemple et al,
thanks everyone for your additional suggestions, code samples etc. As the newbie who kicked off this thread, I greatly appreciate everyone’s willingness to help out. I have gone with an implementation based on Felix’s suggested code (which is nicely succinct) and a second largely redundant text column for printing purposes. This is probably much less elegant than other solutions, but it works, fits my design needs and I understand it.

While I’m a newcomer to Inform, I have done other programming projects over the years and at one time was a good (but not great) programmer in C, Pascal, etc for Windows GUI applications. I also taught object-oriented and event-driven programming, wrote articles for programming magazines and helped create Delphi in a prior life at Borland. And still, I was stumped by all of this. (Or maybe that’s why I was stumped.)

There are great examples in the Inform7 docs and the third party books are excellent. But as a traditionally schooled programmer, it feels to me that Inform7 is a bit of a black box in some areas performing all kinds of crazy magic behind the scenes that often you don’t have to worry about, except when something doesn’t work as you expect. It’s impressive and cool but it is not at all clear to me that the rules and patterns that define good Inform7 programming best practices have been documented beyond a large (possibly infinite) number of code samples. To me that makes the learning curve much tougher than it should be.

If there was a more definitive reference manual that covered language grammar and code libraries and explained what was going on more authoritatively that would be very helpful to those who have some programming experience or whose skills have gone beyond the basics. And I would gladly buy such a book or donate $$$ to it on Kickstarter.

Maybe it’s impossible for a system as rich and broad as Inform7 to have a definitive reference manual as understandable as a classic book like “The C Programming Language” (Kernighan & Ritchie on C) but I don’t know how you ever get beyond anecdotal trial & error learning without it.

And I still have the question: How do you convert between Text and Topic types? How do you convert between types in general?

Note that I am not trying to be critical of Inform7. It’s a fantastic tool and I hope I am able to continue with this project without running into too many roadblocks. Better documentation and a more systematic treatment of some topics could go a long way towards making it even more accessible.

–Zack
z-machine-matter.com

You have a very good point, Jim. There’s no need for this stuff to be in a table at all except for the matter of ordering. Everything about a note could be added as a property of the subject. Even if you did have a table, it could be a single-column table that just lists the order in which subjects were discovered.

I said the exact same thing, including a comparison of current I7 documentation with K&R, about two months ago. If only identifying the need were enough to make such a thing happen! Thankfully, since then I’ve been the beneficiary of a large volume of arcane knowlege shared by people on this forum, and Inform is starting to feel a little less like a black box. Hopefully the same thing will happen to you as you receive suggestions for problems such as this. And eventually I think it may be possible that such a document will come into being when the structure of I7 settles down.

But let’s keep the table-effacement rolling: why use a table for a single column of data? A list is more natural if you only need one dimension. You can even format lists with internal carriage returns and spacing, if you want one item per line as in a table:

{ "Hunger", "Thirst", "Blindness" }

–Erik

I’m strictly a hobbyist programmer, but from what little I recall of C, it seems to me Inform is quite a bit more complex than C. Less complex than writing an app in C that includes the full range of OS function calls … somewhere in the gray area between the two.

After skimming Ron’s guide for programmers and leafing through various chapters in Aaron’s book, it seems to me that what’s needed is for someone to chop up those two texts, my own modest Handbook, and the built-in documentation and use the raw material to carefully construct a single coherent manual. If I can say this without disrespecting any of said authors (Ron, Aaron, Graham, Emily, and myself), it strikes me that what we have here is a case of the blind men and the elephant. If you go through all of these documents and then spend a few months coding by trial and error and posting messages on the newsgroup or this forum, you’ll find that you’re developing a comprehensive mental model of the beast, based on several fragmentary views.

A single comprehensive manual on I7 would, I’d guess, be more than a thousand pages long – and who would have the patience to read it? Maybe in the real world, what we have isn’t too bad.

–JA

That’s why an excellent reference book is needed. A linear manual should give just enough information so that people will know where to look in the reference.