Is it possible to do something like: A person can be X. X can be Y

Specifically, I’m trying to create “classes” of NPCs and give them traits.

Here’s an example of what I’m trying to do:

A person can be a shopkeep. A person is usually not a shopkeep.
A shopkeep can be picky. A shopkeep is usually not picky.

Then I could define a person as such:

Jane is a picky shopkeep.

The idea here is to be able to make traits that determine how the NPCs act. (eg, a picky shopkeep will behave in a way that someone who is just a shopkeep won’t.)

The answer to this question appears to be no, as the code above throws errors. I’m wondering if there might be a tricky way to make it work?

I know I could just do:

A person can be a shopkeep. A person is usually not a shopkeep.
A person can be picky. A person is usually not picky.

That works absolutely fine, of course. It’s just the way I want to do it feels more… optimized, I guess? It should save on memory, maybe performance because only some people can have the traits instead of potentially all.

But, then again, I saw an old post on here recently where someone said: “You’re trying to write clever code. Don’t write clever code.” Maybe what I’m trying to do is “clever.” (I have a bad tendency to want code to be complex simply for the sake of being complex, which is not a great coding practice.)

So, in short, is this worth pursuing or should I just do it the way of the second example?

A shopkeep is a kind of person.
A shopkeep can be picky.
3 Likes

As a subkind however a person couldn’t stop being a shopkeep. So it depends on whether you need someone’s shopkeep status to be changeable at run-time. Probably in this case having shopkeeps always be shopkeeps makes sense.

3 Likes

Yeah. If NPCs can’t become other classes during play, but any NPC’s behavioural attitudes can change during play, I’d make the classes kinds, and all the behavioural attitudes adjectives. e.g.

A person can be picky.
A person can be sneaky.
A person can be greedy.
A person can be helpful.

A shopkeep is a kind of person.
A guard is a kind of person.

If you create qualities with lines like ‘A person can be…’, you shouldn’t also have to specify that ‘A person is usually not…’. When you say ‘a person can be picky,’ Inform’s reading of that is ‘They can be picky, but they usually aren’t.’

Re: ‘clever’ code, I probably err in trying to over-optimise my code too quickly. And it often happens in cases like the one we’re discussing, where I’m deciding whether to define something via a kind or an adjective.

Both have advantages, but with kinds, I can end up overspecifying, and then lose flexibility I find I need later, because I’m trying to run tests on things that can only be run on certain kinds that don’t overlap. Then I have to go unbuild the kinds and create adjectives and round up the incidents. I did this a few days ago in my WIP for various kinds of door-like things, replacing them with the adjective ‘doory’. But this was across about 9 files and 400k words of source. Still wasn’t that bad, but the further along your project is, the more a nuisance this kind of thing is.

This is sort of a fine point for down the line, and you can often only make these calls with experience. And we still get some wrong anyway.

-Wade

Actually I thought I’d throw in a practical example for the OP’s case.

Let’s say there’s a scene where a treasure chest spills open in a public square (maybe some rich person’s riding by on an elephant).

Now you want every greedy NPC to grab some money.

You can create a list of people who are going to try to grab the money by saying ‘let L be the list of greedy people in the square’.

If you had defined only a shopkeep to be capable of being greedy, the above code would fail, because a person can’t be greedy. Only a shopkeep can. This is the kind of mismatch I allude to in my own doors case.

-Wade

Hmm. Thank you, everyone. I think I got it sorted out now.

severedhand also makes a good point that I might want non-shopkeeps to have that property at some point, so maybe my initial idea wasn’t the best.

I’ll have to experiment and see what works. I’m doing a bunch of seat of my pants design here (I am extremely bad at planning things out in advance) and this whole thing was an impulse idea at 2am.