Referring to things by computed properties

Hi,

I’m trying to make a game that has items with ‘elements’:

An element is a kind of value. The elements are cyan, magenta, and yellow.

A reagent is a kind of thing. A reagent has an element.

So far so good; now I’d like to add color mixing:

A reagent has an element called the secondary-element.

To decide what text is the composite color of (E1 - an element) and (E2 - an element):
  if E1 is:
    -- cyan:
      if E2 is:
        -- magenta: decide on "cerulean";
        [ etc etc ]
    [ etc etc ]
  decide on "some other color".

To decide what text is the color of (R - a reagent):
  decide on the composite color of the element of R and the secondary-element of R.

Rule for printing the name of a reagent (called R):
	say "[the color of R] [the printed name of R]".

(The intent here is that the secondary-element of a reagent can be modified as part of the game.)

Finally, a test scenario:

The Lab is a room. The gel is a reagent in the lab. The element of the gel is cyan. The secondary-element of the gel is magenta.

Test ex with "x gel". [ You see nothing special about the cerulean gel. ]

With all this said: is there a good way to allow the user to refer to reagents by their colors (i.e. x cerulean)?

Thanks for your time!

Being able to understand by computed properties would open up a whole can of worms, as it would allow the world state to be mutated during parsing, as well as open the door to non-deterministic parsing (consider putting a random element in your color function).

This is not an optimal solution, but the only one I can see is to store the color on each reagent and update it every time the element or secondary-element changes. This could be handled in an every turn rule as long as you don’t mind the color being out of sync with the elements for a few rules.

You can do this:

Understand "cerulean" as a reagent when the color of the item described is "cerulean".
Understand "purple" as a reagent when the color of the item described is "purple".
Understand "green" as a reagent when the color of the item described is "green".

…and so on for every possible composite color.

It’s annoying that you have to write them all out like that, but it’s not difficult.

This will be somewhat more efficient if the composite color phrase returns a kind of value, rather than a text. That is, if you start by saying

A color is a kind of value. The colors are cerulean, purple, green, [etc]

…then you’re comparing values rather than strings, which is generally nicer. The only nuisance is that element values and color values can’t overlap. If you need that, you’d have to rearrange the plan a bit.

You can understand by computed properties:

The Lab is a room. 

An element is a kind of value. The elements are cyan, magenta, and yellow.

A reagent is a kind of thing. A reagent has an element.

A reagent has an element called the secondary-element.

a reagent has a text called the comp-color.
the comp-color of a reagent is usually "[the composite color of the element of the item described and the secondary-element of the item described]".

Understand the comp-color property as describing a reagent.

To say the composite color of (E1 - an element) and (E2 - an element):
say "cerulean"

Rule for printing the name of a reagent (called R):
	say "[the comp-color of R] [the printed name of R]".

The gel is a reagent in the lab. The element of the gel is cyan. The secondary-element of the gel is magenta.

Test me with "get cerulean".
1 Like

Hm. That’s less verbose, but now you’re relying on building a string and then matching it.

Thanks for the replies! I think Zed’s idea is what I was looking for, though I may switch to Zarf’s system of understanding if performance gets to be too bad :slight_smile:

Thanks again for the help! Cheers!

The problem here is that there’s really no such thing as a computed property. All the solutions above fake it in different ways. (A phrase, or a text property with dynamic content, or a property that you manually update when necessary.)

A true computed property feature would be handy, but that’s a new Inform feature proposal.

Come to think of it, you should be able to make this work with a computed relation (13.12) and then understanding by relation (17.16). I can never make relations do what I want, though, so I’ll leave the sample code to someone else.

I tried that, but the compiler said that something like:

Understand "[something related by coloration]" as a reagent.

is not allowed – only relations between kinds of object can be used in grammar tokens.

@alwinfy: Can elements be reclassified as objects?

2 Likes

given the inability to create objects on the fly, this seems like it’d be awkward, requiring creating in advance a pool of all the elements you’ll need all game long and shuffling them around.

[ Edited: Hmmm. or maybe not. Since it’s a relation, it doesn’t have to be exclusive and you could have one each. But then you’d need to manually add the things to scope to correspond to the reagents in scope, right? ]

