1432 lines
60 KiB
Plaintext
1432 lines
60 KiB
Plaintext
|
WARNING: THIS FAQ IS OUT OF DATE
|
||
|
Please reference the FAQ in the doc/ directory of the distribution
|
||
|
instead. It is significantly more current.
|
||
|
|
||
|
|
||
|
Frequently Asked Questions (FAQ) for Circle DikuMud with Answers
|
||
|
Alex Fletcher, furry@circlemud.org
|
||
|
|
||
|
This file is intended to cover common questions related to the CircleMUD
|
||
|
distributon source by Jeremy Elson (http://www.circlemud.org/~jelson/) and
|
||
|
not general DikuMUD questions. Any contributions and corrections are more
|
||
|
than welcome. It is currently maintained by Alex Fletcher (aka Furry)
|
||
|
<furry@circlemud.org>. Please direct corrections to this address. The
|
||
|
original author was Ryan Watkins (aka VampLestat). More information about
|
||
|
CircleMUD, including up-to-date versions of this documentation in ASCII and
|
||
|
Postscript, can be found at the CircleMUD Home Page
|
||
|
(http://www.circlemud.org/) or FTP site
|
||
|
(ftp://ftp.circlemud.org/pub/CircleMUD/).
|
||
|
|
||
|
______________________________________________________________________
|
||
|
|
||
|
Table of Contents
|
||
|
|
||
|
1. Introduction
|
||
|
|
||
|
1.1 I've never played a MUD before. What should I do?
|
||
|
|
||
|
1.2 I'm new to C and/or coding. What do I do?
|
||
|
|
||
|
1.3 I want to build my own MUD. Where do I start?
|
||
|
|
||
|
1.4 What is CircleMUD?
|
||
|
|
||
|
1.5 What is the history of CircleMUD?
|
||
|
|
||
|
1.6 Where is the original CircleMUD so I can check it out?
|
||
|
|
||
|
1.7 Will the CircleMUD creators visit my mud?
|
||
|
|
||
|
1.8 What is UNIX?
|
||
|
|
||
|
|
||
|
2. Resources
|
||
|
|
||
|
2.1 Where do I find the source code for CircleMUD?
|
||
|
|
||
|
2.2 Where do I find areas, etc. for CircleMUD?
|
||
|
|
||
|
2.3 I have questions about CircleMUD. Where should I go?
|
||
|
|
||
|
2.4 How do I subscribe/unsubscribe to the Mailing List?
|
||
|
|
||
|
2.5 To what platforms has CircleMUD been ported?
|
||
|
|
||
|
2.6 How can I submit code or areas for use with CircleMUD?
|
||
|
|
||
|
2.7 How do I use a patch file and how can I make one?
|
||
|
|
||
|
|
||
|
3. Compiling CircleMUD
|
||
|
|
||
|
3.1 Why do I get many syntax errors with Sun's ``cc'' compiler?
|
||
|
|
||
|
3.2 Why do I get all sorts of errors with ``crypt'' functions and header files?
|
||
|
|
||
|
3.3 When I try to compile, why do I get a lot of undefined symbols
|
||
|
referenced in comm.o for functions like socket, accept, and bind?
|
||
|
|
||
|
3.4 Every time I try to compile Circle (or any other piece of software)
|
||
|
under Linux, it gives me errors and says it cannot find include header
|
||
|
files in the linux/ and asm/ directories. What can I do?
|
||
|
|
||
|
3.5 I'm getting compilation errors from a header file, and I didn't even
|
||
|
change it?
|
||
|
|
||
|
3.6 I'm trying to compile the MUD on Windows '95 and am having problems,
|
||
|
what can I do?
|
||
|
|
||
|
3.7 How can I do a ``grep'' on Windows 95?
|
||
|
|
||
|
3.8 While compiling the MUD, why do I get errors like ``foo.c:1231:
|
||
|
Undefined symbol `_whereamI' referenced from text segment''
|
||
|
|
||
|
3.9 What is a parse error and how do I fix it?
|
||
|
|
||
|
3.10 I have this piece of code that calls bcopy(), bzero(), and bcmp()
|
||
|
and it won't compile, so what can I do?
|
||
|
|
||
|
3.11 My compiler doesn't have ``strdup()'', what can I do?
|
||
|
|
||
|
3.12 I am having trouble with my ``makefile'', what could be the problem?
|
||
|
|
||
|
3.13 How can I handle directories in C?
|
||
|
|
||
|
|
||
|
4. Running CircleMUD
|
||
|
|
||
|
4.1 I typed ``autorun'' but then my terminal just froze.
|
||
|
|
||
|
4.2 I typed ``bin/circle'' and got lots of boot messages, but then it
|
||
|
said ``Entering game loop'' and froze.
|
||
|
|
||
|
4.3 Okay, I think the MUD is running but why don't I get a login prompt?
|
||
|
|
||
|
4.4 How come I get this error when running my MUD: ``Error reading board:
|
||
|
No such file or directory''
|
||
|
|
||
|
4.5 I just got this SIGPIPE, what is it and what Can I Do About It?
|
||
|
|
||
|
4.6 When I run Circle under Linux, it tells me ``gethostbyaddr:
|
||
|
connection refused'' when the MUD boots, and then dies. Why?
|
||
|
|
||
|
4.7 When I run Circle under Windows 95, it tells me ``Winsock error
|
||
|
#10047'' when the MUD boots, and then dies. Why?
|
||
|
|
||
|
4.8 When I run Circle under Windows 95, players can't rent---their
|
||
|
equipment is just dropped on the ground, syslogs don't work, so what
|
||
|
is the problem?
|
||
|
|
||
|
4.9 When someone logs on to my Windows 95 MUD, the console screen gives:
|
||
|
``gethostbyaddr: No such file or directory''
|
||
|
|
||
|
4.10 My MUD crashed and my connection got closed. What can I do?
|
||
|
|
||
|
4.11 Ok, so how do I use ``gdb''?
|
||
|
|
||
|
4.12 How can I hunt bugs more effectively?
|
||
|
|
||
|
4.13 I just added n levels to my MUD (from the stock 34). How do I set
|
||
|
my imps up to level n without a pfile wipe?
|
||
|
|
||
|
4.14 I decided to wipe my pfile away anyway. What steps should I take to
|
||
|
do this?
|
||
|
|
||
|
4.15 I want to expand the ability to pk in my MUD, allowing ASSASSINS
|
||
|
that'll be able to PK without getting flagged. How can I do this?
|
||
|
|
||
|
4.16 Why does it say ``Connection closed by foreign host.'' and not
|
||
|
display the ``Byebye!'' message I'm trying to send before cutting
|
||
|
someone off?
|
||
|
|
||
|
4.17 I run my MUD on a unix system and the pfile/rent file works great,
|
||
|
but on my home system it's all screwed up. What gives?
|
||
|
|
||
|
4.18 How do I get the CircleMUD to autoload when the Linux server is
|
||
|
restarted?
|
||
|
|
||
|
4.19 My server shuts down my MUD everytime I logoff. How do I keep the
|
||
|
MUD running when I logoff?
|
||
|
|
||
|
|
||
|
5. Code Changes for CircleMUD 2.20
|
||
|
|
||
|
5.1 How do I fix the bug where people can junk more coins than available?
|
||
|
|
||
|
5.2 How do I fix the ``vstat'' bug that crashes the MUD?
|
||
|
|
||
|
5.3 How do I fix the ``wizlock'' bug that lets lower immortals lock out
|
||
|
higher immortals?
|
||
|
|
||
|
5.4 How do I fix the ``mudlog'' bug that lets people see me log in, even
|
||
|
if I'm wizinvis?
|
||
|
|
||
|
|
||
|
6. CircleMUD 3.0 Questions
|
||
|
|
||
|
6.1 Are there any bugs in patch level 19?
|
||
|
|
||
|
6.2 How do I access Online Creation?
|
||
|
|
||
|
6.3 How does the new bitvector system work?
|
||
|
|
||
|
6.4 When will the production release of Circle 3.0 be?
|
||
|
|
||
|
6.5 If someone logs in and just sits at the password prompt, the MUD
|
||
|
hangs (i.e., no one else can connect or do anything) until the person
|
||
|
enters their password.
|
||
|
|
||
|
6.6 Why does CircleMUD use BUF switches all through the code, what's
|
||
|
happening here?
|
||
|
|
||
|
6.7 How do I add a new class? How do I add more levels?
|
||
|
|
||
|
6.8 Is there a complete ``coding.doc''?
|
||
|
|
||
|
______________________________________________________________________
|
||
|
|
||
|
1. Introduction
|
||
|
|
||
|
|
||
|
1.1. I've never played a MUD before. What should I do?
|
||
|
|
||
|
Don't try to use your own copy of CircleMUD! There are two levels of MUD
|
||
|
users: players and administrators. Administrators do what you're trying to
|
||
|
do now -- get a copy of a MUD's source code, compile it, and run it.
|
||
|
Players use MUDs that are being administered by someone else. If you try to
|
||
|
actually run a MUD before you've ever played one, you'll get very confused
|
||
|
indeed! Your best bet for now is to play someone else's MUD first. There
|
||
|
are a large number of excellent MUDs out there already, some of which are
|
||
|
based on CircleMUD code. A good place to start looking is the MUD Connector
|
||
|
at:
|
||
|
|
||
|
http://www.mudconnect.com/
|
||
|
|
||
|
The CircleMUD web server also has a smaller CircleMUD Site List at:
|
||
|
|
||
|
http://www.circlemud.org/sites.html
|
||
|
|
||
|
|
||
|
1.2. I'm new to C and/or coding. What do I do?
|
||
|
|
||
|
First, a MUD is not a learning project. It has thousands of lines to it,
|
||
|
many of which are obscure and unclear to even moderately skilled
|
||
|
programmers. Those little, ``Hello, world,'' programs are for learning,
|
||
|
maybe little math tests, etc. A MUD is a pretty ambitous project to start
|
||
|
with. That's like trying to run before you can walk, and while there's more
|
||
|
difficult things than a MUD to start with, there's a ton of easier things
|
||
|
you should start with. Second, if you are persistent, get a good C
|
||
|
reference book and read the code, try to comprehend what everything is doing
|
||
|
(to some small extent). You should probably avoid comm.c as it is home to
|
||
|
the socket functions which general C books don't cover and are usually
|
||
|
explained in other books on network programming. Then try small projects,
|
||
|
something similar to what already exists. This way, you can get away with a
|
||
|
cut-and-paste job and changing some of the code. Adding a simple version of
|
||
|
races isn't all that difficult, just examine the class code in class.c and
|
||
|
the CON_QCLASS block in interpreter.c, cut, paste, and modify. Also look at
|
||
|
structs.h, for "#define CLASS_" You'll begin understanding more and more of
|
||
|
the code as you copy and change it, eventually you'll be able to write a
|
||
|
whole function by yourself. Spend time learning, going with haste will hurt
|
||
|
you more than it will help you.
|
||
|
|
||
|
|
||
|
1.3. I want to build my own MUD. Where do I start?
|
||
|
|
||
|
Many common questions arise from new MUD admins. It is a good idea to pay
|
||
|
attention to them and take their answers to heart. These include things
|
||
|
like the following:
|
||
|
|
||
|
I don't have any coding experience with MUDs, but do have a lot of ideas for
|
||
|
my own. I have played many MUDs for a LONG time, though.
|
||
|
|
||
|
Read the FAQ. MUD Experience doesn't help a huge amount. Code experience
|
||
|
does.
|
||
|
|
||
|
I am interested in having a level system of 1-50 mortal and 51-60 imms. I
|
||
|
am also interested in adding races and classes. How can I accomplish these
|
||
|
things?
|
||
|
|
||
|
By checking the FTP Site under contrib.
|
||
|
(ftp://ftp.circlemud.org/pub/CircleMUD/contrib). Learn a lot from there.
|
||
|
Learn from the Snippets page (http://developer.circlemud.org/snippets/), and
|
||
|
*know* the FAQ.
|
||
|
|
||
|
Also, is there anything that I should know about CircleMUD being a "newbie"
|
||
|
to it?
|
||
|
|
||
|
See the above comment.
|
||
|
|
||
|
|
||
|
1.4. What is CircleMUD?
|
||
|
|
||
|
CircleMUD is a DikuMUD derivitave, developed by Jeremy Elson
|
||
|
<jelson@circlemud.org> and is from the Gamma v0.0 of DikuMUD created by Hans
|
||
|
Henrik Staerfeldt, Katja Nyboe, Tom Madsen, Michael Seifert and Sebastian
|
||
|
Hammer at DIKU (Computer Science Instutute at Copenhagen University). Note
|
||
|
that CircleMUD is a Diku derivative, so its users must follow the DIKU
|
||
|
license agreement---most notably it cannot be used to make money in ANY way,
|
||
|
the original developers' names must be in the login screen and that the
|
||
|
credits command always presents the same information, etc.
|
||
|
|
||
|
Quoting from CircleMUD's release.doc:
|
||
|
|
||
|
"CircleMUD is highly developed from the programming side, but highly
|
||
|
UNdeveloped on the game-playing side. So, if you're looking for a huge
|
||
|
MUD with billions of spells, skills, classes, races, and areas, Circle
|
||
|
will probably disappoint you severely. Circle still has only the 4
|
||
|
original Diku classes, the original spells, the original skills, and
|
||
|
about a couple dozen areas. On the other hand, if you're looking for a
|
||
|
highly stable, well-developed, well-organized "blank slate" MUD on
|
||
|
which you can put your OWN ideas for spells, skills, classes, and
|
||
|
areas, then Circle might be just what you're looking for."
|
||
|
|
||
|
|
||
|
The latest full release of Circle is 2.20, released on November 17, 1993.
|
||
|
Currently 3.0 is in beta, at patch level 19, released on August 14, 2001.
|
||
|
|
||
|
|
||
|
1.5. What is the history of CircleMUD?
|
||
|
|
||
|
o Version 2.00: July 16, 1993
|
||
|
o Version 2.01: July 20, 1993
|
||
|
o Version 2.02: Early August
|
||
|
o Version 2.10: September 1, 1993
|
||
|
o Version 2.11: September 19, 1993
|
||
|
o Version 2.20: November 17, 1993
|
||
|
|
||
|
Version 3.00 is currently in beta right now and is up to patchlevel 19. The
|
||
|
final release is due out Real Soon Now(tm). Don't bother posting requests
|
||
|
for it. It will be out when Jeremy gets it done, and it will be announced
|
||
|
on the mailing list and the newsgroup rec.games.mud.diku.
|
||
|
|
||
|
|
||
|
1.6. Where is the original CircleMUD so I can check it out?
|
||
|
|
||
|
CircleMUD is a public code base, freely distributable, but the author of
|
||
|
Circle doesn't actually run one personally. There used to be CircleMUD, and
|
||
|
while Jeremy Elson continues to develop it, there is no original CircleMUD
|
||
|
any more. To see other MUDs that are using the CircleMUD code base, check
|
||
|
out this Site List: http://www.circlemud.org/sites.html
|
||
|
|
||
|
|
||
|
1.7 Will the CircleMUD creators visit my mud?
|
||
|
|
||
|
While there is a possibility that one (or more) of the CircleMUD creators
|
||
|
will drop by your MUD for a visit, to play, or to simply look around, there
|
||
|
is a slim chance that they will even identify themselves.
|
||
|
|
||
|
Would you like to see us on your MUD? You won't. We don't want free wizzes
|
||
|
or favours for our work here. In fact, we will state categorically that if
|
||
|
anyone comes on your MUD claiming to be associated with us, they aren't.
|
||
|
|
||
|
If you want to check whether or not someone on your MUD really is one of us,
|
||
|
we can all be contacted by email for verification:
|
||
|
Jeremy Elson <jelson@circlemud.org>
|
||
|
Chris Epler <cepler@circlemud.org>
|
||
|
Alex Fletcher <furry@circlemud.org>
|
||
|
George Greer <greerga@circlemud.org>
|
||
|
Daniel Koepke <dkoepke@circlemud.org>
|
||
|
Tony Robbins <tonyr@circlemud.org>
|
||
|
|
||
|
As an interesting side note, there are two interesting things about the
|
||
|
order of the addresses mentioned above:
|
||
|
* They are in alphabetical order by last name.
|
||
|
* They are in chronological order of when each person joined the
|
||
|
CircleMUD team.
|
||
|
|
||
|
|
||
|
1.8. What is UNIX?
|
||
|
|
||
|
UNIX is not an operating system of itself, it's a type (flavour, if you
|
||
|
will) of operating systems. Many different kinds of UNIXes exist. Some of
|
||
|
them are free, some of them are not. How to tell if you have a UNIX
|
||
|
operating system? Well, UNIXes have the `ps' command, tend to have a `%' or
|
||
|
`#' prompt, give you a home directory, `who' will show who else is on the
|
||
|
system, etc. Many UNIX systems (such as Linux) strive to be POSIX
|
||
|
compatible, so you'll probably see POSIX mentioned, too. POSIX is, roughly,
|
||
|
the standards which UNIX operating systems go by. It says what makes an
|
||
|
operating system part of the UNIX family and so forth. Some UNIX operating
|
||
|
systems are not 100% POSIX compatible, actually, most aren't. The following
|
||
|
are types of UNIX (but not all the existing flavours): Linux, FreeBSD, BSD,
|
||
|
BSDi, Solaris. There are others. UNIX operating systems are command-based
|
||
|
and Microsoft does not make a variant.
|
||
|
|
||
|
|
||
|
|
||
|
2. Resources
|
||
|
|
||
|
2.1. Where do I find the source code for CircleMUD?
|
||
|
|
||
|
Circle's complete source code and areas are available for anonymous FTP at
|
||
|
the CircleMUD FTP site:
|
||
|
|
||
|
ftp://ftp.circlemud.org/pub/CircleMUD/
|
||
|
|
||
|
There is also a CircleMUD Home Page:
|
||
|
|
||
|
http://www.circlemud.org/
|
||
|
|
||
|
for additional CircleMUD links and information.
|
||
|
|
||
|
|
||
|
2.2. Where do I find areas, etc. for CircleMUD?
|
||
|
|
||
|
A number of CircleMUD based Implementors have submitted areas to the public
|
||
|
and they are archived at:
|
||
|
|
||
|
ftp://ftp.circlemud.org/pub/CircleMUD/contrib/areas/ (California, USA)
|
||
|
|
||
|
Or you can use one of the CircleMUD mirrors:
|
||
|
|
||
|
ftp://ftp2.circlemud.org/pub/CircleMUD/ (Ohio, USA)
|
||
|
ftp://ftp.stormhaven.org/pub/CircleMUD/ (Virginia, USA)
|
||
|
ftp://ftp.mono.org/pub/mud/CircleMUD/ (London, UK)
|
||
|
|
||
|
If you cannot use FTP, you can contact one of the site maintainers and
|
||
|
request a file. The maintainers are:
|
||
|
|
||
|
Alex Fletcher <furry@circlemud.org>
|
||
|
Chris Epler <cepler@circlemud.org>
|
||
|
George Greer <greerga@circlemud.org>
|
||
|
|
||
|
If the FTP site is down, please try one of the mirrors and then contact Alex
|
||
|
at his alternate address <fletchra@qsilver.queensu.ca> since he will be
|
||
|
able to find out the situation. There is also a code snippets site at:
|
||
|
|
||
|
http://developer.circlemud.org/snippets/
|
||
|
|
||
|
Where a number of code suggestions and hints are located.
|
||
|
|
||
|
|
||
|
2.3. I have questions about CircleMUD. Where should I go?
|
||
|
|
||
|
If you have general questions about the MUD such as how to get it running,
|
||
|
how to add new spells, how to add new skills, etc., the first place you
|
||
|
should look is the documentation. `coding.doc' will have information about
|
||
|
how to add new spells, skills, commands, etc. `building.doc' has information
|
||
|
about how to create new worlds, how to read the database files, etc. There
|
||
|
are many other documents in the doc directory with useful information.
|
||
|
|
||
|
There is also a new project, started in June of 1996, called the CircleMUD
|
||
|
Documentation Project (http://www.circlemud.org/~jelson/circle/cdp/) which
|
||
|
will eventually be a repository for all Circle-related information. It's
|
||
|
still being built as of this writing, but hopefully will become a valuable
|
||
|
resource as more documentation is added.
|
||
|
|
||
|
If you still have questions after reading the doucmentation, you can try
|
||
|
asking on the CircleMUD mailing list (see next section).
|
||
|
|
||
|
If you have a question you think is too "newbie" for the mailing list, try
|
||
|
the help database <help@circlemud.org>. Previous questions are accessible
|
||
|
though the bugs database (http://bugs.circlemud.org/). That is also,
|
||
|
incidently, where you should go to report bugs.
|
||
|
|
||
|
You can also contact the author, Jeremy Elson <jelson@circlemud.org>.
|
||
|
George Greer <greerga@circlemud.org> can also be contacted for most
|
||
|
problems.
|
||
|
|
||
|
|
||
|
2.4. How do I subscribe/unsubscribe to the Mailing List?
|
||
|
|
||
|
There is a CircleMUD mailing list for coders, builders, and administrators.
|
||
|
To subscribe, send a message to the list server <listserv@post.queensu.ca>
|
||
|
with a message body of subscribe circle <first name> <last name>. To
|
||
|
unsubscribe from the list send a message to <listserv@post.queensu.ca> with
|
||
|
the words unsubscribe circle as the message body. DO NOT send subscription
|
||
|
or unsubscription requests to the list in general. There are hundreds of
|
||
|
people on the list, and it will only irritate a ton of people who have no
|
||
|
power to remove you from the list. Read the Mailing List FAQ
|
||
|
(http://qsilver.queensu.ca/~fletchra/Circle/list_faq.html) for more
|
||
|
information.
|
||
|
|
||
|
|
||
|
2.5. To what platforms has CircleMUD been ported?
|
||
|
|
||
|
Version 3.0, although still officially in beta-testing, is very portable
|
||
|
because it uses the GNU autoconf system, meaning you only need to type
|
||
|
``configure'' to have it automatically determine various features of your
|
||
|
system and configure the code accordingly. 3.0 compiles without changes
|
||
|
under most BSD and SVR4 systems, including SunOS, Solaris, Ultrix, IRIX,
|
||
|
AIX, Linux, BSD/OS, HP/UX, and others.
|
||
|
|
||
|
Version 3.0 is also being ported to various non-UNIX platforms. As of
|
||
|
patchlevel 14, you can compile Circle under OS/2 2.x and 3.x with the OS/2
|
||
|
port of gcc, Windows 95/NT using Microsoft Visual C++ version 4.0 or 5.0,
|
||
|
Borland (now Inprise) C++ 4.5, Watcom v.11, Cygnus GNU-WIN32, LCC, Macintosh
|
||
|
with CodeWarrior, Amiga, and Acorn RiscOS.
|
||
|
|
||
|
The older version of the code, Version 2.20, compiles mainly on BSD UNIX
|
||
|
systems but has trouble under SVR4-based systems such as Solaris. The author
|
||
|
has personally compiled and tested v2.20 under Ultrix 4.0, IRIX 4.0.1, 4.0.4
|
||
|
and 4.0.5, SunOS 4.1.1 and 4.1.3, AIX 3.2, Linux 0.99.x and 1.0.x, and
|
||
|
ConvexOS V10.2. Users have reported that v2.20 compiles with relatively
|
||
|
minor changes under NeXTStep 2.1 and 3.0, and HP/UX 9.0.
|
||
|
|
||
|
Jean-Jack Riethoven <J.J.M.Riethoven@ab.agro.nl> ported CircleMUD version
|
||
|
2.20 to the Amiga and has contributed his code for version 3.0 of CircleMUD.
|
||
|
Questions about the Amiga source should be directed to Jean-Jack Riethoven,
|
||
|
not Jeremy Elson or George Greer.
|
||
|
|
||
|
|
||
|
2.6. How can I submit code or areas for use with CircleMUD?
|
||
|
|
||
|
There is a special uploads area:
|
||
|
|
||
|
ftp://upload.circlemud.org/pub/CircleMUD/incoming/
|
||
|
|
||
|
..in the CircleMUD domain for submissions of code, areas, utilities,
|
||
|
scripts, and anything else that might be of use to Circle users. Please
|
||
|
make sure only to upload to upload.circlemud.org and not any of the
|
||
|
CircleMUD mirrors. These portions of code or areas will probably not be
|
||
|
added to the full release of CircleMUD unless you make specific arrangements
|
||
|
with Jeremy for code items, or with Alex for area/lib files.
|
||
|
|
||
|
|
||
|
2.7. How do I use a patch file and how can I make one?
|
||
|
|
||
|
Patch files are created and used using the ``diff'' and ``patch'' utilities,
|
||
|
respectively. They can both be downloaded from the GNU FTP Site
|
||
|
(ftp://ftp.gnu.org/pub/gnu/) under the name ``diffutils- xxx.tar.gz''. If
|
||
|
you happen to be using a DOS or Windows machine, you should get patch for
|
||
|
DOS (ftp://204.119.24.14/pub/patch/patch12.zip). This does not support long
|
||
|
filenames (but can be used with short filenames). There is also a set of
|
||
|
Windows 95 Utilities now available from the Cygnus Gnu-Win32 Project
|
||
|
(http://www.cygnus.com/misc/gnu-win32/).
|
||
|
|
||
|
These are the various parameters to use with diff (all work in general on
|
||
|
unix based systems, but check out the help entries to be certain.
|
||
|
|
||
|
diff -uN [original_src_directory] [altered_src_directory] > Patch
|
||
|
|
||
|
-u is the unified output. ie. it tells diff to output the text what is
|
||
|
called ``patch'' style. On some systems, you will have to use -c but it
|
||
|
generates much larger and harder to follow patches.
|
||
|
|
||
|
-N Tells diff to treat files that are in one directory and not there in the
|
||
|
other as being empty in the one they are not there. It allows entire files
|
||
|
to be included into the patch.
|
||
|
|
||
|
-r recursive, add r to the uN above if you want it to recursively add in
|
||
|
any subdirectories. (be careful with this one)
|
||
|
|
||
|
-p Tells diff to indicate what function is being ``patched'' in each
|
||
|
section. This may not be supported by all versions of ``diff.''
|
||
|
|
||
|
If you download a patch file and would like to add it to your code, first
|
||
|
make sure to read any instructions that the patch author might have written.
|
||
|
The command used to add the patch may vary depending on how the patch was
|
||
|
created. This should given in the first line of the patch or in the
|
||
|
instructions. Normally, if using GNU patch with a unified diff, the command
|
||
|
should be:
|
||
|
|
||
|
patch -u < [patchfile]
|
||
|
|
||
|
If the patch was created with a SYSV patcher (i.e. not a unified diff), the
|
||
|
patch should be added with:
|
||
|
|
||
|
patch -c < [patchfile]
|
||
|
|
||
|
Of course, if the instructions state otherwise, ignore any instruc- tions
|
||
|
given here and follow the instructions given with the patchfile instead.
|
||
|
|
||
|
Finally, in modern patches, there are three characters of interest to note:
|
||
|
|
||
|
o ! :: The line changes between new and old.
|
||
|
o + :: This line is added to the old to make the new.
|
||
|
o - :: This line is removed from the old to make the new.
|
||
|
o The rest of the lines are just there to give you an idea of where
|
||
|
to change.
|
||
|
|
||
|
|
||
|
3. Compiling CircleMUD
|
||
|
|
||
|
3.1. Why do I get many syntax errors with Sun's ``cc'' compiler?
|
||
|
|
||
|
Because Circle is written in ANSI C, and Sun's standard cc compiler isn't
|
||
|
capable of compiling ANSI C code. You can try acc, Sun's ANSI C compiler,
|
||
|
but it costs extra money to get it from Sun so your sysadmin may not have
|
||
|
installed it. Most don't. The best solution is to get the GCC compiler
|
||
|
from the GNU FTP site (ftp://ftp.gnu.org/pub/gnu) and install it, if you
|
||
|
have enough time and space.
|
||
|
|
||
|
|
||
|
3.2. Why do I get all sorts of errors with ``crypt'' functions and
|
||
|
header files?
|
||
|
|
||
|
(This information applies ONLY to Version 3.0 of the code.) CircleMUD
|
||
|
normally uses the UNIX crypt() function to enrypt players' passwords.
|
||
|
Because of export restrictions imposed by the U.S., some systems do not have
|
||
|
the crypt() function. ``configure'' will usually be able to figure out
|
||
|
whether or not your system has crypt(), but if it guesses incorrectly and
|
||
|
you see problems with the crypt() function or headers, you can manually
|
||
|
disable password encryption by going into the sysdep.h source file and
|
||
|
uncommenting the line that reads:
|
||
|
|
||
|
#define NOCRYPT
|
||
|
|
||
|
Be warned, however, that doing this causes the MUD to store players'
|
||
|
passwords in plaintext rather than as encrypted strings. Also, if you move
|
||
|
from a system which has crypt to one that doesn't, players won't be able to
|
||
|
log in with their old passwords!
|
||
|
|
||
|
|
||
|
3.3. When I try to compile, why do I get a lot of undefined symbols
|
||
|
referenced in comm.o for functions like socket, accept, and bind?
|
||
|
|
||
|
SVR4 systems require the socket and nsl libraries for network programs. You
|
||
|
shouldn't see this error any more with version 3.0 because ``configure''
|
||
|
should automatically use those libraries for you; however, if you still have
|
||
|
problems, try adding ``-lsocket -lnsl'' to the line in the Makefile that
|
||
|
links all the object files together into the 'circle' binary.
|
||
|
|
||
|
If you're using V2.20 and you have this error, the best thing to do is
|
||
|
simply to use V3.0 instead. If you insist on using 2.20, go into the
|
||
|
Makefile and search for the comment next to ``SVR4''.
|
||
|
|
||
|
3.4. Every time I try to compile Circle (or any other piece of soft- ware)
|
||
|
under Linux, it gives me errors and says it cannot find include header
|
||
|
files in the linux/ and asm/ directories. What can I do?
|
||
|
|
||
|
Under Linux, you cannot compile any program unless you install the kernel
|
||
|
source code because the kernel source includes the ANSI C header files. You
|
||
|
need the files in /usr/include/linux, which are distributed separately from
|
||
|
the rest of /usr/include.
|
||
|
|
||
|
The easiest way to do this if you're using the Slackware Linux distribution
|
||
|
is simply to install the 'K' series of disks which is the kernel source.
|
||
|
|
||
|
Otherwise, you'll have to set up your include files manually. The easiest
|
||
|
way to get these is to download kernel source from:
|
||
|
|
||
|
http://www.kernel.org/mirrors/
|
||
|
|
||
|
Get the kernel source that matches the kernel you're running (type `uname
|
||
|
-a' to find your kernel version). Then unpack the kernel into the usr/src
|
||
|
/directory. It's about 13 megabytes compressed and 54 megabytes
|
||
|
uncompressed (For the 2.2.9 kernel).
|
||
|
|
||
|
Read the README file that comes with the kernel, and make the symbolic links
|
||
|
you need for /usr/include/asm and /usr/include/linux.
|
||
|
|
||
|
Now compile the MUD. This will take care of most of the errors. You may
|
||
|
have to do `make config' and `make dep' in /usr/src/linux as well, in order
|
||
|
to make linux/config.h and other files that get generated by these steps.
|
||
|
|
||
|
You can remove the whole kernel source tree except for include/ at
|
||
|
this point and get most of your 48.5 megs back.
|
||
|
|
||
|
(Thanks to Michael Chastain for providing this answer.)
|
||
|
|
||
|
|
||
|
3.5. I'm getting compilation errors from a header file, and I didn't even
|
||
|
change it?
|
||
|
|
||
|
Okay, if you really didn't change ``structs.h'' then the error isn't in
|
||
|
``structs.h''. I think I've seen 2 cases where this has happened, the
|
||
|
first, is that the header file you included right before the header file
|
||
|
messing has an error in it. I can't really say much beyond that, but look
|
||
|
for a missing semicolon, are any other errors you can find.
|
||
|
|
||
|
If you include files out of order, it can mess things up. For example, B.h
|
||
|
has stuff in it that is defined in A.h, and if you include B.h before A.h,
|
||
|
you can get errors, your best bet here is to mess with the order of the
|
||
|
headers, making sure you put ``conf.h'' and ``sysdep.h'' at the top,
|
||
|
followed by ``structs.h'', ``utils.h'', etc. Any file specific headers
|
||
|
should be the last one included just for coding style.
|
||
|
|
||
|
|
||
|
3.6. I'm trying to compile the mud on Windows '95 and am having prob- lems,
|
||
|
what can I do?
|
||
|
|
||
|
The first thing to do is to make sure you are compiling a recent version of
|
||
|
the source code. Patch Level 11 and onwards all support Windows '95 winsock
|
||
|
sockets now. Second, you should ensure that you have carefully read the
|
||
|
README.WIN file for instructions on what to include. Next, ensure that you
|
||
|
are using a C compiler that supports long filenames (for example, MSVC 4.0
|
||
|
does, MSVC 1.0 does not). If you happen to be trying to patch something
|
||
|
into your code, you should use patch for DOS
|
||
|
(ftp://204.119.24.14/pub/patch/patch12.zip). This does not support long
|
||
|
filenames (but can be used with short filenames).
|
||
|
|
||
|
|
||
|
3.7. How can I do a ``grep'' on Windows 95?
|
||
|
|
||
|
1. Select ``start menu''->``find''->``files or folders''
|
||
|
2. Enter the files/dirs to search in.
|
||
|
3. Select ``Advanced''
|
||
|
4. In the ``Containing Text'' input box, type in the text you want.
|
||
|
5. Double click on a match to bring up the file that matched.
|
||
|
Even better is to use MSVC's find command (if you have it).
|
||
|
|
||
|
|
||
|
3.8. While compiling the mud, why do I get errors like ``foo.c:1231:
|
||
|
Undefined symbol `_whereamI' referenced from text segment''
|
||
|
|
||
|
You forgot to include a source file into the make. Go edit your Makefile
|
||
|
and make sure all the necessary *.c files are in there, in particular,
|
||
|
whichever C file defines the function that the compiler is complaining is
|
||
|
undefined. If all else fails, try deleting all the *.o files and
|
||
|
recompiling from scratch.
|
||
|
|
||
|
|
||
|
3.9. What is a parse error and how do I fix it?
|
||
|
|
||
|
A parsing error is often a missing or extra semicolon, parenthesis, or
|
||
|
bracket ({).
|
||
|
|
||
|
If the parse error is before a semicolon at the end of a line of code, it is
|
||
|
something on that line.
|
||
|
|
||
|
If it is at the beginning of a line within a function, it is usually a
|
||
|
missing semicolon on the previous line.
|
||
|
|
||
|
If it is at the beginning of a function, count your brackets (especially the
|
||
|
{} ones) in the previous function.
|
||
|
|
||
|
I can't think of any other parse errors. These are the ones I commonly see.
|
||
|
With a bit of practice, they are very easy to locate and fix. For a more
|
||
|
detailed explanation, check out the C Language FAQ.
|
||
|
|
||
|
|
||
|
3.10. I have this piece of code that calls bcopy(), bzero(), and bcmp() and
|
||
|
it won't compile, so what can I do?
|
||
|
|
||
|
All three of these functions are fairly standard on BSD systems. However,
|
||
|
they are not considered to be very portable, and thus should be redefined.
|
||
|
For example, the equivalents for SYSV are:
|
||
|
|
||
|
|
||
|
#define bcopy(from,to,len) memmove(to,from,len)
|
||
|
#define bzero(mem,len) memset(mem,0,len)
|
||
|
#define bcmp(a,b,len) memcmp(a,b,len)
|
||
|
|
||
|
|
||
|
3.11. My compiler doesn't have ``strdup()'', what can I do?
|
||
|
|
||
|
Use Circle's built-in str_dup() function instead.
|
||
|
|
||
|
|
||
|
3.12. I am having trouble with my ``makefile'', what could be the problem?
|
||
|
|
||
|
If you used cut and paste to insert items into your makefile, it is likely
|
||
|
that you accidentally put spaces at the beginning of lines where tabs are
|
||
|
needed. This is how the makefile must be constructed:
|
||
|
|
||
|
foo.o: foo.c conf.h sysdep.h structs.h utils.h interpreter.h \
|
||
|
handler.h db.h
|
||
|
{TAB}$(CC) -c $(CFLAGS)
|
||
|
|
||
|
To add these lines properly, you can use gcc to assist you with the
|
||
|
following shell script (from Daniel Koepke):
|
||
|
|
||
|
#!/bin/sh
|
||
|
gcc -MM $1 >> Makefile
|
||
|
echo "{TAB}\$(CC) -c \$(CFLAGS) $1" >> Makefile
|
||
|
|
||
|
To use this script, replace {TAB} with a tab, and then run the script
|
||
|
like: add_file foo.c
|
||
|
|
||
|
|
||
|
3.13. How can I handle directories in C?
|
||
|
|
||
|
Note that this seems only to be valid for UNIX OSes. Handling of
|
||
|
directories is accomplished through the dirent.h and sys/types.h files. The
|
||
|
function opendir() returns a ``DIR*'' pointer (it's like but not the same as
|
||
|
the ``FILE *'' pointer) when you pass it the name of a directory to open or
|
||
|
NULL if it can't open the dir. After the directory has been opened, you can
|
||
|
step through the files or search for particular files, etc. using readdir(),
|
||
|
seekdir(), and scandir(). When you reach the end of the directory list, you
|
||
|
can either go back to the start with rewinddir() or close the directory with
|
||
|
closedir(). The following code (which has not been tested) should open a
|
||
|
directory and go through it one by one and prints the filenames:
|
||
|
|
||
|
struct dirent * ffile;
|
||
|
DIR * my_dir;
|
||
|
|
||
|
if (!(my_dir = opendir("foo")))
|
||
|
return;
|
||
|
|
||
|
while (1) {
|
||
|
if (!(dirent = readdir(my_dir)))
|
||
|
break;
|
||
|
printf("%s\n", dirent->d_name);
|
||
|
}
|
||
|
|
||
|
closedir(my_dir);
|
||
|
|
||
|
The dirent structure contains only two useful elements, the file's name
|
||
|
(d_name) and the files length (d_reclen).
|
||
|
|
||
|
Thanks to Daniel Koepke for the above.
|
||
|
|
||
|
|
||
|
4. Running CircleMUD
|
||
|
|
||
|
4.1. I typed ``autorun'' but then my terminal just froze.
|
||
|
|
||
|
autorun is a script which automatically runs, logs, and reboots the game for
|
||
|
long-term runs. You should run autorun in the background by typing
|
||
|
``./autorun &'' -- the MUD will start running in the background and you'll
|
||
|
get the normal UNIX prompt back immediately (see section 4.3). The game will
|
||
|
then run unattended until you explicitly shut it down.
|
||
|
|
||
|
On some systems, you may need to prepend ``nohup'' to the autorun command
|
||
|
since some systems will kill off any processes left running when you leave
|
||
|
the shell.
|
||
|
|
||
|
|
||
|
4.2. I typed ``bin/circle'' and got lots of boot messages, but then it said
|
||
|
``Entering game loop'' and froze.
|
||
|
|
||
|
It is not frozen, it is just waiting for people to connect. You have to run
|
||
|
the MUD in the background by typing ``bin/circle &'' and then use telnet to
|
||
|
connect to the game (see next section).
|
||
|
|
||
|
|
||
|
4.3. Okay, I think the MUD is running but why don't I get a login prompt?
|
||
|
|
||
|
In order to play the MUD, you must connect to it using the telnet command,
|
||
|
i.e. ``telnet localhost 4000''.
|
||
|
|
||
|
|
||
|
4.4. How come I get this error when running my mud: ``Error reading board:
|
||
|
No such file or directory''
|
||
|
|
||
|
This is not a bad thing, all it means is that you have some boards on the
|
||
|
mud and that it can't find the file for them. Since it can't find the file,
|
||
|
the mud will just create the file on the fly and use that, so the next time
|
||
|
something is posted to the board, the files will exist. However, if you did
|
||
|
have files for the boards and you are suddenly getting this error, it means
|
||
|
that the board files have been deleted or something similar.
|
||
|
|
||
|
|
||
|
4.5. I just got this SIGPIPE, what is it and what Can I Do About It?
|
||
|
|
||
|
Often it appears that other people send your system SIGPIPEs when their
|
||
|
connection is closed, in fact, it is not the person sending the SIGPIPE, it
|
||
|
is your system. The SIGPIPE is generated when your program attempts to
|
||
|
write to descriptor which has no one listening to it. This occurs if the
|
||
|
character is sent a message by the mud after connecting, but before the
|
||
|
socket is flagged with an exception or reads 0 bytes. By default, CircleMUD
|
||
|
ignores these SIGPIPEs, with the line my_signal(SIGPIPE, SIG_IGN) in
|
||
|
signal_setup(). Where most people see the problems with SIGPIPE is while
|
||
|
debugging with GDB. By default, GDB responds to a SIGPIPE by stoping the
|
||
|
program, printing that a SIGPIPE was received, and passing it to the
|
||
|
program. You can change the action taken by GDB by using the `handle'
|
||
|
command. To stop the program from stoping at SIGPIPE, you would give GDB the
|
||
|
command `handle SIGPIPE nostop'
|
||
|
|
||
|
|
||
|
4.6. When I run Circle under Linux, it tells me ``gethostbyaddr: con-
|
||
|
nection refused'' when the MUD boots, and then dies. Why?
|
||
|
|
||
|
You need to make sure you have Networking and TCP/IP support compiled into
|
||
|
your Linux kernel, even if you aren't actually connected to the Internet.
|
||
|
The easiest way to do this if you're using Slackware is to install one of
|
||
|
Slackware's precompiled networking kernels. Also, make sure to install
|
||
|
Slackware's `N' series of disks which contains other networking support
|
||
|
files.
|
||
|
|
||
|
If Slackware's precompiled kernel isn't available you'll have to compile the
|
||
|
kernel yourself. First make sure the kernel source is installed in
|
||
|
/usr/src/linux (see section 3.1.4) and follow the instructions in
|
||
|
/usr/src/linux/README. When you do `make config' it will ask you a series of
|
||
|
questions about which kernel features you want; make sure to answer ``Y'' to
|
||
|
``Networking support'' and ``TCP/IP support''.
|
||
|
|
||
|
|
||
|
4.7. When I run Circle under Windows 95, it tells me ``Winsock error
|
||
|
#10047'' when the MUD boots, and then dies. Why?
|
||
|
|
||
|
You need to configure TCP/IP networking from the Network Control Panel, even
|
||
|
if you are not connected to the Internet. From the Network Control Panel,
|
||
|
select ``Add Protocol'', and under the vendor ``Microsoft'', choose
|
||
|
``TCP/IP''. It may ask you to insert the Windows 95 CDROM in order to copy
|
||
|
the drivers onto your hard drive.
|
||
|
|
||
|
|
||
|
4.8. When I run Circle under Windows 95, players can't rent---their
|
||
|
equipment is just dropped on the ground, syslogs don't work, so what
|
||
|
is the problem?
|
||
|
|
||
|
The reason that objects aren't saved when your players quit is that certain
|
||
|
unzip programs are buggy and don't completely recreate the MUD's directory
|
||
|
structure (in particular, it doesn't create directories which have no files
|
||
|
in them.) This is fixed in Circle 3.0 patchlevel 12 and above. Before
|
||
|
patchlevel 12, you can fix it simply by manually creating the needed
|
||
|
directories:
|
||
|
|
||
|
CD \Circle30bpl11
|
||
|
cd lib\plrobjs
|
||
|
mkdir A-E
|
||
|
mkdir F-J
|
||
|
mkdir K-O
|
||
|
mkdir P-T
|
||
|
mkdir U-Z
|
||
|
mkdir ZZZ
|
||
|
|
||
|
Object saving should then work. The syslogs are a different story; no data
|
||
|
is written to the system logs because the code currently is configured
|
||
|
simply to write all errors to the standard error file descriptor (stderr),
|
||
|
and Windows doesn't seem to let you redirect stderr to a file the same way
|
||
|
UNIX does. pl12 allows you to direct logs to a specific file instead.
|
||
|
|
||
|
|
||
|
4.9. When someone logs on to my Windows 95 MUD, the console screen
|
||
|
gives: ``gethostbyaddr: No such file or directory''
|
||
|
|
||
|
This means the MUD can't resolve the IP address of the connecting player's
|
||
|
source site innto a hostname. You probably don't have DNS correctly
|
||
|
configured in the Windows Network Control Panel menu (under configuration of
|
||
|
the TCP protocol). Make sure you have the IP address of your ISP's DNS
|
||
|
server listed.
|
||
|
|
||
|
|
||
|
4.10. My MUD crashed and my connection got closed. What can I do?
|
||
|
|
||
|
Just because your connection got closed from the MUD (for example, if you
|
||
|
get too much information sent to you and the telnet session gets closed),
|
||
|
this doesn't always mean that the game itself crashed. Before reporting
|
||
|
something as a crash bug, make sure that the game itself crashed, and above
|
||
|
all, try to duplicate the circumstances before reporting it as a crash bug.
|
||
|
You can also try using gdb to find out why the MUD is crashing if it gives
|
||
|
you a core dump.
|
||
|
|
||
|
|
||
|
4.11. Ok, so how do I use ``gdb''?
|
||
|
|
||
|
GDB has some online help, though it is not the best. It does at least give
|
||
|
a summary of commands and what they're supposed to do. What follows is
|
||
|
Sammy's short intro to gdb with some bughunting notes following it:
|
||
|
|
||
|
If you've got a core file, go to your top circle directory and type:
|
||
|
|
||
|
> gdb bin/circle lib/core
|
||
|
|
||
|
If you want to hunt bugs in real time (causing bugs to find the cause as
|
||
|
opposed to checking a core to see why the MUD crashed earlier) use:
|
||
|
|
||
|
> gdb bin/circle
|
||
|
|
||
|
If you're working with a core, gdb should show you where the crash occurred.
|
||
|
If you get an actual line that failed, you've got it made. If not, the
|
||
|
included message should help. If you're working in real time, now's the
|
||
|
time to crash the MUD so you can see what gdb catches.
|
||
|
|
||
|
When you've got the crash info, you can type ``where'' to see which function
|
||
|
called the crash function, which function called that one, and so on all the
|
||
|
way up to ``main()''.
|
||
|
|
||
|
I should explain about ``context'' You may type ``print ch'' which you
|
||
|
would expect to show you the ch variable, but if you're in a function that
|
||
|
doesn't get a ch passed to it (real_mobile, etc), you can't see ch because
|
||
|
it's not in that context. To change contexts (the function levels you saw
|
||
|
with where) type ``up'' to go up. You start at the bottom, but once you go
|
||
|
up, and up, and up, you can always go back ``down''. You may be able to go
|
||
|
up a couple functions to see a function with ch in it, if finding out who
|
||
|
caused the crash is useful (it normally isn't).
|
||
|
|
||
|
The ``print'' command is probably the single most useful command, and lets
|
||
|
you print any variable, and arithmetic expressions (makes a nice calculator
|
||
|
if you know C math). Any of the following are valid and sometimes useful:
|
||
|
|
||
|
print ch (fast way to see if ch is a valid pointer, 0 if it's not)
|
||
|
print *ch (prints the contents of ch, rather than the pointer address)
|
||
|
print ch->player.name (same as GET_NAME(ch))
|
||
|
print world[ch->in_room].number (vnum of the room the char is in)
|
||
|
|
||
|
etc..
|
||
|
|
||
|
Note that you can't use macros (all those handy psuedo functions like
|
||
|
GET_NAME and GET_MAX_HIT), so you'll have to look up the full structure path
|
||
|
of variables you need.
|
||
|
|
||
|
Type ``list'' to see the source before and after the line you're currently
|
||
|
looking at. There are other list options but I'm unfamiliar with them.
|
||
|
|
||
|
(From Sammy <Samedi@cris.com>)
|
||
|
|
||
|
For more information, you can try checking out the GDB Debugger
|
||
|
(http://www.dgii.com/people/robertl/skunk/gdb/gdb_toc.html)
|
||
|
|
||
|
|
||
|
4.12. How can I hunt bugs more effectively?
|
||
|
|
||
|
There are only a couple of commands to use in gdb, though with some patience
|
||
|
they can be very powerful. The only commands I've ever used are:
|
||
|
|
||
|
run well, duh.
|
||
|
print [variable] also duh, though it does more than you might think
|
||
|
list shows you the source code in context
|
||
|
break [function] set a breakpoint at a function
|
||
|
clear [function] remove a breakpoint
|
||
|
step execute one line of code
|
||
|
cont continue running after a break or ctrl-c
|
||
|
|
||
|
I've run into nasty problems quite a few times. The cause is often a memory
|
||
|
problem, usually with pointers, pointers to nonexistent memory. If you free
|
||
|
a structure, or a string or something, the pointer isn't always set to NULL,
|
||
|
so you may have code that checks for a NULL pointer that thinks the pointer
|
||
|
is ok since it's not NULL. You should make sure you always set pointers to
|
||
|
NULL after freeing them.
|
||
|
|
||
|
Ok, now for the hard part. If you know where the problem is, you should be
|
||
|
able to duplicate it with a specific sequence of actions. That makes things
|
||
|
much easier. What you'll have to do is pick a function to ``break'' at.
|
||
|
The ideal place to break is immediately before the crash. For example, if
|
||
|
the crash occurred when you tried to save a mob with medit, you might be
|
||
|
able to ``break mobs_to_file''. Try that one first.
|
||
|
|
||
|
When you `medit save', the MUD will hang. GDB will either give you segfault
|
||
|
info, or it will be stopped at the beginning of mobs_to_file. If it
|
||
|
segfaulted, pick an earlier function, like copy_mobile, or even do_medit.
|
||
|
|
||
|
When you hit a breakpoint, print the variables that are passed to the
|
||
|
function to make sure they look ok. Note that printing the contents of
|
||
|
pointers is possible with a little playing around. For example, if you
|
||
|
print ch, you get a hex number that shows you the memory location where ch
|
||
|
is at. It's a little helpful, but try print *ch and you'll notice that it
|
||
|
prints the contents of the ch structure, which is usually more useful.
|
||
|
print ch->player will give you the name of the person who entered the
|
||
|
command you're looking at, and some other info. If you get a no ch in this
|
||
|
context it is because the ch variable wasn't passed to the function you're
|
||
|
currently looking at.
|
||
|
|
||
|
Ok, so now you're ready to start stepping. When GDB hit your breakpoint, it
|
||
|
showed you the first line of executable code in your function, which will
|
||
|
sometimes be in your variable declarations if you initialized any variables
|
||
|
(ex: int i = 0). As you're stepping through lines of code, you'll see one
|
||
|
line at a time. Note that the line you see hasn't been run yet. It's
|
||
|
actually the _next_ line to be executed. So if the line is a = b + c;,
|
||
|
printing a will show you what a was before this line, not the sum of b and
|
||
|
c. If you have an idea of where the crash is occurring, you can keep
|
||
|
stepping till you get to that part of the code (tip: pressing return will
|
||
|
repeat the last GDB command, so you can type step once, then keep pressing
|
||
|
return to step quickly). If you have no idea where the problem is, the
|
||
|
quick and dirty way to find your crash is to keep pressing return rapidly
|
||
|
(don't hold the eturn key or you'll probably miss it). When you get the seg
|
||
|
fault, you can't step any more, so it should be obvious when that happens.
|
||
|
|
||
|
Now that you've found the exact line where you get the crash, you should
|
||
|
start the MUD over and step more slowly this time. What I've found that
|
||
|
works really well to save time is to create a dummy function. This one will
|
||
|
work just fine:
|
||
|
|
||
|
void dummy(void){}
|
||
|
|
||
|
Put that somewhere in the file you're working on. Then, right before the
|
||
|
crash, put a call to dummy in the code (ex: dummy();). Then set your
|
||
|
breakpoint at dummy, andwhen you hit the breakpoint, step once to get back
|
||
|
to the crashing code.
|
||
|
|
||
|
Now you're in total control. You should be looking at the exact line that
|
||
|
gave you the crash last time. Print *every* variable on this line. Chances
|
||
|
are one of them will be a pointer to an unaccessable memory location. For
|
||
|
example, printing ch->player.name may give you an error. If it does, work
|
||
|
your way back and print ch->player to make sure that one's valid, and if it
|
||
|
isn't, try printing ch.
|
||
|
|
||
|
Somewhere in there you're going to have an invalid pointer. Once you know
|
||
|
which one it is, it's up to you to figure out why it's invalid. You may have
|
||
|
to move dummy() up higher in the code and step slowly, checking your pointer
|
||
|
all the way to see where it changes from valid to invalid. You may just
|
||
|
need to NULL a free'd pointer, or you may have to add a check for a NULL
|
||
|
pointer, or you may have screwed up a loop. I've done all that and more :)
|
||
|
|
||
|
Well, that's it in a nutshell. There's a lot more to GDB that I haven't
|
||
|
even begun to learn, but if you get comfortable with print and stepping you
|
||
|
can fix just about any bug. I spent hours on the above procedure trying to
|
||
|
get my ascii object and mail saving working right, but it could have taken
|
||
|
weeks without gdb. The only other suggestion I have is to check out the
|
||
|
online gdb help. It's not very helpful for learning, but you can see what
|
||
|
commands are available and play around with them to see if you can find any
|
||
|
new tools.
|
||
|
|
||
|
(From Sammy <samedi@cris.com>)
|
||
|
|
||
|
|
||
|
4.13. I just added n levels to my MUD (from the stock 34). How do I set my
|
||
|
imps up to level n without a pfile wipe?
|
||
|
|
||
|
You can write a quick and nasty function that will advance your imp (and imp
|
||
|
only) to the max level (LVL_IMPL). This can be done with a quick idnum
|
||
|
check so that only the original player (the first imp, he with id 1) can use
|
||
|
the command to get to maximum level.
|
||
|
|
||
|
ACMD(do_upme)
|
||
|
{
|
||
|
if (GET_IDNUM(ch) != 1) {
|
||
|
send_to_char("You think IMP positions are that easy to come by? Go Figure...\r\n", ch);
|
||
|
} else {
|
||
|
GET_LEVEL(ch) = LVL_IMPL;
|
||
|
send_to_char("Advanced.\r\n", ch);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
4.14. I decided to wipe my pfile away anyway. What steps should I take to
|
||
|
do this?
|
||
|
|
||
|
In order:
|
||
|
1. Shutdown the MUD with ``shutdown die'' so that it won't restart.
|
||
|
2. Remove the player file, lib/etc/players
|
||
|
3. Restart the MUD and login to recreate your imp character.
|
||
|
|
||
|
You should probably also remove files in plrobjs, unless you want the
|
||
|
recreated characters to come back with the same equipment they had when they
|
||
|
were deleted.
|
||
|
|
||
|
|
||
|
4.15. I want to expand the ability to pk in my MUD, allowing ASSASSINS
|
||
|
that'll be able to PK without getting flagged. How can I do this?
|
||
|
|
||
|
The simple way to do this is to find all the ``pk_allowed'' checks and
|
||
|
replace them with a can_murder(ch, vict) function call. Prototype the
|
||
|
function in utils.h. Then, in utils.c, create a can_murder() function
|
||
|
something like this:
|
||
|
|
||
|
int can_murder(struct char_data *ch, struct char_data *victim) {
|
||
|
if (pk_allowed == TRUE)
|
||
|
return TRUE;
|
||
|
if (IS_NPC(ch) || IS_NPC(victim))
|
||
|
return TRUE; /* you can always kill these */
|
||
|
if (PLR_FLAGGED(ch, PLR_ASSASSIN))
|
||
|
return TRUE; /* they can kill anyone */
|
||
|
/* Add further checks here */
|
||
|
}
|
||
|
|
||
|
|
||
|
4.16. Why does it say ``Connection closed by foreign host.'' and not
|
||
|
display the ``Byebye!'' message I'm trying to send before cutting
|
||
|
someone off?
|
||
|
|
||
|
This usually happens if you are doing something like this:
|
||
|
|
||
|
send_to_char("Bye bye. Come back soon, ya hear?", ch);
|
||
|
close_socket(ch->desc);
|
||
|
|
||
|
The close_socket immediately dispatches/closes the connection, while
|
||
|
send_to_char puts the message on the output queue to be dispatched next
|
||
|
game_loop cycle. Therefore, the socket is gone. On some systems (ie old
|
||
|
linux), this can even cause a infinite loop attempting to write to a closed
|
||
|
socket. The proper way of doing this and other ``Byebye'' messages is to set
|
||
|
the CON state of the player to CLOSE, like this:
|
||
|
|
||
|
send_to_char("Bye bye. Come back soon, ya hear?", ch);
|
||
|
STATE(ch->desc) = CON_CLOSED;
|
||
|
|
||
|
This will then cycle to the next game_loop, dispatch the output queues
|
||
|
(therefore sending the byebye message) and then close the socket. Further
|
||
|
note, in some bizarre cases, this only seems to send about 40 characters and
|
||
|
no escape codes. Sending more than 40 characters or escape codes (like the
|
||
|
clear screen sequence) will crash the process reporting a problem similar to
|
||
|
writing to a closed socket.
|
||
|
|
||
|
|
||
|
4.17. I run my MUD on a unix system and the pfile/rent file works great,
|
||
|
but on my home system it's all screwed up. What gives?
|
||
|
|
||
|
Some operating systems write binary data least-signifigant-digit- first,
|
||
|
while others write it most-significant-first (big endian vs. little endian).
|
||
|
Moving player files, rent files, mail files, and board files from one of
|
||
|
these systems to the other will result in corrupted files. The solutions to
|
||
|
this problem include:
|
||
|
|
||
|
o Don't bother trying to move those files.
|
||
|
o Edit your code to always write in one format.
|
||
|
o Develop a binary to ascii conversion tool (and ascii to binary) for
|
||
|
all binary files.
|
||
|
o Develop an ascii read/write system to allow portability.
|
||
|
|
||
|
|
||
|
4.18. How do I get the CircleMUD to autoload when the Linux server is
|
||
|
restarted?
|
||
|
|
||
|
In /etc/rc.d/rc.local find where things like sendmail and (maybe) gpm
|
||
|
are started. Add something like:
|
||
|
|
||
|
cd /home/mudlogin/circlebpl19/
|
||
|
su mudlogin -c ./autorun &
|
||
|
cd
|
||
|
|
||
|
Of course, change the "mudlogin" to whatever the name of the account is that
|
||
|
normally has control of the MUD, and change the path in the first cd to
|
||
|
whereever the MUD is run from.
|
||
|
|
||
|
For more info: man su
|
||
|
|
||
|
|
||
|
4.19. My server shuts down my MUD everytime I logoff. How do I keep the MUD
|
||
|
running when I logoff?
|
||
|
|
||
|
Instead of typing "autorun &" to start the autorun script (which starts and
|
||
|
keeps the MUD running), type "nohup autorun &". Running the autorun via
|
||
|
nohup will keep the script and the MUD running when you logoff of the
|
||
|
server. For more information type "man nohup" at the prompt on your server.
|
||
|
|
||
|
|
||
|
5. Code Changes for CircleMUD 2.20
|
||
|
|
||
|
5.1. How do I fix the bug where people can junk more coins than available?
|
||
|
|
||
|
Apprently in Circle 2.2, you can drop any amount of coins, and then be
|
||
|
rewarded with more coins than you had in the first place. Here is the fix
|
||
|
from Jeremy Elson:
|
||
|
|
||
|
Around line 480 of act.obj1.c, you will find the code:
|
||
|
|
||
|
if (!str_cmp("coins", arg) || !str_cmp("coin", arg))
|
||
|
perform_drop_gold(ch, amount, mode, RDR);
|
||
|
else {
|
||
|
/* code to drop multiple items. anyone want to write it? -je */
|
||
|
send_to_char("Sorry, you can't do that (yet)...\n\r", ch);
|
||
|
--> return;
|
||
|
}
|
||
|
} else {
|
||
|
....
|
||
|
|
||
|
It should be changed to:
|
||
|
|
||
|
if (!str_cmp("coins", arg) || !str_cmp("coin", arg))
|
||
|
perform_drop_gold(ch, amount, mode, RDR);
|
||
|
else {
|
||
|
/* code to drop multiple items. anyone want to write it? -je */
|
||
|
send_to_char("Sorry, you can't do that (yet)...\n\r", ch);
|
||
|
}
|
||
|
--> return;
|
||
|
} else {
|
||
|
....
|
||
|
|
||
|
|
||
|
5.2. How do I fix the ``vstat'' bug that crashes the MUD?
|
||
|
|
||
|
To the fix for the vstat bug, from Jeremy Elson:
|
||
|
|
||
|
In the file act.wizard.c, in the function do_vstat, in the mobile section of
|
||
|
the switch (around line 1150), you'll find the code:
|
||
|
|
||
|
mob = read_mobile(r_num, REAL);
|
||
|
do_stat_character(ch, mob);
|
||
|
extract_char(mob);
|
||
|
|
||
|
Add the line char_to_room(mob, 0) before extract_char(), like this:
|
||
|
|
||
|
mob = read_mobile(r_num, REAL);
|
||
|
do_stat_character(ch, mob);
|
||
|
char_to_room(mob, 0);
|
||
|
extract_char(mob);
|
||
|
|
||
|
|
||
|
5.3. How do I fix the ``wizlock'' bug that lets lower immortals lock
|
||
|
out higher immortals?
|
||
|
|
||
|
Simple, insert this code into 'do_wizlock()' in 'act.wizard.c':
|
||
|
|
||
|
if (value < 0 || value > LEVEL_IMPL) {
|
||
|
send_to_char("Invalid wizlock value.\n\r", ch);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
+ /* Do not allow people to wizlock above their level.
|
||
|
+ * This bug came with Circle 2.20 source -- VampLestat
|
||
|
+ */
|
||
|
+ if (value > GET_LEVEL(ch)) {
|
||
|
+ send_to_char("You may only wizlock below your level.\n\r", ch);
|
||
|
+ return;
|
||
|
+ }
|
||
|
restrict = value;
|
||
|
|
||
|
|
||
|
5.4. How do I fix the ``mudlog'' bug that lets people see me log in,
|
||
|
even if I'm wizinvis?
|
||
|
|
||
|
For all the mudlog calls for entering the game, quitting, and so
|
||
|
forth, you must change
|
||
|
|
||
|
mudlog(MAX(LEVEL_IMMORT, ...
|
||
|
|
||
|
to
|
||
|
|
||
|
mudlog(MAX(GET_LEVEL(i), ...
|
||
|
|
||
|
where ``i'' is either ``ch'' or ``d->character'' depending on the
|
||
|
call.
|
||
|
|
||
|
|
||
|
6. CircleMUD 3.0 Questions
|
||
|
|
||
|
6.1. Are there any bugs in patch level 19?
|
||
|
|
||
|
There are no bugs. Only features. Seriously though, if perchance you find
|
||
|
a bug, please mail it (along with a possible fix) to the bugs database
|
||
|
<bugs@circlemud.org> and the CircleMUD list. Once in the bug database, it
|
||
|
will be routed to the correct person. Note that no confirmation is sent
|
||
|
back automatically. You can view the status of the bug at the bugs database
|
||
|
(http://bugs.circlemud.org/).
|
||
|
|
||
|
|
||
|
6.2. How do I access Online Creation?
|
||
|
|
||
|
Online Creation is not yet part of the Circle beta release. When it does
|
||
|
become part of the release, it'll be accessed through a command called olc.
|
||
|
Update: OLC will probably be in release 3.10 now, instead of 3.0. In the
|
||
|
mean time, check out the CircleMUD FTP Server:
|
||
|
|
||
|
ftp://ftp.circlemud.org/pub/CircleMUD/contrib/olc/
|
||
|
|
||
|
|
||
|
6.3. How does the new bitvector system work?
|
||
|
|
||
|
The new bitvector system in CircleMUD 3.0 is an ascii based one. The old
|
||
|
numeric values can still be used, but the new system should make sorting
|
||
|
flags out substantially easier. The system uses an ``a'' as the value for
|
||
|
1, ``b'' for 2, ``c'' for 4, ``d'' for 8, etc. Once ``z'' is reached, the
|
||
|
next letter in sequence is ``A''. Detailed information about how to use
|
||
|
bitvectors with CircleMUD can be found in the CircleMUD Builder's Manual
|
||
|
(http://www.circlemud.org/~jelson/cdp/building/).
|
||
|
|
||
|
|
||
|
6.4. When will the production release of Circle 3.0 be?
|
||
|
|
||
|
I don't know. Don't ask again. Same for the next patch level. If you must
|
||
|
have bleeding edge stuff, check out the CVS Snapshot
|
||
|
(ftp://ftp.circlemud.org/pub/CircleMUD/cvs/) until we get an online
|
||
|
anonymous CVS. And don't ask when the next CVS snapshot will be, we'll do
|
||
|
it when we have some changes worth it.
|
||
|
|
||
|
|
||
|
6.5. If someone logs in and just sits at the password prompt, the MUD hangs
|
||
|
(i.e., no one else can connect or do anything) until the person enters
|
||
|
their password.
|
||
|
|
||
|
Your system's POSIX non-blocking I/O might be broken. Look in the source
|
||
|
file sysdep.h at the comment above the line that says ``#define
|
||
|
POSIX_NONBLOCK_BROKEN" for a possible fix. Once this is done, recompile the
|
||
|
MUD and try again. If you use the POSIX_NONBLOCK_BROKEN constant and it
|
||
|
fixes your problem, please send mail to the bugs database
|
||
|
<bugs@circlemud.org> and let us know exactly what kind of system you are
|
||
|
using and what you had to do to fix it.
|
||
|
|
||
|
|
||
|
6.6. Why does CircleMUD use BUF switches all through the code, what's
|
||
|
happening here?
|
||
|
|
||
|
From Jeremy:
|
||
|
|
||
|
This code is the new output buffering system that I wrote for Circle in the
|
||
|
early (non-released) beta versions of 3.0. The old Diku code for queueing
|
||
|
output (which stayed with Circle until version 2.20) was memory- and
|
||
|
time-inefficient in many cases (and, in my opinion, was inefficient for the
|
||
|
normal behavior of most MUDs).
|
||
|
|
||
|
First, I should explain what output queueing is and why it is necessary. On
|
||
|
each pass through the game_loop(), the MUD performs a number of steps: check
|
||
|
to see if there are any new players connecting, kick out people with bad
|
||
|
links, read input over the network for all players, then process the input
|
||
|
for each player that has sent a complete line over the net. The processing
|
||
|
step is usually where output is generated because it is where MUD commands
|
||
|
are processed (e.g., ``kill'' might generate output of ``Kill who?'') When
|
||
|
output is generated, it is not immediately sent out to the player, but
|
||
|
instead queued for output in a buffer. After all players' commands are
|
||
|
processed (and each command generates the appropriate output for various
|
||
|
players), the next step of the game_loop() is to send all the queued output
|
||
|
out over the network.
|
||
|
|
||
|
The new output system that Circle now uses allocates a small, fixed size
|
||
|
buffer (1024 bytes) for each descriptor in which output can be queued. When
|
||
|
output is generated (via such functions as send_to_char(), act(), etc.), it
|
||
|
is written to the fixed size buffer until the buffer fills. When the buffer
|
||
|
fills, we switch over to a larger (12K) buffer instead. A ``buffer
|
||
|
switch'', therefore, is when the 1024-byte fixed buffer overflows.
|
||
|
|
||
|
When a large (12K) buffer is needed, it is taken from a pool of 12K buffers
|
||
|
that already been created. It is used for the duration of that pass through
|
||
|
the game_loop() and then returned to the pool immediately afterwards, when
|
||
|
the output is sent to the descriptor. If a large buffer is needed but none
|
||
|
are in the pool, one is created (thereby increasing the size of the pool);
|
||
|
the ``buf_largecount'' variable records the current pool size.
|
||
|
|
||
|
If a player has already gone from their small to large buffer, and so much
|
||
|
output is generated that it fills even the large buffer, the descriptor is
|
||
|
changed to the overflow state, meaning that all future output for the
|
||
|
duration of the current pass through the game loop is discarded. This is a
|
||
|
buffer overflow, and the only state in which output is lost.
|
||
|
|
||
|
Now that I've described how the system works, I'll describe the rationale.
|
||
|
The main purpose for the two-tiered buffer system is to save memory and
|
||
|
reduce CPU usage. From a memory standpoint: Allocating a fixed 12K buffer
|
||
|
for each socket is a simple scheme (and very easy to code), but on a large
|
||
|
MUD, 100 12K buffers can add up to a lot of wasted memory. (1.2 megs of
|
||
|
memory used for buffering on a 100-player MUD may not seem like very much,
|
||
|
but keep in mind that one of Circle's big selling points several years ago,
|
||
|
when memory was expensive, was that it had a very small memory footprint (3
|
||
|
or 4 megs total!) And from a CPU standpoint: the original Diku used a
|
||
|
dynamically allocated buffer scheme to queue output, which unfortunately
|
||
|
meant that for each player, on each pass through the game loop, dozens of
|
||
|
tiny buffers (often one for every line of output, depending on the code to
|
||
|
execute the command) were allocated with malloc(), individually written to
|
||
|
the system using individual calls to write(), and then free()'d. My system
|
||
|
saves hundreds or thousands of calls per second to malloc() and free(), and
|
||
|
reduces the number of system calls *drastically* (to at most one per player
|
||
|
per pass through the game loop).
|
||
|
|
||
|
The trick is to choose the size of the small and large buffers correctly in
|
||
|
order to find the optimal behavior. I consider ``optimal'' to mean that 90%
|
||
|
of the time, most players stay within the limits of their small buffer (for
|
||
|
example, when wandering through town or mindlessly killing some monster
|
||
|
while watching damage messages go by). Hopefully, a large buffer switch is
|
||
|
only necessary when a player executes a special command that generates an
|
||
|
unusually large amount of output, such as ``who'', ``read board'', or
|
||
|
``where sword''. This critically depends on the fact that not everyone will
|
||
|
be executing such a special large-output command at the same instant.
|
||
|
|
||
|
For example, imagine you have 10 players on your MUD. They are all
|
||
|
wandering around town, and every once in a while one of them types ``who'',
|
||
|
or reads the board, meaning that they are seeing more than 1024 bytes of
|
||
|
output at a time. On such a MUD, I would hope that there would only be a
|
||
|
single 12K buffer allocated which gets passed around among all the 10
|
||
|
players as needed. Now, all players think they can queue up to 12K of
|
||
|
output per command without getting truncated even though only one 12K buffer
|
||
|
actually exists -- they are all sharing it.
|
||
|
|
||
|
But - there's a problem with this. There are certain cases when many
|
||
|
players have to see a lot of output at the same instant (i.e. on the same
|
||
|
pass through the game_loop()), all of them will need a large buffer at the
|
||
|
same time and the pool will get very big. For example, if an evil god types
|
||
|
``force all who''; or if the MUD lags for several seconds, then suddenly
|
||
|
gets unlagged causing many commands to be processed at the same moment; or
|
||
|
if 20 people are all trying to kill the same MOB and are all seeing 20
|
||
|
damage messages (more than 1024 bytes) on the same pass through the
|
||
|
game_loop().
|
||
|
|
||
|
Unfortunately, the current patchlevel of Circle has no way to destroy large
|
||
|
buffers so such cases are pathological and cause wasted memory.
|
||
|
Unfortunately since I don't run a MUD I can't actually tell how often this
|
||
|
happens on a real MUD. (If there are any IMPs out there who run large MUDs
|
||
|
(say, >= 30-50 players on regularly), and you've read this far, please send
|
||
|
me the output of ``show stats'' after your MUD has been played for at least
|
||
|
several hours.)
|
||
|
|
||
|
Hopefully this clears up the way buffers work.
|
||
|
|
||
|
|
||
|
6.7. How do I add a new class? How do I add more levels?
|
||
|
|
||
|
Adding a new class is fairly easy in 3.0, in fact, someone has taken the
|
||
|
time to put together a fairly complete document on adding a class, in this
|
||
|
case a Knight class. The class.doc is available on the FTP site:
|
||
|
|
||
|
ftp://ftp.circlemud.org/pub/CircleMUD/contrib/docs/3.x/class.txt
|
||
|
|
||
|
The same applies for levels, in the file levels.doc
|
||
|
(ftp://ftp.circlemud.org/pub/CircleMUD/contrib/docs/3.x/levels.txt)
|
||
|
which can be found in the same place.
|
||
|
|
||
|
|
||
|
6.8. Is there a complete ``coding.doc''?
|
||
|
|
||
|
No. Look at the README.NOW in the docs directory. It isn't complete, nor
|
||
|
does anyone have the entire thing. It is being worked upon.
|
||
|
|
||
|
RTFM
|