a link is a kind of value.
the links are defined by the table of linking.
table of linking
link priority reflexive printed input
take-link 9 false "take it" "take [frob]"
place-link 10 false "place it" "place [frob] on"
in my program, I am cycling through a list of things. Right now, there is some pretty laborious code for running through a table to determine the valid links for each thing in the list:
let placeholder be a list of links;
repeat with E running from 1 to the number of filled rows in table of linking:
choose row E from table of linking;
if link entry is take-link and frob is takeable, add link entry to placeholder, if absent;
if link entry is drop-link and frob is droppable, add link entry to placeholder, if absent;
truncate placeholder to four entries;
decide on placeholder;
what I’d like to do is associate each link with its relevant property and push to an if link entry is valid, add link entry to placeholder to avoid a long string of if link entry is... add link code to this project.
However, if there is a way to do it, I haven’t arrived at it yet. I don’t think a table will accept a calculated property, ie something like takeability of frob .
A table can accept named phrases, but I don’t think you can (or at least I don’t know how to) do that with a table also used for definitions. I don’t know how you’ve defined “takeability” but this is what I came up with based on what you’ve posted so far:
This is kind of a hack, but you can store text in a table, and text can do anything a phrase can do!
"[if takability of frob is true]1"
This will be empty if the condition is false, and non-empty if it’s true. Texts can’t quite do everything closures can do (since they don’t capture their scope), but they can do a lot of it!
OK! Both of these suggestions are great. I don’t think I ever knew that I could name a phrase in this way.
With regard to the text, I spent a lot of time trying to wedge a number in there, but I never thought about just putting a condition text in a field. I’ll experiment a bit and come back.
This isn’t what you asked for, but I might also recommend using a rulebook instead of a table, because then you can control the order of the rules and put arbitrarily complex code in them. (“Link rule for a portable thing…”)
Would the rule be generating output? Right now (this is for a command bar), I’m printing up to four links (based on relevance (takeability, etc) and the author’s prioritization) with spacing between.
The rule could print things, or it could append them to a list (a rulebook variable), as desired. If you only want four links per object, appending is probably better.
Like @BadParser said, but dispense with placeholding and use only one table. Untested…
Table of linkable actions
condition label command
[...]
To generate command bar:
repeat with t running through things enclosed by the location begin;
let count be 0;
say "[t]: ";
repeat though the table of linkable actions begin;
if the condition entry applied to t is true begin;
hyperlink "[label entry]" as "[command entry] [t]";
increment count;
if count is link-limit, break;
end if;
end repeat;
if count is 0, say "(no relevant actions available)";
end repeat;
In the course of working on this, I had an idea that I might make an extension for people to use. I’ve been working with that in mind, hoping to help authors configure things as they go.
One concern that I had was that, in a game with several valid actions, the author needed control over which links appeared in the command bar. I saw this working two ways:
Global Priority. When iterating through links, it should print them based on both relevance (what we are discussing) and a configurable priority.
Noun-specific priority override. An author should be able to override the global table for specific nouns. Take the squeeze bottle in Plundered Hearts, for instance. Squeeze might be a low priority link globally, but it may become high priority for the bottle once its function is discovered.
I could shift gears away from values (links) and toward named phrases, but I feel like I’d need to add some complexity somewhere else. It’s too bad named phrases aren’t allowed in a definition table. That was what exactly what I was looking for. I have already thought of another use for named phrases in tables, though, so that was a bit of an ah-ha moment!
I just want to get this cloak of darkness port out the door, but I will revisit all of this before I release the extension.
That’s part of why I think a rulebook might be fitting. If you want SQUEEZE BOTTLE to be a high priority, you can write one rule for squeezing things in general, and a separate rule for squeezing the bottle; the latter can be a higher priority because it’s more specific or because it has “first” attached.
I’m definitely going to have a look at using a rulebook, or a bigger rulebook. I’d obviously learn more that way, but I also want to come up with something a beginning author can use without needing to understand how everything works.
If the single priority value on a per-action basis is good enough for the normal case and needs overriding only for particular thing/action combinations (perhaps under specific circumstances) then a rulebook on things producing a number is probably in order. You’ll need a global to “pass” an identifier for the action to the rulebook since rulebooks can only have 0 or 1 parameters. That identifier could be an action name (you’d probably want to add a column for this to the table of linking) or it could just be the value of the link column itself.
A fairly easy way to store results for consideration would be to add another column for score to the table of linking. At the beginning of considering a thing, set score to 0 for all rows. Then loop through the table, leaving score at 0 if the condition doesn’t pass. If it passes, set it to priority but then check the scoring rulebook, and set the result if it produces one. Then reorder the table by descending score and make hyperlinks for up to the first 4 rows with non-zero scores. You could keep restoring the table order to a consistent known order, but it wouldn’t really matter.
It sounds goofy, but if you compare it to creating a list of 2-element lists so you could sort that by score it starts to look better.
This (and Daniels’s suggestion, too) have me interested in a rulebook approach. I haven’t made a rulebook producing a result before, but I’ve looked at the docs and it makes sense. So I’ll try that and report back. Thanks everyone for the help!
A bump, since this quesiton probably only makes sense in this context.
What belongs between the parentheses beside the “cond” column label? I’ve experimented with “phrase” and “phrase name” and “named phrase”.
Table of Link Conditions
cond (??????) link (a link)
takeability take-link
dropability place-link
As a reminder, “takability” and “dropability” are the names of definition phrases, as in
To decide if (T - a thing) is takeable (this is takeability):
unless T is carried:
if T is portable and T is touchable:
decide yes;
decide no.
The kind of “takeability” is actually not “phrase” but “phrase thing -> truth value”. (Graham Nelson is a mathematician and this is based on the way function types are usually written in type theory.)
If you use a definition instead of a phrase, then “takeable things” would be a “description of things”, which I generally find easier to work with than phrase kinds. Unfortunately there are some bugs around description kinds in I10 at the moment.
I prefer definitions, too. I’m trying to redo the command bar design to use rules instead, and I’ve noted that hyperlink formatting doesn’t not always survive after iterating through lists or tables. One idea I had was this: why not associate the links with objects rather than table values, since texts associated with them do not seem to have such problems.
I haven’t finialized a design; this is just experimentation. I’ve noted that I cannot do things like this (or else I am doing them wrong).
a hyperobject has a description of values called the criterion.
[or]
a hyperobject has a phrase thing -> truth value called the criterion
So perhaps the only was to make an association is through a table? Or it is at least the only way I can currently see.
I may just have to drop it. There’s no mention of phrase things in the documentation, so I don’t really have a way to move forward with this. My goal had been to avoid keeping link data in both tables and objects, but maybe I can’t do that at my current knowledge level.
As Daniel and Zed said, phrases are essentially functions here. In the case of phrases like the this is takeability one, they take a thing as input and return a truth state as output (so their type is: a phrase from thing to truth state; thing → truth state).
I don’t know if it helps with the current undertaking, but you could, for example, do something like this:
The Lab is a room.
A hyperobject is a kind of thing.
A hyperobject has a list of phrases thing -> truth state called the criteria.
To decide if (T - a thing) is takeable (this is takeability):
unless T is carried:
if T is portable and T is touchable:
decide yes;
decide no.
To decide if (T - a thing) is droppable (this is droppability):
if T is carried, decide yes;
decide no.
To decide if (T - a thing) is movable (this is mobility):
if T is fixed in place, decide no;
decide yes.
The widget is a hyperobject in the Lab.
The boulder is a hyperobject in the Lab. It is fixed in place.
The criteria of a hyperobject are usually {takeability, droppability, mobility}.
After examining a hyperobject:
repeat with C running through the criteria of the noun:
if C applied to the noun is true:
say "Criterion [C] is fulfilled.";
[do what's necessary in your system to insert links for the actions here]
otherwise:
say "Criterion [C] is not fulfilled.";
Result:
Lab
You can see a widget and a boulder here.
>x boulder
You see nothing special about the boulder.
Criterion takeability is not fulfilled.
Criterion droppability is not fulfilled.
Criterion mobility is not fulfilled.
>x widget
You see nothing special about the widget.
Criterion takeability is fulfilled.
Criterion droppability is not fulfilled.
Criterion mobility is fulfilled.
>take widget
Taken.
>x widget
You see nothing special about the widget.
Criterion takeability is not fulfilled.
Criterion droppability is fulfilled.
Criterion mobility is fulfilled.