Adding support for Mudlet

54 views
Skip to first unread message

Malcolm Tester

unread,
Feb 18, 2022, 6:11:45 AM2/18/22
to LDMud Talk
Hi,
I've searched through the archives and on the web, and I see mixed opinions about whether to add GMCP or MSDP.  I've also seen references to MXP, MSP, and MSSP.  Not to mention, also MSDP over GMCP or MSP over GMCP.  I want to add support for Mudlet so we can do a custom UI and snazz it up some.  This may include (later) a mobile app, so I may need to use this/these protocols for Android and iPhone as well.

I know GMCP uses JSON, and MSDP uses a not-quite-binary-with-escape-sequences format.  I don't really care which of these I use.

Infinity is using 3.3.720 in compat mode.  I've also considered upgrading to the latest, but that is a pain.

So, questions.
1) Which protocol(s) are best to add, for LDMud.  What do Gnommi and Zesstra see as being the better protocols to work with LDMud?
2) MSDP over GMCP seems overkill. Is it just to get the JSON data + MSDP commands?
3) I assume I'll need to pick GMCP or MSDP.  Is MSSP (server status) or MXP (sound) also needed, or can those be handled with one of the first two as well?
4) Is there anything in more recent versions of LDMud that affect these protocols and make it worth upgrading?
5) Without having touched this and just having read some about them, is there anything I should be careful of with respect to heart_beat() (like sending updates for health etc)?
6) Obviously any working examples of the telnet hooks or efuns or whatever someone may have added to their lib to support this, would be great.  Barring that, a quick outline of things to do, check for, etc would also be appreciated.

Thanks,
Malc @ Infinity

Gnomi

unread,
Feb 18, 2022, 6:51:37 AM2/18/22
to ldmud...@googlegroups.com
Hi,

Malcolm Tester wrote:
> 1) Which protocol(s) are best to add, for LDMud. What do Gnommi and
> Zesstra see as being the better protocols to work with LDMud?

With the H_TELNET_NEG hook you can implement them all with LDMud. I would
think that GMCP is more versatile than MSDP and more widely used. Which
protocol to add will depend on your use case and which clients to support.

> 3) I assume I'll need to pick GMCP or MSDP. Is MSSP (server status) or MXP
> (sound) also needed, or can those be handled with one of the first two as
> well?

Theoretically you could implement everything in GMCP. But the GMCP packages
are not standardized, so you cannot expect a GMCP client (plugin) working
with every MUD implementing GMCP.

MSSP however is for mud crawlers that need to speak with every MUD,
therefore they will not negotiate GMCP, but only speak MSSP directly (Note
that there are two ways of talking MSSP, one is over telnet subnegotiations,
the other one is using text commands. I would recommend implementing both
for best compatibility.)

> 4) Is there anything in more recent versions of LDMud that affect these
> protocols and make it worth upgrading?

I think the H_TELNET_NEG hook is mostly the same between LDMud 3.3 and 3.6.
LDMud 3.5 offers JSON efuns that'll help implementing GMCP.

> 5) Without having touched this and just having read some about them, is
> there anything I should be careful of with respect to heart_beat() (like
> sending updates for health etc)?

I am not aware of anything.

> 6) Obviously any working examples of the telnet hooks or efuns or whatever
> someone may have added to their lib to support this, would be great.
> Barring that, a quick outline of things to do, check for, etc would also be
> appreciated.

