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:
- int
- float
- string
- array
- mapping
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.