GMCP in Aardwolf MUD

GMCP is used to exchange data between the MUD client and Aardwolf server "out of band". Out of band means that the exchange of data takes place behind the scenes rather than via standard game output that is captured by triggers in the client. The benefits of this include a less cluttered screen, fewer triggers to handle and the ability for the MUD and client to exchange data regardless of your status in the game. For example, with regular triggers you may not receive MUD output while in note mode or inside the output pager. With GMCP the data will be received and parsed by the client as long as you are actively connected to the game.

Another advantage with GMCP is lower overhead and bandwidth usage. If you are using the Aardwolf {statmon} tags then all your stats are sent along with each prompt. With GMCP, data is only sent when a value in a module you are subscribed to actually changes.

General GMCP related links



GMCP in MUSHclient


GMCP access is included already in the Aardwolf MUSHclient package. The standalone GMCP plugin for MUSHclient can otherwise be download here: MUSHclient GMCP Plugin. The plugin requires MUSHclient version 4.59 or higher as 4.59 is the first version that includes JSON support as part of the standard MUSHclient package.

For full details on GMCP in Aardwolf using MUSHclient, see the MUSHclient GMCP page.

GMCP in CMUD


Cmud support for GMCP is available in Cmud 3.22 beta and higher.

For full details on GMCP in Aardwolf using CMUD, see the CMUD GMCP page.

GMCP in Mudlet


Mudlet support for GMCP is available in version 2.0 or higher.

While not specifically related to GMCP, anyone using Mudlet on Aardwolf should consider the excellent Mudlet Aardwolf GUI package put together by Zaxes.

GMCP in Tintin++


Since version 2.00.3, Tintin++ has been able to handle GMCP events.

Use event blocks like #event {IAC SB GMCP <event_type> IAC SE} {#var <var_name> %0; ... } to handle the GMCP updates.


Aardwolf GMCP related in-game commands


The protocols command in Aardwolf MUD exists to provide some feedback on which protocols are enabled:

Using the syntax protocols gmcp will show which specific GMCP options are on and off:

The following commands also help configure or debug GMCP within Aardwolf

CommandAction
protocols gmcp sendbaseImmediately send GMCP char.base variables.
protocols gmcp sendcharImmediately send all GMCP char variables.
protocols gmcp sendgroupFlag group data for resend.
protocols gmcp sendmaxImmediately send GMCP char.maxstats data.
protocols gmcp sendstatsImmediately send GMCP char.stats data.
protocols gmcp sendstatusImmediately send GMCP char.status data
protocols gmcp sendvitalsImmediately send GMCP char.vitals data
protocols gmcp sendworthImmediately send GMCP char.worth data
protocols gmcp rawcolorToggle between GMCP rawcolor and ANSI mode
protocols gmcp restartTrigger sending of telnet negotiation to restart GMCP
protocols gmcp debugjsonToggle json packet debugging
protocols gmcp debugpacketsToggle GMCP packet debugging


Aardwolf GMCP Commands


GMCP also supports sending messages from the client to the server. The following "commands" can be sent from the client via GMCP. Some of these duplicate in-game command options, giving you the choice of whether to use GMCP itself to configure the session or in-game commands. The 'request' commands are often useful when a plugin is changed and needs to be redrawn - instead of having special "redraw" functions in the plugin, just let the data refresh and trigger a redraw the normal way.

CommandAction
request areaImmediately request information on your current area
request charImmediately request GMCP char.* data
request questImmediately send current Quest status. See 'comm.quest' module doc below.
request roomImmediately send GMCP room.info for current room
request sectorsSend list of Map sector types and map color
debug on/offTurns the debug mode on or off
debug json on/offTurns the JSON debug mode on or off
debug packets on/offTurns the packet-level debug mode on or off
group on/offTurns group monitor on/off (off by default)
rawcolor on/offTurns the rawcolor mode on or off
gmcpchannels on/offSend channels over GMCP only. NB: this will not enable GMCP channel messages - you must remember to also use Core.Supports.Set
config [option name] [ 'on', 'off', or NULL (no argument) ]Request whether certain config settings are on or change them.


