GMCP Integration Guide
MudMonster supports the Generic MUD Communication Protocol (GMCP) — a Telnet sub-negotiation channel for structured data exchange between MUD servers and clients. This guide explains what MudMonster advertises, what packages it reads, and how to implement server-side GMCP support so your players get the best experience.
What MudMonster Advertises
When GMCP negotiation succeeds, MudMonster sends a Core.Supports.Set message
advertising which GMCP packages it can consume:
Core.Supports.Set [ "Char 1", "Char.Skills 1", "Char.Status 1", "Char.Vitals 1", "Char.Worth 1", "Comm 1", "Comm.Channel 1", "Room 1", "Room.Info 1" ]
Your server should check this list and only send the packages that have been requested. Sending unsolicited GMCP data may be silently ignored.
Core.Hello
Immediately after GMCP negotiation, MudMonster identifies itself with a Core.Hello message:
Core.Hello { "client": "MudMonster", "version": "1.0" }
You can use this to enable MudMonster-specific features or customise the data you send.
The client value will always be "MudMonster".
Wire Format — How to Send a GMCP Packet
GMCP uses Telnet sub-negotiation. A packet is wrapped in:
IAC SB GMCP <package> SP <json> IAC SE.
Any 0xFF (IAC) bytes
inside the JSON payload must be escaped by doubling them.
/* Telnet constants */
#define IAC 255 /* 0xFF */
#define SB 250 /* 0xFA — begin sub-negotiation */
#define SE 240 /* 0xF0 — end sub-negotiation */
#define GMCP 201 /* 0xC9 — GMCP option */
/*
* Send a GMCP packet to the client.
* package — e.g. "Room.Info"
* json — e.g. {"vnum":"1234","name":"Town Square"}
*
* Wire layout:
* IAC SB GMCP <package-bytes> SP <json-bytes> IAC SE
*
* Any 0xFF byte inside <json-bytes> must be sent as 0xFF 0xFF.
*/
void send_gmcp(int fd, const char *package, const char *json) {
/* header */
unsigned char header[] = { IAC, SB, GMCP };
write(fd, header, 3);
/* package name */
write(fd, package, strlen(package));
/* space separator */
write(fd, " ", 1);
/* json body — escape IAC bytes */
for (size_t i = 0; i < strlen(json); i++) {
unsigned char c = (unsigned char)json[i];
write(fd, &c, 1);
if (c == IAC) write(fd, &c, 1); /* escape 0xFF */
}
/* footer */
unsigned char footer[] = { IAC, SE };
write(fd, footer, 2);
} Room.Info — Minimap Overlay
Room.Info drives MudMonster's GMCP minimap overlay.
Send this packet every time the player moves to a new room.
Room.Info {
"area": "Seringale",
"name": "Bakery",
"terrain": "inside (indoors)",
"vnum": "4518",
"symbol": "F",
"exit": { "south": "4647", "up": "4519" },
"map": "`8+`2 \n`8| \n..."
} area— zone or area name, shown in the map headername— room display name, shown in the map footerterrain— terrain type string (optional)vnum— unique room identifier, sent as a stringsymbol— single character used to represent this room type on the map-
exit— object mapping direction strings to destination room vnums (strings). Supported directions:north,south,east,west,up,down -
map— optional pre-rendered ASCII map string with embedded color codes (see Color Codes below). Lines are separated by\n. When present, MudMonster renders this map directly in the overlay instead of computing one from exit data. The player's current position is typically marked with`!@.
Map Color Codes
MudMonster supports both ANSI escape sequences and backtick color codes in map strings.
Backtick codes take the form `N where N is
a single character:
| Code | Color | Notes |
|---|---|---|
| `0 | Light pink | |
| `1 | Red | |
| `2 | Green | |
| `3 | Yellow | |
| `4 | Dark blue | |
| `5 | Purple | |
| `6 | Cyan | |
| `7 | White | |
| `8 | Dark gray | |
| `9 | Bright red | |
| `! | Red | Player position marker color |
| `@ | Bright green | Typically used as the @ player-position glyph |
| `& | White | |
| `^ | Teal | |
| `$ | Blue-purple | Bold |
| `% | Deep pink | Bold |
| `# | Bright yellow | Bold |
| `` | — | Escaped backtick — renders as a literal ` character |
Char.Vitals — Vitals Bar
Char.Vitals drives the HP, MP, and movement bars displayed in
MudMonster's vitals overlay. Send this whenever any vital changes.
Char.Vitals {
"hp": "219",
"maxhp": "219",
"mana": "158",
"maxmana": "170",
"move": "225",
"maxmove": "225",
"wait": "0"
}
All values may be sent as either strings or integers — MudMonster coerces them to numbers internally.
The wait field is received but not currently displayed.
MudMonster accepts the following field name aliases for compatibility with different MUD codebases:
| Canonical field | Accepted aliases | Meaning |
|---|---|---|
| hp / maxhp | health / maxhealth · hits / maxhits | Hit points |
| mp / maxmp | mana / maxmana · magic / maxmagic | Mana / magic points |
| mv / maxmv | move / maxmove · moves / maxmoves · sp / maxsp · stamina / maxstamina | Movement / stamina points |
Only hp and maxhp are
required. Omit mp/mv fields if your game does not use them — MudMonster only shows bars for the stats it receives.
Char.Worth — XP Progress Bar
Char.Worth drives MudMonster's XP progress bar — a slim bar
above the vitals display showing real-time progress toward the next rank. Send this whenever
the character's experience changes.
Char.Worth {
"xp": 12500,
"maxxp": 10000,
"xptnl": 20000
} -
xp— current accumulated experience -
maxxp— XP at the start of the current level (the previous threshold). Used as the lower bound for progress calculation. -
xptnl— XP at the end of the current level (next rank threshold). Whenxpreaches this value, MudMonster plays a rank-up animation.
Progress is calculated as (xp - maxxp) / (xptnl - maxxp).
All values may be sent as strings or integers.
Char.Status — Character Identity
Char.Status provides the player's character name, level, and class.
Send this on login and whenever the character's level or class changes.
Char.Status {
"name": "Gandalf",
"level": 42,
"class": "Mage",
"race": "Elf"
}
Only name is required. level,
class, and race are optional and
stored for future display surfaces.
Char.Group — Group Member Vitals
Char.Group delivers health and mana percentages for each member
of the player's group. MudMonster stores this data for use in future group-display overlays.
Send this whenever group membership or member vitals change.
Char.Group [
{ "name": "Gromglom", "hp": "100", "mp": "91" },
{ "name": "Serafina", "hp": "72", "mp": "55" }
] name— character name of the group memberhp— current HP as a percentage (0–100), sent as a string or integermp— current mana as a percentage (0–100), sent as a string or integer
Note: Group display UI is planned. The data is captured now for forward compatibility — your players will benefit automatically once the feature ships.
Char.Affect — Active Effects
Char.Affect lists the spells and effects currently active on
the character. MudMonster stores this data for future display. Send a full replacement array
whenever any effect is added, removed, or its duration changes.
Char.Affect [
{ "name": "chii", "dur": "3 hours" },
{ "name": "shadow tactics","dur": "-1 hours" }
] name— display name of the effect or spell-
dur— duration string (e.g."3 hours"). A value of"-1 hours"conventionally means the effect is permanent or has no time limit.
Note: Active effects UI is planned. Sending this data now ensures your players get the overlay automatically when it ships.
Room.World — In-Game Time
Room.World provides the current in-game hour.
MudMonster stores this data for future display surfaces. Send this packet each time the
in-game hour advances.
Room.World { "hour": "14" } -
hour— current in-game hour (0–23), sent as a string or integer
Char.Base — Channel Text
Some servers send channel speech through Char.Base rather than
Comm.Channel. MudMonster receives and stores this payload
for future channel panel support.
Char.Base {
"channels": "An apprentice monk says 'Hello world!'"
} -
channels— the channel message as a raw string. May contain MUD color codes (backtick format).
Comm.Channel — Structured Channel Messages
Comm.Channel delivers structured channel message data for use in
MudMonster's dedicated channel panel (in development). Send this whenever a channel message
is broadcast. This is preferred over Char.Base when available, as
it provides speaker and channel metadata separately.
Comm.Channel {
"chan": "gossip",
"msg": "Hello world!",
"player": "Gandalf"
} chan— channel identifier (e.g."gossip","ooc","shout")msg— the message text, stripped of ANSI escape codesplayer— the speaker's character name
Note: The channel panel feature is planned and channel data is captured now for forward compatibility. Your players will benefit automatically once the panel ships.
Testing Your Integration
MudMonster includes a built-in GMCP debug mode to help you verify your server's output.
Enable GMCP debug logging
- Open the MudMonster app and connect to your MUD.
- Tap the hamburger menu (top-right) and go to Settings.
- Enable GMCP Debug Mode.
- Raw GMCP packets will appear in the terminal prefixed with
[GMCP].
Common issues
- Packets not arriving — make sure your server completes GMCP Telnet negotiation
(
IAC WILL GMCP/IAC DO GMCPhandshake) before sending any sub-negotiation data. - Minimap not updating — confirm that
Room.Infois inCore.Supports.Setand that you are sending either amapstring orexitdata with each room change. - Vitals bar missing — MudMonster only shows the bar after receiving the first
Char.Vitalspacket. Make sure you send it on login, not just on change. - XP bar not appearing — confirm
Char.Worthis in yourCore.Supports.Setresponse and thatmaxxpandxptnlare different values (a zero-width range hides the bar). - JSON parse errors — ensure the JSON payload is valid UTF-8 and that any
0xFFbytes are doubled. Stray ANSI escape sequences inside JSON strings will break parsing. - Negotiation timing — do not send
Core.Supports.Setor room/character data until after the client has responded to yourIAC DO GMCP. Wait for theCore.Hellopacket from MudMonster as your signal.
Package Summary
| Package | When to send | Powers |
|---|---|---|
| Room.Info | Every room change | Minimap overlay |
| Char.Vitals | Any vital changes; always on login | HP / MP / MV vitals bar |
| Char.Worth | Any XP changes; always on login | XP progress bar + rank-up animation |
| Char.Status | Login; level or class change | Character identity (future display) |
| Char.Group | Group change; member vitals change | Group panel (planned) |
| Char.Affect | Any effect added, removed, or ticked | Active effects display (planned) |
| Room.World | Each in-game hour advance | In-game clock (planned) |
| Comm.Channel | Each channel broadcast | Channel panel (planned) |
| Char.Base | Channel speech (alternative to Comm.Channel) | Channel panel (planned) |
Further Resources
- GMCP specification (gammon.com.au)
- Mudlet GMCP extensions reference
- Questions or feedback? Email support@mudmonster.site