13
\$\begingroup\$

I am currently working on a text based game, where the outcome of a combat round goes something like this

%attacker% inflicts a serious wound (12 points damage) on %defender%

Right now, I just swap %attacker% with the name of the attacker, and %defender% for the name of the defender. However, the description works, but don't read correctly. Since the game is just all text, I don't want to resort to generic descriptions (Such as "You use Attack on Goblin for 5 damage", which arguably solve the problem)

How do I generate correct descriptions for cases where %attacker% refers to

  • "You", the player? "You inflicts..." is wrong
  • "Bees", or other plural? I need somehow to know I should prefix the name with a "The "
  • If %attacker% is a generic noun, such as "Goblin", it will read weird as opposed to %attacker% being a name. Compare "Goblin inflicts..." vs. "Aldraic Swordbringer inflicts...."

How does text-based games usually resolve such issues?

\$\endgroup\$
15
\$\begingroup\$

The %attacker% approach can be extended to include some information other than just the names of the objects:

  1. The verb may be singular or plural. This depends on the subject. "You attack X" (singular 2nd person subject) vs. "Extrakun attacks X" (singular 3rd person subject) vs. "The goblins attack X" (plural 3rd person subject). Most verbs just need an -s added but there are a few exceptions.
  2. The noun may be a proper noun ("Goblin attacks X") or a common noun ("A goblin attacks X"). Common nouns starting with a vowel sound should use "an" instead of "a". It may be a common noun but having only one instance in the current context ("The goblin attacks X").
  3. The noun may vary in number, from zero ("You hit no goblins") to one ("You hit one goblin") to many ("You hit three goblins"). Many nouns just need an -s or -es added but there are many exceptions.
  4. Subjects and objects may be simple ("A goblin") or compound ("A goblin and her brother").
  5. Common nouns at the beginning of the sentence need to be capitalized, but if the noun has an article or if it's compound you want to only capitalize the first word. Proper nouns are always capitalized.
  6. The subject position ("She hit the goblin") and object position ("The goblin hit her") use different pronouns.
  7. Possessives can be generated by adding 's if singular ("A goblin's axe"), ' if plural ("Two goblins' axes"), but pronouns have their own rules ("Your axe").

For English, I wrote Python a text generation library derived from a MUD called JaysHouseMOO. Feel free to study or copy the code. It doesn't have a good library of exceptional cases; you'll have to add that with the words used in your game. I'm afraid my ported code isn't extensively tested. It might also need more cases added for games (it was designed for a social MUD, not a gaming MUD).

Your example would be written as "%1I %1:(inflicts) a serious wound (%2n damage) on %3i". The numbers %1, %2, %3 tell it which object is to be substituted; I/i tell it to add an indirect article ("a", "an") if needed; n tells it to display the noun without articles; :(inflicts) tells it to conjugate the verb for that object.

Here's the output to show to the attacker, the defender, and to everyone else:

$ python
>>> import msg
>>> m = "%1I %1:(inflicts) a serious wound (%2n damage) on %3i."
>>> attacker = msg.GenderedObject('Amit', 'm', 'proper')
>>> defender = msg.GenderedObject('goblin', 'm', 'unique')
>>> points = (12, 'point')
>>> msg.Msg().sub_parties({1: attacker, 2: points, 3: defender}, 
                          m, [attacker, defender])
(['You inflict a serious wound (12 points damage) on the goblin.', 
  'Amit inflicts a serious wound (12 points damage) on you.'], 
 'Amit inflicts a serious wound (12 points damage) on the goblin.')

Note if you had given it (1, 'point') it would have printed "1 point" instead of "1 points". That's something that bugs me in game text, so I made sure to include a feature to make it easy to print that properly.

Here's another example, with compound nouns, and "a" vs. "an":

>>> m = "%1I %1:(hits) %2'n %2'(head)."
>>> a1 = msg.GenderedObject('goblin', 'm', 'normal')
>>> a2 = msg.GenderedObject('orc', 'm', 'normal')
>>> d1 = msg.GenderedObject('Amit', 'm', 'proper')
>>> d2 = msg.GenderedObject('Extrakun', 'm', 'proper')
>>> msg.Msg().sub_parties({1: [a1, a2], 2: [d1, d2]}, m, [d1, d2])
(["A goblin and an orc hit your and Extrakun's heads.", 
  "A goblin and an orc hit Amit's and your heads."], 
 "A goblin and an orc hit Amit's and Extrakun's heads.")

