Tree [641b33] master /

HTTPS access

File Date Author Commit
 areas 2011-06-05 Marco Fontani Marco Fontani [4402e5] Areas in JSON format; parser for SMAUG areas
 benchmarks 2011-06-04 Marco Fontani Marco Fontani [2ef2e4] Use XS code rather than Inline::C
 datalogs 2010-07-21 Marco Fontani Marco Fontani [75b6c7] Import from older repo
 docs 2011-06-04 Marco Fontani Marco Fontani [d474f1] Big code drop
 lib 2011-06-06 Marco Fontani Marco Fontani [386351] Cache areas list for cmd_list
 scripts 2011-06-05 Marco Fontani Marco Fontani [66dea8] Allow fuzzier to do WHO <arg> or just WHO
 t 2011-06-04 Marco Fontani Marco Fontani [d474f1] Big code drop
 Build.PL 2011-06-04 Marco Fontani Marco Fontani [2ef2e4] Use XS code rather than Inline::C
 EXTENSIONS.mkd 2011-06-04 Marco Fontani Marco Fontani [d474f1] Big code drop
 LICENSE 2010-07-21 Marco Fontani Marco Fontani [75b6c7] Import from older repo
 MANIFEST 2011-06-05 Marco Fontani Marco Fontani [4402e5] Areas in JSON format; parser for SMAUG areas
 MANIFEST.SKIP 2011-06-05 Marco Fontani Marco Fontani [4402e5] Areas in JSON format; parser for SMAUG areas
 Makefile 2011-06-04 Marco Fontani Marco Fontani [2ef2e4] Use XS code rather than Inline::C
 README.mkd 2011-06-05 Marco Fontani Marco Fontani [4402e5] Areas in JSON format; parser for SMAUG areas
 TODO 2010-12-23 Marco Fontani Marco Fontani [091bfe] Todo stuff
 auto 2011-06-04 Marco Fontani Marco Fontani [2ef2e4] Use XS code rather than Inline::C
 log.conf 2011-02-07 Marco Fontani Marco Fontani [81fd15] Fix some module inclusions
 mud 2011-06-06 Marco Fontani Marco Fontani [641b33] fix compilation on linux
 mudanyevent 2011-06-06 Marco Fontani Marco Fontani [869f04] No reason for this to send telnet options as it...

Read Me

What is this?!

Anacronia v4 - Copyright (c) 2009-2011 Marco Fontani - MFONTANI at CPAN dot ORG
Released under the GPL v.3.0 license -- see LICENSE

Anacronia V4 is the fourth rewrite of a Multi User Dungeon (MUD), a multi-user
internet gaming system. It is written in the Perl programming language, and
uses "modern" technologies and modules, such as AnyEvent and Memcached.

In any examples in this document the "$ " indicates the shell prompt; anything
after it indicates the command you should type. Any lines after it, unless it
also starts with a "$ ", indicates the output the command should give.


This MUD cannot (yet) be used as-is. In its current status in the "master"
branch, it will merely start up and shut down my itself after a number of
ticks, whilst gathering statistics.


In order to start the MUD, you'll need the following Perl modules installed.
You will also need a working C compiler, as the program uses XS code.
You may want to use App::cpanminus to install these, as that allows you to
have them installed in your $HOME rather than system wide.
Patches to create a local::lib with the prerequisite modules installed under
inc/ are welcome.

Getopt::Long                    Used to get command-line args for "mud"
Pod::Usage                      Used to show the manpage for "mud"
Digest::MD5                     Used to calculate Memcache keys for help pages
AnyEvent                        Async event loop that makes the mud "tick"
AnyEvent::Gearman::Client       Cmds involving delegating commands to workers
AnyEvent::Handle                Handles server/clients
AnyEvent::Socket                Handles low-level sockets asynchronously
JSON::XS                        To parse the area and help files
Cache::Memcached::Fast          To cache ansified help pages, and soon more
XSLoader                        To load the XS code used by the ansifier
Class::XSAccessor               Used to generate r/w getters/setters
Compress::Raw::Zlib             Used for MCCP (compression) support
Log::Log4perl                   For debugging and logging purposes
Time::HiRes                     Very precise timings and time differences
YAML                            Debugging and dumping data structures
Chart::Clicker                  For creating nice charts

