DGD, which stands for Dworkin's Generic Driver, is a mud server that uses the same overall design as the LP server made by Lars Pensjö. However, there are several important differences: DGD uses less memory because it is disk-based; it can dump state and later restart from a state dump; it uses LPC as an internal interpreted language, but also offers the option of precompiling LPC objects to C, making them part of the program itself.

DGD has two special objects which determine the interface with the server for all other objects: the auto object and the driver object.

The auto object (short for automatically inherited object) is inherited by all other objects, except for the driver object. It can redeclare the predefined functions (called kfuns, kernel functions) that DGD provides, and it can also define standard properties that every object should have. DGD is made in such a way that some kfuns to be redeclared in an environment with several users programming together; for instance, by default there is no file security. The auto object has some other special properties; static functions declared in the auto object cannot be called using this_object()->func() (i.e. they behave like kfuns).

The driver object defines several functions which are called by the driver, mostly to translate pathnames.


The following functions will be called by the driver:
 - in the driver object:

    void initialize()

	Called when the system starts up after a reboot.

    void restored()

	Called after the system has restarted from a state dump.

    string path_read(string path)

	Used to translate a path for an editor read command.  If nil is
	returned, the file cannot be read.

    string path_write(string path)

	Used to translate a path for an editor write command.  If nil is
	returned, the file cannot be written to.

    object call_object(string objname)

	Get the object named by objname as the first argument of a call_other().
	compile_object() may be called from here.

    object inherit_program(string file, string program, int priv)

	Get the object named by program as an object to inherit.  The third
	argument is 1 for private inheritance, 0 otherwise.
	compile_object() may be called from here.

    string path_include(string file, string path)

	Used to translate include path  upon compilation of the
	object with filename .  If nil is returned, the file 
	cannot be included.

    void recompile(object obj)

	If an object A is loaded, A inherits B, B inherits C, and the
	version of C inherited by B is out of date, recompile(B) will be
	called in the driver object.  If B should actually be recompiled
	(inheriting the new version of C from B), the driver object must
	destruct B; if this is done, A will inherit the most recent
	versions of B and C.

    object telnet_connect()

	Return an object for a new connection on the telnet port.

    object binary_connect()

	Return an object for a new connection on the binary port.

    void interrupt()

	Called if the driver receives a kill signal.  The function should
	shut down the system, and possibly dump state.

    void compile_error(string file, int line, string err)

	Handle a compile-time error; there can be several for the same
	LPC file before a runtime error results (calling runtime_error).

    void runtime_error(string error, int caught, int ticks)

	Called when a runtime error occurs.   is 0 if the error
	is not caught, or 1 + an index in the return value of call_trace(),
	indicating the frame in which the error is caught.  runtime_error()
	is called with rlimits (-1; -1) so it will not run out of stack or
	ticks.   specifies the amount of ticks left at the moment
	the error occurred.

    void atomic_error(string error, int atom, int ticks)

	Called when a runtime error occurs in atomic code.   is an
	an index in the return value of call_trace(), indicating the frame in
	which the atomically executed code starts.  atomic_error() is called
	with rlimits (-1; -1) so it will not run out of stack or ticks.
	 specifies the amount of ticks left at the moment the error
	occurred.

    int compile_rlimits(string objname)

	An object uses the rlimits (stackdepth; ticks) { /* code */ }
	construct, which can be used to assign arbitrary limits to function
	call stack depth and ticks; running out of ticks during execution
	causes an error.  -1 signifies an infinite amount of stack space or
	ticks.
	During compilation, driver->compile_rlimits(objname) is called.  If
	non-zero is returned, the object will be able to use rlimits at
	runtime with no restrictions.  If 0 is returned,
	driver->runtime_rlimits() will be called at runtime to further
	verify if an object is allowed to change its rlimits (resource
	limits).

    int runtime_rlimits(object obj, int stack, int ticks)

	Called at runtime for rlimits constructs not already cleared by
	compile_rlimits().  If 0 is returned, the rlimits usage is illegal
	and is aborted with an error.
	Values for stack and ticks: < 0: infinite, 0: no change,
	> 0: set to specified amount.

    void remove_program(string objname, int timestamp, int index)

	Called whenever the program of a master object is removed (because
	the object has been destructed, and all clones and inheriting objects
	have also been destructed).  As this function is called from code
	that cannot be allowed to abort or fail, it is called with
	rlimits (-1; -1) and a catch.
	The "index" is a unique number for each master object, also
	available with status(obj), which can help distinguishing between
	different issues of the same object.

 - in every object:

    void create()

	Called in an object which has just been cloned, or if it is not a
	clone, just before a function is called in it for the first time.
	The actual name of this function is configurable.

 - in the user object (returned by driver->telnet_connect() or
   driver->binary_connect()):

    int open()

	A connection has just been opened for this object.
	For a binary connection, if the return value of this function is
	non-zero, a UDP channel will be opened for the same object.  UDP
	datagrams can be received from the same host and port as the TCP
	connection is on, and after at least one datagram has been
	received, send_datagram() can be used to send datagrams to that
	destination.
	For a telnet connection, the return value will be ignored.

    void close(int flag)

	The connection for this object has just been closed.  close() is
	called when the user goes linkdead, or when the user object is
	destructed.  The flag argument is 1 if the object is destructed,
	0 otherwise.

    void receive_message(string message)

	This function is called with the text the user typed.  For telnet
	connections, this is always an entire line, with the newline at
	the end filtered out.  For binary connections, this is whatever
	the other side of the connection saw fit to send, without any
	filtering or processing.

    void message_done()

	This function is called when a buffered string that could not be
	sent entirely when send_message was called, was fully transmitted.

