NPC Gender Selection in adv3

Continuing to navigate treacherous seas, and soliciting input of much more capable sailors than myself. In my WIP I am being pretty diligent about not assuming anything about the player, wrt gender, preferences and pronouns. This is not so hard to do (and only occaisionally clumsy) for a second person UI situation.

However, with NPCs it is much more intrusive into text. I have been creatively sidestepping things successfully until the introduction of the PC’s love interest. While still being pretty circumspect about not assuming anything about the PC, NPC pronouns could be a minefield. For one, they can start to read really clumsily over time.

adv3 seems to have a fairly usable model of pronoun management between the isHim, isHer, and isPlural properties, effectively giving three options: him, her, them. Granted, these are not fully flexible in this day and age, but for an NPC, is this reasonably accommodating of player preferences? (Let’s assume for purposes of this discussion I have engineered an extremely tasteful and respectful way to even ask the question.)

Assuming so, it is then a technical matter of leveraging the parameter substitution capability to let messages tailor themselves. For those unfamiliar, the Technical Manual has a section on this: Message Parameter Substitution.

It is really just a question of creating a ‘global’ object selector that you can use… everywhere. There are many ways to do this, but a pretty easy way is to

// effectively adds luvobj as available param substitution for all verbs
modify Action 
    getMessageParam(objName) {
        if (objName == 'luvobj') return loveInterestNPC;
        else return inherited(objName);
    }
;

The original getMessageParam already provisions ‘magic’ objNames, so I didn’t feel too bad about that. This makes the ‘luvobj’ identifier available to all verbs in the game. (The standard mechanism would want to be executed verb by verb.)

Then, I use a method in the appropriate Actor

loveInterestNPC : Person
    setGender(pref) {
        if (pref == 'them') isPlural = true;
        else {
            isPlural = nil;
            isHim = (pref == 'male');
            isHer = !isHim;
        }
    }
    [&etc]
;

All that’s left is to diligently populate descriptions and messages with these hooks to keep things on the beam. ie

loveInterestNPC : Person 'true love' 'true love'
    "{It luvobj/he} {is} everything you hoped for in a partner.  "
    uselessToAttackMsg = 'Why would you do that to {it luvobj/her}?  '
    // ...and so on
;

Note you COULD use {it dobj/him} in a lot of cases (ie when the NPC is the dobj of the command), but I find it is more auditable to force myself to use luvobj anyway. Special attention needs be paid to the verb handling for ‘they’ vs ‘he/she’, as in ‘they are cool’ ‘he/she is cool’, which is the purpose of {is} above.

Anyway, any thoughts on the appropriateness/technical validity of this approach?

I don’t know anything about TADS so I can’t answer the technical portion of the question, but one important thing to note is that gender-neutral language is not grammatically the same as plural in cases where the subject is the actual name/noun & not the pronoun “they.” So if you just label a person as plural you might end up with messages such as “Morgan are standing behind you,” which is presumably not what you want.

2 Likes

From a narrative standpoint, the best solution is keeping ambiguous the genre of NPC and PC. I reckon that is a difficult narrative effort (and a thing well beyond my handling of English…); that is possible is shown in Graham Nelson’s Jigsaw where, save a weakness in narrative in the segment aboard the Titanic the genres of the PC and NPC was successfully kept ambiguous.

Best regards from Italy,
dott. Piergiorgio.

ps. I’ll be offline for some days because of some repair work in my house, which involves also the power and 'net cabling; So, please don’t be worried if I’m silent for between half week and a full week.

1 Like

Avery is right re: plurality vs singular they (though I imagine in TADS when using someone’s name you just wouldn’t use the {is} interpolation lol).

I also want to remind that @inventor200 made a custom gender pronoun library in adv3Lite. Perhaps the implementation there would be useful to reference, as I don’t think that he/she/they (but the way you refer to glasses and pants) is too accomodating (speaking as a genderqueer person). It may work quick for your WIP but I wouldn’t say it’s satisfying for general use.

3 Likes

Even if you avoid using {is} in custom dialogue about that character, presumably there are existing default library messages that currently use it that you would need to worry about. When I updated the Dialog standard library to support singular “they” I had to edit a few of those sorts of messages (e.g. “they appear to be harmless,” “you apply a bit of force to [name] but they don’t budge,” et cetera).

