DefaultSpeakTo - weird output?

Hi

In the final stages of testing my little game now, and here's a strange thing: if I 'Speak to [object]' then the output is '[it/he/she] saies nothing.' rather than 'says' nothing. Seems to be something to do with the DefaultSpeakTo template. Any ideas about how to fix it?

Many thanks, as ever.


This is a known bug in the functions WriteVerb and Conjugate. (The function is used so that it will correctly output "they say nothing" if you talk to something plural)

There used to be a bug that it would output "trys" instead of "tries" for some sentences. I pointed this out (I believe a few others did), and the English language library was patches so that it changes "y" to "ies" for any words that end with "y" but not "ey". Unfortunately, this isn't quite correct – it fails for a few words, including "buys" and "enjoys". But I think "says" is the only one that's used in one of the built in templates.

Here's a trivially modified version of the Conjugate function to fix this bug:

  <function name="Conjugate" type="string" parameters="obj, verb">
    gender = obj.gender
    if (gender = "he" or gender = "she") {
      gender = "it"
    }
    switch (verb) {
      case ("be") {
        switch (gender) {
          case ("i") {
            return ("am")
          }
          case ("you") {
            return ("are")
          }
          case ("it") {
            return ("is")
          }
          case ("we") {
            return ("are")
          }
          case ("they") {
            return ("are")
          }
          default {
            return ("is")
          }
        }
      }
      case ("do") {
        switch (gender) {
          case ("i") {
            return ("do")
          }
          case ("you") {
            return ("do")
          }
          case ("it") {
            return ("does")
          }
          case ("we") {
            return ("do")
          }
          case ("they") {
            return ("do")
          }
          default {
            return ("do")
          }       
        }
      }
      default {
        if (gender = "it") {
          if (EndsWith(verb, "y") and not (EndsWith(verb, "ey") or EndsWith(verb, "ay") or EndsWith(verb, "uy") or EndsWith(verb, "oy"))) {
            return (Mid(verb, 1, Lengthof(verb) - 1) + "ies")
          }
          else {
            return (verb + "s")
          }
        }
        else {
          return (verb)
        }
      }
    }
  </function>

Alternatively, here's my own version of Conjugate, which works for almost all English verbs (so can also be used for your own commands without worrying about similar issues):

    <function name="Conjugate" type="string" parameters="obj, verb">
      genders = LCase(obj.gender)
      if (genders = "he" or genders = "she") {
          genders = genders + ";it"
      }
      cmd = GetObject (verb)
      foreach (gender, Split(genders)) {
          if (not cmd = null and HasString (cmd, "conjugate_"+gender)) {
              return (GetString (cmd, "conjugate_"+gender))
          }
          dict = GetAttribute (game, "conjugations_"+gender)
          if (not dict = null) {
              if (DictionaryContains (dict, verb)) {
                  return (DictionaryItem (dict, verb))
              }
              foreach (ending, dict) {
                  if (Left (ending, 1) = "@" and EndsWith (verb, Mid (ending, 2))) {
                    return (Conjugate (obj, Left (verb, LengthOf(verb) - LengthOf(ending) + 1)) + DictionaryItem (dict, ending))
                  }
                  else if (Left (ending, 1) = "*" and EndsWith (verb, Mid (ending, 2))) {
                      return (Left (verb, LengthOf(verb) - LengthOf(ending) + 1) + DictionaryItem (dict, ending))
                  }
              }
          }
      }
      return (verb)
  </function>

This one expects the game object to have a couple of string dictionaries containing a list of conjugations:

    <attr name="conjugations_i" type="stringdictionary">
      <item><key>be</key><value>am</value></item>
      <item><key>'be</key><value>'m</value></item>
    </attr>

    <attr name="conjugations_you" type="stringdictionary">
      <item><key>be</key><value>are</value></item>
      <item><key>'be</key><value>'re</value></item>
    </attr>

    <attr name="conjugations_we" type="stringdictionary">
      <item><key>be</key><value>are</value></item>
      <item><key>'be</key><value>'re</value></item>
    </attr>

    <attr name="conjugations_they" type="stringdictionary">
      <item><key>be</key><value>are</value></item>
      <item><key>'be</key><value>'re</value></item>
    </attr>

    <attr name="conjugations_it" type="stringdictionary">
      <item><key>be</key><value>is</value></item>
      <item><key>have</key><value>has</value></item>
      <item><key>@n't</key><value>n't</value></item>
      <item><key>'ve</key><value>'s</value></item>
      <item><key>'be</key><value>'s</value></item>
      <item><key>*ay</key><value>ays</value></item>
      <item><key>*oy</key><value>oys</value></item>
      <item><key>*ey</key><value>eys</value></item>
      <item><key>*uy</key><value>uys</value></item>
      <item><key>*y</key><value>ies</value></item>
      <item><key>*ss</key><value>sses</value></item>
      <item><key>*s</key><value>sses</value></item>
      <item><key>*sh</key><value>shes</value></item>
      <item><key>*ch</key><value>ches</value></item>
      <item><key>*o</key><value>oes</value></item>
      <item><key>*x</key><value>xes</value></item>
      <item><key>*z</key><value>zes</value></item>
      <item><key>*</key><value>s</value></item>
    </attr>

With this version, you can use WriteVerb (object, "guess") to get "he guesses", "she guesses", "you guess", or "they guess" as appropriate. I looked in a grammar book when writing this, so I think it should cover all English verbs correctly.


Thanks, mrangel! Your ability to immediately diagnose and fix any problem continues to amaze.

The trivial fix works, but your more thorough fix gives 'he say nothing' instead of 'he says nothing'. It needs a tweak,but I can't see how to do it...


I can't see the problem there; it should only do that if it can't find game.conjugations_it.

What is the gender of the object?


It happens with any gender of object: 'he say nothing', 'she say nothing', 'it say nothing'...


Can you share the game? I'm not sure what's wrong there, might be easier if I can take a look at it.


Yes - what is the easiest way to share it?


Sorry, just spotted a typo in the code. Should be fixed (I hope).


Ok, thanks. Is the corrected code above, or will you post separately?


I edited the post above. For some reason I had game.conjunctions instead of dict. Hope that helps.

I think that this code should be effective for other languages too; just with different dictionaries. It would be nice if some of the unstable code for handling gender in other language libraries could be replaced by a consistent function.


Sorry, this feels terribly pernickety, but it is still outputting 'he say'. Is the emended code in the string list or the other bit? Just wondering if I'm putting the string list in the wrong place (pasting it within the game object)?


Sorry, this feels terribly pernickety, but it is still outputting 'he say'. Is the emended code in the string list or the other bit? Just wondering if I'm putting the string list in the wrong place (pasting it within the game object)?


Sorry, this feels terribly pernickety, but it is still outputting 'he say'. Is the emended code in the string list or the other bit? Just wondering if I'm putting the string list in the wrong place (pasting it within the game object)?


Sorry, this feels terribly pernickety, but it is still outputting 'he say'. Is the emended code in the string list or the other bit? Just wondering if I'm putting the string list in the wrong place (pasting it within the game object)?


Log in to post a reply.

Support

Forums