<!-- MHonArc v2.4.4 --> <!--X-Subject: [MUD-Dev] mud client development systems --> <!--X-From-R13: Ehaal Uhyngv <fhaaljvmNenqvxf.arg> --> <!--X-Date: Sun, 6 Dec 1998 13:37:17 -0800 --> <!--X-Message-Id: 2.2.32.19981206213849.006b44d4#pop,radiks.net --> <!--X-Content-Type: text/plain --> <!--X-Head-End--> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <html> <head> <title>MUD-Dev message, [MUD-Dev] mud client development systems</title> <!-- meta name="robots" content="noindex,nofollow" --> <link rev="made" href="mailto:sunnywiz#radiks,net"> </head> <body background="/backgrounds/paperback.gif" bgcolor="#ffffff" text="#000000" link="#0000FF" alink="#FF0000" vlink="#006000"> <font size="+4" color="#804040"> <strong><em>MUD-Dev<br>mailing list archive</em></strong> </font> <br> [ <a href="../">Other Periods</a> | <a href="../../">Other mailing lists</a> | <a href="/search.php3">Search</a> ] <br clear=all><hr> <!--X-Body-Begin--> <!--X-User-Header--> <!--X-User-Header-End--> <!--X-TopPNI--> Date: [ <a href="msg00906.html">Previous</a> | <a href="msg00908.html">Next</a> ] Thread: [ <a href="msg00912.html">Previous</a> | <a href="msg00908.html">Next</a> ] Index: [ <A HREF="author.html#00907">Author</A> | <A HREF="#00907">Date</A> | <A HREF="thread.html#00907">Thread</A> ] <!--X-TopPNI-End--> <!--X-MsgBody--> <!--X-Subject-Header-Begin--> <H1>[MUD-Dev] mud client development systems</H1> <HR> <!--X-Subject-Header-End--> <!--X-Head-of-Message--> <UL> <LI><em>To</em>: <A HREF="mailto:mud-dev#kanga,nu">mud-dev#kanga,nu</A></LI> <LI><em>Subject</em>: [MUD-Dev] mud client development systems</LI> <LI><em>From</em>: Sunny Gulati <<A HREF="mailto:sunnywiz#radiks,net">sunnywiz#radiks,net</A>></LI> <LI><em>Date</em>: Sun, 06 Dec 1998 15:38:49 -0600</LI> <LI><em>Reply-To</em>: <A HREF="mailto:mud-dev#kanga,nu">mud-dev#kanga,nu</A></LI> </UL> <!--X-Head-of-Message-End--> <!--X-Head-Body-Sep-Begin--> <HR> <!--X-Head-Body-Sep-End--> <!--X-Body-of-Message--> <PRE> This is a dump of my thoughts on a particular subject that makes my brain drool. I'm hoping to find other people similarly interested; i'm also interested in feedback. This is long - like 380 lines. I started writing in a non-technical mood.. it picks after the first 40-50 lines. [for the impatient, skip down to STATE OF AFFAIRS] BACKGROUND Ever since 1989, when I was sitting in the Dungeon Cafeteria in Friley at Iowa State University, sharing lunch with my friend Xeno (Gary Snethen), I've had a dream. It was a dream of creating a mud kinda like (back them) the Temple of Kesmai, a multi-user 2D pay-by-the-hour environment that Gary would play. I had been hooked since the day that I saw him trying to take out a dragon inside a dungeon. He kept dodging the flames and hiding behind walls and stuff.. it was awesome. I wanted to write my own! Well, I tried a couple of different things. In 1990, I had a 80286 with 640k of memory, a 1.2M floppy, turbo pascal, and no hard drive. I wrote a map caching/paging thing which allowed lookups into a large virtual map - which was mostly stored on disk, with the most recently used parts being kept in memory. That's about as far as I got - I had no idea how to go about writing a driver - especially not in Turbo pascal. I realize now that my confusion was from a lack of socket libraries, lack of knowledge about sockets in general, and not knowing the wonderful world of fork(). In 1994, a friend and I started redesigning our mud - (Vincent's Hollow, mud.vhdev.com 1991, currently in the middle of a move, temporarily at gatekeeper.e-markets.com 1991). I revived some of my ideas about a 2D world, by proposing a "wasteland", where higher level characters could go and attempt to manage economies, using a 2D-based setup kinda like Civilization (the board game). Well, we got the mud up and running, but the Wasteland was shelved. THE STATE OF AFFAIRS in 1996(?) something wierd happened. I heard about this game called Ultima Online. OH MY GOD. They stole my idea. THEY COULD DO IT RIGHT! How dare they? YIPPEE!!... I had mixed feelings about the subject. (To this day i have not played Ultima Online. After having been god for 7 years on a mud, its hard to be just a player.) Since then, it seems that mudding is making a comeback - of sorts. Everybody is playing multiplayer online games. But they're very graphical, real world (2d + 3d) oriented. The clients are pretty.. uh.. optimized, proprietary, etc. Not high-level - where one can deal mostly in concepts. (That's what brought me into muds.. I have turned out to be a mostly high-level concept/design type programmer. I suck at hacking tons of C, but I'm awesome at Perl/Java etc. LPC was ahead of its time, and I really loved developing in it.) [Note: there are clients out there like UO for Linux - i don't know how much source is available.. but thats still a specific implementation of a solution. See below to my dream] MY OVERALL DREAM From most general to more specific, these are my dreams: 1. I want to build a world where the players take part in the economy and law of the world, where socializing is looked towards. [that's a whole 'nuther topic, and doesn't require dream #2 to be implemented first] 2. I want to build a client/server/mudlib combination that can be used to implement an ultima-online type of world. This is a very tall order. I can't do this myself. 3. I want to publish a framework/API/convention that makes it easy for OTHER people to build a client/server/mudlib combination, to make ultima-online type of worlds. Make it open source :), see where the world takes it. MY TECHNICAL DREAM Okay, going to get down and dirty. This is my first time spewing these ideas into a document, everything else was scribbled on recycled printer banner pages (while dodging a cat who insisted on being the writing board.) Im going to prefix portions of "spec" with "**". -- Use Telnet -- ** Everything still depends on "telnetting" into a mud just as we do nowadays. I want to layer the client/server connections on top of telnet. That way, you don't have to write a new driver - you just write new objects in your mud. The driver mods can come later after the framework is settled. -- how exactly the client/server relationship works -- I'll do this by example. Note that I don't remember LPC syntax anymore. user joe has connected to the mud. he has requested to join a particular channel/chatline. We're calling a function in the channel server that initiates the channel. we pass Joe in as an arg. int setupChannel(object user) { object chatwindow; chatwindow = user->newclientobject("VH-textwindow-1.0","chat"); chatwindow->print("Welcome to the Chat Channel!\n"); user->setenv("chatwindow",chatwindow); } okay, so there's a ton of holes in here. The point is, the server simply opens up a chat window on the client, and addresses it like it like any other object. Specifically: ** there's a server-side object that gets the method invocations, and passes them (over telnet) to the client - probably using a special character to begin/end an object message. ** The client sends back its responses via a special user verb. (detailed further below) Now, i'm going to run into latency problems like this - don't want the mud to pause while waiting for the new chat window to open on Joe user's client. He might be running a *gasp* 386 or something. (or by today's standards, a Pentium 60. Heh.) I would like this system to be runnable over a 14.4 or 28.8 link. Actually, i have my mom's laptop - its a 486/25 running win95. If I can get the client written in Perl/Tk, get it running on there, connected to the mud via PPP on a nullmodem cable running at 19200 and it seems to work well, then I'll say i've designed a good system. So, I would say that: ** Method invocations are asynchronous, call-back type functions. The standard I would use is: ** to do a call, do: object->func(callbackfunc, payload, args) (ie, call_client(object,function,callback,payload,args...)) ** to receive a callback, somethign like: callback(callerinfo,status,payload,args) This would rewrite the code snipplet above to something like: int setupChannel(object user) { object chatwindow; object userkernel = user->getClientObject(); int queryid = userkernel->newobject((:this object,"setupChannel2":), user, "VH-textwindow-1.0","chat"); // queryid is a query that is in progress. we could save it for // killing the query later or something. } int setupChannel2(int query, int status, object user, mixed arg) { if (status == FAIL) { tell_object(user,"sorry, no can do. your client does not support blah"); return; } else { // arg has the user's VH-textwindow-1.0 object object in it. // specifically, it has the server side mirror of the object. arg->sendMessage("Welcome to the Chat Channel!\n"); user->setenv("chatwindow",arg); } } and later on, to send a chat message to that window, you just do: user->getenv("chatwindow")->sendMessage(msg); Now, the astute reader will note ... many things. What I noticed was: First off, the userkernel used above - I'm not so sure about that. that's a client/server shared object. Its the bootstrap object that all other objects get created and destroyed through. Further down in the explanation of how exactly communication occurs, i use a different model for initiating conversations between server and client. Secondly: I need to make sure async functions can chain to other async functions. This means: every async function needs to be told where to return to - and it will have to payload this information to any other async functions it calls. Might have to make that payloading a little more customized to make this easier. Thirdly: sendMessage is not an asynchronous function. That's right. Not all queries require answers. ** I specifically see three types of queries: ** queries that don't need an answer. No need for a callback on these. I figure most things would be like this - "move object o to location x,y" - "display this line of text" - "update the who list" - "play this background music now" - "play this sound now", etc. ** queries that need one answer (like, create a new object-> gives you back the object). ** queries that, once started, will continue to send back answers from time to time, till they decide to stop (somehow). (like, some sort of event dispatch mechanism. - like a who list which you can click on someone's name to send them a personal message.) (actually, that would be better done as a client object that initiates a conversation with the server to send a message). -- client side of things -- What would the client side of things look like? Well, the abovementioned VH-textwindow-1.0 object would look something like this (in perl) sub new { .. do some sort of nifty wizardry. I'm waiting eagerly for the Perl/Tk book to come out from orielly. } sub print { .. do something to display something in my self. } What I'm trying to say: It should look REALLY simple. Easy for mass numbers of bozos to be able to work on them. -- actual client/server message passing -- What would the actual server/client interaction look like? I'm kinda thinking about something like TCP, but without the acknowledgements: ** SERVER->CLIENT: "hey I want a connection to your object xyz, instance foom, and my socket id is 8192". (different socket number for every connection) ** CLIENT->SERVER: "8192, i refuse your connection" or ** CLIENT->SERVER "8192, acknowledge connection, my socket is 1283" then, ** SERVER->CLIENT "8192 to 1283, message "PRINT" args "Welcome to the Chat Channel" " Both the server and client would have their own maps as to which socket number points to which object. -- even more detail on message passing -- Here's what I envision a conversation looking like to someone with a packet sniffer: S->C ~8192 0000 NEW VH-textwindow-1.0 chat<CR> S->C You feel better. C->S MCSL 0000 8192 NAK<CR> -or- C->S MCSL 1283 8192 OK<CR> S->C ~8192 1283 MSG PRINT Welcome to the Chat Channel \n<CR> C->S n<CR> S->C You travel north. <CR> S->C You are in a maze of twisty little passages, all alike. <CR> S->C > S->C ~8192 1283 MSG PRINT Sunnywiz: Hey folks, what's up?\n<CR> Note that: ** Regular mud stuff is interspersed with the communications protocol. ** Note that the client responds using a verb like MCSL (or something, anything, to differentiate itself.) The portion of the client that takes what the user types will mask out that particular verb so the user cannot fake a response maliciously. ** server/client socket numbers are PER CONNECTION, ie your MCSL can never come in on another user's socket by using the same socket number. ** Might have to modify the receive()(?) funtion to make special cases of any regular "~" characters (escape them somehow), and have a seperate driver function to send the server/client stuff. But for now, i'll just have the client pass incorrect messages to the main telnet screen. I dont have any examples in here of queries with responses. Here's how to handle that: ** rather than MSG, use "Q1 <id#> method arg arg arg" ** the response to that would be "RS1 <id#> stuff stuff" ** for multiple queries, use "QN <id#>" ** the response would be "RN <id#> stuff stuff" (several times), with a final "RE <id#>". Also note that the server is initiating all the connections here. I would go beyond that: ** the client can initiate connections too, if it wants. Like you could have the client .rc file run a widget takes your username and password.. then attempts to log you into the mud. Maybe a single client could be connected to multiple muds, but that's beyond the scope of my "run-over-telnet" client here. -- multiple author support -- Note the name "VH-textwindow-1.0". "VH" stands for the author. (I apologize to any other muds who go by those initials - for me VH has been Vincent's Hollow for 8 years now.) "textwindow" is the name of the protocol you're aiming for. "1.0" is the version you're aiming for. Note that I say PROTOCOL. I don't care if your client side object is written in Java, C++, Perl, Tcl, Visual Basic, WHATEVER - you must provide the interface that "VH-textwindow-1.0" stands for, which is a single "PRINT" method. umm.. forgive the case change. I was just thinking SMTP, POP, etc protocols. Maybe uppercase would be a good idea at the protocol level - and "print()" function on the mudlib can generate a "PRINT" message at the lower level. CLIENT SIDE DREAMS I'm thinking for initial implementation, I would write the following client-side objects: -> something to pop up a window and display text in it -> something to download a "library" of information, and allow other objects to retrieve the information from it (ie, provide a url type syntax. like "library://sunnywiz1/song1.midi" would pull from this library, and "<A HREF="http://www.vhdev.com/~sunnywiz/song1.midi">http://www.vhdev.com/~sunnywiz/song1.midi</A>" would pull from the internet. This "lookup" would be a client side kernel api function. -> something to play a midi song (which can stop that song and start a different song). -> Maybe the client kernel can request download from the server of the specific library mentioned above. That would be a good test for client->server talks. I don't know which language to do this in yet.. probably Java, since it has multimedia support (or is supposed to). I've heard it has become more stable in the last 2 years since I last used it. Which would be a good thing. WRAPPING UP - WHATS NEXT I'm showing this to everybody to gauge a couple of things: 0. Is there any previous work on this? I've only been on this list for about 2 months now. I've tried going through the archives.. there's a LOT of stuff out there. One of these days I'll just download all the .tar.gz's and less and grep through them. (JCL, I could not get the "search" function to work well.. it never returned on me. waited about 5-10 minutes.) 1. Is there any other interest in this? 2. By discussion, my goals would become more refined as to what I want to do (ideas I like), and what I don't want to do. 3. Would anybody care to pick up on it and run with it? Like I said initially, i don't know how far I'm going to get. 4. If I did manage to get a rudimentary system put together, would other people be interested in adopting it and writing their own.. umm... widgets/client side objects? or providing support for non-LP muds? or as the protocols become stabilized, write a nice fast gtk or other cool crossplatform gui-based client? 5. Maybe theoretically design a 2D view window object. I have a lot of ideas on this, but that's call for a seperate paper. Lots of pros and cons, and I can probably find a lot of stuff in the archives here before I write that. And first steps first, I need the communications framework. 6. MCSL = mud client server link. Any better names? Something cheeky would be cool. :) 7. Looking like this would involve a bunch of short packets. I'm not sure what the effect is of various packet sizes regarding congestion and stuff. Maybe some sort of buffering is in order; bundling several individual messages into one ~...<CR> and MCSL...<CR> pair? How much of a difference would this make? Maybe the layers can be designed so that actual interpretation of a ~message<CR> allows for decoding of an array of messages (though initial implementation, only one message is returned). 8. [after reading a thread from march..] This will still be susceptible to lag. Its running over telnet which runs over TCP. Maybe the Async model should be extended to deal with a timeout on the method invocations (actually, it absolutely should.) - could maintain a queue of dispatched async events - only allow so many to build up while waiting for responses. - the send-message-only-no-response system could be set up with a message# for each message, and have an ack packet that states the last message # seen. (sent at least once every N seconds?) That way, the server knows how badly lagged a client is, and can choose to send a full update rather than the list of changes. Comments, Questions? Would love to hear from you guys. Y'all Rock. // Sunny Gulati // sunnywiz#radiks,net (Home) </PRE> <!--X-Body-of-Message-End--> <!--X-MsgBody-End--> <!--X-Follow-Ups--> <HR> <ul compact><li><strong>Follow-Ups</strong>: <ul> <li><strong><A NAME="00908" HREF="msg00908.html">[MUD-Dev] Re: mud client development systems</A></strong> <ul compact><li><em>From:</em> Caliban Tiresias Darklock <caliban#darklock,com></li></ul> </UL></LI></UL> <!--X-Follow-Ups-End--> <!--X-References--> <!--X-References-End--> <!--X-BotPNI--> <UL> <LI>Prev by Date: <STRONG><A HREF="msg00906.html">[MUD-Dev] Introduction</A></STRONG> </LI> <LI>Next by Date: <STRONG><A HREF="msg00908.html">[MUD-Dev] Re: mud client development systems</A></STRONG> </LI> <LI>Prev by thread: <STRONG><A HREF="msg00912.html">[MUD-Dev] Re: Stack-Based NPC AI</A></STRONG> </LI> <LI>Next by thread: <STRONG><A HREF="msg00908.html">[MUD-Dev] Re: mud client development systems</A></STRONG> </LI> <LI>Index(es): <UL> <LI><A HREF="index.html#00907"><STRONG>Date</STRONG></A></LI> <LI><A HREF="thread.html#00907"><STRONG>Thread</STRONG></A></LI> </UL> </LI> </UL> <!--X-BotPNI-End--> <!--X-User-Footer--> <!--X-User-Footer-End--> <ul><li>Thread context: <BLOCKQUOTE><UL> <LI><STRONG>[MUD-Dev] Re: Stack-Based NPC AI</STRONG>, <EM>(continued)</EM> <ul compact> <ul compact> <LI><strong><A NAME="00914" HREF="msg00914.html">[MUD-Dev] Re: Stack-Based NPC AI</A></strong>, Par Winzell <a href="mailto:zell#alyx,com">zell#alyx,com</a>, Mon 07 Dec 1998, 01:18 GMT <UL> <LI><strong><A NAME="00925" HREF="msg00925.html">[MUD-Dev] Re: Stack-Based NPC AI</A></strong>, David Bennett <a href="mailto:ddt#discworld,imaginary.com">ddt#discworld,imaginary.com</a>, Mon 07 Dec 1998, 20:03 GMT </LI> <LI><strong><A NAME="00926" HREF="msg00926.html">[MUD-Dev] Re: Stack-Based NPC AI</A></strong>, David Bennett <a href="mailto:ddt#discworld,imaginary.com">ddt#discworld,imaginary.com</a>, Mon 07 Dec 1998, 20:05 GMT </LI> </UL> </LI> </ul> <LI><strong><A NAME="00912" HREF="msg00912.html">[MUD-Dev] Re: Stack-Based NPC AI</A></strong>, Marc Hernandez <a href="mailto:marc#ias,jb.com">marc#ias,jb.com</a>, Mon 07 Dec 1998, 00:22 GMT </LI> </ul> </LI> <LI><strong><A NAME="00907" HREF="msg00907.html">[MUD-Dev] mud client development systems</A></strong>, Sunny Gulati <a href="mailto:sunnywiz#radiks,net">sunnywiz#radiks,net</a>, Sun 06 Dec 1998, 21:37 GMT <UL> <LI><strong><A NAME="00908" HREF="msg00908.html">[MUD-Dev] Re: mud client development systems</A></strong>, Caliban Tiresias Darklock <a href="mailto:caliban#darklock,com">caliban#darklock,com</a>, Sun 06 Dec 1998, 22:04 GMT </LI> </UL> <UL> <li><Possible follow-up(s)><br> <LI><strong><A NAME="00962" HREF="msg00962.html">[MUD-Dev] mud client development systems</A></strong>, Sunny Gulati <a href="mailto:sunnywiz#radiks,net">sunnywiz#radiks,net</a>, Mon 14 Dec 1998, 04:07 GMT <UL> <LI><strong><A NAME="00977" HREF="msg00977.html">[MUD-Dev] Re: mud client development systems</A></strong>, J C Lawrence <a href="mailto:claw#under,engr.sgi.com">claw#under,engr.sgi.com</a>, Thu 17 Dec 1998, 04:47 GMT </LI> </UL> </LI> <LI><strong><A NAME="00971" HREF="msg00971.html">[MUD-Dev] mud client development systems</A></strong>, Jay Carlson <a href="mailto:nop#mitre,org">nop#mitre,org</a>, Tue 15 Dec 1998, 22:56 GMT </LI> </UL> </LI> </UL></BLOCKQUOTE> </ul> <hr> <center> [ <a href="../">Other Periods</a> | <a href="../../">Other mailing lists</a> | <a href="/search.php3">Search</a> ] </center> <hr> </body> </html>