Way of the Force
Mudmode transport protocol specification

Mudmode transport protocol specification

What is mudmode?

The Intermud 3 network versions 1, 2 and 3 make use of so called mudmode connections. Mudmode is a way to serialize LPC variables into a special string format, and deserialize that data again at the receiver side.
In many ways, the format is similar to JSON, even the string representation is very similar, but not identical.

Variable types that can be represented in mudmode

In theory, every variable that can exist in LPC can also be represented as a string in mudmode format with the exception of function pointers (would be possible in theory as well, but there is no defined way of doing this).
In practise, mudmode on the I3 network uses the following types:
While it is possible to encode object references, this is never used, and is actually filtered by some Intermud 3 routers. The reason is that LPC object references become rather useless outside the runtime environment in which the reference was created. The result will be that routers cannot resolve the object references, and cannot pass them on. Sometimes the object reference can be resolved by accident, which results in unexpected behavior.

Packet format

A mudmode packet consists of a 4 byte length value, followed by a string, followed by a \0 byte.
So, roughly spoken it is a \0 terminated C string prepended by its length (including the terminating \0) The \0 primarely serves to make it easy to use C string handling. The consequence is that per specification, \0 bytes are not allowed anywhere within the body of a mudmode packet.

For good interoperability with other participants on the intermud 3 network packets should be no larger than 256kb (leading size and trailing \0 included) The hard limit for packet size is 2mb, new implementations should make sure to accept packets upto 2mb in size.

Variable encoding

Mudmode parsers typically don't consider spaces to be whitespace, and they are not allowed outside strings.

int

simple string representation of the integer.
The bytes 00 00 00 04 31 32 33 00 are a complete mudmode packet encoding the int 123

string

quoted string representation, \ serves as escape character, " needs escaping (as does \ itself).
"this is a string"
"this is a string containing a \" character"

arrays

Arrays look like LPC array litterals, starting with a ({ token, followed by a comma seperated list of encoded values ending in a , and closed by a }) token.

({"this","is","an","array",})

Any supported type can be used as an element in an array.

Mappings

Mappings look like LPC mapping litterals, starting with a ([ token, followed by a comma seperated list of key value pairs ending with a , A key value pair is encoded as 2 values with a : as separator. A mapping is closed with a ]) token.

(["key1":"value1","key2":"value2","key3":3,])

Both keys and values can be simple scalar types (int, string, float), values can also be another mapping or an array.

The intermud 3 v3 protocol only uses strings as key, and when implementing mudmode for an I3 client, this is sufficient for typical use.

Floats and ints can occur as keys in mappings for custom packets, and a mudmode implementation for an intermud 3 v3 router should support this so it can forward custom packets.

A pseudo grammar for a mudmode parser looks as follows (kept in a very similar format to the JSON grammar to make the similarities obvious)

mapping
    ([])
    ([ members, ]) 
members
    pair
    pair , members
pair
    string:value
array
    ({})
    ({ elements, })
elements
    value
    value,elements
value
    string
    number
    mapping
    array

string
    ""
    " chars "
chars
    char
    char chars
char
    any-ascii-character- except-"-or-\-or-control-character-or-\0
    \"
    \\
    \n
number
    int
    int frac
    int exp
    int frac exp 
int
    digit
    digit1-9 digits
    - digit
    - digit1-9 digits 
frac
    . digits
exp
    e digits
digits
    digit
    digit digits
e
    e+
    e-

Note that many mudmode parsers do not ignore whitespace, if you want other implementations to understand the mudmode serialized data you produce, you should not insert whitespace anywhere between tokens.

Also, as mentioned before, mudmode also allows serializing/deserializing LPC object ids, this is beyond the scope of this documentation, and cannot be used on the Intermud 3 network.

Floats are supported by many, but not all implementations. They are not used anywhere in the I3 specification, but may occur in custom packets.
Mappings can also have ints or floats as key. This is not used in regular I3v3 packets, but can be used in custom packets. Objectids cannot be sent over the I3 network, and hence should be avoided.

Because a router must be able to forward custom packets, the above grammar needs some additions to the 'pair' rule to also allow ints and floats as keys. Consequently, modifying a JSON parser to support mudmode will be sufficient for clients usually, but for a router some extra work is needed.