Aardwolf GMCP Modules




Aardwolf Char. modules

The goal with these groups is to separate the total pool of stats into groups that tend to change together, rather than sending the whole set of data when any single value changes.

char.base

The 'char.base' set of data contains are items that will rarely change such as your class, subclass, race, clan, name. The char.base data is sent at login for scripts that want to capture this 'header' information and then not sent again unless one of these items changes.

char.base { "name": Lasher, "class": Warrior, "subclass": Soldier, "race": Elf, "clan": wolf, "pretitle": "Testing ", "perlevel": 1000, "tier": 1, "remorts": 7, "redos": 0, "classes" : "0123456", "level": 210, "pups": 12345, "totpups": 23456 }

The "classes" field is:

0	Mage
1	Cleric
2	Thief
3	Warrior
4	Ranger
5	Paladin
6	Psionicist

char.vitals

Contains health, mana and moves information. Example output is:

char.vitals { "hp": 100000, "mana": 90000, "moves": 41599 }

char.stats

Contains stats that are usually affected by spellups and training:

char.stats { "str": 251, "int": 250, "wis": 250, "dex": 250, "con": 250, "luck": 250, "hr": 2298, "dr": 207, "saves": 13 }

char.maxstats

Contains max values for stats. In a separate group because these change far less often:

char.maxstats { "maxhp": 50099, "maxmana": 50029, "maxmoves": 41629, "maxstr": 51, "maxint": 134, "maxwis": 50, 
                "maxdex": 183, "maxcon": 99, "maxluck": 200 }

char.status

Experience to level, enemy if fighting and enemy percentage. Hunger and Thirst levels, position, etc:

char.status { "level": 210, "tnl": 1000, "hunger": 70, "thirst": 70, "align": 1867, "state": 3, 
              "pos": "Standing" , "enemy": "an owl", "enemypct": 93 }

The 'state' field is the character's current state. It partly duplicates the 'position' field but provides more information. The list of values for state is given below. The value of this field is that if you use plugins that send commands to the MUD, you can detect if your character is in note mode or the pager and wait before sending those commands. This is particularly useful for things like spellup scripts.

  1         At login screen, no player yet
  2         Player at MOTD or other login sequence
  3         Player fully active and able to receive MUD commands
  4         Player AFK
  5         Player in note 
  6         Player in Building/Edit mode
  7         Player at paged output prompt
  8         Player in combat
  9         Player sleeping
  11        Player resting or sitting
  12        Player running

char.worth

These fields are related to achievements or 'worth' in the game and cover qp, tp, etc:

char.worth { "gold": 23128310661, "bank": 750000, "qp": 5052186, "tp": 10930, "trains": 6, "pracs": 14, "qpearned": 12345678 }

Aardwolf Group. module


Group GMCP messages are only sent once per second and are only sent then if the group itself has changed or the vitals/stats of a group member have changed. For larger groups this may be once every 2 seconds (10+ players) or every 3 seconds (20+ players).

The GMCP group information consists of two main sections, the group header and an array of members. The group header contains:

group { "groupname": "lsdkfs", "leader": "Lasher", "created": "28 Dec 14:05", "status": "Private", "count": 2, 
        "kills": 0, "exp": 0, "members": <member array here> }

The array of member information contains:

"members": [  { "name": "Lasher", "info": { "hp": 50054, "mhp": 50054,"mn": 65655, "mmn": 65655, "mv": 41629, "mmv": 41629, 
                "align": 2500, "tnl": 43500, "qt": 0, "qs": 0, "lvl": 210, "here": 1 } } , 
              { "name": "Razor", "info":  { "hp": 31191, "mhp": 31191,"mn": 6199,  "mmn": 6199, "mv":  5775, "mmv": 5775,  
                "align": -2496, "tnl": 790, "qt": 0, "qs": 0, "lvl": 201, "here": 0 } } 
           ]

