@(#) MDG Multi-user Dungeon Game, Copyright 1990 John C. Gonnerman.
@(#) README Version 1.6, 1/11/91


MDG is a multi-user Hack/Larn/Rogue type of game.  It uses System V IPC 
calls (message queues and shared memory) so it is only available for 
those systems.  It is not a "MUD" or any sort of a network game.  
Rather, it is intended to be played on a single Unix-based system, 
perhaps a BBS (such as the Tree in Sacramento... there's your plug Alan).

No reason why it could not be played over Telnet, though... on a LAN it
could really scream!


PORTING NOTES:

As stated, MDG is a SysV game.  Getting it to run on any other system may
be impossible at this time.  It was developed on a Xenix System V host,
but I only used the standard AT&T SysV Release 3.2 manual as a reference.  
Therefore, I expect it to be fairly portable over most SysV systems.  
Recent work on SunOS 4.1 leads me to believe that MDG will compile and
run there also.

Players of MDG must be identified by number.  The distributed version of
MDG includes a program, ident.c, which will return the uid number and
real name of a user for use by MDG.  This program is automatically called
by MDG to identify a player.  For BBS systems, however, this may not be
acceptible; if it is not, you will need to write your own ident.c to
provide this information.  For instance, here on Tree the BBS password
file is consulted by MDG to get the BBS userid-number and the player's
handle.  ident can also be a shell script, if desired, though it will be 
slower that way... remember that the slowdown caused by ident affects
ALL current players, since the daemon task must run ident.  It is a 
tradeoff to have a separate ident program, but the additional overhead 
of the current program seems minimal.

System resources:  MDG is tuned (as delivered) for a system with 40
message headers configured in the kernel.  If you have fewer than this, do
not attempt to use MDG until you reconfigure as the daemon task can hang
if insufficient message headers are available.  If you want to use more
(to speed up MDG's response or allow for more users) tune the
queue-sizing parameters in struct.h.

Likewise, MDG needs sufficient shared memory to store the current
players, the map, and the item table.  (The monster table is stored in
"conventional" memory by the daemon, as is the note table).  This is
harder to figure because of the variable size of these tables.

Finally, MDG needs as many semaphores as there are to be concurrent 
players... for 9 players (the maximum, see below) a single semaphore set
of 9 semaphores is created.

The game can handle up to 9 players if it is configured for that many.
The shipped version is tuned and configured for only 6.  For purposes of
a clean screen display, set MAX_PLAYERS to 3, 6, or 9.  The tuning of
message queue usage is based on 6 players so you will need more messages
to run 9 players.


ADMINISTRATION:

The primary MDG game programs will need to be installed in /usr/games (or
wherever you store your games.)  These programs are:

	mdg		user-side MDG game program.

	mdg_char	player "editor" used to buy lives, and review
			stats.

	mdg_daemon	the real game (daemon task).

	mdg_stop,	really one program.  mdg_stop stops the game 
	mdg_save	daemon (by sending a message).  mdg_save causes
			the game to write a save file immediately.

The MDG programs will need to be setuid to "games" (or some other userid
which will own the files).  Alternately it can be setgid if the files
have correct permission modes.  At the minimum, mdg_char will need this 
so it can access player files.  The daemon can safely be made setuid 
because it will protect itself using a lock file so that it can't be 
started twice; this would allow players to restart the daemon if the 
system admin forgets.  If the daemon dumps core, it will not remove it's 
lock file, which is a "feature" that prevents a presumably buggy daemon 
from being restarted.  The user-side game program, mdg, also needs to be 
setuid so it can access the ident program.  The control program, 
mdg_stop/mdg_save, should likely NOT be setuid so that players can't stop 
the daemon in progress.

MDG will need a directory (GAME_HOME in setup.h) to store the game save
files and support programs (ident) in.  The shar'ed version of MDG includes 
a public domain set of save files in a subdirectory (mdg_dir) under the 
source directory.

The following files comprise the game save:

	map.start,	the game map.
	map.save,
	map.old

	item.start,	item list save files.
	item.save, 
	item.old

	monster.start,	monster table save file.
	monster.save,
	monster.old

	note.start,	note table save file.
	note.save,
	note.old

These files contain data that is saved each time the game is stopped, 
and each time a player leaves the game.  EXCEPTION:  map saves are done
only when the map has been changed and are delayed until there are no
players in the game.

The .start files are used only if the .save files do not exist.  The
.old files are created by renaming old .save files before writing new
ones.

Additionally, in the GAME_HOME directory of a running system you will find:

	LOCK.daemon	used to prevent more than one daemon from being
			started.  this is just a rudimentary protection.

	errorlog	stderr output of mdg_daemon... check this if
			the daemon core dumps.

	statlog		when shut down, the daemon saves the peak
			messages per second it experienced while running
			in this file.

	bin/mdg_clock	the daemon clock program; sends pulses to the
			daemon task for timing.

	bin/ident	described above.

	players/default	standard beginning character.

	players/plNNNNN player game save.

	players/prNNNNN player "profile" (just the preferred name).


RUNNING THE GAME:

The daemon task must be started before you can play MDG.  Just run
mdg_daemon.  It will find and run the mdg_clock task, automatically.
(When you shut down the daemon with mdg_stop, mdg_daemon will kill the
clock before shutting itself down).

Players can then enter the game by running mdg.  Player stats can be
viewed, names changed, and extra lives purchased by running mdg_char.

For players to leave MDG, they must go HOME.  This is done by running off
the map onto a HOME sector.  (See mdg.doc for more info.)  The Quit spell
can also be used.


HOW IT WORKS:

	+--------------+      ----------       +-------------------+
	| Daemon Task  |---->| Shared   |----->| Viewer Task (mdg) |
	| (mdg_daemon) |     | Memory   |      |-------------------|
	+--------------+      ----------       | Input Task (mdg)  |
        	^ ^   		               +-------------------+
   Message >    | |                                 |
   Queue   >    | +---------------------------------+       
		|       
	+--------------+
	| Clock Task   |
	| (mdg_clock)  |
	+--------------+

mdg_daemon, when started, starts in turn mdg_clock.  The clock accesses
the daemon's common input queue, and each second sends a "pulse" to
cause the daemon to update it's timers and perform monster moves and
other scheduled operations.

When mdg is started on the user side, it fork()'s into two processes.
One is responsible for parsing user input, and sends messages to
mdg_daemon on the common input queue.  The other, the Viewer, accesses
the shared memory of the daemon to read map sectors, player stats, and
the item list.

Not shown are the Viewer semaphores.  Each viewer task watches a
semaphore, doing screen updates when the semaphore is raised.  The 
daemon raises a player's semaphore to indicate that a screen update is
needed.

This is an efficient system in terms of CPU resources.  Each process is
suspended much of the time (the daemon blocked on a message queue, the 
viewer(s) blocked on semaphores, the clock sleeping, and the input task 
blocked on the keyboard).

There is an additional shared segment private to each pair of mdg
processes, used for the "help line" on the bottom of mdg's screen.


CREATING YOUR OWN DATA FILES:

Four basic datasets comprise a game startup set: map.start, item.start,
note.start, and monster.start.  The formats of these files are listed
below:


Map File map.start:

The first line is a sector count.  It is used to avoid a prescan, that
is, so the map file need only be read once.  The sector count is used in
creating a shared memory segment large enough for the map.

Following this are 16-line long sector entries, consisting of 13 lines
of actual sector layout and 3 lines of other data.  A sample sector
follows:

	+-----------------------------------------------+
	|~                                     .  0	|
	|~          #..#..#..#..#..#..#        .	|
	|~~         .                 .        .	|
	|~~      #..#                 #..#     .	|
	|~       .                       .     .	|
	|        #                       #     .	|
	|        .                       .     .	|
	|        #                       #     .	|
	|        .                       .     .	|
	|        #..#        #..#..#..#..#     .	|
	|         ~~~~       ~~~~              .	|
	|   ~~~~~~~~~~~     ~~~~~~~~~~~~~~~    .	|
	|~~~~~~~~~~~~~      ~~~~~~~~~~~~~~~~~~~.	|
	|Start Sector...				|
	|26 -1 1 21 / -3 -3 / -3 -3 -3 -3 -3 -3 -3	|
	|0 1 0 '~' G0					|
	+-----------------------------------------------+

(A border has been added for clarity.)

Each of the first 13 lines contains 38 columns of map codes, a single
period (for ease of editing), and on the first line only, 2 spaces and a
sector number.  Note that the first number is 0, so that in a 10 sector
map the highest sector number is 9.

The 14th line is the sector name, which is allowed to be up to 39
characters long.

The 15th line is the link-list.  Each sector connects in up to 11
"directions" to other sectors.  Negative link numbers refer to one of
several special locations, as shown in mapstruct.h; the implemented
links are as follows:

	LOC_HOME	-1 	(used to indicate where players may 
				exit the game.)
	LOC_NONESUCH	-3 	(nowhere, used to "block" a direction.)
	LOC_TRADER	-4	(leads to the Trader's place of 
				business.)

-2 is LOC_PLAYER, and is not used on the map.

The link-list is read as follows:

	N S E W / U D / G1 G2 G3 G4 G5 G6 G7

where N is North, S is South, etc., U is Up, D is Down, and the Gn
entries are teleport gates 1 to 7.

Note that the link-list is used only to LEAVE a sector; entry to a
sector depends entirely on the link-list of the sector you are leaving.

Line 16 of the sector is a general data line, as follows:

	   0 1 0 '~' G0
 	   ^ ^ ^  ^  ^
level -----+ | |  |  |
light -------+ |  |  |
jump inhibit --+  |  |
border character -+  |
god limit -----------+

Level is used to distribute monsters; see below, under monster.start.

Light may be one of the following levels:

	-1	Tends to "cancel" player-provided light.
	0	"Normal" darkness.
	1	Lighted in the day only.
	2	Lighted full-time.

Jump inhibit is used to limit teleportation to or from sectors.  It only
limits teleportation by spell use, that is, it does not affect gates.

Border Character is a single character to show on the borders of a sector 
which lead to LOC_NONESUCH.

God Limit is used to block or limit Godlike map changes in the sector.  It 
may be an integer from 0 up.  1 or higher is interpreted as a multiplier 
to apply to the cost in Creation Points spent modifying the sector.  If 
the God Limit is 0, modifications are not allowed.


Item File item.start:

This file, like map.start (and in fact like the other game save files)
begins with a count of items.  Following the item count are the items,
where each item consists of two lines.  The first line of an item is
it's name, and the second is a stat record in the following format:

	[0] 5, 6 <$$, 0, 0> 1:1 0 $600 (0) C0
         ^  ^  ^  ^^  ^  ^  ^ ^ ^  ^    ^   ^
sector --+  |  |  ||  |  |  | | |  |    |   |
x ----------+  |  ||  |  |  | | |  |    |   |
y -------------+  ||  |  |  | | |  |    |   |
type -------------+|  |  |  | | |  |    |   |
symbol ------------+  |  |  | | |  |    |   |
effect or value ------+  |  | | |  |    |   |
range -------------------+  | | |  |    |   |
max uses -------------------+ | |  |    |   |
remaining uses ---------------+ |  |    |   |
age ----------------------------+  |    |   |
cost ------------------------------+    |   |
modification count ---------------------+   |
curse flag ---------------------------------+

Sector, x, and y indicate where the item is.  If the sector is negative,
the meaning is as follows:

	-2	LOC_PLAYER... x is the player number who has it, y is 0.
	-3	LOC_NONESUCH... the item is "lost," but may turn up when
		a monster dies.
	-4	LOC_TRADER... the item is in the Trader's.

-1 (LOC_HOME) is meaningless here.

Type indicates what sort of item it is.  Symbol usually is the same
code, but may be an underscore, which indicates an Obscured item.

Effect (or value) is used as max damage for weapons, as protection for
armor or shields, as note index for notes, and for other objects it is
used to indicate what effect or power the item confers.  See the
effects.h file for more details.  Note that any cursed object other than
weapons and armor/shields acts as POISON! when activated by a player.

The handling of $ (treasure) and * (crystal) items is special... the
sector number is never LOC_PLAYER.  Instead, when such an item is picked
up it is set to LOC_NONESUCH and the value of the item is added to a
counter in the player structure.  Do not create an item file with no
entries of these types!

Range is normally only used by missile weapons, although I have plans in
a future release to use it as an "effectiveness" value for generic
objects.

Max Uses and Remaining Uses are normally used only on potions, scrolls,
and "objects" (these three item types are the ones I refer to as
"generic objects").

Age is used to prevent an item from lying about on the map, in the
Trader's, or on an idle player for too long.  We had problems in
playtest with players who would get ahold of all the good items, and
then leave for a month on vacation.  So, item aging (or "decay") was
added using this field to put items in LOC_NONESUCH after a certain
delay (defined in setup.h as the DECAY_* parameters).

Cost is simply the base cost (value when sold) of the item.  It is
multiplied by 1.5 when a player buys something.

Modification Count is used to limit changes to items made by Godlike
characters.

Curse flag may be C0 (not cursed) or C1 (cursed).  Godlike characters
can remove or apply curses to items.  A generic cursed item acts as
POISON! to the character activating it.  Cursed notes are unreadable.
Cursed weapons do little or no damage, and cursed armor and shields
provide no protection.


Monster File monster.start:

This file starts with a count of monsters.  Each monster is thereafter
represented in two lines, the first being the monster's name, and the
second being a stat record as follows:

	a [-3] 24, 11 15:15 2 0/60:10 L3 D2 IQ=50
	^  ^   ^   ^  ^  ^  ^ ^ ^  ^  ^  ^  ^
code ---+  |   |   |  |  |  | | |  |  |  |  |
sector ----+   |   |  |  |  | | |  |  |  |  |
x -------------+   |  |  |  | | |  |  |  |  |
y -----------------+  |  |  | | |  |  |  |  |
max hit points -------+  |  | | |  |  |  |  |
current hit points ------+  | | |  |  |  |  |
movement -------------------+ | |  |  |  |  |
attack type ------------------+ |  |  |  |  |
to hit -------------------------+  |  |  |  |
max damage ------------------------+  |  |  |
map level ----------------------------+  |  |
danger level ----------------------------+  |
intelligence -------------------------------+

Code is the character (must be a letter or ampersand) to be used to
display the monster.  Use of a character other than a letter or
ampersand will result in a monster immune to almost all attacks.

Sector, x, and y are used to indicate the monster's current location.
Dead monsters have a -3 sector (LOC_NONESUCH).  No other negative sector
number is meaningful.

Max Hit Points and Current Hit Points indicate the potential damage the
monster can take before death.  Monsters do not heal.  However, a dead
monster can be resurrected automatically...

Movement is the number of moves per "pulse" that the monster may take.

Attack type is used to select between normal attacks and several special
monster attacks... see the file "combat.h" for details.

To Hit and Damage are used (in most attack types) as the odds to hit a
player and the maximum damage that may be done.  The To Hit value is
compared with the player's Fighting score to generate an actual percent
chance.

Map Level is used to distribute the monster when resurrecting it.  A
monster of level N may be resurrected in any sector of level N up to and
including level N+4.  Thus a "level band" is 5 levels wide.

Danger Level is used to determine how much treasure the monster is
worth.  Danger Levels equal to or greater than DANGER_CUT (setup.h) will
result in a monster able to "cough up" Magic Crystals when it dies.

Intelligence is used to determine if the monster uses the stupid or
smart movement routine.  It is a simple percentage chance that the
monster will select a smart move.  Note that smart moves are not all
THAT smart.


Note File note.start:

This file consists of a record count, followed by the note text, one
note per line.  Notice that more than one note item can reference the
same note in the note table... see the Mystic Slate(s) in the example
item.start file.


TIPS ON ADMINISTRATION:

- Monsters are moved on the "pace and pulse with tick limit" method.
  The original (beta) version of MDG used "pace and pulse"... monsters
  each being moved once for each player move (if the monster had
  movement left) with all remaining moves, if any, being made all at
  once on the pulse.  This however was shown to move monsters all at
  once pretty much at the beginning of the pulse.  Therefore, monsters
  are moved in this version once per each N player moves.  Exception:  
  if any monster is under attack, monsters move once per player attack.
  "N" is set to the value TICKSPERPACE in setup.h.  It may need to be
  increased on fast machines or decreased on slow ones.  Use the values
  in the file "statlog" to help with the tuning... the value of
  TICKSPERPACE should be around 1/4th or 1/5th of the Peak Messages per
  Second of mdg_daemon.

- Avoid giving out CP for free.  Players with possibly excellent ideas
  will beg the game administrator to give them a few extra CP so they
  can finish the area they are building.  Don't give in.  CP are hard to
  come by for a reason... there would be little challenge if they were
  cheap.

  However YOU (the game admin) should have a large number of CP much of
  the time, to allow you to patch up the map as needed.

- By far the hardest part of administrating MDG is the God Powers.  Once
  you have a Godlike player in the game, the map will begin undergoing
  strange metamorphoses.  It is HIGHLY suggested, if you remodel the
  sample map or build your own, that you LOCK (God Limit 0) all sectors
  that have links to HOME in them.

- The game limit values (in setup.h) can be changed to give a much
  different feel to the game.  You might wish to raise the limits of God
  Powers to make only the VERY toughest players Godlike.  Other limits
  can be altered too... spell durations, limits for the levels of the
  Detect spell, etc.

- The Trader is located near HOME as a way of assisting newbie players.
  You might make it harder to get to if your players require more of a
  challenge... but don't remove it entirely.  Note that regardless of
  how many ways you can enter the Trader's, there is effectively only
  one Trader in the game.  One suggestion is to place the Traders at the
  top or bottom of a set of stairs (what a surprise).

