Again, here's our "simple" room code:
simpleroom.c
inherit STD_ROOM_OB;
void create()
{
   ::create();
   set_short("Grey's workroom");
   set_long("Welcome to Grey's workroom.\n\n"+
     "You are in a small, barren room.  There isn't much to see here, "+
     "so consider taking one of the exits.");

   add_exit("east",  "/domains/std/rooms/equip");
   add_exit("north", __DIR__+"northroom");
}

Now let's add a monster who's wielding our simple weapon and wearing our simple armour! Here's what the new simpleroom.c code would look like:

inherit STD_ROOM_OB;
void create()
{
   ::create();
   set_short("Grey's workroom");
   set_long("Welcome to Grey's workroom.\n\n"+
     "You are in a small, barren room.  There isn't much to see here, "+
     "so consider taking one of the exits.");

   add_exit("east",  "/domains/std/rooms/equip");
   add_exit("north", __DIR__+"northroom");
}

void reset()
{
   object monster, coins;
   ::reset();

   if(!present("rat"))
   {
      monster = new(__DIR__+"simplemonster");
      monster->move(this_object());
      new(__DIR__+"simpleweapon")->move(monster);
      new(__DIR__+"simpearmour")->move(monster);
      monster->force_me("equip all");

      coins = new("/std/obj/coins");
      coins->set_value("2d5");
      coins->move(monster);
   }
}

Now let's take this apart and see what it does.

void reset() {
The "reset" function is called in all objects every 20-30 minutes (the exact timing depends upon the current configuration of the MUD). This is the function that's used to "re-pop" a room with monsters and/or treasure. Note that putting the "reset" function in your room is totally optional... only use it if you want the room to do something every 20-30 minutes -- such as cloning in monsters.

::reset();
This tells the MUD to execute all the code contained in the reset() function within STD_ROOM_OB. Do this after you've declared your local variables. In the above example, I've first declared 2 local variables: "monster" and "coins". You can give variables any name you want, as long as it doesn't conflict with a "reserved word" (meaning, an LPC function name, such as "create", "reset", "this_player", and so on).

if(!present("rat")) { .... }
Here's the first "if" statement we've seen. The stuff contained within the curly braces { } will be called only if the condition within the parenthesis ( ) is true. In this example, we're checking if a monster named "rat" is not present in the room's inventory. By the way, the exclamation point ! means "not". So if the rat is not present, the stuff within the { } section will be executed.

monster = new(__DIR__+"simplemonster");
The "new" function attemps to clone the file listed within the ()'s. In this example, it will look for a file named simplemonster.c (the .c extension is assumed by the MUD) within the same directory as our room. A new copy of the monster is loaded into memory and assigned to the object variable we've named "monster".

monster->move(this_object());
But, loading a monster into memory puts the new copy of the monster in a state of "limbo" -- it has NO environment. The "move" function transfers the monster object from limbo into the inventory of the object specified within the ()'s. In this example, the object we've moving the monster into is this_object(), a function that refers to... you guessed it... this object, whose code we're executing right now.

new(__DIR__+"simpleweapon")->move(monster);
Now we're cloning a copy of our simpleweapon.c and moving it into our monster's inventory. The "->" tells the MUD to call the function on the right-hand side of the "->" in the object on the left-hand side. This is a shorter way of saying:

object weapon;
weapon = new(__DIR__+"simpleweapon");
weapon->move(monster);

monster->force_me("equip all");
Monsters are considered living objects, just like players. Other things like weapons, rooms, coins, etc. are not living objects. Living objects can be "forced" -- the MUD thinks the living object has typed the command listed as the argument to the force_me function. Monsters can type any command that a player can. This includes emotes (like "smile"), casting spells, movement, using equipment, and so on.

coins = new("/std/obj/coins");
The file /std/obj/coins.c is CorePirate's system of currency: the Guilder coin.

coins->set_value("2d5");
This tells the MUD how many coins are in our little pile of Guilders. Two 5-sided dice will be rolled to calculate a random number between 2-10. The resulting number determines how many coins are in the pile. This does NOT say there's 2-10 distinct objects here... the pile of coins, regardless of how many coins are in the pile, are treated by the MUD as a SINGLE object.

coins->move(monster);
The coins are moved out of limbo and are placed inside the monster's inventory.

I'd like to conclude by saying that the above is a poor example, since rats don't wield weapons or wear armour! :) Also, they'd have a pretty hard time carrying any coins around! But this also makes a fair point about MUD design considerations: Just because the MUD allows you to do something (after all, it doesn't really know what a "rat" should be) doesn't always mean it should be done. You could turn this into a much better example by going back and changing simplemonster.c from a rat into an orc.


This page may be viewed from any browser, not just one from Redmond.
Last Modified: Jan 1, 2001
Page written by Dave Shay (how to contact me).
Page content copyright ©2000-2001 by Dave Shay. Do not copy without express permission.
Dungeons & Dragons is a registered trademark of TSR, Inc., a subsidiary of Wizards of the Coast.
D&D rules, races, classes, features, etc. used in accordance with the TSR, Inc. Internet Policy.