Most of the group information is fairly self explanatory but 'qs' is worth explaining further - this field indicates what 'qt' (quest time) actually represents:

  0 - Player has no quest timer and can quest. Qt should be zero.
  1 - Player is questing. Qt represents time left on quest.
  2 - Player is waiting to quest. Qt represents time until they can quest.
  3 - Character is a mob, unable to quest.

Full GMCP data for a sample group with 2 members:

group { "groupname": "lsdkfs", "leader": "Lasher", "created": "28 Dec 14:05", "status": "Private", "count": 2, 
        "kills": 0, "exp": 0, "members": [  { "name": "Lasher", "info": { "hp": 50054, "mhp": 50054,"mn": 65655, 
        "mmn": 65655, "mv": 41629, "mmv": 41629, "align": 2500, "tnl": 43500, "qt": 0, "qs": 0, "lvl": 210, "here": 1 } } , 
        { "name": "Razor", "info": { "hp": 31191, "mhp": 31191,"mn": 6199, "mmn": 6199, "mv": 5775, "mmv": 5775, 
        "align": -2496, "tnl": 790, "qt": 0, "qs": 0, "lvl": 201, "here": 0 } } ] }

The "here" field is for whether or not the member is in the same room as the one receiving the GMCP information.

Note: Group information is not sent by default. It needs to be turned on either by:

  • Sending 'group on' or 'group off' via GMCP. If you are using the Aardwolf MUSHclient, this can be achieved manually by using 'sendgmcp group on'.
  • In the GMCP initialization sequence add 'group 1' to the 'core.supports.set' message. In CMUD, this can be added to the config box. In MUSHclient, it would be included in the GMCP handler as:
     Send_GMCP_Packet ('Core.Supports.Set [ "Char 1", "Comm 1", "Room 1", "Group 1" ]')

Note: As with room exits, group information needs to be cleared with each GMCP data refresh so that members who have left the group do not remain in the data.

Aardwolf Room. modules


room.info

Room.info contains information about the current room and is in 3 main sections:

  • The header data such as room name and similar.
  • The exit directions and where they lead, with the following notes:
    • Inside a maze, room ids are not shown, just directions.
    • Custom exits are not shown, only the regular n/e/s/w/u/d for mapping purposes.
    • The recommended way to capture the ASCII map is still using maptags - there is no value in sending this out of band.
  • The coordinate info. The continent list is:
 0 = Mesolar
 1 = Southern Ocean
 2 = Gelidus
 3 = Abend
 4 = Alagh
 5 = Uncharted Oceans
 6 = Vidblain
room.info { "num": 5922, "name": "At the entrance of the park", "zone": "zoo", "terrain": "city", "details": "", 
            "exits": { "e": 5920, "s": 5916, "w": 12611 }, "coord": { "id": 0, "x": 37, "y": 19, "cont": 0 } }

"id" is a single digit from the continent list above. "x" and "y" are the x/y coordinates for your current room (or area), and "cont" is a bit (0 or 1) designating whether the current room is on a continent.

There is also a special case for room.info when a room is not mappable such as a clan room. In these cases you will receive a valid room and area name, everything else will be default values:

room.info { "num": -1, "name": "Emerald Clan Room", "zone": "emerald", "terrain": "", 
            "details": "", "exits": {}, "coord": { "id": -1, "x": -1, "y": -1 } }

Aardwolf Comm. modules


comm.channels

The 'comm.channels' set of tags contain channel data and include regular channels, auction/market, tell, say and yell. Unlike the old output tags, these all share the same type of message format and the channel name within the GMCP data is what changes:

comm.channel { "chan": "gossip", "msg": "You gossip 'Testing'", "player": "Abelinc" }

comm.channel { "chan": "tell", "msg": "You tell Razor 'testing gmcp tells'", "player": "Abelinc" }
  • The following Channels are covered by GMCP:
