[MUD-Dev] Threading and Queues (What Fun)

Sean Miller unvexis at yahoo.com
Mon Feb 17 07:11:43 New Zealand Daylight Time 2003

This is my first post to this mailing list--in fact, my very first
to any mailing list whatsoever--so I hope I'm doing this correctly.

<EdNote: Attribution added.>

On Sun, 16 Feb 2003 01:29:33 -0500 
Ben Chambers <bjchamb at bellsouth.net> wrote:

> I was considering just looping but I feel that it could
> potentially introduce lag into the system.

Traditional asynchronous I/O need not introduce any lag into a
well-designed system. Calls to select() with well-managed fd_sets
can do what you what quite easily and efficiently. The Windows
Sockets library does support asynchronous I/O with FD_SETs, of
course, but it will require you to heavily utilize preprocessor
magic to generate portable source. So perhaps threading is the most
portable solution after all, as can assume that POSIX-threads
libraries will exist on nearly all modern platforms.

> I'm considering a system that uses two or three threads and has
> MySQL as a database.

This would, of course, introduce quite a bit of overhead. Queries to
databases will never be as quick as calling the member functions of,
say, your game objects. Threading would introduce synchronization
complexities--and let's not forget the context switching. Some
people may be eager to propose fork()ing, but that's even less
portable (you'd be constrained to *nixes), so I'd think you'd be
better off either threading or select()ing.

If you wish to be able to stuff your game data into a database,
merely design your MUD so that you can dump everything into, say,
CSV format. Then you can import it directly into any spreadsheet,
database, or whatever. Except MS Access, which has a lot of catching
up to do in the DBMS world.

Also, don't take this as a flame or insult, but perhaps you ought to
look into PostgreSQL. Unlike MySQL, Postgre fully supports
subselects and transactions and other incredibly useful
features--and it's free, too.

> Each space has a pointer to the head of two linked lists, delayed
> actions (for timed actions) and immediate actions.

Timed actions such as spellcasting? I'm sure you can imagine a
finite number of timed actions that will take place in your MUD;
therefore, you ought to hard-code them with appropriate status
flags, if possible. If you design your game well, it will be trivial
to add new timed actions via simple modifications to your code-base.

> Has anyone used threads like this before?

Yes, I have done exactly this, once before. I implemented a MUD
wherein I maintained a pair of queues--one for input and one for
output--which contained the incoming and outgoing messages,
respectively. One thread was spun off to block on accept(); another
was spun off to check for messages in the outgoing queue and send()
them, if any. Whenever the accept-thread received a new connection,
it spun off a thread to handle user input from the new connection
which would stuff each command from the player into the incoming
queue. The main thread handled parsing the commands, executing them,
shoving the results into the outgoing queue, updating the game world
every tick, etc..

As you can already imagine, this was not a particularly efficient
approach to asynchronous I/O.  Using that design, you would have 2 +
n extra threads running at any given time, where n = the number of
player connections. Sure, modern processors can switch context
millions (billions?) of time per second, but that still constitutes
significant overhead.

Unless you're planning on running this on a 486 DX2 66MHz or
something like that, I don't think you need to be as concerned with
performance as you seem to be.

Sean Miller
MUD-Dev mailing list
MUD-Dev at kanga.nu

More information about the MUD-Dev mailing list