From the NannyMUD documentation

LAST CHANGE

2001-09-29

TOPIC

NAME

        guild design - 

DESCRIPTION

	Introduction
	------------

	With the steady growth of the MUD and an increasing number of guilds,
	some standards have to be set to facilitate maintenance of guilds for
	the administration and guildheads. With as many different guild
	designs as there are guilds, the difficulty in maintenance is
	apparent. This document tries to outline a set of basic principles
	new guilds shall adhere to.


	Coding standard
	---------------

	Enforcing a strict coding standard is impossible and not even
	desirable for a multitude of coders of varying background in computer
	programming, but a few guidelines should be kept in mind.

	* Choose function and variable names that are meaningful, and not
	  cryptic names such as 'bbf', 'sfb', 'chsh'.

	* Do not compress the code into a suffocating compactness. More
	  space and strategical separations make it much easier to read.
	  Compact code does not run any faster.

	* Use an editor that supports indentation. Look at your code using
	'more' and compare with how it looks in the editor. GNU Emacs is a
	recommended editor and is available for free under Unix and Windows.

	* Keep the size of files below 50K so that they can be copied using
	the standard MUD 'cp' command.

	* Use #pragma strict_types for *all* your code.

	* Use defines for all paths accessed in your code, i.e. use HOME or
	GUILDHOME for /guilds/myguild/ and CMDS for HOME+"cmds/" to give an
	example.


	Guild architecture
	------------------

	There are basically two types of architectures normally employed.

	* Contained guildmarks.

	* Modularized guildmarks.

	(and a mixture of the two).

	There are advantages and disadvantages with both types of
	architectures.  The contained guildmarks are usually more complex to
	maintain and breaks easier. It forces the wizard making changes to
	the guild to know more about its design than necessary to avoid
	breaking things.

	The modularized version is the preferred way of implementing a
	guild. Guilds consists of commands, hooks, server daemons, and
	sometimes shadows. Commands are ideally located in files of their
	own. From inside your guildmark you can add a command with a command
	handler and direct execution of the command into the right file and
	with the necessary parameters.

	Example:

	add_command("blast %s", "@cmd_blast()");

	int cmd_blast(string cmd, string arg)
	{
	  return "/guilds/myguild/cmds/blast"->do_blast(arg, p1, p2, p3, p4, ...);
	}


	Hooks are also ideal for residing in a separate file(s). Have each
	hook as a separate file or group hooks together.

	Example:

	player->add_hook("die_hook", load_object("/guilds/myguild/hooks/die_hook"));


	One problem with dislocation of code into separate files is the
	guildmark object itself. How do I access it? Doing a
	present("guild_mark", player) in every command and object is not so
	fun. There's a simple solution to this as well. When a player logs
	on, or when add_guild_powers() are executed set the property
	"GUILD_guild_mark" in the player with the guildmark object as a
	value.

	Example:

	void add_guild_powers()
	{
	  player->add_property("MYGUILD_guild_mark", this_object());

	  ... setup of commands, hooks etc.
	}

	Then to obtain the guildmark object you only have to query its
	property value. If the player loses the "GUILD_guild_mark" property
	you need some means of restoring it. In one of your server daemons,
	have a function restore_guild_mark() which resets the property.

	Example:

	object restore_guild_mark(object player)
	{
	  object mark;

	  mark = present("MYGUILD_mark_id", player);

	  if (!mark)
	  {
	    // dead end, inform player of situation
	    return 0;
	  }

	  player->add_property("MYGUILD_guild_mark", mark);
	  return mark;
	}

	Let's look at an example of how this can be used in a die_hook.

	Example:

	void die_hook(mixed* args, object player)
	{
	  object mark;

	  if (!player)
	  {
	    // player is no more, do nothing
	    return;
	  }

	  if (!(mark = player->query_property("MYGUILD_guild_mark")))
	  {
	    if (!(mark = GUILDD->restore_guild_mark(player)))
	    {
	      // dead end, do nothing
	      return;
	    }
	  }

          // now we have the guildmark ready for use

          tell_object(player, "Oops! You died!\n");
          mark->reduce_guild_points();
        }

	Directory structure
	-------------------

	The preferred directory structure is:

	backup/  - backups of save-files
	banish/  - banished players etc
	daemons/ - various guild daemons
	data/    - daemon save files
	doc/     - various documentation about the guild
	help/    - your ihelp structure
	line/    - your line controller
	log/     - log files
	members/ - member save files
	npc/     - guild npc's
	obj/     - guild objects, weapons and armours
	powers/  - one file for each power, place related hooks together with
	           the power they support,
        rooms/   - guild area rooms

	Different guild drawbacks should be kept as separate from the guild
	mark as possible.


	This is of course a little bit more work than having everything into
	a single guildmark, but it improves the guild's maintainability
	greatly.

	If you have questions or need technical assistance with your guild,
	please don't hesitate to talk to the guild coordinator or any other
	member of the administration.