On startup, the system is configured with a configuration file, which must specify the following configuration parameters:

param		type	meaning
--------------------------------------------------------------------------
telnet_port	number	The port number on which the driver will accept
			telnet connections.
binary_port	number	The port number on which the driver will accept
			binary connections.  Communication on the binary
			port is raw TCP/IP without additional protocol.
directory	string	The base directory for the system.
users		number	The maximum number of active telnet and binary
			connections.
editors		number	The maximum number of simultaneously active
			editor instances.
ed_tmpfile	string	The proto editor temporary file (actual files
			will have a number appended).
swap_file	string	The name of the swap file.
swap_size	number	The total number of sectors in the swap file.
cache_size	number	The number of sectors in the swap cache in memory.
sector_size	number	The size of a swap sector in bytes.
swap_fragment	number	The fragment of all objects to swap out at the end of
			each thread (e.g. with a swap_fragment of 32, 1/32th
			of all objects will be swapped out).
static_chunk	number	The size in bytes of a static or dynamic chunk
dynamic_chunk	number	of memory.  Memory is divided into static memory
			and dynamic memory; static memory is never freed.
			Both are allocated in chunks of the specified size.
			Setting the size of the static chunk to 0 will
			cause the system never to swap out everything to
			make more room for static memory, but will also
			increase fragmentation.
dump_file	string	The name of the state dump file.
typechecking	number	If zero, only functions with a declared type are
			typechecked.
			If one, all LPC functions are typechecked.
			If two, additionally, nil (the value of an uninitialized
			string, object, array or mapping variable) is a value
			distinct from integer 0.
include_file	string	The standard include file, which is always
			included automatically for each compiled object
			(relative to the base directory).
include_dirs	string*	The standard system include directories (relative
			to the base directory).  In the first of those,
			the include files which are automatically
			generated on startup will be placed.
auto_object	string	The file name of the auto object (relative to the
			base directory).
driver_object	string	The file name of the driver object (relative to
			the base directory).
create		string	The name of the create function.
array_size	int	The maximum array and mapping size.
objects		int	The maximum number of objects.
call_outs	int	The maximum number of simultaneously active
			callouts.

Examples of the auto object, driver object and config file are present in the kernel library, which is distributed with DGD.