Contents: This document contains editing information for the Q3A bot.
The Q3A bot is an artificial player for the computer game Quake III Arena.
Author: Mr Elusive
Last update: 2000-01-04

Copyright 2000 id Software, Inc.


 bot chat system 

The bot chat system has five parts:

The pseudo code below shows how the different parts of the chat system are used.

if environmental change then
   if bot wants to chat then
      choose initial chat
      use random strings if referenced
      replace synonyms using chances
      output chat message
   endif
endif

if message appears on the console then
   replace synonyms in the console message
   try to 'understand' message using match templates
   if match found then
      perform action
   else
      if console messages is a chat message then
         if bot wants to reply to this message
            find a reply chat
            use random strings if referenced
            replace synonyms using chances
            output chat message
         endif
      endif
   endif
endif

 Synonyms 

The synonyms are used to unify strings before processing and also used to create some variation when outputting a message. The synonyms are stored in the file syn.c. The bot uses context dependent synonyms. Every context has a flag that is defined in the file syn.h.

A context with synonyms is constructed as follows:

context flag
{
   [("first synonym", X), ("second synonym", Y), ...]
   ...
}

The X and Y are values in the range [0-1]. These values are chances the synonyms are used in chat messages the bot outputs.

A few examples:

CONTEXT_NEARBYITEM
{
   [("Heavy Armor", 0), ("red armor", 0), ("Heavy Armour", 0), ("red armour", 0), ("ra", 0)]
}

CONTEXT_NORMAL
{
   [("do not", 1), ("don't", 1), ("dont", 1)]
   [("checkpoint", 1), ("check-point", 1), ("cp", 1)]
}

In case some word in a bot chat message should never be replaced by a synonym the tilde character ~ can be placed in front of that word. All tilde characters ~ will be removed from the bot chat messages before a bot outputs them.

 Random strings 

The random strings are used in the initial and reply chat messages to add some variation. The random strings are stored in the file rnd.c.

A set of random strings is constructed as follows:

rndname = {"first random string"; "second random string"; ...}

A set of random strings is used in a chat message as follows:

" part of the chat message ", rndname, " part of the chat message ";

Multiple references to random strings can be used in a chat messages. Multiple references to random strings separated by semi colons can also be used directly after each other.

A set of random strings may also contain references to other sets of random strings.

ferrari = {"F40"; "F50"}
BMW = {"BMW Z3"; "BMW Z8"}
cars = {ferrari; BMW"F1 Mc Laren"}

However make sure there is no recursion when referencing other sets of random strings.

 Match templates 

The bot uses the match templates to 'understand' chat- and other console messages. The match templates are stored in the file match.c.

A match template is constructed as follows:

matchtemplate = (id, typeflags);

Fixed strings and variables alternate in a match template and they are separated by commas. For instance: "you are ", 0, " don't you think?" Here the 0 is the index of a variable. Currently a maximum of 8 variables is allowed (index in the range [0-7]). It is not allowed to have two consecutive variables.

The bot will try to find a match with one of several fixed strings in the template when they are separated by the | token. For instance: "you"|"we", " are ", 0, " don't you think?" will match to both "you are crazy don't you think?" and "we are crazy don't you think?". The bot will try to match the strings separated by the | token in the order they are listed. An empty string is also allowed with the | token. However make sure the empty string is always the last one in a sequence of strings separated by | tokens because the empty string will always match. For instance: "I am the ", "team "|"", "leader" will match to both "I am the team leader" and "I am the leader".

The id is used to identify the message. The type flags specify certain characteristics of the message. The id and type flags are defined in the file match.h.

The bot uses context dependent match templates. Every context has a context flag and several match templates can be grouped within a context. The context flags are stored in the file match.h.

context flag
{
   ...
}

An example:

MTCONTEXT_INITIALTEAMCHAT
{
   "(", NETNAME, "): ", ADDRESSEE, " camp at ", KEYAREA, " for ", TIME = (MSG_CAMP, $evalint(ST_ADDRESSED|ST_NEARITEM|ST_TIME));
   ...
}

The bot uses the match templates in the order they are listed in the file match.c. The first match found is used.

 Initial chats 

The initial chats are used by the bot to initiate a chat when something in the environment changes or the bot just feels like chatting. Each bot has a personal set of initial chat lines. In the characteristics of a bot there's a reference to the file with the initial chats for that bot. There is also a reference to the "name" of the chats in that file.

