Objective pronoun {him obj} evaluates to reflexive case

Hi, long time lurker here. I am working on a game where the player character changes, so message substitution parameters are important for the game output to be consistent with the current POV. It’s a challenge to get it right, but this is the first issue I haven’t been able to work out for myself.

The problem is that when I request the objective pronoun (eg - him, her, it) with {him obj}, I am getting the reflexive case pronoun (eg - himself, herself, itself) instead. After some tinkering, it seems that the parser is using information from elsewhere in the sentence and decided that what I really need is the reflexive case, even though I used {him obj} and not {himself obj}. Indeed, I was able to get the objective case by cutting out other message substitution parameters from earlier in the sentence, using embedded expressions instead.

Here is some sample code to show what I mean. What I’ve done here is modified the jump verb to give an output to illustrate my issue.

joe: Actor 'Joe;;man;him'
    isFixed = true       
    person = 3  // change to 1 for a first-person game
    contType = Carrier    
    location = startroom
;

modify Jump
    execAction(cmd)
    {
        // Here is the way I'd like to do it using message substitution parameters. The problem is the output is giving reflexive pronouns instead of objective.
        
        "{I} {do} jumping-jacks for a long time, leaving {him actor} tired and sweaty. {He actor} {know} that exercise is good for {him actor}. ";
        
        "<br><br>";

        // This way gives the correct case pronoun, but the code is unnecessarily verbose.
        "<<if joe.person == 1>>I do<<else if joe.person == 2>>You do<<else>>Joe does<<end>> jumping-jacks for a long time, leaving {him actor} tired and sweaty. <<if joe.person == 1>>I know<<else if joe.person == 2>>You know<<else>>He knows<<end>> that exercise is good for {him actor}. ";
    }
;

My output then looks like this.

Joe does jumping-jacks for a long time, leaving himself tired and sweaty. He knows that exercise is good for himself. 

Joe does jumping-jacks for a long time, leaving him tired and sweaty. He knows that exercise is good for him. 

I tried using the debugger to find out why the parser does this, but that rabbit hole was dark and scary. It seems like what I am trying to do should be possible.

Any hints or ideas?

I had a quick look at the Library Manual for adv3Lite (not to be confused with the Library Reference Manual). Offhand, I’d say it looks like you’ve found a bug in the library – possibly something that pops up only when {actor} is the argument.

Possibly there’s a workaround that’s less clunky than what you’ve worked out. It appears from the doc that the dmsg() function (not to be confused with the DMsg() macro) can take arguments, in the form {1}, {2}, and so on. The arguments could be replaced by single-quoted strings of the form gActor.name, gActor.pronounSubj, gActor.pronounObj, gActor.pronounRefl, and so on. That way, when gActor evaluates to Evangeline or Boopsie rather than to Joe or Murgatroyd, the argument substitution should take care of it.

I haven’t tried this, God knows. I’m just thinking out loud.

Well, you were on the right track suspecting my use of {actor}.

After some more tinkering and reading about reflexive pronoun grammar, I have come up with another couple examples and a (hopefully) feasible workaround. In the final analysis, I would call this an undocumented feature of the code, but it’s not too bad once you know how to deal with it.

For my first example, I found another inelegant workaround which I think does a good job of illustrating exactly where the issue is (thanks, Jim). I made a clone of Joe, exactly the same as original Joe except that his location is nil. By using the clone instead of the real Joe in the objective pronoun request, the parser doesn’t give the reflexive case. Presumably, the parser at some point checks for an exact match between the object referenced in the subject and in the predicate of the sentence. If there is an exact match, then the reflexive case is given. This makes perfect sense if you think about what reflexive pronouns are. I looked at myself in the mirror. She sent the email to herself. The person doing the action is the same as the person that the action is done to.

With that in mind, I went on to construct a simple sentence where the parser gives a good result, which I am showing in my sample code as the second example.

After thinking about it, I began to suspect that the parser is confused about what the subject of the sentence is. I am hardly a grammar expert, but after looking through the library manual, I noticed this:

{dummy} Expands to nothing but acts as a singular subject marker for a verb that follows to agree with (e.g., 'There{dummy}{‘s} nothing {here}.’)

So, on a lark, I tried dropping that into my sentence… and it works. Not exactly what it was intended for, according to the manual, but this is what I am going to try using from here on.

In short: Insert {dummy} preceeding {him actor} in each sentence when you REALLY want the objective case.

If anybody knows a better solution, please let me know! If my workaround breaks at some point, I will report back here in case other people decide to use this solution.

Here is my test code.

joe: Actor 'Joe;;man;him'
    isFixed = true       
    person = 3  // change to 1 for a first-person game
    contType = Carrier    
    location = startroom
;

cloneJoe: Actor 'Joe;;man;him'
    isFixed = true       
    person = 3  // change to 1 for a first-person game
    contType = Carrier    
    location = nil
;

modify Jump
    execAction(cmd)
    {
        local otheractor = cloneJoe;
        gMessageParams(otheractor);
        
        // FIRST EXAMPLE: Here, I am referencing a different actor (cloneJoe) in my request for the appropriate objective pronoun. This gives the correct
        // result, but I wouldn't want to actually code a game using this method.
        
        "{I} {do} jumping-jacks for a long time, leaving {him otheractor} tired and sweaty. {He actor} {know} that exercise is good for {him otheractor}. ";
        
        "<br><br>";
        
        // SECOND EXAMPLE: The parser seems to be doing a good job inserting the reflexive case, even though it was not explicitly requested.
        
        "In other words, {I} {make} {him actor} sweaty. ";
        
        "<br><br>";
        
        // MY WORK-AROUND: Insert {dummy} preceeding {him actor} in each sentence when you REALLY want the objective case.
        
        "{I} {do} jumping-jacks for a long time, leaving {dummy}{him actor} tired and sweaty. {He actor} {know} that exercise is good for {dummy}{him actor}. ";
    }
;

And my output.

>jump

Joe does jumping-jacks for a long time, leaving him tired and sweaty. He knows that exercise is good for him. 

In other words, Joe makes himself sweaty. 

Joe does jumping-jacks for a long time, leaving him tired and sweaty. He knows that exercise is good for him.

On reflection (ha), I think that the parser is trying to be too clever, correcting a possible error on the users part. Unless there is a good reason for it to be this way, I think that the objective pronoun should always be returned when requested. Leave it to the user to decide whether to use {him obj} or {himself obj}.

I’ve spent a lot of time wrestling with this bit of code, which adv3Lite inherited from the (incomplete) Mercury library, trying to curb its excessive enthusiasm for using reflexive pronouns, but I suspect that I’ve probably got the balance as good as it’s going to get.

The problem with your suggestion, appealing though it looks in the cases you give, is that there are other cases where it will give the wrong result. For example, suppose there needs to be a library message for a HIT action:

   hitMsg = '{He actor} {hit} {him dobj}. '

The library can’t know whether or not the actor and the dobj are going to be the same or not when this message is displayed, so in general it will give the best results if is displays “He hits him” when actor and dobj are two different objects and “He hits himself” when the actor and the dobj are one and the same.

The trouble is that the routine that expands these message substitution parameters isn’t smart enough to distinguish between simple sentences of this sort and more complex ones such as those you were trying to deal with, when the subject and object of the sentence are the same but are in a more complex relation, unless you help it out. So, in your example:

"{He actor} {know} that exercise is good for {him actor}. ";

The expansion goes wrong because the subject of the verb in the subordinate clause is “exercise”, but the routine that does the expansion can only go by what’s been explicitly marked as a subject, and the last one marked is “{He actor}”, so that it appears to the library that {him actor} is the object of “{He actor} {know}”, which is (in one sense) correctly expanded as “He knows himself.” There’s nothing in the string “that exercise is good for” that signals the actual sentence construction to the expansion routine; from the software’s point of view it’s structually identical to:

"{He actor} {know} everything about {him actor}. ";

Where “He knows everthing about himself” would be correct.

Your workaround is along the right lines. You basically need to tell the game what the actual grammatical subject of your sentence is, which you can mark with {dummy}, hence:

"{He actor} {know} that {dummy}exercise is good for {him actor}. ";

Which should tell the routine that “exercise” and not “actor” is now the subject.

It might be worth making this a bit clearer in the docs somewhere.

Ah ha, that makes perfect sense. If I may humbly suggest where you should make the docs clearer…

In the Adv3Lite Library Manual, Part IV: Actions, Subsection: Messages. There is a big table that shows all of the message substitution parameters with a column for the parameter and a second column for the meaning. Currently, the row for {dummy} has an explanation that says:

Expands to nothing but acts as a singular subject marker for a verb that follows to agree with (e.g., 'There{dummy}{‘s} nothing {here}.’)

I think this entry should be re-written to more precisely explain what {dummy} does.

Does it take precedence over any other subjects in the sentence? How much does it matter where you place it? I can puzzle this out for myself, but it might be nice to have it in the manual.

I decided to try {dummy} out because I had a hunch that my issue was of the subject agreement type, but there’s nothing currently in the manual to suggest that {dummy} could also be used for disambiguation purposes.

They are excellent manuals, btw. I don’t know that my little game will ever see the light of day, but I have fun tinkering with it in my free time.

I think that’s the right general section to add an explanation, but probably not in the table itself (which really isn’t suitable for complex explanations). I was thinking of adding some more explanatory text after the table on the use of {dummy}, perhaps along the lines of the explanation in my previous reply.