The Ways of the Power of MUDChat

The purpose of this document is to understand the MUDChat behavior and the richness it can add to a world. No programming is needed.

Basic Chat.Dat Information

If you've ever popped open the resources/chat.dat file and tried to read the instructions, you'll be familiar with this:

# pattern matching: Which work only in ( string | string & (str ~ str))
# | or
# & and
# ~ and-not
# special pattern matching:
# ^ match start This anchors the match to the beginning of the
# input string.
# = exact match This must match the input string entirely.
# / beginning of a coffeemud specific zappermask
# pass 1 scan operators:
# ( beginning of a 'say' expression
# [ beginning of a non-say expression targeted
# { beginning of a non-say expression not targeted
# < beginning of a set matched every mudchat tick, may contain
# a number 1-100 representing percentage chance of triggering
# * combat expression, must precede (, [, or {
# L LLM/AI expression, must precede (, [, or {
# . Anti-LLM/AI expression, must precede (, [, or {
# # remark
# " output to stderr
# ' output to stdout
# > start of named database, there can be more than one name
# to a database '> dragon red_dragon' The _ here is treated
# as a space in the name. You may also use the / operator.
# % include another file inline Ex: %talk.data
# @ adds a continue jump to link to the database. Ex: @dog
# will make a continue link to the dog database. Use @default
# to link to the default database. Only 1 @ per database.
# @ cannot do forward links!!!
# @ is more memory efficient than % but less flexible.
# You must avoid circularities with @.
#${VAR=VAL} define or override variable values. LLMPROMPT & LLMMEM vars
# are for LLM init. Other STATS or special variables
# mentioned below under ${...}. Value can contain other
# ${variables}! Use ${VAR+VAL} to append.
# response operators:
# 1-9 weights are the numerals. First column only. Mandatory.
# " Issue response as "say". Muds and 2nd column only. Optional.
# ` Response issued by LLM/AI as "say", text is prompt. Optional.
# : Issue repsonse as "emote". Muds and 2nd column only. Optional.
# ! Issue response as command. Muds and 2nd column only. Optional.
# special response variables:
# $r Rest of sentence after the match.
# $w The entire message matched.
# $n The character npc/chatters name
# $t The targets name (the person who being replied to)
# $$ Equal to $
# ${...}Returns a variable value, or a generic stat value for the
# speaker. See LIST STATS.
# $<...>Returns a variable value, or a generic stat value for the
# target. See LIST STATS.
# Variables include: THEMEDESC, ROOMDESC, and PERSONALITY
# $%...%Causes the part of the sentence to be evaluated by the MOBPROG
# Scriptable system as a function.
# ~ Separates one or more responses on a line. May be followed by
# one of operators: ", :, `, or !.
# $@ switches to another chat database temporarily until a different player.
# Use #@default to link to the default database. Put this at the end of
# the response. Use #@+ to append a new database instead of switching.
#
#Syntax of a simple pattern match:
#
#( A | B & C ~ ( D | E | F)) 'say command targeted at the mob
#[ A | B & C ~ ( D | E | F)] 'another action targeted at the mob
#{ A | B & C ~ ( D | E | F)} 'another action not targeted at mob
#
#The above would mean if A or B and C and-not D or E or F was in the
#sentence then pick one of the responses.
#
#The responses take on the form:
#
#9this is most likely
#4somewhat likely
#1least likely
#
#Responses or pattern match strings may not span more than one line. #The guaranted line length is a magic 80 characters (letters) wide. #
#Please note the system will return the first match found. So
#please put more ambiguous matches last!!
#
#I suggest adding to this database.
#

Helpful and clear, eh? Here's a breakdown of the basics:

The chat.dat file is basically a giant text file that is used for pattern-matching, with a couple of extra features. What this means is that you enter 'trigger' text and when the MOB hears someone say it, they'll respond with whatever you set for them to say. An example is warranted:

Bo decides he wants MOBs to praise CoffeeMud in a couple ways when it's mentioned. He opens up his chat.dat file. He would enter this:

(coffeemud)
9I've heard of CoffeeMud. Isn't that that slick Java MUD codebase?
6CoffeeMud? What the heck is that?
2:smiles warmly.

