And… rewrote large portions of monster_speech.txt. I think I may now finally have understood how this works, so in the not so distant I will have have to clean up some of the hopelessly complicated functions I introduced when I only thought I'd grasped the details. As usual, explaining it to someone else (if only in writing the documentation) really helped.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3591 c06c8d41-db1a-0410-9941-cceddc491573
64RZSOR4B4T5QO3FAERBTH2QJIQFSCIFHI4WYK3MDAEAZVAHRLVQC S7KC3IFKCUNBO3XO4TV3KEQEIDZWSRJSKXY65DPONKMG54VHU3UQC YM3U5YZEFIYLRJVDWQCSP75JL56WC36XLQSL5ZBT4IWSXYJRBCBAC J7KCPTGASQNRAKVKQ5FCXZ75E75PK7I2BB6MFSI3COWU6HRKTWSAC UQFNR6PCRYPSUWMFF7KHITOVE4DZJ4CEAHFSXO7NG6GYZRF5JKUAC J6APXOT4QOGQFONWB7G546VTVF6QG42HVOROMHF7YBDJPR4K26OAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC AIIVH43Z5X3GTPFY4FXQRZPG6Y7QPH2KJ47VM2Q43PCGGD5MTMOAC G5WLU3B4MR3ZDJLGR6OHNIMLZXGQS2EWBJ5YYY5J2GWM6DTD44BAC BMHUBADDGIOZRVN4P3O5QKIDUYD4RFWBS7MP5X6LZWAYHUBRVD2QC G7CTMQ3VNTAB73ZI3LNZHKTAJ5LEQEGG772MVFQQ5XXLCMJVORTQC FYD4A5TIETIV2ZLFYWGHXANU6WQFKMVREHM7OZY2TAXSBMMCDLJAC %%%%################################################# Religious messaging################################################good_godZinThe Shining OneElyvilon%%%%holy_beingw:2SPELL:@The_monster@ intones a prayer.SPELL:A sense of peace washes over you.w:1@The_monster@ says, "Thou must remain pure in the battle against evil."w:1@The_monster@ says, "May @player_god@ always shine on thee, @player_name@!"w:1@The_monster@ says, "@player_god@ be with thee, mortal!"w:1@The_monster@ says, "Praised be @good_god@ in the heavens above!"%%%%neutral good god 'cap-A'__NONEw:2@holy_being@
friendly good god 'cap-A'@default friendly humanoid@w:4@holy_being@%%%%############################################################## evil monsters may also have some choicy things to say...#############################################################good god '&'w:20@_demon_taunt_@w:1@The_monster@ screams, "@player_god@ won't protect you, @player_name@!"w:1@The_monster@ screams, "@player_god@ is but a nuisance to me, mortal!"%%%%
speech has been outsourced by Matthew Cline into shout.txt andspeak.txt. This makes changing existing messages, or adding new onesreally easy. This file will hopefully help you in this endeavour.
speech has been outsourced by Matthew Cline. This makes changingexisting messages, or adding new ones really easy. This file willhopefully help you in this endeavour.
If you take a look through the two files, you'll see that all entrieshave basically the same structure: a key, followed by one or morevalues. Here is an example.
If you have a look at these files, you'll see that all entries havebasically the same structure: a key, followed by one or more values.Here is an example.
Key lookup is always case-insensitive. The game looks up severaldifferent keys when finding monster speech.
Key lookup is always case-insensitive. The game will make manydifferent attempts when trying to find monster speech, all of whichare explained in detail below. You'll find some examples at the end ofthis section.
1. The actual monster name.Examples: "crystal golem", "default confused moth of wrath"2. Then the monster glyph, with prefix "cap-" for capital letters.Examples: "default 'cap-J'", "default confused 'k'"3. A group description (such as 'insect' or 'humanoid') defined by themonster's body shape (winged, tailed etc). The latter is entirelyhardcoded, though.Examples: "default winged insect"
First, a monster may have one or more of a list of attributes thatmight influence its speech. We will henceforth refer to theseattributes as prefixes.
default friendly/hostile fleeing silenced confused monster
default <attitude> fleeing silenced confused <player god> <monster>where <attitude> can be any of friendly, neutral or hostile. Note thatthe game generally treats neutral monsters like hostiles as they stillpose a danger to players.
First the database is searched for the whole prefix string, then,reading from left to right, combinations are tested, beginning atthree prefixes and ending at none, at which time the prefix "default"is used instead.
The <player god> prefix is constructed according to the religiousbelief of the character. If the monster in question is a member of theorc species and the character worships Beogh, the prefix "beogh" getsadded to the list. If you worship one of the good gods (Zin, TheShining One, or Elyvilon) the prefix "good god" is used instead.Conversely, worshippers of one of the evil gods (Yredelemnul,Kikubaaqudgha, Makhleb, Lugonu, Xom, Beogh, or Vehumet) will use theprefix "evil god".This allows fine-grained handling of monsters depending on yourcharacter's religion status, e.g. orcs will use special speech forBeogh worshippers, and neutral holy beings (Angel, and Daeva) mayshout messages of encouragement to followers of the good gods, whiledemons will attempt to slander the good gods.Now that the entire set of prefixes has be constructed, we only needto add the monster name and start the database search.First we search for the whole database string in combination with themonster name. If that didn't yield any results, reading from left toright, combinations are tested, beginning at three prefixes and endingat none. At this stage the list of prefixes is always prefixed itselfwith "default". This ensures that, for example, fleeing uniques won'toutput their normal menacing speech but rather the default speechdefined for fleeing humanoids in general.Only keys that match a search string perfectly (ignoring case) willbe used. Once all prefixes have been exhausted and still no match hasbeen found, the database lookup will try for a more general monsterdescription. There are several possible ways this is attempted, in thefollowing order:
Only keys that match a searching string perfectly (ignoring case) willbe used.
1. The actual monster name.Examples: "crystal golem", "default confused moth of wrath"2. The monster species and genus.Examples: If "friendly ogre-mage" wasn't found, try "friendly ogre"instead. Same for "dragon" if "swamp drake" wasunsuccessful.3. Then the monster glyph, with prefix "cap-" for capital letters.Examples: "default 'cap-J'", "default confused 'k'"4. A group description (such as 'insect' or 'humanoid') defined by themonster's body shape (winged, tailed etc). The definition of thelatter is entirely hardcoded, though.Examples: "default winged insect", "default confused humanoid"
is prefixed to the search string.
is prefixed to the search string, depending on the monster type, e.g.a "stupid humanoid" may still be smarter than a "smart arachnid".Here's a list of allowed monster shapes that should hopefully beself-explanatory:humanoid, winged humanoid, tailed humanoid, winged tailed humanoid,centaur, naga, quadruped, tailless quadruped, winged quadruped,bat, snake, fish, insect, winged insect, arachnid, centipede, snail,plant, fungus, orb, and blob.
If no matching keys are found after all 3 rounds, the monster stays silent.
If no matching keys are found after all of these rounds, the monsterdefinitely stays silent.Example 1:The monster we want to make "speak" is a "confused killer bee".However, such an entry cannot be found in the database, so the gametries first for "default confused killer bee", then "default killerbee", neither of which yields any results.Species and genus are also plain "killer bee", so that doesn't helpus any. For the next round we try again with "confused 'k'", which,by itself, also can't be found in the database, but once the prefixcomparison tries it together with "default", we have a match:%%%%default confused 'k'SOUND:@The_monster@ buzzes around in tight circles.%%%%Example 2:This time, we're interested in "friendly fleeing beogh orc wizard".This obviously made up example also has no direct equivalent in thedatabase, so one after another, we first check for "default friendlyfleeing beogh orc wizard", "default friendly fleeing orc wizard","default friendly beogh orc wizard", "default fleeing beogh orcwizard", "default friendly orc wizard", "default fleeing orc wizard","default beogh orc wizard" and "default orc wizard", none of which issuccessful.Both species and genus of the orc wizard is "orc", so we retry theabove using "orc" instead of "orc wizard". The same is repeated for"friendly fleeing beogh 'o'", and we still haven't found anything.This is starting to get ridiculous, so it's time for desperatemeasures:With the help of some rather complicated functions the game works outthat orcs can be described as humanoids of average intelligence.Thus, in a final attempt of making this orc wizard speak, we searchthe database for "friendly fleeing beogh humanoid", something that,not surprisingly (since Beogh and humanoid don't go well together)doesn't exist. Still, we haven't yet tried the prefix combinations:"default friendly fleeing beogh humanoid" is still unsuccessful, butwith "default friendly fleeing humanoid" we finally strike gold:%%%%default friendly fleeing humanoidw:30VISUAL:@The_monster@ tries to hide somewhere.@The_monster@ @shouts@, "WAIT FOR ME, @player_name@! Could you help me?"...We'll leave it at that, even though the database code still has workto do, namely add up the weights of all the entries (and there areseveral more), and randomly choose one of them.Weapon speech-------------
shout/speak.txt, in which case they are replaced with a random valuefrom the entry; or they may have hardcoded expansions defined by thegame.
shout.txt, monspeak.txt or one of the other files, in which case theyare replaced with a random value from the entry; or they may havehardcoded expansions defined by the game.
Note that if variable replacement is recursive, so be careful to avoidinfinite loops.
Note that variable replacement is recursive, so be careful to avoidinfinite loops. Though the game will abort after a number ofreplacement attempts, it will still look ugly in the monster speech.
@monster@ : Plain monster name, e.g. "rat" or "Sigmund"@a_monster@ : Indefinite article plus monster name,or only the name if it is unique ("Sigmund").@the_monster@ : Definite article plus monster name ("the rat"),or a possessive if it is friendly ("your rat"),or only the name if it is unique ("Sigmund").@something@ : Like @monster@, with monster name replaced by "something"if the monster is invisible and the player cannot see invis.@a_something@ : similar
@monster@ : Plain monster name, e.g. "rat" or "Sigmund"@a_monster@ : Indefinite article plus monster name,or only the name if it is unique ("Sigmund").@the_monster@ : Definite article plus monster name ("the rat"),or a possessive if it is friendly ("your rat"),or only the name if it is unique ("Sigmund").@something@ : Like @monster@, with monster name replaced by"something" if the monster is invisible and theplayer cannot see invisible.@a_something@ : similar
@player_name@ : Player name.@player_god@ : Player's god name, or "you" if non-religious.@Player_god@ : Player's god name, or "You" if non-religious.@god_is@ : replaced with "<god name> is" or "you are", if non-religious.@God_is@ : replaced with "<god name> is" or "You are", if non-religious.@surface@ : Whatever the monster is standing on.@feature@ : The monster's square's feature description.@pronoun@ : it, she, he, as appropriate@possessive@ : its, her, his, as appropriate@imp_taunt@ : imp type insults (see insult.txt)@demon_taunt@ : demon type insults (see insult.txt)@says@ : synonym of 'say' that fits monster's (hardcoded)speech pattern and noise level.
@player_name@ : Player name.@player_god@ : Player's god name, or "you" if non-religious.@Player_god@ : Player's god name, or "You" if non-religious.@god_is@ : replaced with "<god name> is" or "you are", ifnon-religious.@God_is@ : replaced with "<god name> is" or "You are", ifnon-religious.@surface@ : Whatever the monster is standing on.@feature@ : The monster's square's feature description.@pronoun@ : it, she, he, as appropriate@possessive@ : its, her, his, as appropriate@imp_taunt@ : imp type insults (see insult.txt)@demon_taunt@ : demon type insults (see insult.txt)@says@ : synonym of "say" that fits monsters' (hardcoded)speech pattern and noise level.
Pre-defined variables in the database include _high_priest_,_mercenary_guard_, _wizard_, _hostile_adventurer_, _friendly_imp_,_hostile_imp_, and _tormentor_. There are also a few synonyms definedat the beginning of speak.txt such as for @ATTACK@, @pointless@,@shouts@, @wails@, and others.
Examples of pre-defined variables in the database include_high_priest_, _mercenary_guard_, _wizard_, _hostile_adventurer_,_friendly_imp_, _hostile_imp_, and _tormentor_, but more get added allthe time. There are also a few synonyms defined at the beginning ofspeak.txt such as for @ATTACK@, @pointless@, @shouts@, @wails@, andothers.
Note, though, that these rarely will take effect as usually the"silenced humanoid" types will take precedence. In the case ofsilenced monsters, first the database is searched for the monster keyalong with several prefixes including "silenced", and only if nomessage can be found through all iterations of monster name, glyph andgroup description, the search will repeat ignoring the "silenced"prefix and only then these special VISUAL cases can apply.
Note, though, that these only will take effect if the "silenced" prefixhasn't been defined for this monster, or at least not in combinationwith the other applying prefixes. In the case of silenced monsters,first the database is searched for the monster key along with all itsprefixes including "silenced", and only if no message has been found,the search will repeat ignoring the "silenced" prefix and only thenthese special VISUAL cases can apply.This will actually double the amount of rounds the database searchgoes through, so you might expect chances for speaking to be higher.In fact, though, the opposite is the case: once a matching message hasbeen found, the database search stops, and if this randomly chosenspeech message doesn't happen to be VISUAL it will simply not beprinted, so the monster stays silent after all. All in all, chancesare lower (as is intended) but only VISUAL messages even have a chanceto be printed under these circumstances.
Messages may also be one of these special commands. These aren'tvariables, so they aren't surrounded by @@. They are not expanded, butrather they produce special game behavior.
Message entries may also be one of several special commands. Thesearen't variables, so they aren't surrounded by @@. Accordingly, theyare not expanded, but rather they produce special game behavior.
(make monster friendly/unfriendly) and 's' (make monster shout). Theselast two are of particular interest to monster speech designers.
(make monster friendly/neutral/hostile) and 's' (make monster shout).These last two are of particular interest to monster speech designers.
Note that the definition of which monsters are capable of speech isentirely hardcoded. We think we made this apply to all sensiblemonsters, i.e. all intelligent humanoid monsters, but of course it ispossible we've overlooked something, so if you find that yourcarefully constructed monster speech never gets printed, and thisdocumentation also doesn't help you solve the problem, you might wantto post a bug report on Dungeon Crawl's SourceForge site [1].