"Dynamic" Descriptions?

I’m trying to understand how to write more efficient code in Inform. In this example, I’m trying to make the description of a person not necessarily have to be written out explicitly, but be inherited from a global default for all person descriptions, but also have differences depending on variables. Specifically, the description of a person includes the items the person is holding.

I know this doesn’t work, and why (“a person” or “the person” doesn’t reference the person in question, but just “any person” in a sense…)

What needs to be done to make a variable that refers to the specific person that is currently being described?

The description of a person is usually "[the printed name of the person][if the person is holding something] is holding [list of things held by the person][end if].";

Nevermind, I think… I think I got it:

The current person is a thing that varies.

Before examining a person (called the person examined):
	now the current person is the person examined;

The description of a person is usually "[the printed name of the current person][if the current person is holding something] is holding [list of things held by the current person][end if].";

This seems to work. Does anyone see any caveats or things that will go awry with this though?

What you’re looking for is “item described”.

The description of a person is usually "[The item described][if the item described is holding something] is holding [list of things held by the item described][end if]."

This is better than a global variable in that a) it saves a global variable and b) it works even when printing the description from code instead of as a response to player-initiated examine action.

Thank you for that. It’s always a journey trying to find that Inform “slang” for something that was already defined!

Now that I have this piece working, I have found a strange issue. If I add more conditions, like wearing and holding together, items that are worn are held… so the item get’s listed in both lists! For example, this might produce “Bob is wearing a pair of pants. Bob is holding a pair of pants.” It is, however, the same pair of pants! How can I prevent this?

The description of a person is usually "[the item described][if the item described is wearing something] is wearing [list of things worn by the item described][end if].[if the item described is holding something][the item described] is holding [list of things held by the item described].[end if]";

Also, a very related question, what if I wanted to replace the second [the item described] with a pronoun? I’ve searched on the term “pronoun” but I am not sure I see a way to do that. Meaning, how can I make this work, so that [he-she-it] is not nonsense?

The description of a person is usually "[the item described][if the item described is wearing something] is wearing [list of things worn by the item described][end if].[if the item described is holding something][he-she-it] is holding [list of things held by the item described].[end if]";

Try using “carried” rather than “held”. There are a few different verbs for holding, which all mean slightly different things. (The most general AFAIK is “to enclose”, which includes carrying, wearing, having-as-a-component-part, or enclosing something which encloses it.)

Sadly, Inform is not very good at writing pronouns. I’ve been working on an extension to remedy this, but it isn’t released yet. For now you might try adapting the example “Odins” from the manual.

For that you need to use the extension Plurality, by Emily Short. The particular substitution you need will be [it-they]. (Well, to get capitalisation right it should be [It-they].)

Oh, does it-they do gender pronouns as well? I did not know that.

Aha, carried is much better, thanks!

This is a great resource. I wish more stuff like this could be part of the standard rules, then I’d know what I was looking for! I get that not everyone needs all the overhead for every project though, but these extension references are great. Works like a charm.

So, it turns out I have more to ask here.

Using the list of items gives the printed name as a list… is there a way instead to get a list of the descriptions of the printed items? I tried something like this, knowing it was wrong, but maybe this will explain what I am trying to do (the difference is “the descriptions of the items in the list of the things worn by the item described”):

The description of a person is usually "[the item described][if the item described is wearing something] [is-are] wearing [the descriptions of the items in the list of the things worn by the item described][end if].[if the item described is holding something][it-they] [is-are] holding [the descriptions of the items in the list of things held by the item described].[end if]";

Is this possible?

You could try something like this.

To say descriptive (L - list of objects): repeat with the item running through L: say " description of the item".

Thank you again! So, you can append a variable to a new text or other object in a rule, and then just put the reference to the object next to the explicit value of the variable and it will cue it to run the rule in context? Wooo… it does seem to work, but I did put this in the right place right? Shouldn’t be any surprises? I only modified it slightly to use a bracketed [description of the item] so it substitutes as expected.

To say descriptive (L - list of objects):
	repeat with the item running through L:
		say "[description of the item]".

Before examining a person:
	instead say "[The item described] [if the item described is wearing something][is-are] wearing [descriptive the list of things worn by the item described].[end if][if the item described is carrying something][It-they] [is-are] holding [descriptive list of things carried by the item described].[end if]";

You’re overcomplicating it. The description is a property of things. Your line

say “[description of the item]”.

…prints out that property, for any given item. When you run it in a loop, you print a bunch of stuff. There’s no rules in this code, just a phrase (function) containing a loop containing a print statement.

Sorry, I seem to have forgotten the brackets. They certainly should be on there.

Ok, now that that is in hand… the next piece of this puzzle is to try to tackle giving the items themselves “dynamic” printed names and descriptions.

So, for example, when you make an item of a kind, by default you have to create a unique name for it, and then that unique name may or may not be nice to display to the player, so you have to create a printed name for it. Is there a better, less manual way to do this?

