Browsed by
Category: MUD Projects

My MUD Projects

Diff Script for Applying DS Updates

Diff Script for Applying DS Updates

Here’s a command I wrote for DS lib, it goes in as /secure/cmds/admins/diffit.c and responds to the “diffit” and “help diffit” commands.

Steps to use:

  1. When an upgrade is available, do a `liveupgrade all`
  2. Once it has finished downloading, do a `diffit`. You will be prompted for each file that is being upgraded to [K]eep the current version, or [R]eplace it with the new version.
  3. Once finished, see /log/diff.log for errors, and /log/diffkeep.log for files you chose to [K]eep (You will need to upgrade these files manually).

Future features:

  • “More” for long diffs
SQL Daemon for DS

SQL Daemon for DS

With much anticipation, here is my SQL code: it allows both blocking and non-blocking SQL sockets to be used simultaneously. I’ve tried to be very verbose in my commenting, and I will include some examples later on, too.

This stuff works to the best of my knowledge. If not, leave me a comment and I’ll try to look at it.


  1. “Non-blocking SQL sockets” are sockets that execute a callback function once the SQL data is retrieved. Ideally, this is how you will access all SQL data. (Technically: This type of socket uses extern_cmds to pipe data to and from the ‘mysql’ command through the use of callbacks)
  2. “Blocking SQL sockets”, however, are sockets that take 100% of the driver’s attention until the SQL data is received. Nothing else is executed while it is in use. The ONLY reason you would use this type of socket is when you NEED a
    response from the SQL server before continuing to the next line of code. (Technically: This type of socket uses efuns compiled into the driver to communicate with the SQL server directly)

Planned features:

  1. Allow MSSQL, Oracle, and other databases
  2. Transaction support (Partially implemented so far)

The code contains three distinct sections:

  1. Shared code
  2. Exclusively “Non-blocking” code
  3. Exclusively “Blocking” code

Steps you will need to take to make this usable:

  1. Compile a driver with SQL support
  2. Make sure you have a usable SQL server
  3. Create a database for MUD-related stuff, default ‘mud
  4. Create a user for general-purpose access with only the required permissions (ie, SELECT, INSERT, UPDATE on non-sensitive tables only) and restrict the user to the mud database.
  5. (Optional, strongly recommended): Create a user for mud-admin access with only the required permissions (ie, SELECT, INSERT, UPDATE, DELETE) and restrict the user to the mud database.
  6. Place db.h in /secure/include/ and edit it to suit your installation
  7. Place sql.c in /secure/daemon/
  8. Edit /secure/daemon/master.c to allow the SQL daemon to access a socket (See attachment)
  9. Add “external_cmd_1: /usr/bin/mysql” (without the quotes) to /secure/cfg/mudos.cfg
  10. Create tables to support data for your mud (See attached “mud.sql“)
  11. Add SQL support to files that you want to be able to access the database (See attached examples)
Add your driver and addr_server to monit: How-To [Beta]

Add your driver and addr_server to monit: How-To [Beta]

This how-to is still in testing. I got it to work, however, the how-to may not be totally complete or correct. Please let me know how it works for you.

  1. Set up monit Monitoring Service on your Linux box
  2. Add the following to your /etc/monit/monitrc: (The “as uid” line is optional, use it only if you want to run your mud as a different user)

    check process driver with pidfile /home/mud/bin/
    start program "/home/mud/bin/startdriver"
    as uid mud and gid mud

  3. Optional: If you want addr_server, add this to /etc/monit/monitrc too: (The “as uid” line is optional, use it only if you want to run your addr_server as a different user)

    check process addr_server with pidfile /home/mud/bin/
    start program "/home/mud/bin/startaddr_server"
    as uid mud and gid mud

  4. Create a file called startdriver in your MUD’s “bin” directory: (change /home/mud to the location of your mud’s directory (the one containing ‘bin’ and ‘lib’)):


    export MUDHOME="/home/mud"

    umask 007
    ulimit -n 120
    $MUDHOME/bin/driver $MUDHOME/lib/secure/cfg/mudos.cfg &

    ps -ef | grep /bin/[d]river | awk '{print $2}' >

  5. Optional: If you want to set up addr_server, create a file called startaddr_server in your MUD’s “bin” directory (again, change /home/mud to the location of your mud directory):


    /home/mud/bin/addr_server 9999 &

    ps -ef | grep /bin/[a]ddr_server | awk '{print $2}' >

  6. Restart the monit service:
    /etc/init.d/monit restart
Mod: Wizzes can’t be killed

Mod: Wizzes can’t be killed

Add this block of code to the beginning of varargs int eventDie(mixed agent) in /lib/player.c.

int mhp, msp, mmp;
string *limb_arr = ({});

if(!agent) agent = previous_object();
if(!agent) agent = this_object();