The initial chats for a bot are constructed as follows:

chat "name"
{
   type "type name"
   {
      "initial chat message";
      "another initial chat message";
      ...
   }
   type "type name"
   {
   }
   ...
}

 Reply chats 

The bot uses the reply chats to reply to chat messages from other players. All bots use the same reply chats because the number of reply chats tends to grow pretty large. Creating different reply chats for each bot character would be too much work and also take up to much memory.

The reply chats are stored in the file rchats.c. The reply chats in this file have keys, a priority and several reply chat lines.


[key1, key2, ...] = priority
{
   "reply chat message";
   "another reply chat message";
   ...
}

key prefixes:

& key must be true
! key must be false


keys:

name key is true when the name of the bot is found in the chat message the bot wants to reply to
female key is true when the bot is female
male key is true when the bot is male
it key is true when the bot is not male nor female
<"",""> key is true when the bot has one of these names, any number of names can be listed between the < and >
"" key is true when the string is found in the message to reply to
( ) key is true when the chat message to reply to matches the template between the ( )
The match templates work in exactly the same way as the match templates described above. The matched variables can be used in the reply chat messages. For example:

[("I'm not ", 0)] = 4
{
   "yes you are ", 0;
}


The priority is a floating-point value that is relative to the priorities of other reply chats.

The bot evaluates the keys to find out if the reply chat can be used to reply to a certain chat message from another player. When all the keys with the prefix & are true and all the keys with the prefix ! are not true and there is at least one key without prefix true then the bot may use the reply chat. When several reply chats can be used to reply to a message the one with the highest priority is chosen.


reply chat examples:

["hate you", !"not"] = 7
{
   "why do you hate me";
   "there's no reason for you to hate me";
}

Bots can use the above reply chat when someone types the message "I hate you". However if a player types the message "I don't hate you" the bot cannot use the above reply chat because of the key "not" with the prefix !. (Note: "don't" will be replaced by "do not" because of the contraction synonyms in the synonym list.)

["love you", !"not", &female] = 6
{
   "am I the only woman you love?";
   "I love you to";
}

Only female bots can use the above reply chat.

["camper", !"not", &<"Grunt", "Stripe">] = 6
{
   "I love camping";
   "I'm the king of all camp grounds";
   "camping with the rocket launcher is what Graeme told me to do";
   "so?.. you got a problem with campers?";
}

Only Grunt and Stripe can use the above reply chat.


bad reply chats:

[&"looser", !"not", &female] = 6
{
   "I'm not a looser";
}

All the keys in the above reply chat have either the ! or & prefix. No bot will ever use this reply chat because at least one key without prefix must be true.

[("I hate ", 0), "hate you"] = 7
{
   "are you sure you hate ", 0;
}

In the above reply chat the variable 0 does not have to be valid when the bot tries to output the message "are you sure you hate ", 0; because the key "hate you" could be the only true key. For instance only the key "hate you" is true when the bot tries to reply to the message "we hate you".

[("get lost"), &name] = 7
{
   "I never get lost";
}

The above reply chat will never be used because there is no room for the name of the bot in the match template. However the name of the bot is required to be in the chat message to reply to because of the key &name.

[("do not say ", 0, " want to ", 1), !"not"] = 7
{
   "but ", 0, " really want to ", 1;
}

The above reply chat will never be used because "not" is a sub-string of "do not say ".


bad reply chat combination:

["allowed"] = 7
{
   "everything is allowed.";
}

["not allowed"] = 5
{
   "why isn't that allowed?";
}

If both of the above reply chats are in the rchat.c file then the bot will never reply with "why isn't that allowed". If the bot for instance wants to reply to the message "cheating is not allowed" then the bot figures out it can use both of the above reply chats according to the keys. The message "cheating is not allowed" has the sub-string "not allowed" and also the sub-string "allowed". Because the keys allow the bot to use both reply chats the priority is used to select one of them. The priority of the reply chat with the key "allowed" is higher and will be used. Reversing the priorities will fix the problem.


 Chat messages 

Both the initial chats and reply chats store chat messages. Random strings can be used in these chat messages to add some variation. Variables from match templates in the reply chats or specified in code for initial chats can be used in chat message. The tilde character ~ can be placed in front of words in a chat message to make sure these words will not be replaced with synonyms. Colors can also be used in chat messages. A color is specified with the ^ character followed by a number in the range 0-7.