Defining topics outside of a table?

Given what I knew about topics, this code looked like it should work in 6M62, but it didn’t:

Wet Wood is a room.

a room has a topic called reject-topic.

reject-topic of wet wood is "whet/would".

after reading a command:
    if the player's command includes reject-topic of location of player:
        say "(1) Homonyms aren't quite what you want.";
        reject the player's command;

However, this works:

Wet Wood is a room.

after reading a command:
    repeat through table of reject-topics:
        if loc entry is location of player and if the player's command includes top entry:
        say "(2) Homonyms aren't quite what you want.";
        reject the player's command;

table of reject-topics
loc	top (topic)
Wet Wood	"whet/would"

The solution above is more than acceptable, but I’m curious: is there any way to meaningfully include topics outside of tables, and if not, is there any good quick and dirty explanation? I suspect it may have something to do with the problem of having an empty topic, but I don’t have the technical knowledge to nail things down. Thanks!

1 Like

You can define a topic ad-hoc by using a quoted string in a topic context. For example, in this rule:

After reading a command:
	if the player's command matches "foo":
		say "It was foo.";

The phrase is defined as if (S - a snippet) matches (T - a topic), so the compiler knows to compile the literal string “foo” as a topic.

This is deliberately narrow; you can’t define topics as values in most of the places you define values. For the most part, topics only appear in tables.

1 Like

This sometimes leads to very weird behavior that I would consider a bug. (Example output is from 6L38.)

Lab is a room. Ethan is a man in the lab.
A room has a topic called the local-topic.
The local-topic of the lab is "test topic".
Instead of answering someone that when the topic understood matches the local-topic of the location: say "Matched!".
>say test topic
(to Ethan)
*** Run-time problem P29: Attempt to see if a snippet of text matches something which is not a topic.
>showme lab
Lab - room
[…]
local-topic: 581589

I honestly have no idea what’s going on here; it’s not storing “test topic” as a string (strings get printed literally in showme output), but apparently it’s not storing it as a topic either? The runtime type system in Inform is somewhat of a mystery to me.

I might be totally wrong, but could the cryptic number be the address of the routine representing the topic ? (topics are routines at the I6 level, right ?)

There were some changes in 6M62, although I don’t know how much there are related to Draconis’ issue. Relevant ones seem to be the following.

A clarification: a list is sayable if and only if its contents are sayable. In previous builds lists were always sayable, but would produce meaningless output if the contents weren’t sayable (for example, for a list of topics). [http://inform7.com/changes/CI_2_17.html]

I remember that in 6L38, printing a list of topics would show numbers like you got.

(But then I don’t remember if it was possible to make use of a list of topics. or if you’d encouter the same kind of run-time problem.)

Bug fixed (0001495, 0001425, 0001448) whereby Inform would allow a text value to be assigned to a topic variable, but the result would be an I6 error about a nonexistent routine called TEXT_TY_to_UNDERSTANDING_TY, or in some cases a Glulx virtual machine error. Such assignments aren’t legal, and there’s now a problem message for it. [http://inform7.com/changes/CI_2_17.html]


Returning to the original question, it’s true being able to use topics like that could be really poweful, but it’s always possible to use tables instead.

Regarding empty topics, I guess the default topic could be one that never matches against anything?

That’s what I would assume, but then when it’s called at runtime, the typechecker complains that it’s not a topic. So I’m not sure what else it could be…

The value is a string, but it’s stored illegally in a topic property, so the code behaves inconsistently. The compiler should reject this.