1 Like

Hm, interesting. From an adv3 perspective that would imply some standard messages using <<name>> is... which I don’t think I’ve come across myself. I have peppered a few of those in myself, but there I can and do manage verb tense directly. Will paw through msg_neu.t a bit.

I appreciate you folks weighing in on this, I can def use the insight. I hoped this might be an acceptable compromise on the strength of two factors: 1) I am not limiting or steering the player’s identification in any way; 2) I am provisioning player choice to define their ‘love interest’ identification among those three. For sure I understand that the presence of a ‘love interest’ at all IS imposing something on the player, which is why I am seeking counsel. Does only having those three possibilities for an important NPC feel exclusionary?

EDIT: additional Q: is the presence of the option more or less intrusive than limiting to default ‘they’ everywhere?

EDIT/EDIT: another Q: if both those are unsatisfactory, what would feel like the optimal selection options?

I did see this, btw, but remain pot committed (for the moment) to adv3. Just reading about the work it took to implement made my head hurt!

2 Likes

Fwiw, while I’m actively dealing with irl stuff and also putting my chips entirely into IF-Octane, I’m not gonna be the one to learn Adv3 and port this extension to it. My apologies to anyone disappointed by this.

EDIT: Unless you meant you’re not committed to Adv3, in which case please ignore me.

EDIT 2: So it turns out that “pot committed” is a phrase. I wholeheartedly recommend you ignore me, lmao.

1 Like

he said pot commited :slight_smile: (tho maybe he edited a typo where it originally said “not committed”)

I think that given it’s a love interest and not the PC, he/she/they is fine.

2 Likes

Oh that’s an actual phrase. Oops. I’ll edit accordingly, then. Today I learned.

This is what I get for never learning about poker.

3 Likes

Reading this has inspired me to include a way of handling this in the adv3Lite library which I think I’ve just just managed to get working. I need to do a bit more testing but it should be included in the next release of adv3Lite, which shouldn’t be that far off now. It occurs to me that it could have wider applications than just gender-ambiguous love interests.

7 Likes

I cannot describe how excited I am to see what you’ve come up with! :grin: Having pronoun flexibility be a standard feature in Adv3Lite would be incredible.

2 Likes

TLDR; Oh my God there are so, so many…

Lol, ok, this sent me into a DEEP hole. Probably an Alpha testing delaying hole, but thank you so much for the observation! To restate, the problem is this:

adv3 has a single pronoun option mechanism, and using isPlural to get ‘they’ pronouns leaves no mechanism to distinguish between a proper name (‘Sean is…’) and pronoun (‘they are…’) for verb conjugation

In unrolling that, there are several facets to this.

  1. Thing (inherited by Actor) defines a series of helper verb conjugations and phrases which sometimes apply to pronouns and other times proper nouns. This would need to be expanded to differentiate those cases.
  2. msg_neu.t sometimes uses those hooks and other times uses message parameter substitution (in Part II of the Technical Manual) to craft default messages.
  3. Where msg_neu.t uses those thing-based phrases, messages might need to be retooled.
  4. Message Parameter Substitution is a dark hole of problem. If you take the tack I did, that isPlural will get you pronoun-based verbs and should be corrected for properNoun-based verbs, there are three problematic constructs: {the dobj/he}, {a/she} and {You/he} These sub in name based properties, where a Proper name could appear and disagree with pronoun-based verb forms. AVOID THOSE CONSTRUCTS IN GAMES WHERE PRONOUN VERB AGREEMENT COULD BE AN ISSUE.
  5. msg_neu.t default messages that do not handle this would need to be overridden in bulk. The problem is large. I did a full pass of the file, and of 5000+ lines of code, about 500 lines of code need addressing. 10% feels like ‘hey, not so bad’ except I made a bad parsing decision as I went. “Hey, Openable doesn’t apply to actors, those messages are fine.” Completely obviating the idea that someone will one day implement a gender-neutral robot that can be opened. I’m just one guy! Clearly not John or Eric!
    (This parse, by the way was 100% visual, so the idea that I missed something is not so far-fetched, and even at this size represents a SIGNIFICANT testing burden should I presume to create a community module.)