The LDMud source (https://github.com/ldmud/ldmud/blob/master/mudlib/telnetneg.c)
contains a telnet hook implementation with the following telnet protocols:
NAWS, STATUS, TTYPE, TSPEED, NEWENV, ENVIRON, XDISPLOC, EOR, LINEMODE, TM,
BINARY, SGA and ECHO.
In addition our mudlib (ftp://unitopia.de/pub/UNItopia/mudlib.tar.gz)
extends this implementation (in /i/player/telnet_neg.c) with the following
protocols: CHARSET, COMPRESS, COMPRESS2, STARTTLS, AUTHENTICATION, MSSP, MXP
and GMCP.

Greetings,
Gnomi

Travis Everett

unread,
Feb 18, 2022, 11:41:49 AM2/18/22
to ldmud...@googlegroups.com
I imagine the UNItopia implementation will be more informative, but FWIW the blog post I wrote on GMCP negotiation in LDMud was based on work I did on Tsunami running LDMud 3.3.719--with json efuns added. If you run into any hitches in negotiation it may at least help disambiguate.

--
You received this message because you are subscribed to the Google Groups "LDMud Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ldmud-talk+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ldmud-talk/Yg%2BIRkrygPYqArJY%40platinum.motzkau.

Malcolm Tester

unread,
Feb 18, 2022, 3:11:13 PM2/18/22
to LDMud Talk
Thanks Gnomi and Travis.  Travis, link to the blog post?

Malc

Zesstra

unread,
Feb 18, 2022, 3:43:58 PM2/18/22
to ldmud...@googlegroups.com
Hello Malcom,

the protocols you mentioned are all independent and non-exclusive - if you
like you can offer them all to clients, but that will be much work. BTW: most
of the work is not the protocol itself, but the changes you have to do in the MUD.

My personal take on them:
GMCP: I like the transport layer. I dislike half of the module/package
definitions floating around and the chaos it is surrounded with. Most of the
work and the never-ending story is defining and implementing the
packages/modules for a specific mud.
MSDP: I never used it and I prefer the transport layer of GMCP. I would avoid
supporting MSDP and GMCP at the same time.
MSDP-over-GMCP: For me it is not worth the effort to implement it (at least at
the moment).
MSSP: not designed for players/clients - implement if you like... But not too
important.
MXP: I don't really like it, because of the focus on physical text styles and
do not want to implement custom HTML + browsers.
MSP: mhmm, ok, if you have Sounds+Audio. But I don't like the in-band
transmission and never used it so far.
MSP-over-GMCP: solves the in-band problem problem. I would choose this, but
did not use it so far.

For LDMud it should not be a great difference, which you choose. Although for
GMCP and 3.3.x you somehow need the JSON package or something else to
serialize/parse JSON.
The question is more, what features do you want or your players want.

You can have a look at Morgengrauens variant for telnet negotiations, they are
different to Unitopia and leave some options to the driver.
https://github.com/MorgenGrauen/mg-mudlib/blob/master/secure/telnetneg.c
Maybe also in the mudlib master, login object and player object for the
integration.
For GMCP and MSSP:
https://github.com/MorgenGrauen/mg-mudlib/blob/master/std/player/protocols/gmcp.c
https://github.com/MorgenGrauen/mg-mudlib/blob/master/secure/misc/mssp.c

Bye,
Zesstra
--
MorgenGrauen -
1 Welt, mehr als 200 Programmierer , mehr als 16000 Raeume,
viel mehr als 7000 unterschiedliche Figuren, 90 Quests, 13 Gilden,
ueber 5000 Waffen und Ruestungen, keine Umlaute und ein Haufen Verrueckter.
Existenz: mehr als 25 Jahre
http://mg.mud.de/

Malcolm Tester

unread,
Feb 18, 2022, 6:58:57 PM2/18/22
to LDMud Talk
Thanks for the response too, Zesstra!  Gives me a good lead to start deciding.

Travis Everett

unread,
Feb 18, 2022, 9:23:30 PM2/18/22
to ldmud...@googlegroups.com
On Fri, Feb 18, 2022 at 2:11 PM Malcolm Tester <malcolm...@gmail.com> wrote:
Thanks Gnomi and Travis.  Travis, link to the blog post?

I don't think there's a ton on the topic out there, so it's probably nothing new if you've searched on ldmud + gmcp, but https://t-ravis.com/post/mud/ldmud-gmcp-negotiation/ (originally posted on mudflinging.tumblr.com, but migrated it a few years back).

T

Zesstra

unread,
Feb 19, 2022, 5:27:57 AM2/19/22
to ldmud...@googlegroups.com
Hello Malcom,

if you look at our telnet negotiations, I probably should add some pointers...

First, look also at
https://github.com/MorgenGrauen/mg-mudlib/blob/master/secure/telnetneg-structs.c
for the struct in use and especially this is important:
telopt_s->lo_wishes->localside: the state we want to be in (WILL/WONT)
telopt_s->lo_wishes->remoteside: the state we want the other side to
be in (DO/DONT)
telopt_s->re_wishes->localside: the state the other side wants US to be in
(DO/DONT)
telopt_s->re_wishes->remoteside: the state the other side wants to be in
(WILL/WONT)
telopt_s->state: the currently effective state of the option on the two
sides.
[explanation:
The side that sends WILL wants to use the option on their side. The other can
respond with DO (yes, use it on your side) or DONT (no, don't use it on your
side).
The side that sends DO wants the OTHER side to use the option and the other
side can respond with WILL (yes, I will use it) or WONT (no, I won't use it).
Often, both direction channels can be negotiated independently, e.g. it would
be possible to negotiate BINARY transmission only for the direction mud->client.
]

The basic telnet option handler works by registering closures for handling
remote and local sides for each supported option.
If a remotehandler exists, the client is allowed to switch on the option on
their side (and usually we send DO) and the remote handler gets all sideband
(SB) data that the client sends us plus status changes on the client side
(activation, deactivation).
If a localhandler exists, we try to switch on the option on our side (we send
WILL) and the handler will receive any status changes of the option
(activation, deactivation) on the mud side.
A new option is supported by adding and registering the needed handlers and
the basic one delegates to them.

The basic handler keeps track of the wishes of both sides during negotiation
(keep in mind, that most telnet options are *symmetrical*, i.e. mud and client
can use or not use them independently) and switches the active state only when
negotiation is concluded for the respective option.

To complicate matters, the handler is inherited by the login object
(/secure/login) and the basic player object (/std/player/base), because both
have to negotiate with the client (not only during login). And when the
connection is switched to the final player object, the state has to be
transferred as well.

Also, some options are already negotiated during login (e.g. EOR), but some
are only available once the player object took over the connection after login
(e.g. CHARSET and GMCP).

Tamarindo

unread,
Feb 19, 2022, 8:22:14 AM2/19/22
to LDMud Talk
Some simple examples of the protocols here too: https://github.com/age-of-elements/age-of-elements/tree/master/obj/login.  If the JSON goodies are not included your driver version there is a copy of something you could do mudlib side that could be shared.

-Tamarindo@StickMUD

Malcolm Tester

unread,
Feb 20, 2022, 3:01:47 AM2/20/22
to LDMud Talk
Thanks again Zesstra.  I've been studying the differences between the LDmud master of telnetneg.c and MG's version and Unitopia's, all of which are very fleshed out.  Age of Elements is simpler, so I may start there to get a working version, and then worry about adding more to it.  I think I have a pretty good grasp on the DO/DON'T/WILL/WON'T, but of course once I get into it I may find differently.

Tamarindo, thanks for your pointer as well.  I am actually on a version of the driver prior to JSON being added in. I was going to look at either backporting some of that, or just writing one in LPC...but if you have one you can share, that would save a bunch of effort!

Thanks for all the pointers, everyone!
Malc @Infinity

Malcolm Tester

unread,
Feb 20, 2022, 5:14:24 PM2/20/22
to LDMud Talk
Zesstra, why do you have the struct for the telopts in a separate file (telnetneg-structs.c) inherited by telnetneg.c, instead of just being in telnetneg.c?

Malc @Infinity

Invisible

unread,
Feb 20, 2022, 6:11:53 PM2/20/22
to ldmud...@googlegroups.com
On 20.02.22 23:14, Malcolm Tester wrote:
> Zesstra, why do you have the struct for the telopts in a separate file
> (telnetneg-structs.c) inherited by telnetneg.c, instead of just being
> in telnetneg.c?
>
> Malc @Infinity


That's necessary if you want to use the struct in other programs as
well, e.g. pass them via call_other().

Re-defining the same struct elsewhere does not do the trick, because in
LDmud structs are identified by the program they are defined in (the
program is even referenced in the serialized form from
save_object/save_value). So having them in a separate program and
inheriting them wherever necessary is an elegant way to solve this.

cya,

  Invisible@Beutelland

Reply all
Reply to author
Forward
0 new messages