(fish)
9Fish with Chips is the Best!
6I don't care for fish, $t.

There's a few different things to understand there:

  • (coffeemud)- This is the matching trigger text. Anyone saying "Hey - how do you feel about CoffeeMud?", "whats coffeemud", or anything else with (case insensitive) 'coffeemud' in it will trigger the following response lines.  

  • (fish) is the matching trigger text for another set of responses that only applies to fish.  

  • 9I've heard of... 2:smiles warmly.- These are the possible responses. This is where things get a little trickier. The system is looking for what's in the first two columns:

    The first column must be a number (the weight), from 1-9. It's not exactly a percentage type thing, but just understand that 9 means it's really likely and 1 means highly unlikely. You can have as many possible responses as you'd like at whatever weight you'd like.

    The second column optionally can be either : "  ` or !. If it'none of these, the MOB will simply say the line.

    • If it's : then the MOB will emote the line.
    • If it's " then the MOB will simply say the line.
    • If it's ` then the line will be submitted to the AI/LLM you have installed, or be ignored if not.  The MOB will then say whatever the LLM responds with.   Use the $w variable to include the original triggering phrase..
    • If it's !, the MOB will treat the line as a normal mud command.

      The other thing to note here is that you don't need a space after either the 1st or 2nd columns.
  • Trigger matches like (coffeemud) or (fish) can be prefixed with zero or more certain special characters that inform MudChat about how and when they apply.  
    • If you prefix the trigger with an asterisk, like *(fish), then the trigger will only apply if the MOB is in combat.
    • If you prefix the trigger with a capital-L, like L(fish), then the trigger will only apply if an AI/LLM integration is installed (see Installation Guide)
    • If you prefix the trigger with a period, like .(fish), then the trigger will only apply if an AI/LLM integration is NOT installed.
  • So!  The MOB, upon hearing 'coffeemud', will say 'I've heard of CoffeeMud. Isn't that that slick Java MUD codebase?', or may say 'CoffeeMud? What the heck is that?', or (least likely, it will emote 'smiles warmly').   If someone says "Hey, do you like CoffeeMud or Fish?", it will match both (coffeemud) and (fish), expanding the number of possible responses.

So, with those basics of triggers and responses clear, you can do some fancier things pattern matching that just one word patterns like (coffeemud). There are and, or, and and-not characters you can use in the pattern matching.

  • & - This is the obvious and character. So (java&mud) would trigger on anyone saying both 'java' and 'mud' in the same sentence.
  • | - This is the or character. So (hello|hi) would trigger on anyone saying either 'hello' or 'hi'
  • ~ - This is the and-not character. So, "c1">(kill~yourself) would trigger on anyone saying 'kill' but would if anyone said 'kill him yourself' etc..
  • / - This is the zapper mask character, so (coffeemud&/-GENDER +FEMALE/) would trigger only if a female says coffeemud.  See help on ZAPPERMASK for more information.

You can also use all of the <S-HIS-HER> type codes that CoffeeMud uses (See Programming Guide) in your trigger/match strings in order to capture normal non-speaking messages. 

In the responses, several variables are available for inserting into the response strings in order to enhance them, such as the $t in 6I don't care for fish, $t.  from the examples above.

  • $r - rest of triggering message after the match.
  • $w - the entire message matched.
  • $n  - the character npc/chatters name
  • $t - the targets name (the person who being replied to)
  • $$ - equal to $, making it the surest way to get a displayed $ character.
  • ${...} Returns a generic stat value for the NPC. See LIST STATS from the mud for a complete list.
    • Examples: ${GENDERNAME} for the NPC.
  • $<...> Returns a generic stat value for the target. See LIST STATS.
    • Example: ${ALIGNMENTDESC} for the targets alignment word.
    • STATS also include: THEMEDESC, ROOMDESC, and PERSONALITY
  • $%...% Causes the part of the sentence to be evaluated by the MOBPROG Scriptable system as a function.
    • Example $%INAREA($n)% to show the area name of the NPC.
  • ~ Separates one or more responses on a line. May be followed by one of operators: ", :, or !.
    • Example 6I don't care for fish, $t.~"They are too slimey.~:pukes.