Note that MOST of the msg_neu.t problems are in the niche case of ordering gender-neutral actors to do EVERY LAST THING (like lighting matches for example) and getting the default answer. It seems at least plausible that if you are letting NPCs light matches, you are probably handling that directly anyway.

Further note that all this is in service of the laughably inadequate goal of enabling barely-broader NPC gender options… adding ‘they’ and nothing else. (It kind of extends to PC, for third-person games.)

I offer this list as a warning to others. Between @inventor200 and @Eric_Eve , pronoun/verb management could be an adv3lite problem. For those like myself, too deep to abandon adv3, you get me.

So yeah, I already have code to address 1 and 3. I am investigating the parameter substitution problem, hoping I can find a way to manage verb substitution by accounting for proper v pronoun noun substitution. My initial diagnosis is not encouraging. Worst case, I will need to modify 500 lines of excrutiating-to-test default messages (probably by altering them to use the Thing parameter/methods developed in 1 and 3).

Will likely share my work here, more as a cautionary tale than of use to community. BY GOD THOUGH IT WILL BE PRESENT IN MY WIP.

4 Likes

With Dialog, at least, I found it easier to assume singular conjugation by default, and treat cases where the subject is a pronoun as the special case, rather than the way you’re doing it where you try to use plural by default. But I guess TADS/adv3lite could be different.

1 Like

Yeah, that was a deliberate choice based on the VERY complicated pronoun handling baked into TADS. It was easier to leverage it as the default than try to somehow recreate it. (As a reminder, I am working in adv3, not adv3lite.)

Relative the above, I have had a breakthrough dealing with 4,5 by baking properName handling into langMessageBuilder (TADS default english language parameter substitution infrastructure). Will publish once I have thoroughly tested it. Best part, it cuts the message-by-message rework by 70% AND reclaims both the openable, gender-neutral robot and the three problematic substitutions from 4!

1 Like

It does sound like this was easier to do in adv3Lite. The main challenge was to get message parameter substitutions to work properly with gender neutral actors so that, for example, {the subj ali} {is} expands to “Ali is” while {he ali} [is} expands to “they are”, but once I cracked that the rest was fairly straightforward. Unlike adv3, adv3Lite doesn’t have a bunch of separate npc library messages to worry about, and I’m pretty sure that any adv3Lite library messages involving pronouns would have to use message substitution parameters, which should take care of things. The only other main thing to do was to ensure that player’s can refer to a gender-neutral actor using the pronoun “them”.

Otherwise, I pretty much took the approach that gender-neutral actors should be considered singular except when expanding pronoun message substitution parameters and verbs that need to agree with them.

It may have been a little easier for me to handle this in adv3Lite as the library author adding it as a library feature and so free to change library code directly rather than having to work round it in game code or extension code.

It’s possible that there’s some possibility I hadn’t considered that will come to light when other people start implementing gender-neutral actors in adv3Lite. but it alll seems to work okay in the situations I envisaged.

4 Likes

Ok, attaching my ‘final’ solution which has survived my WIP testing. Cannot guarantee no niche bugs still to find. Will probably upload to github once I have sufficient confidence. In meantime, call it a Beta implementation.

Reduced list above to 3 categories of fix:

  1. Provisioned alternate ‘helper’ verb phrases in Actor for use when Proper name and pronouns disagree.
  2. modified langMessageBuilder to handle legacy and user-implemented message parameter substitutions
  3. Modified adv3 standard messages in msg_neu.t which were not automatically handled by 2. above. Really just the array of ActorArriving/Departing messages. I could not find other standard messages that needed flexing, but might have missed some strays!

USAGE: compile with gamefiles, then ensure gender-neutral NPCs set both isThey and isProperName properties. Rest should be automatic!

Finally can get back to WIP!
gender_neu.t (21.3 KB)

3 Likes

First bug found, with some complicated default messages. Will gitHub final version, but if needed in meantime, change:

    if (targetObj.ofKind(Actor) && (info[2] is in (&theName, &aName)))
        subjectProperName_ = true;

to:

    if (targetObj.ofKind(Actor) && (info[2] is in (&theName, &aName)))
        subjectProperName_ = true;
    else if (info[6] == nil) subjectProperName_ = nil;
2 Likes