if(wizardp(agent)) {
mhp = agent->GetMaxHealthPoints();
msp = agent->GetMaxStaminaPoints();
mmp = agent->GetMaxMagicPoints();
if(agent->GetPoison() > 0) agent->AddPoison(0 - agent->GetPoison());
limb_arr = agent->GetLimbs();
foreach(string limb in limb_arr) {
return 1;

This code is formed such that when a wizard should die, they are instead healed and restored to full health, stamina, and magic.

This code falls under the Dead Souls license.

No Zapping Arch Wizzes

No Zapping Arch Wizzes

Here’s how to prevent zapping of arch wizards:

In /verbs/creators/zap.c, change:

if(!living(ob)) {
write("You can only zap living things.");
return 1;
else name = ob->GetName();


if(!living(ob)) {
write("You can only zap living things.");
return 1;
} else if (archp(ob)) {
write("You can't zap an Arch!");
return 1;
} else name = ob->GetName();

Dead Souls 2.3a1 Wordy Exit Code

Dead Souls 2.3a1 Wordy Exit Code

This is my update to the /lib/exits.c, /lib/std/room.c and /lib/interactive.c to allow for worded exits in verbose mode, and the usual short exits in brief mode.


  • Verbose:
    • Creators’ Hall
    • Immortals come here to communicate with each other about the world they are building. The Adventurer’s Guild is north. The Arch Room is south. To visit the Dead Souls test and development mud, go west. The test lab facilities are east.
    • There are five obvious exits: west, north, east, south, and up.
  • Brief:
    • Creators’ Hall [n, s, e, w, u]

This code includes my HideExit Modifications:nod:

As usual, please see the license at Dead, this code is not GPL.

Update: Moved one block of code in GenerateVerboseExits() in room.c to allow you to HideExit() enters. (Example: HideExit(“enter office”); )

Update 2: Fixed a problem with grammar by adding (Example: “desc” : “gate leading”) to the SetSide Mapping. If there is no “desc”, it will show “door” in the verbose exits. This was needed to be able to colorize the door based on its open/closed status. Added a modified door.c and door.h for this purpose.

Dead Souls HideExit code

Dead Souls HideExit code

This is my update to the /lib/exits.c and /lib/std/room.c to make obvious exits easier to use and worth with. It adds the following:

  • a sub-mapping to the Exits mapping in exits.c to include ([ “obv” : 0 or 1 ]).
  • HideExit(dir), which hides the given exit (and should be used in your room code to hide exits)
  • GetObvMap(), which returns a mapping of direction and hidden [Example where south is hidden by HideExit(“south”): ([ “west” : 1, “north” : 1, “east” : 1, “south” : 0 ]) ].

Room Exits default to Obvious, so there is no need to set them. The old SetObviousExits and its related functions are still included and valid for compatibility purposes.

I will be releasing another version of this code for use with muds who want more than the [n, s, e, w, u] exit list.


Insert this code into /lib/exits.c:

//Use this to get whether or not an exit is obvious.
int GetExitObv( string str ) {
    if( !Exits[str] ) return 0;
    else return Exits[str]["obv"];

//Use this or GetFullExitData to get a mapping of obvious or not, to use for visible/invisible doors in std/room.c
mapping GetObvMap() {
    mapping ret = ([]);
    foreach(string key in keys(Exits)){
	ret[key] = Exits[key]["obv"];

    return ret;

//Use this to hide an exit
int HideExit( string dir ) {
	  return Exits[dir]["obv"] = 0;

Replace the existing GenerateObviousExits() in /lib/std/room.c with this:

 int GenerateObviousExits(){
    string *normals;
    string *exits;
    string dir_string, enters;
    mapping obv;

    exits = GetExits();
    obv = GetObvMap();

    enters = "";
    normals = ({ "north", "south", "east", "west", "up", "down" });
    normals += ({ "northeast", "southeast", "northwest", "southwest" });
    normals += ({ "out" });
    dir_string = "";

			foreach(string enter in this_object()->GetEnters(1)){
			    if (obv["enter "+enter] == 1) {
				    enters += "enter "+enter;
				    if(member_array(enter,this_object()->GetEnters(1)) !=
				     sizeof(this_object()->GetEnters(1)) -1) {
							  enters +=", ";

    if(member_array("north",exits) != -1 && obv["north"] == 1) dir_string += "n, ";
    if(member_array("south",exits) != -1 && obv["south"] == 1) dir_string += "s, ";
    if(member_array("east",exits) != -1 && obv["east"] == 1) dir_string += "e, ";
    if(member_array("west",exits) != -1 && obv["west"] == 1) dir_string += "w, ";
    if(member_array("northeast",exits) != -1 && obv["northeast"] == 1) dir_string += "ne, ";
    if(member_array("northwest",exits) != -1 && obv["northwest"] == 1) dir_string += "nw, ";
    if(member_array("southeast",exits) != -1 && obv["southeast"] == 1) dir_string += "se, ";
    if(member_array("southwest",exits) != -1 && obv["southwest"] == 1) dir_string += "sw, ";
    if(member_array("up",exits) != -1 && obv["up"] == 1) dir_string += "u, ";
    if(member_array("down",exits) != -1 && obv["down"] == 1) dir_string += "d, ";
    if(member_array("out",exits) != -1 && obv["out"] == 1) dir_string += "out, ";

    if(sizeof(this_object()->GetEnters(1) - ({0}) )) {
			if(sizeof(this_object()->GetExits())) dir_string += ", ";
			dir_string += enters;

    if(last(dir_string,2) == ", ") dir_string = truncate(dir_string,2);
    dir_string = replace_string(dir_string,", , ",", ");
    if(ObviousVisible) SetObviousExits(dir_string);
    return 1;