What I mean is, is there a way to create a specific item without having to explicitly type in a specific name or a printed name for it into the code each time? Why might this be desirable? Well, for one example, a game that generates random loot. If you have a “leather chest piece” kind, for example, and some other function is producing new instances of it programmatically, you can’t manually type in names for each… you have no idea how many will exist in a given game. It will matter which one is which, because the items might have other properties, like say, durability, so which one you pick up matters. I’m still not there on making complex number-based calculations and variables either, so I’m not going to put that into my example as such to distract from the question at hand, so I’m just going to use “adjectives” instead.

The below, quite obviously, doesn’t work, but maybe this pseudo code will help illustrate what I mean. This isn’t the auto-generate loot part, which is probably far more advanced and I’ll get to later, but just the part that would be responsible for naming said auto-generated loot (and all other things). This code is psuedo code, obviously some of it will not be correctly written, particularly as I am still trying to learn values syntax properly as well. Assume that somewhere else in the code, some mechanism for changing the durability of the items is occurring, and each item has a different durability, and that the armors are placed somewhere.

A durability is a kind of value. Durability are perfect, damaged, broken.
An armor is a kind of thing. An armor is wearable. An armor has a durability. An armor's durability is usually perfect.
A leather chest piece is a kind of armor.

[later on these would be generated programmatically, so I'm not sure how to display this properly]
leather chest piece 1 is a kind of armor.
leather chest piece 2 is a kind of armor.
leather chest piece 3 is a kind of armor.

The printed name of an armor is usually "a [durability] [the kind of armor]". The description of an armor is usually "a [durability] [the kind of armor]".

This should produce results like:

look leather chest piece
a damaged leather chest piece

I am aware it could also produce lots of ambiguities, like:

look leather chest piece
which do you mean, a damaged leather chest piece, a damaged leather chest piece, a perfect leather chest piece

(or something like that)

but that is something I’m hoping to resolve with further code, possibly with the extension Numbered Disambiguation Choices by Aaron Reed.

tl;dr
Is it possible to programmatically generate items and the descriptions and printed names for these items based on their kind and values associated with them?

Yes, certainly. You’re on the right track using “kinds” of thing, check out the worked example The Reliques of Tolti-Aph for something close to what you’re writing.

Try this.

Before printing the name of an armor: say "[durability] ". Understand the durability property as describing an armor.

Now it automatically adds the adjective before printing the name, and understands if the player tries to refer to it that way.

This seems to still leave the printed name of the armors as stuff like “broken leather chest piece 1”. I realize that my example may not be very good, because it isn’t fleshed out and the need may not be readily apparent, but though I’m finding it hard to describe why, I know that if I ever get an application to a finished state, I’m going to want functionality that gives these items unique ids, but hides them from the player. I want the player to just see “broken leather chest piece”, sans the 1, but do this programmatically. Adding the durability seems to be able to be done in more than one way, but I’m missing the part where I can make the printed name itself have a token in it like:

the printed name of an armor is "[durability] [the kind of armor]".

The key here is “[the kind of armor]”. This is not the right syntax, Inform doesn’t know what that is. I’m trying to figure out what could be put into a token to reference the “printed name” (not really) of a kind, rather than an instance of a kind. So, I would hope the above would print out something like “broken leather chest piece”. So, I want to take something like this:

A whatever is a kind of whatsit.

And make “whatever” end up as the value of a token like

The printed name of a whatever is "[kind of whatsit]".

In that example, it sounds like you could just write The printed name of a whatever is "whatever". But if you need to deal with complications like subkinds, it is possible to tell Inform how to say the kind of something:[code]To say the kind of (O - an object): (-
if ({O} provides KD_Count) {
print (I7_Kind_Name) (KindHierarchy–>(({O}.KD_Count) * 2));
} else {
print “object”;
}
-).

There is a room.
An armor is a kind of thing; armor is usually plural-named.
The printed name of armor is usually “[bracket]put adjective here[close bracket] [the kind of the item described]”.
Here is some armor.
A reflective armor is a kind of armor.
Here is some reflective armor.[/code]

Holy… I don’t have time to try to implement it right now, but thank you! So, obviously, Inform doesn’t normally have the ability to reference that, but this function here is great, thanks so much. No way would I have ever got that of course… phew.

Wait, I think I see your problem. Are you using something like “There is a leather chest piece called leather chest piece 1. There is a leather armor called leather chest piece 2.” to create your objects?

For a new kind, you can just say “There are five leather chest pieces in the Armory.” Inform will give them all the printed name “leather chest piece” automatically, and won’t disambiguate between them unless the player uses an adjective.

Aha! Ok, the word “a” was messing me up, instead of using a number. This does work.

However, yes, now there is no way to disambiguate between them… even Numbered Disambiguation Choices doesn’t seem to disambiguate them. So, I added:

Understand "[durability]" as armor.

This made it get picked up as needing disambiguation. However, if I add more adjectives, this doesn’t seem to work anymore:

Understand "[durability]" or "[quality]" as armor.

This returns an error “but grammar tokens must have the same outcome whatever the way they are reached, so writing a line like 'Understand “within” or “next to [something]” as “[my token]” must be wrong: one way it produces a thing, the other way it doesn’t.”

Huh?

A simpler way to ask what I’m asking is just how can I add an instance of a kind to a room without specifying it (as Draconis pointed out) but still have a particular one of these items selected based on the adjectives that are assigned to them?