* SMAUG HOWTO by Nivek aka Kevin London (london@cs.utk.edu) * HTML by Thargof aka Paul Peltz (peltz@cs.utk.edu) * HTML Revised by Tical aka Steve Cherry (webmaster@game.org) * This version covers 1.4a * Doc date: 1/31/00 * The FAQ in section 11 is a large portion of Altrag's FAQ * The section on gdb was written by Thoric. * This document resides at: http://www.cs.utk.edu/~london/smaug/
A printable text version of this page can be viewed here.
This doc is for SMAUG release 1.4a and higher. When later releases come out if there is a change to how something is done it will be noted like this:
***Version 1.4b update***
This document is an ongoing process so if you see anything you would like added, more clarification on a subject or I messed up something email me at the above address.
So you need to get started do you? Will the first question is do you have a Windows box or a Unix box? Go to the appropriate section that applies to you.
First thing you need to do is untar the distribution, this can be done in one of two ways depending on the tar version you are using. If you have GNU's version of tar it can be done like this:
tar -zxvf smaug.tar.gz (Where smaug.tar.gz is the name of the distribution)
or if you don't have that version (Doesn't like the -z flag) you can do it in two steps like this:
gunzip smaug.tar.gz
tar -xvf smaug.tar (Notice it removes the .gz ending
So now you should have several directories under a main dist directory. Next you need to go to the source directory to get there from the directory you untarred the distributions type:
cd dist/src
Here you need to make the directory. This is done through the make command. Simply type:
make all
If you have errors it could be a couple of reasons. First you may not have crypt linked in. Edit the makefile with your favorite editor, if you don't know how to use one, read the man pages on pico, joe, vi, emacs and I am sure there are more out there. To use man type:
man <subject> --- Example: man vi
Then uncomment the line specified in the Makefile. Anyline with a # at the
beginning is a comment remove the # to uncomment a line. Another error you might get is
about sockets, if you are on a solaris box, then there are also lines you need to
uncomment in the makefile for it to work. If you still have problems porting to a new
architecture contact the smaug mailing list: smaug@game.org
or myself london@cs.utk.edu for some help.
Now all you need to do is startup the mud, startup on the ports you need to by specifing
it on the command line, or it defaults to port 4000 but it will also bind to that port +1,
+10 and +20. So with the case of 4000 it will setup on port 4000, 4001, 4010, and 4020. To
start it up in the src directory, type:
./startup 4000 &
If your mud stops when you logout try running it this way:
nohup ./startup 4000 &
The first time you login you should change waitforauth so you can log in. To do this type the following:
cd ../system (Will be in dist/system)vi sysdata.dat (Switch vi for your favorite editor)Change the 1 beside Waitforauth to 0
Then you can logon by telneting to the port you set it up on:
telnet localhost 4000
Make your char, save and quit out. Then you will need to edit your pfile. You will need to change your level to 65 by the following:
cd ../player
Then you will need to go to the directory with your name which is the lowercase first letter of your name. So for example Shaddai would be:
cd s
Then edit the pfile:
vi Shaddai
Change the 2 beside Level to 65 save it.
Now your ready to go. ENJOY.
First you must setup the new race this is done online via: setrace The syntax to use is * setrace <new race name> create So for example to create a half-coder race you would type: setrace half-coder create This simply sets up the data and name to be set, it does not save the race. To do that you must use setrace save this will also write out the list of races to load at boot time. Once this is done you can start custimizing the race there are several options that you can set. But remember after you set your options you need to save them with the following command: setrace <race name> save
First you must setup the new class. This is done online via: setclass The syntax to use is * setclass <new class name> create * So for example to create a coder class you would type:
setclass coder create
This simply sets up the data and name to be set, it does not save the class. To do that you muse use * setclass save * this will also write out the list of classes to be loaded at boot time. *NOTE* If you don't want anyone to use this class yet, which you probably don't..... Use ban, to ban the class and this will prevent it from being choosen. Once this has been done you can start custimizing the class. There are several options that you can set, but remember to save your changes after you make them with the following command:
setclass <class name> save
setclass mage mtitle 2 the Apprentice.
To set these, use: * setclass <class name> <prime/second/deficient> <attribute>
The valid attributes are: <none, strength, dexterity, intelligence, wisdon, constitution, luck>
For example I could setup a mage like this:
setclass mage prime intelligence
setclass mage deficient strength
Then the mage would have a max of 25 in intelligence and a max of 16 in strength
<fire, cold, electricity, energy, blunt, pierce, slash, acid, poison, drain, sleep, charm, hold, nonmagic, magic, paralysis>
So for example to set mages resistant to charm and magic, the command would be:
setclass mage resist charm magic
To turn a resist off simply reset it for example:
setclass mage resist charm magic
Would set the mage class to not be resistant to those two again.
setclass mage affected truesight scrying
Once again to turn a affect off you just reset it by setting that affect again and it will toggle it off.
setclass mage expbase 1000
setclass mage hpmin 3
setclass mage hpmax 6
setclass vampire mana N
setclass warrior thac0 18
setclass warrior thac32 6
The first thing you need to do to create a new skill/herb or ability is create a new one with the sset command.
sset create herb 'new herb'
sset create skill 'new skill'
sset create ability 'new ability'
If these give you a error message about MAX_HERB or MAX_SKILL needing to be upped you need to open up mud.h, up the appropriate variable a few places, make clean and then make. The difference between a skill and an ability is that an ability gets set to type SKILL_RACIAL. Which means only certain races can use that ability. Right now this is unsupported however. So to set up a new herb called sunflower and a new skill called coding, you would issue the following commands:
sset create herb 'sunflower'
sset create skill 'coding'
Once you do that you will be able to set various fields on each:
Example: sset 107 name sunflower
Example: sset 107 code spell_smaug
Example: sset 107 target offensive
Example: sset 107 minpos 10
For Example: sset 107 slot 1000
For Example: sset 107 mana 100
Example: sset 107 beats 12
Your fireball brushes Shaddai.
Example: sset 107 dammsg fireball
Example: sset 107 wearoff The torrents of cascading energy suddenly fade away.
For example: sset 107 guild 1
For example: sset 107 minlevel 25
Example: sset 107 type spell
Example: sset 107 damtype fire
For example: sset 107 classtype death
sset 107 powertype none
For example: sset 107 seffect absorb
For example: sset 107 flag noscribe
For example: sset 107 dice l/3 + 3
For example: sset 107 value 1000
For example: sset 107 difficulty 5
For example: sset 107 affect luck 4
For example: sset 107 rmaffect 1
You would use: sset 107 level 2 20
You would use: sset 107 adept 2 80
T### this checks for item of type ###
V##### this checks for item of vnum ####
Kword check for item with keyword 'word'
G#### check if player has ##### amount of gold
H#### check if player has #### amount of hitpointsThere are several operators that can be used....
! spells fails if player has this,
+ dont' consume this component,
@ decrease component's value[0], and extract it if it reaches 0
# decrease component's value[0], and extract it if it reaches 0
$ decrease component's value[2], and extract it if it reaches 0
% decrease component's value[3], and extract it if it reaches 0
^ decrease component's value[4], and extract it if it reaches 0
& decrease component's value[5], and extract it if it reaches 0Here are a couple examples:
sset 107 components V@43 need item with vnum 43 to cast this spell, decrease it value[0] by one and use it up if it reaches 0.
sset 107 components T+01 would look for itemtype 01 to cast the spell but don't use it up.
sset 107 racelevel human 50
sset 107 raceadept human 70
To create a new language you need to find the lang_array in act_comm.c which in smaug 1.4a is around line 2970.
Here add LANG_(Your Lang Name) before LANG_UNKNOWN.
Then go to the lang_names which is just below lang_array and right before "" (and right after "gith", in SMAUG 1.4a)
Add "(your lang name)",
Example: Last line of lang_array would look like this:
LANG_CLAN, LANG_GITH, LANG_CODER, LANG_UNKNOWN };
Last line of lang_name would look like this:
"halfling", "clan", "gith", "coder", "" };
Then you need to open up mud.h
Then search for LANG_ after the last BV language add in the in yours.
For Example: #define LANG_GITH BV19 #define LANG_CODER BV20 <--------Added this line
Then in the VALID_LANGS add your language into that:
For Example:
| LANG_HALFLING | LANG_GITH )
becomes
| LANG_HALFLING | LANG_GITH | LANG_CODER )
Then make clean and recompile.
Then online you have to make that language......
sset create skill (language)
sset (lang) type tongue
sset (lang) guild -1
sset (lang) code spell_null
sset save skill table
Then you need to edit the levels at which the classes get that language by
editing the class files or by sset level (classnum) (level)
Then sset adept (classnum (adept%)
You can also set it up as innate race ability for example:
setrace coder language (language)
Example:
sset create skill coder
sset coder type tongue
sset coder guild -1
sset coder code spell_null
Then to set it up by classes add:
sset coder level 0 1
sset coder adept 0 99
Or to make it an inate race ability:
setrace coder language order
sset save skill table
That should about do it for languages now on to channels.......
First create a file in the clan directory with the name of the clan. For example dslay.clan and setup a very basic clan file like:
#CLAN
Name Dragonslayer~
Filename dslay.clan~
End
#END
Then add that to the name in the clan.lst For example in this case we would add the following:
dslay.clan
Then reboot the mud and you will be ready to start setting up the clan online with the setclan command. You can use the following options:
setclan dragonslayer deity Shaddai
setclan dragonslayer leader Nivek
setclan dragonslayer members 200
setclan dragonslayer board 1200
setclan dragonslayer recall 1200
setclan dragonslayer storage 1200
setclan dragonslayer guard1 1200
setclan dragonslayer guard2 1201
setclan dragonslayer memlimit 50
setclan dragonslayer leadrank Loser
setclan dragonslayer obj1 40
setclan dragonslayer filename manslayer.clan
For example:
setclan brujah motto Die in your boots, not on your knees.
This would show up something like this when using clans brujah Brujah, 'Die in your boots, not on your knees.'
setclan dragonslayer type 0
setclan dragonslayer class 2
setclan dragonslayer pkill1 0
setclan dragonslayer pdeath2 0
The first thing you need to do is:
makeboard <filename>
For example makeboard myboard.brd
This will create a new board file and setup defaults. The next thing you need to do is
setup a board object, to do this create an object and setup the object just like you would
do for any object and remember its vnum. Then you need to set up the defaults on the board
using bset.
The arguments that can be used with bset are as follows:
Example: bset myboard.brd 1000
bset myboard.brd read 51
bset myboard.brd post 1
bset myboard.brd remove 58
bset myboard.brd maxpost 200
bset myboard.brd filename codecouncil.brd
bset myboard.brd type 0
For a mail board it would be:
bset myboard.brd type 1
bset myboard.brd read_group Newbie Council
bset myboard.brd post_group Newbie Council
bset myboard.brd extra_readers none
And then reset the ones you want as readers. For example to add Nivek and Shaddai as extra readers you would use:
bset myboard.brd extra_readers Nivek Shaddai
bset myboard.brd extra_removers Nivek Shaddai
bset myboard.brd oremove $n clears up some clutter.
bset myboard.brd otake $n takes a bounty note.
bset myboard.brd olist $n reads over the bounties.
bset myboard.brd ocopy $n makes a note of a bounty.
bset myboard.brd opost $n puts up a new bounty.
bset myboard.brd postmesg
You post a new bounty.
Then just make sure you add the board object into resets and you have a new board :)
The first thing you need to do is create the deity file. This is done using the makedeity command. So for example if you wanted a deity called Shaddai:
makedeity Shaddai
This creates the file and sets up some defaults and writes it to the list of deities to load during bootup. Then you use setdeity to setup the deity the way you would like it.
setdeity shaddai filename Shaddai.dty
setdeity shaddai name Nivek
setdeity shaddai description
This will drop you into an editor and then you can work on it just like you would a note or a room description.
setdeity shaddai alignment 0
setdeity shaddai npcfoe 4 OR setdeity shaddai npcfoe coder
setdeity shaddai susceptnum 500
setdeity shaddai race human
To clear this value set it to -1, like this:
setdeity shaddai race -1
setdeity shaddai race2 dwarf
Just like above to clear this flag set it to -1.
setdeity shaddai npcrace human
First you need to create the morph you do that with the morphcreate command. There are two different ways to use it, first if you just want to create a new morph, you use:
morphcreate <name>
For example: morphcreate 'Dire Wolf'
or if you want to copy a morph that already exists you would use:
morphcreate <vnum> copy
This will setup a new morph with a different vnum but with all the defaults setup for you.
Once you have a morph created, it is time to start changing it to how you would like it to be. This is done through setmorph. Remember also that when you change the morph you need to save it by:
setmorph <vnum/name> save
When you set it up there are several other commands to help you with your morphs, first there is morphstat that will take the name or vnum of the morph as an argument. And if you use:
morphstat <vnum/name> help
It will list the descriptions, shorts, etc......
Then there is immmorph and immunmorph which allows an immortal to morph/unmorph into anything themselves OR morph/unmorph any player into anything.
morphdestroy deletes a morph, this is safe to use even if a player is already morphed into that and even if they have logged off and log back in morphed as that.
The spell polymorph will allow players to morph into whatever they can according to what has been setup.
And finally mpmorph and mpunmorph for mob/room/obj progs to allow you to setup morphs that players can't morph into with a spell and/or morphs that don't have a timer so they have to find a "healer" or something to unmorph.
To use in conjuction with the mpmorph and mpunmorph there are a couple new ifchecks that progs can use:
if morph($n) == 1000
setmorph is very complicated and has several things you can set:
morphset 1000 ac -50
morphset 1000 affected sanctuary
morphset 1000 blood l/2 Also note that this adds to the persons blood level.
morphset 1000 bloodused 20
morphset 1000 cha 1
morphset 1000 class vampire
To disallow a class after you have set it, just set it again and it will untoggle the class.
morphset 1000 con -1
morphset 1000 damroll -l/2
morphset 1000 dayfrom 2
morphset 1000 deity Shaddai
morphset 1000 desc
This will drop you into a note editor and then you can edit the description just like you would with a note.
morphset 1000 defpos 6
morphset 1000 dex 2
morphset 1000 dodge 20
morphset 1000 favourused 500
morphset 1000 gloryused 100
morphset 1000 help
morphset 1000 hitroll l/2
morphset 1000 hp l/2
morphset 1000 hpused 100
morphset 1000 immune magic
morphset 1000 int -3
morphset 1000 str 3
morphset 1000 keyword bat
morphset 1000 lck -3
morphset 1000 level 25
- morphset 1000 long A large dire wolf is resting here.
morphset 1000 mana l/2
morphset 1000 manaused 50
morphset 1000 $n shrinks down into the form of a cute puppy.
morphset 1000 You shrink down into the form of a cute puppy.
morphset 1000 move -100
morphset 1000 moveused 100
morphset 1000 name puppy
morphset 1000 noaffected sanctuary
morphset 1000 nocast 1
morphset 1000 noimmune magic
morphset 1000 noresistant magic
morphset 1000 noskills bash
morphset 1000 nosusceptible magic
morphset 1000 obj1 1200
morphset 1000 objuse1 1201
morphset 1000 parry -50
morphset 1000 pkill pkill
morphset 1000 race pixie
Also to remove that race, simply reset it to toggle it off.
morphset 1000 resistant fire
To remove the resistant just set it again to toggle it off.
morphset 1000 sav1 -10
morphset 1000 sex 1
morphset 1000 short A cute puppy
morphset 1000 skills bash
morphset 1000 susceptible cold
morphset 1000 timefrom 23
morphset 1000 timer 100
morphset 1000 timeto 4
morphset 1000 tumble 20
morphset 1000 The puppy before you explodes and $n appears where it was standing.
morphset 1000 You revert to your original form.
morphset 1000 wis 5
First create a file in the council directory with the name of the council. For example build.council and setup a very basic council file like:
#COUNCIL
Name Builers's Council~
Filename build.council~
End
#END
Then add that to the name in the council.lst For example in this case we would add the following:
build.council
Then reboot the mud and you will be ready to start setting up the council online with the setcouncil command. You can use the following options:
This how to was written by Thoric with a few edits to make it more general.
Using GDB.
Gdb is a very powerful debugging tool. It is what you use to examine the dreaded core files that the mud makes when it crashes... and it can even be used to attach to a running mud process if it gets locked up (looping).
Syntax:
gdb
<executable> <core file>
gdb <executable>
<process id>
gdb <executable>
The current mud executable should be: dist/src/smaug
The latest core dump file should be: dist/area/core
If the mud is locked up, you can debug the running copy by using the second syntax mentioned above. The process id can be found via the "ps" command. Type "ps ax | grep mud". The number on the far left is the process id, and make sure to grab the one for "../src/smaug".
When debugging the running mud, you'll need to press control-C to stop the process so that you can see at what point it is currently executing. To make it continue from where it left off... type "cont". You can then press control-C in a second or two, see where it stopped, and repeat this a few times to get a good idea of what is causing the looping. (Almost always a mobprogram).
When you have gdb going on a core file, or have stopped the running mud process, you have many choices before you. (Note: you need to be logged in as "mud" to attach to the running mud process).
GDB Commands.
o bt: This command will trace back through all the functions called to show the path of execution to the current function. This can help you determine what lead up to the crash.
o up: This command will move you up to the function that called the function you currently in.
o down: This command will move you down to the next function that gets called from the function you currently in.
o list: This will list the lines of source code surrounding the line that you are currently on. You can also specify the line to start from, as well as the file to look at. o cont: This command will continue execution of the program from where it last stopped.
o break: This command will set a breakpoint on the specified line, and optionally the specified file. (ie: break comm.c:150) A breakpoint is a spot where the program will stop executing so that you can examine the variables at that point.
o print: This command will allow you to examine variables. It accepts typecasts just like in your C code, as well as pointer defererencing. You can type "print ch->name" to see the name of a character in a function, "print *ch" to dump the entire char_data structure pointed to by "ch", etc. This is one the most important and most powerful commands.
Some of these FAQs were taken from Altrag's FAQ and updated to 1.4a if necessary
Q: What is Smaug?
A: SMAUG (Simulated Medieval Adventure multiUser Game) is a multi-user internet gaming
system. It is an extension of the MERC 2.1 gaming system over the last approximately five
years on Realms of Despair, by Thoric and various other people he recruited as the game
got larger. In December of 1996, Thoric released SMAUG 1.01 for other games to use as a
"code base", or starter set of code to expand on as MERC 2.1 is the base for
SMAUG.
Q: Where can I get SMAUG?
A: SMAUG may be obtained by ftping to ftp.game.org, in the /pub/smaug directory, or can be
downloaded from the world wide web at http://www.game.org
Q: SMAUG defaults to port 4000, how do I change which
port to run on?
A: Run it with a different argument. In unix, run ./startup . In Windows, run
..\src\smaug.exe . On the unix version you can edit the startup script and change 4000 to
whatever you want it to bind to.
Q: SMAUG says it can't bind to the port but I know
4000 is free.
A: SMAUG also uses several other ports, it uses port+1, port+10 and port+20 for several
other interfaces. So this means the default is for it to bind to port 4000, 4001, 4010 and
4020
Q: Do I really need all those ports?
A: No not really, realms of despair uses them for different interfaces so people can log
on quicker.
Q: How do I remove them then?
A: Load up comm.c in your favorite editor and find the folloring:
int control; /* Controlling descriptor */
int control2; /* Controlling descriptor #2 */
int conclient; /* MUDClient controlling desc */
int conjava; /* JavaMUD controlling desc */
Delete the lines containing with control2, conclient and conjava.
Then find the following:
log_string("Initializing socket");
control = init_socket( port );
control2 = init_socket( port+1 );
conclient= init_socket( port+10);
conjava = init_socket( port+20);
Delete the lines beginning with control2, conclient and conjava.
Then find the following:
closesocket( control );
closesocket( control2 );
closesocket( conclient);
closesocket( conjava );
Once again delete the lines containing control2, conclient, conjava.
Then find:
accept_new( control );
accept_new( control2 );
accept_new( conclient);
accept_new( conjava );
Once again delete the lines containing control2, conclient, conjava. Recompile and you are ready to go.
Q: I am getting a ton of logfiles, how do I stop
this?
A: Usually this means that you have more than one startup script running. Why does this
create many logs? Because one of the startup scripts, starts writing a log, gets to bind
to a socket, can't kills itself off, and startup waits a minute and then tries again. The
solution is to make sure you just have one startup script running.
Q: Thats all good but how do I find that out?
A: Use ps -aux, ps aux, or ps -elf depending on your system
and pipe it to grep username (You will know which one, if it works then that is the one to
use):
So for example say the username is mud you would use:
That will produce output like:
mud 19926 0.0 0.4 2020 1092 ? S N Jan 18 0:00 csh -f ./startup
mud 20125 0.0 0.4 2020 1092 ? S N Jan 18 0:00 csh -f ./startup
mud 27523 11.4 17.3 45720 44840 ? R N 06:00 85:38 ../src/mud 4000
Ok so here there are two startup files running, and that is a bad thing. So just kill one of them off and you should be ok.
Q: How do I kill off one of the processes?
A: To kill one off grab the PID (Process ID #) which is in the second column. So say we
want to kill off the second startup. I would use:
kill -9 20125
-9 (SIGKILL) is the signal that I am sending it, and programs can't ignore it, it is usually better to send -1 (SIGHUP) and see if it shuts down first.
Q: That didn't kill off the process now what?
A: This means one of two things, you have to be the user or root to kill off a processor,
the first column is the user name. So if you are user nivek and try to kill off the above,
it won't work. The other possibility is that your system is REALLY hosed. Only way to fix
this is to reboot the machine. There are other possibilities too but those are the most
common.
Q: I'm running something other than unix or Windows,
can I use SMAUG?
A: There is a Macintosh port of SMAUG which can be found on the MacOS web pages at these
two locations:
http://www.eden.com/~hsoi/mud/
http://rarloa-4.pr.mcs.net/~fear/
As far as I know, there are currently no ports of SMAUG to any other operating systems up for ftp from ftp.game.org. You will either have to write your own port, or find someone who already has written a port to your operating system.
Q: I'm running Windows 3.1, can I use SMAUG?
A: The currently available Windows ports of SMAUG are for 32-bit Windows. They will not
run in 3.1's 16-bit environment. I don't know if they can be used with Win32s.
Q: SMAUG is up and running, how do I connected?
A: Load up your telnet program, and connect to port 4000 on localhost. If you do not know
what a telnet program is, try the command
'telnet localhost 4000' (without the quotes).
Q: How can other people connect?
A: You will need to know your ip address, or (if you have one) your host name. People can
then telnet to port 4000 at that address.
Q: SMAUG is up and running, why can't I be like God?
A: Version 1.02 and 1.02a (and possibly others) have authorization turned on by default.
You will need to load up your favorite text editor and edit /dist/system/sysdata.dat, and
change WaitForAuth to 0. This will turn off authorization. Now log on as a new player and
save. Log off and edit your player file and change Level to 65. Player files are found in
/dist/player. The subdirectories are the initials of the player names. Select the
appropriate directory for your name.
Q: How do I change the message you see when logging
on?
A: As a god online type 'hedit greeting' (without the quotes) Edit it and when you are
finished use 'hset save' (without the quotes) to save the file.
Q: What other known bugs are there in SMAUG?
A: In Release 1.4a the only known bug is that is you oset/mset on something and it gets
purged, then when you try to set something the mud will crash. There will be a workaround
for this in 1.4b.
Q: What can I do with SMAUG?
A: Anything you'd like. As long as you follow all three license agreements (DIKU, MERC,
and SMAUG), you are free to modify or distribute SMAUG as you'd like. Please read the
license agreements completely. If you do not agree with any part of any of the three
agreements, remove SMAUG and either find a code base with whose license you can agree, or
write your own code base.
Q: I don't run SMAUG, but I'd like to implement some
of SMAUG's features into my game, am I allowed to do this?
A: Yes. You may use any part of SMAUG, as long as you follow all of the license agreements
as listed in question 10a. The same license applies for part of SMAUG as it does if you
use SMAUG in its entirety.
Q: I run SMAUG, but I'd like to implement features
from another code base, am I allowed to do this?
A: Again, yes. You must, however comply with the other code base's license as well as
those listed in question 10a. This applies to any code that has been written and released
by an author other than yourself.
Q: I want to build areas for SMAUG, but I don't know
where to start
A: There is extensive (if somewhat confusing) online help for building in SMAUG, as well
as a (out of date) text file in /dist/doc. There are also two web pages dedicated to
building on SMAUG. They are located at:
Q: Adding the power of Crayola -- inline color
parsing
A: SMAUG 1.02a+ have added the option of inline color parsing - the ability to change
colors from within a string, whether it be a channel or a room description. However, in
the distribution this ability has been limited to certain commands (such as help files).
Q: Adding color parsing to say and other one-liners
-- act()
A: Open comm.c and find the call to write_to_buffer on line 2740 in 1.02a and on line 2933
in 1.4a. This line should be in the function act(), and look like:
write_to_buffer( to->desc, txt, strlen(txt) );
Change that line to read:
send_to_char_color( txt, to );
Q: Adding color to the entire game!
A: Open mud.h, and goto the very end of the file. Add the two lines:
#define send_to_char send_to_char_color
#define send_to_pager send_to_pager_color
This well tell the compiler to use the color counterparts whenever either of those two functions are called. Then in comm.c, comment out the two functions send_to_char() and send_to_pager() so that the compiler won't be trying to compile two compies of the same function (the real one and the one that's created when the #defines are convertted by the preprocessor).
Q: I only want to add color part of the game, not all
of it!
A: This one you'll have to do by hand. Start with copying ch_printf and pager_printf to
ch_printf_color and pager_printf_color respectively. Change the send_to_char and
send_to_pager calls to send_to_char_color and send_to_pager_color, which will activate the
color routines for those two functions. If you only want some calls to act() parsed for
color, but not others, you will need to add a boolean to the parameter list and either
call the write_to_buffer or send_to_char_color as mentioned above depending on that
boolean.
Q: I want to add color to the initial login screen,
before players enter their names.
A: This one is tough, because they won't have a character yet. You will also need to add
another CON_ state to ask whether or not they would like ANSI color before the screen is
displayed, and a bool to DESCRIPTOR_DATA to record their answer. Probably the easiest
would be to create a dummy character in nanny(), such as the following:
CHAR_DATA dummy;
if (!d->character)
{
memset(&dummy, 0, sizeof(dummy));
d->character = &dummy;
dummy.desc = d;
if (d->ansi) /* The bool mentioned above */
SET_BIT(dummy.act, PLR_ANSI);
}
You can then replace all the write_to_buffer()s with send_to_char_color()s in nanny(), the same as was done in act() above. ** Make sure you NULL-terminate all your strings before you send_to_char_color() them. The one in act() was NULL-terminated previously, but there may be some in nanny() which aren't.
Q: How do I add color to the new player login
sequence?
A: The new player login is run through nanny() just as the initial login screen would be
once you added the 'Would you like color' prompt as mentioned above. Therefore, the same
procedure applies.
Q: Send_to_char_color is outputting two copies of
everything -- the real copy and an uncolorized copy.
A: In comm.c, around line 2302 in smaug 1.02a and, there should be a line that looks like:
write_to_buffer(d, prevstr, (colstr-prevstr));
This problem is already fixed in smaug 1.4a The problem comes when the first character in a string is a color code. It makes colstr equal to prevstr, so subtracting them returns 0, which write_to_buffer() uses to mean find the length of the string itself, so the result is write_to_buffer() writing out the full string and then the function continuing the write the colorized string. Before that line, add the following, such as:
if (colstr > prevstr)
write_to_buffer(d, prevstr, (colstr-prevstr));
This will make it so that write_to_buffer() is only called when subtracting the two values returns a result greater than 0.
Q: What are all these string macros/functions?
A: In SMAUG, strings have the ability to be hashed, but aren't necessarily. You must not
mix up hashed and unhashed strings or bad things will happen. The rule is:
STRALLOC()'d or fread_string()'d -> STRFREE() /* hashed */
str_dup()'d or fread_string_nohash()'d -> DISPOSE() /* not hashed */
Any strings that you want to keep past the end of a function MUST be allocated. As a general rule, its also not a good idea to mix in the system allocation functions -- it just adds more confusion, and the SMAUG functions do the same job.
QUICKLINK must only be used with hashed strings (STRALLOC/fread_string). If QUICKLINK is used on an unhashed string, bad things can result. QUICKMATCH should also only be used with hashed strings. Although it won't create a fatal error, it will always return FALSE on unhashed strings.
Q: Where do I use hashed strings and where do I use
unhashed?
A: Hashing is normally used for strings which are repeated in the MUD often (mob names,
object, names, etc), where as unhashed strings are more for things that are a one-shot and
are not likely to be duplicated (player names, etc). Having an unhashed string with the
same literal characters as a hashed string is not a problem, as long as they aren't the
same physical string (a player whose name is the same as a mob's name or something, for
example).
Q: What are all these other memory macros?
A: CREATE() should always be used to allocate non-string memory, and DISPOSE() should
always be used to free it. RECREATE() can be used to resize an old block of memory, but be
careful if you have other pointers into the same memory block, as it may not return the
same block as it was when you called RECREATE(). These functions are basically overheads
for the system allocation routines, which again shouldn't be used in SMAUG for the sake of
simplicity.
Q: Whats this LINK/UNLINK/etc stuff?
A: In a singly-linked list (like MERC/ROM/Envy uses), 'a' points to 'b', which in
turn points to 'c', looking somewhat like a->b->c->NULL. SMAUG uses doubly-linked
lists. This means that 'a' points to 'b', which points both back to 'a' (prev), and
forward to 'c' (next). This structure looks something like
NULL<-a<->b<->c->NULL. Doubly-linked lists, although using a little bit
more memory (4 bytes with 32bit pointers), is both much easier to use and much faster to
unlink (you already have a pointer to the previous item in the list). This also brings
rise to the macros.
LINK(): add a pointer to the END of a list.
INSERT(): insert a pointer BEFORE the item 'insert'. If you want to insert an item after,
reverse first, next, and prev in the call (so it would be called INSERT(link, insert,
last, prev, next), which will insert it before insert, but backwards, so when the list is
read forward, link will be after insert.
UNLINK(): remove a pointer from anywhere in a list.
CHECK_LINKS(): Will run through a doubly-linked list and report any errors in the list. It
will also attempt to fix the errors, but if you DO see an error from CHECK_LINKS, you
should probably reboot the mud as soon as possible, as the error correction routine is not
overly intelligent. It does what it can, but you could easily lose part or all of the
list.
Q: How do I change the default prompt?
A: This is very easy but you have to recompile, find default_prompt in comm.c and change
it the way you would like.
Q: What are these extended bitvectors?
A: Extended bitvectors allow more than 32 bits to be used, in the default smaug
configuration there are space for 4 ints or 128 usable bits. This can be changed in mud.h
by changing XBI from 4 to how many ints you want (Each int holds 32 bits). However
remember when you change this you change this for ALL extended bitvectors so use it only
if you need more than 128 bits and it might be better to just make another variable to
hold the bits.
Also for extended bitvectors instead of things like:
#define variable1 BV00
#define variable2 BV01
You would use:
#define variable1 0
#define variable2 1
All the way up to 128 (If you use the default XBI=4.
You can use the following macros to manipulate the new vectors:
xIS_SET(var,bit) checks to see if bit is set in var.
xHAS_BITS(var,bit) works like xIS_SET except bit is an extended bit field.
xSET_BIT(var, bit) sets the bit on the variable var.
xSET_BITS(var,bit) works like xSET_BIT except that bit is an extended bit field.
xREMOVE_BIT(var,bit) removes the bit from the variable var.
xREMOVE_BITS(var, bit) removes all the bits, except that bit is an extended bit field and not an int.
xTOGGLE_BIT(var,bit) if the bit is set it removes it, and sets it if it isn't there.
xTOGGLE_BITS( var, bit) is the same as above, except that bit is an extended bit field and not an int.
xCLEAR_BITS(var) clears all the bits on the variable var.
xIS_EMPTY(var) checks to see if any bits are set on variable var.
xSAME_BITS(var, bit) checks to see if the two are the same where var and bit are extended bit field.
Q: Hey these extended bitvectors are just what I need
but how do I change variables that currently use just normal bits to use extended
bitvectors?
A: This takes alot of time but is fairly straight forward. The first thing to do is to
find where the #defines are for the variable for example RIS_FIRE or whatever. Now this
could look one of two ways depending on how the coder did them (Base smaug code all use
BV?? defines):
#define RIS_FIRE BV00
#define RIS_COLD BV01
#define RIS_BLUNT BV02
#define RIS_ACID BV03
or it might look like:
#define RIS_FIRE 0
#define RIS_COLD 1
#define RIS_BLUNT 2
#define RIS_ACID 4
(Then 8, 16, 32, IE multiple of 2)
And change it to:
#define RIS_FIRE 0
#define RIS_COLD 1
#define RIS_BLUNT 2
#define RIS_ACID 3
(ie 1,2,3,4,5,6,7,8,etc...)
Then you have to find all the macros, SET_BIT, REMOVE_BIT, IS_SET, etc... And change them
to the appropriate xSET_BIT, xREMOVE_BIT, xIS_SET,etc... Just remember that the SET_BIT,
REMOVE_BIT, and IS_SET can work with multiple bits at the same time while the extended
bitvectors can't unless you are using an extended bit vector to check with. The way to fix
this is just to change it to work with one bit at a time.
Q: Q: How do I change the games name?
A: Its easy use: cset mudname
cset mudname Realms of Despair
cset save
Q: I subscribed to the mailing list but I can't
unsubscribe.
A: These could be several reasons for thist. You need to send a emaiL to smaug-request@realms.game.org with the
line 'unsubscribe smaug' (without quotes). If that doesn't work check to make sure you
have html turned off if sending mail from a browser. If that doesn't work send a email to smaug-request@realms.game.org with the
line 'who smaug' (without quotes). Then find the email address that is yours and send a
email to smaug-request@realms.game.org
with the line 'unsubscribe smaug username@your.host.com' (without quotes).
Q: Can I get all the areas Realms of Despair uses?
A: No
Q: Can I go to realms and ask smaug questions?
A: Most immortals on realms have nothing to do with the smaug releases, so they can't
answer your questions. Also those that do don't whant to answer smaug related questions
when they are online. So if you see Nivek .....[Head of Code Council] online don't ask I
won't answer. This is rude and should not be done. If you have a question send it to the
smaug mailing list. If you don't know how to sign up go to the bottom of this FAQ.
Q: Will realms upgrade to version 1.4a?
A: Realms of Despair runs the most current version of smaug all the time. That means
realms was running version 1.4a months before it was released.
Q: I've read the FAQ, but still have questions. Where
do I turn?
A: There is a mailing list set up for questions about SMAUG. To subscribe send an email to
smaug-request@realms.game.org with the
line 'subscribe smaug' (without the quotes).