09 Mar, 2009, David Haley wrote in the 21st comment:
Votes: 0
Oh? Where else would the OOB signals be supported?
09 Mar, 2009, quixadhal wrote in the 22nd comment:
Votes: 0
Tyche is correct, the Diku authors didn't understand (or were just too lazy to bother with) the plain old telnet protocol, let along OOB signals, so when an OOB request shows up, they really do treat it as an error and drop the connection. Look for the comment "freaky folks" in comm.c, under most Diku variants.
09 Mar, 2009, Barm wrote in the 23rd comment:
Votes: 0
David Haley said:
Oh? Where else would the OOB signals be supported?


After a cup of coffee, I realized that was a silly comment.

Edit: Looked it up and had my layers wrong. My only experience with OOB signalling was years ago using DS1's. I was thinking it was restricted to the transport layer but then TCP *is* the transport layer.

My Telnet server class currently ignores this list but I'll re-think it if I'm actually dropping useful data.
09 Mar, 2009, elanthis wrote in the 24th comment:
Votes: 0
quixadhal said:
However, under linux, every thread is a first-class process, meaning you get all the overhead of having seperate (possibly duplicated) memory pages, a full context switch, and the scheduler treats them all as seperate scheduled entities.


Your claims are incorrect, good sir. Unlike other OSes, a "first-class process" in Linux is almost an entirely meaningless term. Threads do not, for example, duplicate memory pages ever, as multiple threads in one processes share a single page table. The only thing that would get duplicated in the the stack, which is going to be duplicated in ANY threading system unless you don't want to be allowed to use local variables. Even when you call fork(), no new memory is allocated other than the stack. The pages are copy-on-write in that case, so only if you start modifying data will pages be copied.

The weight of a context switch is also very light. When one of the threads is sleeping most of the time it will incur no overhead at all. The kernel itself is implemented as a large number of threads specifically because they are so very lightweight and efficient. Linux's threads implementation outperforms every other popular general purpose OS, iirc.

That said, you still get better performance for highly synchronous software (like most MUDs) by using select/poll/epoll/kqueue/etc.

If you're going to use threads in a MUD, you are far better off implementatinig it by giving each separate area its own thread. Since entities rarely interact between areas in most MUD designs, that would result in each thread being able to run most of the times (instead of constantly blocking due to synchronization needs).

That said, I'd actually recommend avoiding threads and going with full processes in that case, especially if you're using a C/C++ (but I still recommend it even for people using Ruby, Java, and so on). The reason for this is that each process, serving one area, only has a need to access the data local to it. It has no need to access data in other areas, and such a separation makes it far easier to safely implement this. Even in languages that offer automatic synchronization between threads you can still end up with deadlocks or with mysterious performance problems (because it's way to easy to accidentally start using shared writable data without realizing it).

The multi-process approach does require an arbiter/gateway process that players connect through. This process's job is mostly just to launch (and possibly relaunch) area threads, to accept player connections and route them off to the proper area thread, and to handle any kind of MUD-wide chat requests.

One of the neatest things about a multi-process approach is that if the code crashes (and it's not the arbiter) then the arbiter can just restart the crashed area. A bug in the code would only bring down a small portion of the MUD instead of the entire thing. The arbiter is (hopefully) less likely to have bugs since it will be very simple code. TELNET handling, login and account creation, process management, and chat would be it. No need to deal with rooms, mobs, AI, objects, complex data serialization, etc. The most complex part would be redirecting the player input. You could even eliminate most of that by passing the player socket description to the relevant area using domain sockets, and then redirecting them back when the player follows an exit into a new area.

Probably above the heads of most hobbyist MUD coders (who can't even implement a TELNET state machine), but the architecture is sound. It's similar to what most MMOs use, just simplified down a lot.
09 Mar, 2009, David Haley wrote in the 25th comment:
Votes: 0
I've been toying with the idea of "sharding" the MUD like that, although not dividing things by area but rather by some actual game-geographical division. The main reason is that I don't think of areas as separate, independent, orthogonal chunks of game. They're just convenient divisions. So, there actually could be a fair bit of interaction between certain area clusters as mobs wander around between them. Nonetheless the game would be more or less clustered so it could make sense to separate things into processes like this. The annoying thing is keeping track of various forms of global state, but that could be worked around.
09 Mar, 2009, elanthis wrote in the 26th comment:
Votes: 0
I am somewhat confused as to the purpose of areas if you're not using them for meaningful divisions, but your call. You could add a Zone or Shard object that areas are in. You know, whatever displaced volume of liquid exerts upward force on the hull of your transport of lesser density, as the saying goes…
09 Mar, 2009, David Haley wrote in the 27th comment:
Votes: 0
A forest and the village inside it might be two separate areas, and are therefore meaningfully divided into logical chunks, but that doesn't mean that they are fully independent. In fact, they might be quite dependent as villagers wander into the forest and so forth. However, together they form a cluster that is independent from the jungle on the other side of the continent.
11 Mar, 2009, Tyche wrote in the 28th comment:
Votes: 0
IRT OOB…
The only mud use I could think of at the time for OOB data was to clear the command buffer. So that's what TeensyMud does when an attention is received from PuTTY or Telnet. I remember playing on Dikus and one could accidentally or purposely stack commands in combat, and regret it if the situation changed. Such a thing would have been useful. Of course OOB data isn't the only way to implement such a thing, as one could always code their server to process a clear command buffer immediately in-band.

IRT Shards…
CoolMud (circa 1993!) is rather interesting as it allows one to connect multiple servers together into a distributed mud. The muds communicate with each other via a UDP network. It's transparent to the player.
11 Mar, 2009, Scandum wrote in the 29th comment:
Votes: 0
elanthis said:
Probably above the heads of most hobbyist MUD coders (who can't even implement a TELNET state machine), but the architecture is sound. It's similar to what most MMOs use, just simplified down a lot.

I think you get better results with load balancing.
20.0/29