The following event loops (supported by AnyEvent) are suggested to be installed,
for the server to be as performant as it can be. The "mud" executable will require
and load Event on OSX and EV otherwise. The "mud" executable will refuse to run if
it senses it would run under the "default" pure-Perl event loop.
    EV                          For Linux; seems to not work correctly on OSX
    Event                       For OSX

You may install the prerequisite modules by issuing commands similar to the following:

$ cpan  Digest::MD5
$ cpanm Digest::MD5

A Build.PL file is also included, and it may (or may not) help you installing
the right prerequisites, too.

In order for the XS code to be built, at least the following must be ran:

$ perl Build.PL
$ ./Build

Launching the MUD

Once the prerequisite modules are installed and working, you can launch the
MUD by typing, in the root of this repository:

$ perl mud
[...] lots of output
TCP ready on address * port 8081

The "mud" program accepts several options; you can see these options by
typing the following:

$ perl mud --help
    ./mud [options]
#  ..  follows list of options

Once the mud is running, you will be able to connect to it and play around once
you have decided a handle name for yourself. Currently the MUD requires no passwords
to connect, and all commands are available to all users.

The MUD's Perl modules

The various mud-related modules that constitute Anacronia V4 are located in the
lib/ subdirectory of this repository.

Their purpose is as follows:

lib/                  The server. It loads the area files, accepting
                            connections, and handles the connections. Some
                            of the subs and behaviour here should be moved
                            to Av4::Server, in due time.
lib/Av4/           The object that identifies the server. It contains
                            the input and output buffers for the clients, the
                            parsed help pages, etc.
lib/Av4/           Contains constants used for handling telnet options.
                            None of the modules on CPAN fulfilled the purpose of
                            this module precisely.
lib/Av4/    Handles all the supported telnet options for a
                            connection: MCCP, TTYPE, NAWS, as well as analysing
                            incoming data and sending data to the connected sockets.
lib/Av4/             Handles the ANSI colorization of MUD strings by the MUD
                            itself, or as inputed by the players.
lib/Av4/           A basic MUD entity all entities inherit from. This handles
                            a basic command queue for all entities, and can execute
lib/Av4/Entity/    A mobile (monster) which can execute random commands
lib/Av4/Entity/    A player, whose ouput is sent rather than discarded.
                            Any connection made to the MUD gets assigned one of
                            these objects. This handles the connection's state,
                            as well as the telnet options associated, etc.
lib/Av4/          An object which identifies a MUD command, with its
                            name, queue priority, the amount of ticks it delays
                            for, the code that should be executed, and manages
                            its execution.
lib/Av4/         A list of all the commands (by category) supported
                            by the MUD. Here strings which trigger a command are
                            associated with the code (from other modules) which
                            executes such command.
lib/Av4/Commands/   All the basic commands which every user gets. In this
                            release any user is able to use the @shutdown command
                            to shutdown the MUD process or @mpall to force all
                            entities in a room to execute a command.
lib/Av4/Commands/     All the commands that handle the MCP protocol: the
                            authentication key, the negotiation, and some MCP
                            extensions. The support for MCP is far from working
                            reliably, as it needs tested with more clients.
lib/Av4/Commands/     Commands to test MXP with clients which support it.
                            Currently the MUD advertises MXP but doesn't do much.
                            A test "delegated" command, which uses Gearman to
                            ask a Gearman worker to execute an action and returns
                            output to the user once the callback returns with
                            output. The idea is to use this for long-running and
                            CPU intensive tasks which the MUD cannot do for
                            performance reasons (such as finding the shortest path
                            between two points).
lib/Av4/            A get_logger() function that gets the right logger
                            (Log::Log4perl instance) for a function; the cached
                            ansify() function which uses Memcached.
                            It also contains the commonly used %Av4::Utils::ANSI
                            hash which is used throughout where there is no need
                            to repeatedly ansify strings.
lib/Av4/             A "help page" object, with the level, keywords and
                            the data that actually comprises the help page.
lib/Av4/             An "area" object, which contains a number of prototype
                            rooms and mobiles.
lib/Av4/             A "room" object, which contains a number of players
                            and entities, has a description and exits, etc.
lib/Av4/        A utility module to parse area files and create the
                            relevant Area, Room, Help and other objects from it.

Other bits and pieces of information

The command queue concept.