ChatGroups

There's some very unhelpful sentences in there about databases. This is a better explanation.

There are several ChatGroups defined in the distribution copy of chat.dat. Some are pretty clear. Here's one (shortened a bit):

############################################################
>healer cleric doctor

(hi|hello)
9hello $t, how may I help you?
2I could heal you.

(help & (healer|cleric|doctor) | hurt | pain | sick)
7:prays for you
2Please undress, so I can see your injuries.
5You look great.

(job|career)
7I cure the pitiful
1I am a healer

@default

You'll find this pretty much at the end of the file. What this means, is the ChatGroup is named "healer", "cleric", and "doctor" (the line of #'s is just remark characters, marking it up a bit for readability - it's the '>' that marks a ChatGroup). So, any MOB set to the ChatGroups 'healer', 'cleric', or 'doctor' will respond with these patterns.   

Another trick you can use to narrow matches on a ChatGroup with the > command is to include a CoffeeMud Zapper Mask. In that case the zapper masks would be included in your set of matching words by surrounding it with '/' characters like so: 

>healer cleric doctor /-GENDER +female/

Adding the mask at the end will give the additional requirement that the healer be a female before the chat group is matched.  Check the Archon help files on ZAPPERMASK for more information on the kinds of values you can put in there.

At the bottom of our original ChatGroup is a linking character, @, pointing to default. That means that this group will respond with the pattern you see here first, and if nothing matches, will then go on to check in the default for matches.

The default ChatGroup is simply any patterns entered BEFORE any other ChatGroups are defined, hence why all the ChatGroups are, and should be, towards the bottom.

The linking character preceded by a $, as in '$@mygroup' can be appended to the end of a response string to cause the ChatGroup to either switch to another (in this case 'mygroup'), or append another if '$@+mygroup' with the plus sign is used.  This absolutely must occur at the end of the response string though.   If you don't recall what a response is, see the previous section.

There are some caveats to using @. You can only link to groups that were defined before the link. So, if you wanted a ChatGroup called 'clericforhire' that included some of its own patterns, plus the 'cleric' patterns, you would need to create >clericforhire in the file AFTER >healer cleric doctor, and put @cleric at the bottom of >clericforhire. (More tricks with ChatGroups are in the Power Tricks section).

Important Note: The files are loaded as part of the startup process - changes made to chat.dat while the MUD is running are not applied until the next startup, or until the UNLOAD command is used against the chat RESOURCES (LIST RESOURCES command)

Applying MUDChat Behaviors

Applying the MUDChat Behavior to MOBs is super easy, and setting the MOB to use a particular ChatGroup is straight-forward as well.

Methods

Edit/Create a MOB as usual. In the Behavior list, put MUDChat.   The empty box next to it is the MudChat parameters.

Edit/Create a MOB as usual. In the Behavior list, add MUDChat. It will ask you for any parameters.

If any case you leave the options box empty, the MOB will only use patterns in the @default ChatGroup. If you want to specify which ChatGroup, type its name in the options box. So, if you were setting up a cleric, you would put 'cleric' in the options text.

MudChat Parameters

If you specifiy no parameters, the MOB will only use patterns in the @default ChatGroup, or attempt to find a chat group that shares its name or race. 

If you want to specify which ChatGroup from chat.dat to use, type its name in as the parameter.

If you want to specify a different .dat file to use AND which chat group in that new file to select, use an equal sign, like:

mychat.dat=mychatgroup

The above will load the file /resources/mychat.dat file, which uses the same rules as the chat.dat above.  In the example, "mychatgroup" would be the name of a chat group in that file that the npc will use.

If you want to include any additions or variable overrides to an existing .dat file, you would put those after a plus sign +, after an equal sign, and semicolon ; delimited  for example:

chat.dat=mygroup+(here there);9neither ${hnt};5well, where?;1nowhere;${hnt=Here nor There!}

The above would select the chat group "mygroup" from the default chat.dat file, but add the following to it:

(here there)
9neither
${hnt}
5well, where?
1nowhere

${hnt=Here nor There!}