This seems like a fine solution if you make phrases for (pseudocode follows):

To set element1 of (r - reagent) to (e - element): [...]
To set element2 of (r - reagent) to (e - element): [...]
To update composite-color of (r - reagent): [...]

and always do your element-setting via the first two phrases and have them call the last. Then the color would always be up-to-date and the reagent could be understood as described by the composite color property and this time it’s an ordinary static property. (When play begins, one could loop through the reagents, calling update composite-color on them to ensure the colors are consistent with whatever elements they have at game start.)

yeah, until you forget and set them directly. :man_facepalming:

1 Like

No, you should be able to keep the element objects off-stage. They never have to be in scope.

Confirmed; this works:

lab is a room.

color is a kind of thing. red, green, blue are colors.
reagent is a kind of thing.
goo, gel are reagents in the lab.

coloring relates various reagents to various colors.

the verb to be colored means the coloring relation.

gel is colored blue.
goo is colored blue.

understand "[something related by coloring] reagent" as a reagent.

That doesn’t help one say blue gel though. One can say:

understand "[something related by coloring] [reagent]" as a reagent.

but then referring to blue gel when there’s blue goo around gets “Which do you mean, goo or gel?”

One can also say:

understand "[something related by coloring] gel" as the gel.
understand "[something related by coloring] goo" as the goo.

and that’s not too bad, but many players would expect get blue to work and it wouldn’t with the above implementation.

[ Edited: I tried making color a kind of object instead of a kind of thing, and it compiled, but didn’t work: despite “kind of object” in the error message Otis quoted, it seems to really be “kind of thing”. ]
[Re-edited to correct previous addendum: Otis called it; I had neglected to make colors publicly-named.]

OK, that’s interesting. The following (which is slightly different than the original example) does NOT work:

An element is a kind of value. Some elements are defined by the Table of Available Elements.

Table of Available Elements
element
cyan
magenta
yellow
red
green
blue

A reagent is a kind of thing. A reagent has an element.

A reagent has an element called the secondary-element.

Table of Color Mixing
primary (element)	secondary (element)	blend (element)
cyan	cyan	cyan
cyan	magenta	blue
cyan	yellow	green
magenta	cyan	blue
magenta	magenta	magenta
magenta	yellow	red
yellow	cyan	green
yellow	magenta	red
yellow	yellow	yellow

To decide what element is the composite color of (E1 - an element) and (E2 - an element):
	repeat through the Table of Color Mixing:
		if the primary entry is E1 and the secondary entry is E2:
			decide on the blend entry.

To decide what element is the color of (R - a reagent):
  decide on the composite color of the element of R and the secondary-element of R.

Rule for printing the name of a reagent (called R):
	say "[the color of R] [the printed name of R]".

The Lab is a room. The gel is a reagent in the lab. The element of the gel is cyan. The secondary-element of the gel is magenta.

Coloration relates a reagent (called R) to an element (called E) when the color of R is E.

Understand "[something related by coloration]" as a reagent.

The Problem message that is issued says:

Problem. The grammar you give in ‘Understand “[something related by coloration]” as a reagent’ contains a token which relates things to values - ‘something related by coloration’ . At present, this is not allowed: only relations between kinds of object can be used in ‘Understand’ tokens.
See the manual: 17.16 > 17.16. Understanding things by their relations

It seems the Problem message is outdated and/or misleading in that it only actually applies to computed relations.

Note that just

Understand "[something related by coloring]" as a reagent.

takes care of >X BLUE GEL or >X BLUE (the latter via disambiguation) in your example. Still, that’s a stored relation not a computed relation, as the OP is seeking, so it has limitations similar to understanding by property.

1 Like

Did you by any chance forget to declare the following in the object-based version?

An element can be privately-named or publicly-named. An element is usually publicly-named.
2 Likes

Whoa. I see now that Puncak Jaya does this, but I never guessed you could make a token with just the relation or that you could use it in a command that didn’t mention the related thing (you know, like the only example given in the text of the only documentation available does).

This opens up so much stuff.

It does if you make element a thing instead of a value.

You called it!

1 Like

This is part of why concepts are going to be so useful! It seems like they do basically nothing—they’re just a kind of object that’s not a thing—but they’ll handle the basics like this for us.