Ack..Two topics....sorry....Trouble with Tables

Sorry! But I’m really stuck with this.

Following code:

[code]t_stage is a number that varies. t_stage is 1.

After reading a command when the tutorial_mode is true:
if the player’s command matches the TR1 in row t_stage of the Table of Tresponses
begin;
say_next_tutorial;
end if;
increase t_stage by 1;
reject the player’s command;

To say_next_tutorial:
if t_stage is 1, say “first text”;
if t_stage is 2, say “second text text”;
if t_stage is 3, say “third text”.

Table of Tresponses
TR1
“take book”
“examine book”
“read glossary”
[/code]

I’m getting the abject failure message as follows :
An internal error has occurred: tried to set associated kind for wrong spec. The current sentence is ‘if the player’s command matches the TR1 in row t_stage of the Table of Tresponses begin’ ; the error was detected at line 322 of “inform7/Chapter 20/Specifications.w”. This should never happen, and I am now halting in abject failure.

I can’t for the life of me work out what I’m doing wrong…

I see a couple of things wrong.

First, you need to declare tutorial_mode as a value that varies (maybe you did this in another part of the code that you didn’t copy here; anyway it’s worth mentioning):

tutorial_mode is a truth-state that varies. tutorial_mode is true.

Second, when you’re matching text strings against the player’s command, you can’t just use any old text string; you have to use a special kind of string called a “snippet”. And the only way to store a bunch of snippets in a table is to use the column heading “topic” (this is another somewhat unintuitive part of Inform; sorry). I think this is actually what is causing your abject failure message.

Finally, your code is incrementing t_stage by 1 every turn, whether it matches the player’s command or not. That means that it’s checking a different row of the table each turn, and after 3 turns you’re going to get a runtime error because you’ll have run out of rows. Correct me if I’m wrong, but it looks like what you actually want to do is check the player’s command against the whole table each turn, and if you find a match, [i]then[i] you 1) print a message, 2) increment t_stage, and 3) reject the player’s command.

So that would look like this:

[code]After reading a command when the tutorial_mode is true:
repeat with N running from 1 to the number of rows in the Table of Tresponses:
choose row N in the Table of Tresponses;
if the player’s command matches the topic entry:
say_next_tutorial;
increase t_stage by 1;
reject the player’s command.

To say_next_tutorial:
if t_stage is 1, say “first text”;
if t_stage is 2, say “second text text”;
if t_stage is 3, say “third text”.

Table of Tresponses
topic
“take book”
“examine book”
“read glossary”[/code]

Thanks Mike, I had done the other two, but the bit I was missing was ‘snippet’ and the topic thing. Thanks again.

McT

Mike has already posted this but a few things, since I already wrote out a response:

  1. The abject failure message is a bug (abject failure messages always are). It should be giving you a nicer error message.

  2. Strictly speaking, snippets and topics aren’t the same thing. “The player’s command” is a snippet, and the thing you match it against is a topic. See Writing with Inform §18.33 on this syntax.

  3. The reason that topics are different from just plain texts is that you can actually do more sophisticated parsing stuff in topics. So you could make one of your topics “x/examine book” and either “x book” or “examine book” will match against it–kind of like when you Understand “gray/grey mouser” as the Grey Mouser, and it allows for either slashed alternative.

  4. Nevertheless, this is still super unintuitive.

  5. It seems to me as though, contrary to what WI §16.13 says about topic columns, you don’t actually have to call the column “topic” for Inform to realize that it’s topics. You can also explicitly declare it as a topic, like so:

Table of Tresponses TR1 (topic) "take book" "examine book" "read glossary"

But it is definitely true that if you don’t explicitly declare it or call the column “topic,” Inform will assume those are texts.

  1. I think you might not want to run through the whole tutorial table every turn–if the player types “examine book” before “take book” maybe you don’t want that response to run. The issue is going to be partly that you should only implement t_stage if you’ve successfully matched the current t_stage, so you should move the “increase t_stage by 1” line up 1 to inside the block where you’ve tested “if the player’s command matches…”

Quite so. Thanks for catching my goofs, Matt.