Describes useful functions for dealing with noun cases and noun/verb agreement.
Noun cases and noun-verb agreement
Online fiction generates a lot of text (to be displayed or spoken)
by splicing together two strings. For example: When a PC picks
up and object, such as a lantern, the Circumreality code will
need to splice together "You" + "pick up" + "a lantern" + ".".
However, at the same time, Circumreality may need to display the string
to other players in the room, in which case it becomes
"Fred Smith" + "picks up" + "a lantern" + ".". Notice how
not only does the name change from "You" to "Fred Smith", but
the verb changes from "pick" to "picks". This is the crux
of the problem... it's called noun cases (going from "You" to
"Fred smith") and noun/verb agreement ("pick" to "picks").
So if you have an oLantern object, how do you get its name,
"the shiny lantern"?
The easiest way to get an object's name is just to concatenate
the object to a string, such as "You pick up " + oLantern;
However, this doesn't give the system much to work with. For example,
it's not sure if you want "the" or "a" before the lantern's
name, or if you want the full (long) name "shiny lantern" or
a the short one ("lantern"). As a result, getting an object's
name using this method will work, but you won't be able to control
the results.
Similarly, you could call oLantern.Name(); it would return
the same string as was appended above.
The correct way to get an object's name is to use the
NLPName() method. It allows you to specify some paramters
that enable a better name display:
The first (optional) parameter is the actor's name. The actor
is the one looking at the object. Most of the time this won't
make any difference. However, if the actor is the same as the
object, then NLPName() will automatically display the
correct pronoun. Thus oLantern.NLPName(oLantern, ...) will
automatically return "you", or whatever is appropriate for
the current language.
The second (optional) parameter is a bit-field that lets you
control what form of the object's name should be displayed;
it is "a shiny lantern", "the lantern", or "10 lanterns".
The flags are global variables of the form gNC_XXX_YYY.
You "or" them together, like: (gNC_Art_Definite | gNC_Count_Many
| gNC_Caps_Upper).
Some ones which you may find useful:
-
gNC_Art_Definite causes "the" to be
displayed. gNC_Art_Inefinite causes "a" or "an"
to be displayed. gNC_Art_None shows the
name without any articles.
-
gNC_Caps_Upper will capitalize the first
character in the same, useful for the start of a sentence.
-
gNC_Case_Subjective causes pronouns to use
the subjective case ("I", "he", "she"),
while gNC_Case_Objective causes pronouns to
be objective ("me", "him", "her"). You can
display the possessive form ("The lantern's")
using gNC_Case_Possessive. A whole
host of gNC_Case_YYY flags are available for langauges
other than English.
-
gNC_Case_Single causes the singular version
of the object to be displayed, such as
"lantern". gNC_Case_Few and gNC_Case_Many will
show the plural form, "lanterns". Some languages have
two definitions of plural, "few" (either 2 or 3) and "many" (4+).
That's why there are two plural cases. If your interactive
fiction will only every be English then use either one.
-
gNC_Gender_Male, gNC_Gender_Female,
and gNC_Gender_Nuter will control the gender
of the object's string. In English, this usually only affects
pronouns such as "he" and "she".
-
gNC_Verbose_Long and gNC_Verbose_Short let
you specify the use of the object's short string ("lantern") or
long string ("shiny lantern"). Not all objects will differentiate though.
You only need to use a flag if the default result isn't
right. Usually the defaults will be correct.
The third parameter (also optional) is a boolean that specifies
whether the "noun-case" string is to be appended. If this
is TRUE or not set, a number surrounded by brackets will be
appended to the object's name. This number stores the noun-case
information (such as plural or singular), and is useful later
on for noun/verb agreement. If you will eventually pass this
string on to NLPStringFormat() to do noun/verb agreement,
then you'll want the noun-case string added.
If you wish to display an object being possessed by another
object, such as "Mike's lantern", then use the NLPNamePossessed()
call. It not only saves you some work, but it makes localization
to other languages easier. For example: Spanish does not use
's to identify possession, but instead uses "the lantern of Mike".
The NLPNamePossessed() function will automatically handle such
changes.
Creating objects that display the right name
If you create an object in MIFL and then call the NLPName()
method, you'll be sorely disappointed. First of all, it will
display the object's name, such as "oLantern" as the actual
string. Second, if your object's name is in any way
irregular, such as "person" vs. "people" (singular and plural forms)
then NLPName() won't work properly.
To make NLPName() produce the right string, you may need to change
some of your object's properties, and maybe even an occasional
method:
First off, you will need to modify pNLPNounName to
your object's name, such as "lantern". (Note: Keep the first
character lower case unless it's a proper name and you always
want it capitalized.) Be aware that pNLPNounName is
different than pNLPParseName, which is used to
identify the object in a command; see "How command parsing
works" for a description of pNLPParseName.
If the name has a long vs. short form, you'll need to use
some special tags within pNLPNounName. In this example, to
create a long name of "shiny lantern", you'll
need to set pNLPNounName to "(long?shiny )lantern".
The parenthsis in the string identify that the noun-case needs
to be tested. The "long" part before the '?' chacter indicates
that the gNC_Verbose_Long setting is to be tested. If it
is set then the "shiny " string is placed before "lantern".
You could also make the short version be "lamp" by
changing the string to "(long?shiny lantern:lamp)".
The characters after the colon (and before the last parenthesis)
are used it gNC_Verbose_Long is not set.
The string, "(lon?shiny lantern:lamp") would also work.
Notice that "long" has been shortened to "lon". You can
abbreviate the noun case to two to four letters depending upon
the name. It cannot be so short that it's indistinguishable
from another name. For example: There is also a "short" test to
see if the short form of the noun is desired (which is the opposite
of the "long" test) and a "single" test to see if the noun
is sinugular. You can't abbreviate "short" down to just "s" because
then the computer wouldn't know if you meant "short" or "single".
You can use a similar technique if the noun has irregular
plurals. For example: To show "hippopotumus" when one hippo
is around, and "hippopotumi" when several around about,
you would set the object's pNLPNounName to
"hippopotum(plur?i:us)". The "plur" test checks for a plural
noun case. If pNLPNounName handles the plural case,
set pNLPNounNoAutoPlural to TRUE.
But that's not all...
-
Some languages, like French, differentiate between animate and
inanimate objects. To indicate that your object is
animate, change the pNLPNounAnimate property.
-
To indicate that your noun is plural by default,
change the pNLPNounCount property. For example:
You'd use this object was "pants".
-
To change the gender of your object,
use pGender. This is particularly
useful for pronouns. Objects default to the
neuter gender.
-
If you never want to prepend an article ("a", "an", or "the")
in front of your object's name,
set pNLPNounNoAutoArticle. You'll want to do
this for proper names, since "the Mike" or "a Mike" is not
standard English. You can also use this, along with
the noun-case tests in pNLPNounName to create
custom aritcles, such as "(indef?lots of:(defi?the)) gold".
-
Possessive forms of an object automatically have "'s" or "s'"
added. If you would rather handle the possessive case
in pNLPNounName, then set pNLPNounNoAutoPossessive to
TRUE.
-
To always display a quantity in front of the noun,
set pNLPNounQuantity to TRUE. For example, if
you have a stack-of-gold object, you may wish to have it
always display the number of coins in it. You may
also wish to write your own NLPNounQuantity() method for
the object.
As shown at the beginning of this tutorial, your will encounter
situations where a noun string and a verb string are concatenated
together, and you need to conjugate the verb to match the noun...
"I am...", "You are...", "He is...", "We are...", "You(pl) are...",
and "They are...".
Circumreality provides some functions that make this easy...
You've already seen the first set using the NLPName() method.
It automatically appends a number surrounded in brackets. This
number indicates the number and person (1st, 2nd, or 3rd) of
the noun. For example: oLantern.NLPName() might return
"The shiny lantern{3543434}".
When you use a verb that relies upon a concatenated noun
string (which will have the "{number}" appended), you
must write out the three verb forms in parenthesis
and separated by a '/'. For example: "(am/are/is) in good shape.".
The first form is used for the 1st person singular ("I").
The second is used by the 2nd person singular and all plural forms
("you", "we", "they"). The third entry is for
the 3rd person sinular ("he" or "she").
Then the noun string and verb string are concatenated they will
look something like this: "The shiny lantern{3543434} (am/are/is)
in good shape."
If you pass this string to NLPVerbForm(), it will return
"The shiny lantern is in good shape.". It uses the number in
curly braces to determine which form the verb should take.
An even better way of displaying the string is to use
the NLPStringFormat() function, which is a combination
of the StringFormat() method and NLPVerbForm(). It
works by replacing "%1", "%2", etc. in the string to the given
argument, and then passing the concatenated string to
NLPVerbForm().
Example: NLPStringFormat("%1 (am/are/is) in good shape.",
oLantern.NLPName(Actor, gNC_Caps_Upper | gNC_Art_Definite));
Will produce the same results.
NLPStringFormat() is the recommended solution for concatenating
nouns and verbs since it also makes localizing easier.
Not all languages use the same word order, so the "%1", "%2", etc.
allow the order of insertion to be flipped depending upon the
language.
-
You might wish to look at the NLPPronoun() function. This will
return a pronoun string, such as "he", "she", or "it" based
upon the noun-case information passed in.
-
There is more to an object's name than just pNLPNounName and
pNLPNParseName, especially when dealing with characters.
You may wish to set pNLPNameReal and pNLPNameRealParse with
the character's name, such as "Bill Smith". Or, you might
even with to write your own code for NameReal().
If your character has an obvious profession, such as "innkeeper" or
"guard", then provide
a pNLPNameProfession and pNLPNameProfessionParse,
or write your own NameProfession.
If you have races, such as cRaceElf, then you will need to
write your own NameRace().
In fact, if your character has a NameRace(), you don't even need
to provide a pNLPNameReal or pNLPParseName!
Share with your friends: |