Letting the player identify between similar things?

Hey, to cut to the chase I’ve been trying to find a way to allow a player to attack any of a specific kind of monster, for example if I were to write:


A monster is a kind of thing. A wolf is a kind of monster. A pillow beast is a kind of monster. Every monster has a number called hp. A hp is usually 10.

After examining a monster:
	say "HP:[the hp of the noun]";

Kicking is an action applying to one thing. Understand "kick [something]" as kicking.

Check kicking:
	if the noun is not a monster:
		say "You can't attack that.";
		
Carry out kicking:
	now the hp of the noun is the hp of the noun - 1;
	say "You kick [the noun].";
	if the hp of the noun <= 0:
		say "You kill [the noun].";
		now the noun is off-stage;

The dark forest is a room. The player, two wolves and 1 pillow beast are here.

Then I could not choose which wolf to attack, I must go through one by one. This could be seen as minor, but it’s really annoying to work around for a game and googling the problem has brought up nothing; help is appreciated :slight_smile: .

The problem is that there isn’t any way for the player to distinguish the wolves–they’re both just “wolf”. When two things are indistinguishable like this, Inform won’t even try to distinguish or disambiguate them; it’ll just pick one.

One way to do this would be to give the wolves individual names in the source code:

The black wolf is a wolf, here. The gray wolf is a wolf, here.

Or you could give them a distinguishing mark by which they can be understood:

Understand "healthy" as a wolf when the hp of the item described is 10. Understand "wounded" as a wolf when the hp of the item described is less than 10. Before printing the name of a wolf: say "[if the hp of the item described is 10]healthy[otherwise]wounded[end if] ".

Or you could use understanding by properties. (The main complication that I know of is that understanding by relations won’t work–if the only way the player has of distinguishing two things involves a [something related by…] token then Inform will treat the items as indistinguishable, even though the player in fact can distinguish them.) But if you just have two anonymous instances of the wolf kind, Inform won’t let you choose which one to attack… because you have no way of expressing your choice.

It seems like you may want to attack the most wounded or most healthy wolf–in which case, I got some help from Matt W earlier.

https://intfiction.org/t/i7-picking-up-the-happiest-cat-solved/4217/9

It might also be possible to attack a random wolf if two were totally identical? This is pseudocode & I can’t vouch for it, but it feels right at least:

carry out kicking:
repeat with x running from 1 to max_health:
if there is a visible wolf with health of x:
try attacking random wolf with health of x instead;

This wouldn’t help distinguish between wolves, but it might allow the player to attack more smartly.

Interesting, is there a way I could make it such that any opponent could be chosen based on their hp, something like this:

Understand "[targethp - a number] [a monster]" as a monster with targethp hp.

I know this doesn’t work, but is there a way you could make something similar to this?

Yes, that’s built in. You can write

Understand the hp property as describing a monster.

And that takes care of it. (Check out the section in the documentation on Understanding By Properties.)

In this case you probably don’t want to have the player write “kick 8 monster,” so you should also ensure that “kick 8 hp monster” gets understood. And you also want to probably print the hp of the monster when you print its name, so the player knows which wolf to kick. So:

[code]A monster is a kind of thing. A wolf is a kind of monster. A pillow beast is a kind of monster. Every monster has a number called hp. A hp is usually 10.

When play begins:
let arfy be a random wolf;
now the hp of arfy is 8.

After examining a monster:
say “HP:[the hp of the noun]”;

Kicking is an action applying to one thing. Understand “kick [something]” as kicking.

Check kicking:
if the noun is not a monster:
say “You can’t attack that.”;

Carry out kicking:
now the hp of the noun is the hp of the noun - 1;
say “You kick [the noun].”;
if the hp of the noun <= 0:
say “You kill [the noun].”;
now the noun is off-stage;

The dark forest is a room. The player, two wolves and 1 pillow beast are here.

Understand the hp property as describing a monster. Understand “hp” as a monster.
Before printing the name of a monster when not kicking: say "[hp of the item described] hp ".
After printing the name of monster when kicking: say “, which now [have] [hp of the item described] hp”.[/code]

The business at the end about printing the name differently when kicking/not kicking comes because if you just write “Before printing the name of a monster…” then when you kick the 8 hp wolf it’ll say “You kick the 7 hp wolf,” which seems undesirable.

This accepts funny inputs like “kick hp pillow monster” and “kick hp 8 8 8 hp 8 wolf,” but there’s really no harm in that.

Another thing you could do is specify hp as a unit (see §15.8 of Writing with Inform)–I think you’d have to do that if you wanted the player to be able to type “8hp” with no space.

Nevertheless, I think it would be better to individuate the wolfs by making specific wolves, e.g., the “old wolf” and the “lean wolf” and so on. Unless you need to randomly add more wolves to your game, this is just more friendly for the player and gives his enemies the needed individuality. (But if you do need a limitless supply of wolves, you can’t do this, of course!)

Wow, thanks! I’ll defiantly look into using descriptions more (I’m somewhat new to inform 7), but names being easier on the player is a good point. Would it be possible to use descriptions to essentially assign names at random to all the different monsters via a large list? This seems like a more scale able system, but I’m not quite sure if it would work as intended. I’ll come back when I’ve tested it out some more.