In many MUDs commands are parsed and executed in a first-come first-served fashion, at
every tick which handles incoming text: if the character is currently performing an
action which delays (casting a spell for example), any other command (including the ones
which conceptually shouldn't be delayed such as SCORE) need to wait for the first
command to be executed, before being executed.
In other more modern MUDs there may be multiple command queues which allow the player
to perform delaying actions which don't overlap with each other. As an example, using
an attack prevents the player from attacking again before N seconds, but meanwhile
the player is "attack-delayed", they can still ready a defensive command, or see
their statistics via SCORE.
Anacronia V4 implements a queue system in which all the user's input is bunched into
a queue of commands, and commands are executed in order of priority. Adding
specific queue types (attack, defense, movement) is on the roadmap and should be
fairly easy to implement.

The process through which the queue system works is found on lib/Av4/ and
in lib/Av4/Entity/ There are some tests for it in t/001-av4-queues.t.

The datalogs, under datalogs/

Since the MUD supports a number of telnet and MUD-specific protocols, I've gathered
log dumps of the input/output of a number of MUD clients which connected to the
MUD a number of times. These can be found in the datalogs/ directory. They are
included for reference, and will/should be used to construct tests or debug non
working features. Some tools to massage these datalogs are found under scripts/.

The benchmarks

Using Devel::NYTProf several slow subroutines were found and sped up. For
example, the ansify() subroutine used to take most of the CPU time for the MUD.
Since then, the subroutine has been rewritten in XS. A benchmark file has been
added to benchmarks/ to allow users to repeat the benchmark and decide for
themselves if they want to use the XS version or substitute the much slower
pure Perl one.

The directory also contains some excerpts of older Devel::NYTProf runs on the MUD
executable, just in case these details need to be referenced or compared in the

The lib/ file can sense if it's running under Devel::NYTProf, and enable and
disable debugging before and after running the "main loop". This reduces the code
being profiled to the part that makes more sense (running the mud) rather than the
part which doesn't (the startup and shutdown, which only happen once).

To invoke the MUD under Devel::NYTProf, asking it to not start straightaway, use:

$ NYTPROF=start=no perl -d:NYTProf ./mud
$ nytprofhtml -d          # or with --minimal for only "lines" output

The scripts

There are some scripts which have been used during the development at one time or
the other.


The most used is scripts/ which allows a number of clients to connect
to the MUD and start sending a number of commands, fast. This is used to
benchmark various parts of the MUD and see which areas are slow or need some
The fuzzier is usually started using the scripts/launch-fuzzier helper, which
launches four fuzziers in the background, with 250 clients each.

Chart plotter:

scripts/ allows you to plot some statistics about the MUD, namely
the amount of clients connected and the time it took to perform the 'commands'
and 'flush' ticks, throughout the mud's uptime. The script needs Chart::Clicker,
and relies on the MUD creating the various *.csv files containing the information
for each tick.

The SMAUG area parser:

scripts/smaug-area-parser allows you to parse (some parts of) a SMAUG area file
and convert it into a JSON format that can be used by Av4. Not all functions
are working or implemented, but the most important parts are.

The simple telnet server:

The program "mudanyevent" can be used for testing whether it's Av4 that is
handling things erroneously or if it's anything to do with a general "telnet
server" problem, or an AnyEvent limitation or what-have-you. As of the last
invocation, "mudanyevent" handled ~1000 concurrent connections, launched via:

$ scripts/launch-fuzzier 10 --clients 99 --waitdelay0 0 --idlecmds 0.05

There is something that pegs the "mudanyevent" (and Av4) when >1000 connections
are made: the CPU goes to 100% and the SIGTERM handler isn't invoked.
With ~800+ connections, the last connections take ages to get connected, and may
even just flat out time out and never connect for >~950.

AnyEvent can be quite performant, as the "mudanyevent" stats for the above fuzzier
run displayed on my last run (whitespace munged):

Received 695472    bytes - 9937.407    bytes/sec
Sent     216840410 bytes - 3098372.483 bytes/sec - 3025.754 KiB/sec - 2.955 MiB/sec
Total run time: 69.985262 seconds
Handled 60258 commands in 69.985262 seconds: 861.010 commands/second

The tests

The t/ directory contains a number of tests for some of the features of the MUD.
Not all features are tested. If you do want to write a small test file or contribute
a test case you're more than welcome to do so. Meanwhile, the test files that
are provided exercise the ANSIfication of strings and the inner workings of the
priority queue, two widely used features of the MUD.
Both achieve quite high branch coverage in the subroutines they call. The aim is
for all areas of the MUD code to be exercised, and achieve and maintain a high level
of branch coverage.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.

No, thanks