The above defines a new pattern to match (here there), with a few responses, and then defines the variable "hnt" to be "Here nor There!", which can be used like ${hnt} in response strings.

If you want to keep the default chat.dat file AND the default chat group, but still add new stuff, you can still do that by leaving the first two fields blank:

=+(here there);9neither ${hnt};5well, where?;1nowhere;${hnt=Here nor There!}

LLM

If you have configured CoffeeMud to use an AI/LLM system (see Installation Guide), then you can use MudChat to immediately take advantage of it, by overriding or supplementing its default behaviors with LLM activities.

To get started, there are two internal MudChat variables that LLM will set need for best results.   Variables are defined either in a chat.dat, or in the parameters, by using the ${VAR=VAL} and ${VAR+VAL} syntax.  'VAR' would be the name of the variable, and VAL would be the value to set to it.  VAR+VAL is the syntax for appending to a previously defined variable.

The variable relevant to AI/LLM is LLMPROMPT and LLMMEM.  

LLMMEM is the number of messages that the session will remember, not including the first one, which is always remembered no matter what.   Without setting this variable, the default amount of memory is about 10 messages.

LLMPROMPT is the message that is sent to the LLM preceding the its first input when the session is created.  Without setting this variable, the default prompt would be empty.  Of these, the LLMPROMPT is most important, as it is normally used to establish the rules for its personality.  The default chat.dat file uses the following LLMPROMPT definition:  "Pretend to be a ${GENDERNAME} ${RACE} whose name is ${NAME}, and who lives in a ${THEMEDESC} area called $%INAREA($n)%. You are currently at ${ROOMDESC}, are usually seen by others as "${DISPLAY}. ${DESCRIPTION}". Your moral alignment is ${ALIGNMENTDESC}, and your personality traits are ${PERSONALITY}. Please only deliver dialog responses, never emote, and keep responses under 3 sentences. Begin now: ".  You'll notice how many variables are referenced in building this string for the AI to consume, but also note the last sentence, that strives to keep the AI brief and well formatted as dialog.

When writing your matching trigger patterns, you can write them in 3 different ways to be LLM aware:

L(hi|hello)
9hello $t, I am capable of LLM speech!

The first is to prefix it with a capital L, which denotes a trigger pattern that will ONLY be used if CoffeeMud has an LLM integrated and active.  It otherwise works normally.

.(hi|hello)
9hello $t, I am capable of LLM speech!

The second is to prefix it with a period, which denotes a trigger pattern that will ONLY be used if CoffeeMud does not have any active LLM integration, but is 'stock'.

(hi|hello)
9hello $t, I am capable of LLM speech!

The last is to not put a prefix at all, but use the normal matching character (, [, etc.  These trigger patterns will be evaluated regardless of LLM integration.

The next special LLM feature is around the LLM response, which is prefixed with a single quote character ':

(here there)
9"Hello.  This is a normal response.

5'Hello LLM, please respond to the prompt '$w'.

The single quote character does not work like the double quote.   Instead of the message after the quote being spoken by the NPC, it is instead sent to the LLM, and the NPC will then say whatever the LLM responds with.

Some MUDChat Power Tricks

Suppose you have a city called Yares. In this city are various mobs - guards, shopkeepers, commoners, bankers, etc.. You can setup groups in the chat.dat called guard, shopkeeper, banker, commoner, etc, and give them each appropriate patterns and responses for their type.

Then, you setup two more .DAT files, Yares and World. In Yares, you can put a bunch of patterns in relevant to getting around in the city (like 'weapons'
or 'inn' - both trigger directions to relevant shops). In World, you can put more global geography (IE, 'avalon' gets 'avalon is west of yares').

Now, back in Chat.dat, you created more groups, called YaresGuard, YaresShopkeeper, etc... The only lines that went into each were:

 %Yares.dat
%World.dat
@guard (or @banker or @default or whatever)

%filename includes the filename's contents in-line (as if it were typed in)

This sets up each type to know a little about their city, something about the world, and gave them some text for their profession.

So, in our system, if a new player is walking around Yares, they can ask a cityguard where Market Street is or where they can find a healer and get useful answers (well, not if you want to code misinformation for a chuckle)