These examples are in English, and only track male/female, pronouns, singular/plural verbs/nouns, and proper/common nouns. What you need to track will vary across languages and the type of text in your game. In Spanish there are formal and informal pronouns. Several languages have masculine and feminine forms of verbs. Japanese pronouns depend on the status of the subject relative to the object. In some languages the verb conjugation can implicitly include the subject. Determine all the kinds of text you want to generate and the languages you want to translate to, and that'll tell you what you need to track in your game objects. When you're creating the content, you can include the necessary annotations and exceptional cases.

\$\endgroup\$
  • 1
    \$\begingroup\$ +1, great summary of the issues. One thing I'll add is that players tend to be pretty forgiving of minor grammatical errors for generated text like this as long as the rest of the information (damage amount, source, target, procs) is accurate - shoot for 95% correct grammar, because the last 5% is ridiculously hard. \$\endgroup\$ – user744 Jan 8 '11 at 14:52
6
\$\begingroup\$

Instead of having a single string, and trying to substitute into it properly, you could have a whole set of them. Start with the objects. You know, when creating the mob, what to refer to it as. You can give it a specific property, separate from it's name, for substituting into attack strings. Weapons can have multiple strings for variety, and can substitute in more detail. Instead of 'attacker', they can ask specifically for 'attacker-pronoun' or 'attacker-propername'. Mobs can have plural versions of these identifiers too, if your 'bees' are represented by multiple mobs and not just a single mob that happens to be called 'bees'.

So you would have a mob like

name = goblin
pronoun = he
plural = goblins
proper = goblin
common = a goblin
specific_common = the goblin
possessive = the goblin's
possessive_pronoun = his

Then your attack string asks for specific items like so..

%attacker-pronoun% hit %defender-specific_common% for %damage%! %defender-pronoun% really felt that one!

\$\endgroup\$
5
\$\begingroup\$

There is a set of modules for Perl starting with Lingua::EN::Inflect that deals with these issues. Even if you're using a different language, the API choices made might help you frame your own design.

\$\endgroup\$
3
\$\begingroup\$

The way I handle this is through a large set of systemry that, among other things, involves modeling the message as a data structure rather than a string. The values for the attacker and the defender are their actual objects; the verb ("inflict" in your message) is marked as such, and knows the object for the person performing it, so that the message renderer knows that it needs to be displayed in first person to the actor and second person to everybody else. Objects also know whether their nouns are proper or not (and therefore, whether "the" or "a/an" should ever be applied to them), there are data models that allow me to specify that "the" or "a/an" would normally be expected to be applied to a non-proper noun in that position, and a lot more.

This thread on Mudconnector is very similar to your question, and I go into my system's details extensively there. Basically, the way I do it is what you would want if you want to be completely unconstrained by your messaging system's underlying capabilities and are willing to pay a price in learning curve for that. (Much like vi vs. nano.)

\$\endgroup\$
0
\$\begingroup\$

I would advise you to KISS (keep it stupidly simple), and exploit advantages of the text interface.

Simplify, simplify, simplify as much as you can. Remove complexity before you even start thinking about coding. Instead of one sentence, use two sentences to describe an event, like many games do. Do you remember Baldur's gate ? It's not a text game, but damage is described with text ;)


Split the information between the source of the event and its consequence.

For example :

  • Merlin cast a spell of fireball.
  • Madmax is hit with 3 damages of fire.
  • A goblin is hit with 2 damages of fire.
  • A goblin is hit with 10 damages of fire.
  • etc...

I would also advise to always use the third person singular, would it be either proper or common noun.

Moreover, though English is an important international language, if you want to have more emotional impact, and touch a bigger market, you may need to translate your game in to other languages.

If you intend to do so, be aware that the sentence structure may be different in other languages. According to Wikipedia, 45% of the available languages build the sentence in the SOV (subject-object-verb) order, where 42% (like English) build the sentence in the SVO order; like english.

\$\endgroup\$
  • \$\begingroup\$ Baldur's Gate has a fully graphical engine to go along with it to show output, but for an interactive fiction, text is all the interface and feedback there it. It ought to be more polished for that case, IMHO. \$\endgroup\$ – Extrakun Oct 18 '16 at 8:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.