answerauctionbartercantchantclaninfoclantalk
communecursedebateftalkgametalkgclangossip
grapevinegratzgsocialgtellhelperimmtalkinform
ltalkmarketmusicnewbienobletalkpokerinfoquestion
quoteracetalkrestoresrpsayspousetech
telepathytelltiertalkwangrpwardrumsyell
  • Notes on channels
    • Tell channel is used for tells to/from all players. For player tell separation use the 'player' attribute for incoming tells and parse the message for outgoing (i.e. "You tell <player> <msg>). See idea post 39603.
    • Says from mobs have their own channel known as 'mobsay'
    • Question and Answer channels are separate channels, but are used interchangeably as though they were a single channel by players. If splitting out communication channels it's probably best to combine these. The same is true of Say and Mobsay (though these would be better never being split out from game play)
    • Colors can be configured to be ANSI or Raw. See GMCP options.

comm.events

The 'comm.events' group of tags are for actions and events the player may want to know about. Ticks, a global quest starting, the player requesting or completing a quest are all examples of 'events' that can be reported via GMCP. The event group of tags so far is:

comm.tick:

comm.tick { }

comm.quest:

Sends information when anything related to a quest happens. The full set of messages is:

  Starting a new quest:
   comm.quest {"action": "start", "targ": "a swamp ape", "room": "Swamp Ape Enclosure", "area": "Aardwolf Zoological
                Park", "timer": 52 }

  Failing a quest:
   comm.quest {"action": "fail", "wait": 15 }

  Completing a quest:
   comm.quest {"action": "comp", "qp": 18, "tierqp": 9, "pracs": 0, "trains": 1, "tp": 0,
                "mccp": 2, "lucky": 0, "double": 0, "totqp": 29, "gold": 3553, "completed": 98, "wait": 30 }

  Running out of time:
   comm.quest {"action": "timeout", "wait": 30 }

  Quest target killed:
   comm.quest {"action": "killed", "time": 52 }

  Quest time warning:
   comm.quest {"action": "warning", "time": 5 }

  Can now quest:
   comm.quest {"action": "ready" }

  Qreset self:
   comm.quest {"action": "reset", "timer": 1 }

Responses to 'request quest' GMCP command. These messages are sent in response to a request for status rather than being true 'events'. 

  Able to quest right now:
     comm.quest {"action": "status", "status": "ready" }

  Currently on a quest (same as 'quest request' except action is 'status'):
     comm.quest {"action": "status", "targ": "A spirit of strong essence", 
                  "room": "The Path of the Dead", "area": "The Deadlights", "timer": 60 }

  On a quest but target missing:
     comm.quest {"action": "status", "targ": "missing", "room": "", 
                  "area": "", "timer": 60 }

  On a quest, target killed:
     comm.quest {"action": "status", "target": "killed", "time": 59 } 


comm.repop:

Sends a simple message with area key when an area repops:

comm.repop { "zone": "aylor" }

config [option name] [ 'on', 'off', or NULL (no argument) ]:

A number of the game config commands can be queried and turned on or off via GMCP. The syntax, via GMCP, is:

     config [option name]  [ 'on', 'off', or NULL (no argument) ]

If you send no argument the current flag setting will be returned. The on / off options explicitly set the option and return the new setting as confirmation.

In Mushclient you can try these manually by doing, for example, 'sendgmcp config autoexit' which will return whether or not you have autoexit toggled.

Note the option name carefully. If the option begins "no" then the answer might be the opposite of what you expect. For example "Noweather" will return YES if the "noweather" flag is on, which means "do not show weather". Also note that some options are not quite the same as the in-game commands.

GMCP Config Option List:

   Autoexit,
   Autoloot,
   Autorecall,
   Autosac,
   Autosave,
   Autotick,
   Bprompt,
   Catchtells,
   Color,
   Compact,
   Deaf,
   Echocommands,
   Invmon,
   Maprun,
   Noexp,
   Nomap,
   Noobjlevels,
   Nopagerepeat,
   Noprefix,
   Nopretitles,
   Noweather,
   Prompt,
   Promptflags,
   Quiet,
   Rawcolors,
   Savetells,
   Shortflags,
   Shortmap,
   Statmon,
   Strictpager,
   Strictsocials
   Tickinfo,
   Xterm

GMCP Debug Modes


GMCP is a very quiet protocol - all data exchange takes place behind the scenes. This is great when things are working, but can make the protocol difficult to debug when things are not. Aardwolf supports a number of debug options to provide the client with feedback on what is happening server side.

Standard Debug Mode - "Debug 1"


When "debug 1" is set in the "packages supported" window, any GMCP errors recognized server side will be sent to the screen. Depending on your client, a situation may occur where you cannot get GMCP working well enough to establish the initial exchange of tags supported so are unable to turn on 'debug 1'. On the Aardwolf test port (aardmud.net 6555) GMCP debug mode defaults to 'on'. To turn it off, explicitly set 'debug 0' in your Cmud settings.

The data below shows several invalid "supported package" strings and the output seen in the client when debug mode is on:
badopt 1
testopt 3
pudding 1 2 3 4
2

MUD Output:
GMCP Error: core.supports.set -> unsupported keyword badopt (data:badopt 1)

GMCP Error: core.supports.set -> setting should be 0 or 1 - received 3 (data:testopt 3)

GMCP Error: core.supports.set -> expected format is [key 0|1] - received (data:pudding 1 2 3 4)

GMCP Error: core.supports.set -> expected element to be string, got Integer


JSON Debug Mode - "Debug.json 1"


A number of the standard tags in GMCP use the JSON data format. For each piece of GMCP data sent to Aardwolf, whether or not it will be processed through a JSON parser will depend on the tag type. Most of the standard tags such as 'core.' are in JSON format, most of the Aardwolf specific tags (see below) are not.

There will be times when it is useful to see how the JSON parsed data appears to the server. The 'debug.json' config option is available on the test port only. When this option is turned on, JSON received by the server will be echod back to the client. Note that during connection time no JSON debug information is sent as the "debug.json 1" message has not been exchanged yet. Using the sample program from the CMUD GMPC link with the JSON debug option on:


$response = ""
#addkey $response client "CMUD"
#addkey $response version 3.22
#SENDGMCP "core.hello" $response
$list = {core 1|char 1|room 1|comm 1}
#SENDGMCP "core.supports.set" $list

Gives the response:

------------ Json Message Received -----------
{
   "client": "CMUD",
   "version": 3.2200000000000002
}
-------------- End Json Message --------------

------------ Json Message Received -----------
[
   "core 1",
   "char 1",
   "room 1",
   "comm 1"
]
-------------- End Json Message --------------


Packet Debug Mode - "Debug.packets 1"


If all else fails and GMCP debug mode combined with Json debug mode are not enough to resolve a problem, turning on this option will cause a byte-level dump of all GMCP (protocol 201) data received to be echod back to the client. For example, with this option active, the program above returns the output below. Note that there are two separate IAC-SB-201 messages because there are 2 'SENDGMCP' statements in the program:

--------------- Telnet Data Start-----------------
IAC SB 201
63 6f 72 65 2e 68 65 6c 6c 6f 20 7b 22 63 6c 69      core.hello {"cli        
65 6e 74 22 3a 22 43 4d 55 44 22 2c 22 76 65 72      ent":"CMUD","ver        
73 69 6f 6e 22 3a 33 2e 32 32 7d                     sion":3.22}             
IAC SE
---------------- Telnet Data End -----------------

--------------- Telnet Data Start-----------------
IAC SB 201
63 6f 72 65 2e 73 75 70 70 6f 72 74 73 2e 73 65      core.supports.se        
74 20 5b 22 63 6f 72 65 20 31 22 2c 22 63 68 61      t ["core 1","cha        
72 20 31 22 2c 22 72 6f 6f 6d 20 31 22 2c 22 63      r 1","room 1","c        
6f 6d 6d 20 31 22 5d                                 omm 1"]                 
IAC SE
---------------- Telnet Data End -----------------

\\