Writing this has been a very good learning experience for me. Learning the code myself, finding the answers to these questions, has helped me, in running my own MUD. I would like to take this time to thank all those who have helped me to compile this list. Specifically, I would like to thank Altrag, for letting me use his original FAQ as a resource. I also owe a great debt of gratitude to Rjael, of Salt Wind MUD, and to Gabe Yoder, probably more than they realize. Not only did they add personal input, but many of the code fixes, etc, were taken from posts, that they made to the SMAUG mailing list. Which brings me to the mailing list. Many thanks go to all those who were willing to post help to the SMAUG mailing list, which I used as one of my main resources. I have tried to give credit to those who gave code fixes, etc. If I have neglected to credit you for something you wrote, that is included here, please contact me, and I will rectify the error ASAP. Also, if you have an idea, for a question, that should be included in the FAQ sheet, please send it along (with the answer, too, hopefully!) and I will add it. I can be contacted at: BSName@aol.com And now, without further ado, here is Sadiq's SMAUG FAQ sheet: ---------------------------------------------------------------------------- /* SMAUG FAQ SHEET by SADIQ March 1998 */ Table of Contents: 1. Getting SMAUG - Setting it up. 1.1 Where can I get SMAUG? 1.2 Which platforms (O/S) can I run SMAUG on? 1.3 Which platform is best, to run SMAUG on? 1.4 Will SMAUG run, on Win3.1x ? 1.5 How do I set up SMAUG, on a *NIX system? 1.6 How do I set up SMAUG, on a Win95 system? 1.7 How do I set up SMAUG, on a macOS system? 1.8 How do I set up *NIX, on my PC? 1.9 I got *NIX set up, on my PC. What commands should I know? 1.10 Where can I get a good compiler? I don't have much money... 1.11 Where can I get cygwin.dll? 1.12 Okay, I got it compiled, but got warnings, in interp.c 1.13 I'm getting a crypt() error 1.14 How do I define NOCRYPT, in my Makefile? 1.15 I'm getting other compiling errors 1.16 Okay, it's up and running. How do I connect, to play? 1.17 What's the IP address of 'localhost'? 1.18 How can my friends connect to my MUD? 1.19 SMAUG defaults to port 4000. Can I change that? 1.20 Wait a minute! SMAUG is binding 4 ports! 1.21 How do I create my first immortal character? 2. Things you need to fix... Known bugs. 2.1 My log shows an error, regarding 'shieldwork' 2.2 My log shows an error, regarding clan vaults 2.3 What the hell?? Hell doesn't work! 2.4 If I try to use REDIT ON (or OSET ON, or MSET ON), my MUD crashes 2.5 Omenu won't change object names properly 2.6 How do I get ban to work? 2.7 MOBprogs don't know when a player is polymorphed 2.8 Is it true, that a low level imm can FORCE a mob to FORCE me? 2.9 The reset flag that randomizes exits isn't working 2.10 The spell, 'extradimensional portal' won't create a portal 2.11 How do I make GRUB work? 2.12 Okay...so how do I make the GRUX utility, and run it? 2.13 My MUD isn't automatically rebooting, every day 3. Building.....OLC......General operations questions 3.1 I want to build areas, but don't know where to start. 3.2 The area.txt file mentions a proto.are file, but I didn't get it. 3.3 Can I use areas, written for other code bases, in SMAUG? 3.4 How do I give a builder a new area, to work with? 3.5 The polymorph spell won't let me change into what I want 3.6 What is this hitroll, and damroll stuff all about? 3.7 What is EXP base used for? 3.8 What's the difference between Clans, Orders, Guilds, and Councils? 3.9 I mset a mob's HP, but when it resets, it's much lower. 3.10 How do I make a note board into a mail board? 3.11 My shopkeepers will only sell 5 items. Can I raise that? 4. Making it special... 4.1 What am I allowed to do, legally, with SMAUG? 4.2 I run another code base. Can I use SMAUG features? 4.3 I run SMAUG. Can I use features, from other code bases? 4.4 Does SMAUG have color capability? 4.5 Adding color parsing to act() 4.6 Adding color to the entire game. 4.7 Adding color to parts of the game - but not all of it. 4.8 Adding color to the initial log-in screen. 4.9 Adding color to the new player log-in sequence. 4.10 send_to_char_color is outputting two copies of everything. Colored, and uncolored 4.11 What are all these string macros/functions? 4.12 Where do I use hashed strings? Unhashed strings? 4.13 What are all these other memory macros? 4.14 What's this LINK / UNLINK / etc. stuff? 4.15 How do I add a command? 4.16 How do I add a skill? 4.17 How do I add a spell? 4.18 How do I add a social? 4.19 How do I add a class? 4.20 How do I add a race? 4.21 How do I increase the maximum number of levels? 5. Misc. stuff.... 5.1 Can you recommend any good books, on C ? 5.2 I've read the FAQ, but still have questions. 5.3 UNSUBSCRIBE from the mailing list. ==================================================================== 1.Getting SMAUG - Setting it up. 1.1 Where can I get SMAUG? You can get it, via FTP, from: ftp.game.org You can also get it from: http://www.game.org/ftpsite 1.2 Which platforms (O/S) can I run SMAUG on? There are three, that I know of. It can be run on a *nix system, Win95, and macO/S. 1.3 Which platform is best, to run SMAUG on? SMAUG was written to take advantage of unix features, so it is best run on some flavor of unix. 1.4 Will SMAUG run, on Win3.1x ? No, sorry, it won't. SMAUG is a 32 bit program, and Win3.1x is a 16 bit operating system. 1.5 How do I set up SMAUG on a *nix system? Obtain the version of SMAUG that you want to run. At the time of this writing, the latest version is SMAUG1.02a. To install it, move the SMAUGx.xxx.tgz file into your home directory. Enter the command: gunzip -cd | tar -xvf . Where is actually the name of the SMAUG file. This will create a directory named DIST in your home directory, and place SMAUG, and it's data files in subdirectories beneath that. Now change directories, to ~/dist/src, by entering the command: cd ~/dist/src. Now you need to compile the code into an executable program. You do this by entering the command: make. Now you are ready to start your MUD! To start it up, make sure you are still in the ~/dist/src directory, and enter the command: ./startup &. Startup is a script which will run SMAUG repetitively until a shutdown command is executed by an immortal in the game. 1.6 How do I set up SMAUG on a Win95 system? You need to obtain two files. The first file you will need is the .tgz file, that corresponds to the version of smaug that you wish to run. (SMAUG1.02a.tgz is the most recent, at the time of this writing) The second file you need, is SMAUGW32_native.zip file. Both of these files can be found at the ftp.game.org site. You will need a file compression utility that can handle .tgz files. Personally, I like Winzip. (Winzip may be obtained, on the WWW, from: www.tucows.com.) Run your utility, and uncompress (unzip) the SMAUG*.tgz file. This will create subdirectories, so I recommend uncompressing the SMAUG*.tgz file into the root directory. This will be C:\ on the main drive (usually). Next, uncompress the SMAUGW32_native.zip file into C:\dist\src. After doing that, you need to find a file, in ../dist/src, named cygwin.dll. Move that file into C:\windows\system (or wherever your windows system directory is). Next, you need to make a few directories manually. Winzip will not create empty directories, so some directories, which will be empty now, but vital later, will need to be created. The following is a list of the directories you need to make: C:\dist\backup C:\dist\building C:\dist\corpses C:\dist\deleted C:\dist\gods C:\dist\log C:\dist\new C:\dist\player C:\dist\player\a C:\dist\player\b .... C:\dist\player\z (You need to go through the whole alphabet. Make a \dist\player\.. directory for each letter) Once you have done all that, you are ready to start up your MUD! Move into the C:\dist\area directory. (Note that, unlike a *nix version of SMAUG, Windows version cannot be run from the /dist/src directory. It expects to be run, from the ../dist/area directory. The reason for this is that the startup script that the *nix version uses, automatically switches to the /area directory.) Once you are into the ../dist/area directory, run ../src/smaug.exe 4000. The windows version does not have a batch file to keep rebooting the game, at this time. You will have to manually reboot the game, every time it crashes. 1.7 How do I set up SMAUG on a macOS system? You can obtain a version of SMAUG, ported for macs, at: http://www.valkyrie.com/~chrisj/ I have no information, at this time, as to how to set it up, on a mac system. 1.8 How do I set up *nix, on my PC? The only flavor I have information on, right now, is LINUX. You can obtain the most current information on LINUX from www.linux.org. If you don't mind spending a few bucks for some excellent developer's tools, then you can also check out www.redhat.com and www.infomagic.com. 1.9 I got *nix set up, on my PC. What commands should I know? All of them! But here are a few *NIX commands: man -- gives you online manual pages. grep -- stands for 'global regular expression print'. This let's you find a pattern within a file, or group of files. vi emacs pico jove -- use whatever editor floats your boat, but learn the hell out of it. You should know EVERY command in your editor. ctags -- makes 'tags' for your editor. allows you to find areas in code that you have previously worked on. > >> < | -- input and output redirection. get someone to show you, or dig it out of 'man csh'. These are the basic day-in, day-out development tools. Developing without knowing how to use all of these well, is like driving a car without knowing how to change gears. 1.10 Where can I get a good compiler? I don't have much money. How does free sound? One of the most popular compilers for ANSI Standard C is the Gnu 'gcc' compiler, produced by the Free Software Foundation. It's available by anonymous ftp from: prep.ai.mit.edu. 1.11 Where do I get the cygwin.dll file? You can get it, via ftp, from: ftp.cygnus.com/pub/gnu-win32/latest/cygwin.dll 1.12 Okay, I got it compiled, but got warnings, in interp.c that look like this: interp.c: In function 'interpret': interp.c: 551: warning: long int format, int arg (arg 7) interp.c: 551: warning: long int format, int arg (arg 7) Older versions of LINUX used a long int in the time structure. If you have one of these older versions, you will have to change the two %ld's to %d's, on line 551 of interp.c. Other flavors of UNIX may also see these warnings, and the same fix applies. 1.13 I compiled, and got a crypt( ) error. You need to either define NOCRYPT in your Makefile, or try to find the crypt library. Note that some flavors of UNIX do have crypt, but needs the crypt library linked in, when the MUD compiles. 1.14 So how do I define NOCRYPT, in Makefile? In Makefile, change: $(CC) $(L_FLAGS) -o smaug $(O_FILES) to this: $(CC) $(L_FLAGS) -lcrypt -o smaug $(O_FILES) 1.15 I'm getting other compiling errors. Some flavors of UNIX may require extra libraries, or may have slightly different header files. Consult with your system administrator, if you do not understand the errors. 1.16 Okay, I got it up, and running....how do I connect, to play? If you are running SMAUG on a host (not on your PC): Fire up your telnet program, and connect to the address you were given, by the system administrators at whichever port you started up SMAUG on. (If you didn't change the port then it will be 4000) If you are running SMAUG on your PC: Fire up your telnet program, and connect to local host, on whichever port you started SMAUG on (if you didn't change it, it is 4000). If you don't know what a telnet program is then try the command telnet localhost 4000. 1.17 What's the IP address of 'local host'? Usually, localhost defaults to: 127.0.0.1 1.18 How can my friends connect to my MUD? You will need to know the IP address of your MUD, or (if you have one) your host name. People can then telnet to that address, at whichever port you are running on. 1.19 SMAUG defaults to port 4000. Can I change that? Yes. Run SMAUG with a different argument. In UNIX, run ./startup . In Windows, run ../src/smaug.exe . Alternatively, you can edit the startup file and change the default port setting, to whatever you wish. 1.20 Wait a minute! SMAUG is binding up 4 ports! What's up? If you take a look through comm.c, you will find that SMAUG binds 4 ports for the MUD. Assuming you are using port 4000 as your main port, it looks like this: control (4000) -- the main port control2 (4001) -- a secondary port conclient (4010) -- a reserved port for clients conjava (4020) -- a reserved port for Java clients Control is the main port that you will use. The secondary port, client port, and Java port have been reserved in the rare event that the primary port becomes blocked, or unusable. Also, Realms of Despair (which is the MUD run by the creators of SMAUG) offers a custom Windows client, and a Java client for it's users. You may change the port assignments by changing these lines, in comm.c: control = init_socket( port ); control = init_socket( port+1 ); control = init_socket( port+10 ); control = init_socket( port+20 ); To remove the extra ports, simply comment out the corresponding lines dealing with the ports you wish to remove. 1.21 How do I make my first immortal character? Go into ../dist/system and open the sysdata.dat file. Change the Waitforauth value to 0. This will "turn off" the system of requiring an immortal to authorize your name, before allowing you into the game. Go into the game, and create your character. The game will automatically start you at the academy. Save your character, and quit. Go back into ../dist/system/sysdata.dat and change the Waitforauth value back to 1. Next, go into ../dist/player/?/ (the final directory will be a letter corresponding to the first letter of your character's name, not '?'). There you will find a file with the same name as your character. Open it, and change the level value to 65. Your character will now be the Supreme Entity the next time you log onto your MUD. 2. Things you need to fix.....known bugs 2.1 My log file shows an error, regarding 'shieldwork'. Shieldwork was a spell that was going to be included, in SMAUG, but which was never completed. The error will, in no way affect your mud, and can be safely ignored. However, if you just can't live, with seeing the error messages, go into db.c, and either remove, or comment out the two lines that deal with 'shieldwork' (lines 99, and 474, in the stock release). I suggest not removing, and simply commenting out the lines. This way references to lines of code, for future changes, patches, etc, won't be off. Also, you just may see shieldwork appear, in future releases. 2.2 My log file shows an error, regarding clan vaults. This simply means that the files, which store information on which objects are saved in which clan storeroom don't exist, yet. Again, this is nothing to be worried about. When players in your mud start joining guilds, and storing stuff, in the storerooms, the files will be automatically created. However, if you can't live with the error messages, until then, simply create the files manually. Go into your "clans" directory (usually ../dist/clans) and make one file, for each guild, clan, or order you have. The files must be named .gui.vault, where is the same name as the guild's filename. For example, if you have a mages guild, and it uses the file: mage.gui, then you would need to create a file named mage.gui.vault. All the .vault files that you create must contain the line: #END, in the file. 2.3. What the hell??? Hell doesn't work! SMAUG harded coded the HELL/UNHELL commands to send the victim to room (vnum) # 8. However, in the limbo.are file (which stores the room), Hell was made as vnum # 6. To fix this, go into limbo.are, and change the vnum of hell to 8, then go down to the resets section, and change the 6 to an 8. (Lines 556, and 1023, respectively, in the 1.02a release) 2.4 Using REDIT ON (or oset on, or mset on), crashes my MUD. To fix this, you will need to go into build.c, and search for the ocurrences of 'subprompt'. There, you will find three instances (in do_redit, do_oset, and do_mset) of an if statement, that looks like this: if ( ch->pcdata && ch->pcdata->subprompt ) STRFREE( ch->pcdata->subprompt ); Change those to look like this: if ( ch->pcdata && ch->pcdata->subprompt ) { STRFREE( ch->pcdata->subprompt ) ch->pcdata->subprompt = NULL; } Make sure to change the correct ones. These fixes go into the part of each function that deals with the "off" or "done" arguments. (This fix comes from the SMAUG mailing list, thanks go to Kharas.) 2.5 OMENU won't change object names, properly.... Okay...this is a relatively easy problem, with a very time consuming way to fix it. Here is what is happening. Let's assume you have an object, "iron box". You want to use omenu to modify the short description. Normally, you would go into omenu, and type this: 1 b a small, sturdy, iron box This is what omenu SHOULD do.... oset 'iron box' short a small, sturdy, iron box This is what omenu ACTUALLY does.... oset iron box short a small, sturdy, iron box Which fails... To make this work properly, you are going to have to change a LOT of lines of code. But fear not, the changes are simple. Go into ibuild.c and go down to the MENU DATA part, that deals with omenu. (around line 441) There, you will see many lines of code, that look similar to this: "1", "d", 3, 23, "%1.1s", NULL, STRING, 1, "oset %s type armor" You need to go through, and in every place where you see the "oset %s ", you need to change that, and add single quote marks around the "%s" part, so that it looks like this: "1", "d", 3, 23, "%1.1s", NULL, STRING, 1, "oset '%s' type armor" There are a lot of lines, like this, so be sure to get them all. The code we are dealing with here, ends around line 1031..... One other thing. There are some lines that will have more than one instance of "%s"...like this: ...."oset %s affect intelligence %s" Be sure that you only change the FIRST %s in the string (the one that immeadiately follows the word "oset". Don't change the others. You want it to look like this: ...."oset '%s' affect intelligence %s" 2.6 How do I get BAN to work? The ban command checks the prefix (first part) of the site. If you have name resolving on (i.e. you see words, not numbers), that makes ban pretty much useless. You will have to either: a). ban the whole sitename, which will exclude ANY player from that site. (imagine banning AOL, for example... you'd lose every player you had, that signed on, from AOL......ugly) b). turn off name resolving, or c). go into the code, and make it a suffix check, instead of a prefix check. Here is a piece of code, that looks like it will add a suffix check, to the prefix check (i.e. check prefix...if prefix matches, ban. If prefix does not match, check suffix. If suffix matches, ban.) WARNING: I HAVE NOT TESTED THIS CODE, AND DO NOT VOUCH THAT IT WILL WORK, AS INTENDED. USE THIS, AT YOUR OWN RISK. (This snippet was sent to the SMAUG mailing list, by Matt) In comm.c, change: Old code: /*snipped of course */ for ( pban = first_ban; pban; pban = pban->next ) { /* This used to use str_suffix, but in order to do bans by the first part of the ip, ie "ban 207.136.25" str_prefix must be used. -- Narn */ /* from this: * if ( !str_prefix( pban->name, dnew->host ) && * pban->level >= LEVEL_SUPREME ) * to this: */ if ( ( !str_prefix( pban->name, dnew->host ) && pban->level >= LEVEL_SUPREME ) || ( !str_suffix( pban->name, dnew->host ) && pban->level >= LEVEL_SUPREME ) ) { write_to_descriptor( desc, "Your site has been banned from this Mud.\n\r", 0 ); free_desc( dnew ); set_alarm( 0 ); return; } } < also gotta change in nanny() > for ( pban = first_ban; pban; pban = pban->next ) { /* This used to use str_suffix, but in order to do bans by the first part of the ip, ie "ban 207.136.25" str_prefix must be used. -- Narn */ /* from this: * * if ( !str_prefix( pban->name, d->host ) && * pban->level >= ch->level ) * to this: */ if ( ( !str_prefix( pban->name, d->host ) && pban->level >= ch->level ) || ( !str_suffix( pban->name, d->host ) && pban->level >= ch->level ) ) { write_to_buffer( d, "Your site has been banned from this Mud.\n\r", 0 ); close_socket( d, FALSE ); return; } 2.7 MOBprograms doesn't know when a player is polymorphed. Many of the MPcommands only have: if ( !IS_NPC( ch ) ) As a check, against character... This can cause a problem, if the character is polymorphed. Any of these instances should be changed to: if (( !IS_NPC( ch ) ) || (!IS_SET(ch->act, ACT_POLYMORPHED)) ) (That snippet posted by Golias to the SMAUG mailing list) 2.8 Can a low level Imm FORCE a mob, to FORCE me? In earlier versions of SMAUG, there was no check, to see if a mob was forcing an immortal to do weird things. Mainly, this bug was exploited by lower level imms, by forcing a mob to force a higher level imm to advance the low level imm to higher levels of trust. This error has already been corrected, in later versions of SMAUG (It is, anyway, in 1.02a). In the latest version, the only way that a mob can force you, is if you are actually in the game, and not link-dead. That way, you will immeadiately see, if someone tries to cheat the system, and you can deal with it, on the spot. It also leaves the way open, for legitimate MOBprogs to force an imm, when needed :) 2.9 The flag that randomizes exits, every reset, is messing up. Go into db.c, in function load_resets. Under "case 'R' ", find this line: if( arg2 < 0 || arg2 > 6 ) And change it to: if( arg2 < 0 || arg2 > 9 ) That allows for all nine possible exits: N, S, E, W, NE, NW, SE, SW, and SOMEWHERE (Which is SMAUG's special exit) 2.10 The spell, 'extradimensional portal' always fails. That is because there is nothing, for the spell to create :) Aassign yourself an area (I used limbo.are - that's where a lot of the other generic object stuff is) and find an unsed object vnum. Create an extradimensional portal object, making sure to set all the values to what you want the portal to be (type: container, etc.) and save it, via the foldarea command. Then use slookup, to find the SN of 'extradimensional portal' (let's say it's 65, for the sake of example). Set the vnum of the object that the spell creates by typing: sset 65 value then: sset save spell table. The spell should then work. :) 2.11 How do I make grub work? In order to make the grub command work, you must make the grux utility and run it. 2.12 Okay...so how do I make the grux utility, and run it? Grux is an external executable (program) that creates the file that grub uses, to work properly. It also maintains your player files. You need to make a few changes, in order to get it fired up, and running properly. You will first need to change grux.c like this: 1). Change MAX_SITE_LENGTH from 16 to a slightly higher number. (I made mine 50) Remember what number you use...you'll need it later. (This is a "just in case" so that you won't run into any problems with displaying a target's IP address...) 2). Find two instances where grux.c references the mud's directories. (Use "home" as a keyword, for a search) The first (about line 14) will be a reference to the player directory. Change this to reflect the true path to your player directory. It will look something like this: /home//dist/player where is the name you use, to log onto your server. The next instance (about line 218) will referance a file, in the system directory. Change this to: /home//dist/system/grub.dat. Make sure in both cases, that you are using the exact pathway, to the specific directories, or it won't work! 3). This part is optional, and grux will work, just as it is, with out doing this, but just to keep things neat, and tidy, you may want to comment out all references to RoD specific clans, and councils. 4.) Now bounce up into the src directory, and open up grub.c. There, you want to change the MAX_SITE_LENGTH to the same number you changed it to, in grux.c. Then, using 'home' as a search word, find the line (it's around 1024) that accesses the file in the system directory. Change this to the exact same thing, that you wrote into grux.c. In other words: /home//dist/system/grub.dat (I know, the file is grub.new, in the original grub.c.....trust me..... these two references must be the same!) You also may want to take the time here, and comment out all the RoD clan/ council references.... 5). Now you are ready to rock-n-roll! Recompile your mud, so that the changes you made, in grub.c, will take, then drop back down into the utils directory, and type: gcc -c -g3 -Wall grux.c. And then: gcc -o grux grux.h. This will make an executable (runnable) called grux. Type: ./grux to run it. This will create the grub.dat file, that grub uses. Once you've run grux once, you can use the grub command, in the game! What grux does.... When you run grux, it will go through the player files, and extract the information grub needs, and copy it into grub.dat. It also checks pfiles, for inactivity, and automatically deletes character files, that have been inactive over a period of time (that period defined by the level of the character: 2nd levels are deleted, after one week of inactivity, 3rd levels are deleted, after 2 weeks of inactivity, 4th levels are deleted, after 3 weeks of inactivity, and any characters over 5th level are deleted, after 3 months of inactivity.) This is a very handy tool, and it should be run, every day. It is worth noting, that when you do an online grub, the information extracted is only as current as the last time you ran grux. So if you haven't run it, for a week, any grub info, will be a week old. Be warned! :) 2.13 My MUD isn't automatically rebooting every day. ... The problem with the auto-reboot is that on startup, the new_boot_time is set properly, but new_boot_time_t is not initialized. Thus the test as to whether it has been 18 hours since boot always indicates that it has been less than 18 hours. To fix the problem find the following section in comm.c: new_boot_struct = *new_boot_time; new_boot_time = &new_boot_struct; new_boot_time->tm_mday += 1; if(new_boot_time->tm_hour > 12) new_boot_time->tm_mday += 1; new_boot_time->tm_sec = 0; new_boot_time->tm_min = 0; new_boot_time->tm_hour = 6; /* Update new_boot_time (due to day increment) */ new_boot_time = update_time(new_boot_time); new_boot_struct = *new_boot_time; new_boot_time = &new_boot_struct; Now simply follow this section with: new_boot_time_t = mktime(new_boot_time); That should fix it. (This fix was posted to the SMAUG mailing list, by Gabe Yoder) 3. Building.....OLC......General operations questions 3.1 I want to build areas, but don't know where to start. There are a great many (if somewhat confusing) online help files, for building, in SMAUG. There are also some (out of date) text files, in /dist/doc. There are also some fairly decent docs available, at: www.game.org/ftpsite. Just go there, enter the SMAUG directory, and download a file called olchelp.zip. Also, my next project (after this FAQ sheet *grin*) will be a comprehensive OLC guide, referencing all of SMAUG1.02a's stock features. There are several other OLC guides out there, but generally, they were written specifically for the MUD's of the authors. This can, and usually does include changes that the imps have made, in the MUD, and can be a little misleading. The OLC guide that I propose to write, will only contain stock SMAUG1.02a features. Keep an eye out :) 3.2 The area.txt file mentions a proto.are file, but I didn't get it. This is a throw-back to the days of MERC. MERC didn't have online creation, and so new areas had to be written, directly into the area file. MERC provided a 'template' file, to help guide builders in creating their areas. This is totally uneccessary, as SMAUG creates the file for you, online. However, I know there are a few die hards out there, that NEED one, so here is my template of a SMAUG proto-area file: #AREA {PROTO} Someone's area in progress~ #AUTHOR Buildersname~ #RANGES 0 0 0 0 $ #FLAGS 0 #ECONOMY 0 0 #MOBILES #0 #OBJECTS #0 #ROOMS #0 #RESETS S #SHOPS 0 #REPAIRS 0 #SPECIALS S #$ 3.3 Can I use areas, written for other code bases, in SMAUG? Yes, with a small amount of modification. The most easily converted format is MERC. SMAUG can read in the rooms, mobs, and objects, of MERC area files, as is. The only thing you need to change, is the minor stuff, near the top. For example, where a MERC area file may read: #NAME {1 50} Diku Midgaard~ You would have to change that to read: #AREA Midgaard~ #AUTHOR Diku~ #RANGES 1 50 1 50 $ For SMAUG to be able to read it. Be sure that the vnums used by the file do not conflict with vnums already on your MUD. If they do, you will have to go through, and change them all, by hand. 3.4 How do I give a builder a new area, to work with? Use the command: rassign . SMAUG will automatically make an area file, for the builder, and assign him the area, to work on. (NOTE: rassign will create the area file, for the builder, but you will also need to oassign, and massign him vnums, so that he can create objects, and mobiles.) 3.5 Polymorph won't let me change into what I want to... Polymorph is a sort of modified version of the switch command. Basically, this is what it does: It loads up the mob, that you want to change into, switches you into that mob, and then sends your original body into a 'storage' room, in limbo, to wait until you revert, or the spell wears off. When you revert, it essentially does the reverse. The mobs you can polymorph into, are hard coded into the game. You can only polymorph into these particular mobs, which ones being determined by the class of the caster. To wit: Class of caster: Mob that can be polymorphed: Vampire Mist, Wolf, or Bat Mage Hawk or Cat Cleric Dove or Fish You can't polymorph into anything else, unless you code them in, yourself. 3.6 What is this hitroll, and damroll stuff all about? They are modifiers that affect how well a player, or mob, does in combat. Hitroll is your chance of actually striking a blow, against your opponent. The higher your hitroll, the better chance you have, of hitting him. Damroll is how much damage you do to your opponent, when you do hit him. The higher the damroll, the more damage you will inflict, per blow. 3.7 What is EXP base used for? EXP base is a base number acted upon, by the game to help determine much experience a particular class needs, to gain levels. The lower the EXP base number that is assigned to a class, the less experience points members of that class will need, to make levels. 3.8 What's the difference between Clans, Orders, Guilds, and Councils? Kind of tricky. In essence, they can be whatever you want them to be. However, the way stock SMAUG is set up, these are the differences: First, you have two main groups: Clans, and Councils. Generally, any Clan is a group of mortal players. A Council is a group of immortals. (These aren't hard and fast rules - just generalizations. An immortal can belong to a Clan, and a mortal can belong to a Council). Under Clans, are the sub-groups: clans, guilds, and orders. The difference between these (again, speaking generally) groups are: Clans: Are groups of pkill players banded together, for whatever reason they have in common. Usually open to all pkillers. Orders: Are groups of peaceful players banded together, for whatever reason they have in common. Usually open to all peacefuls. Guilds: Are groups of players banded together, usually for mutual aid, and protection, and the furthering of the group type's position. Usually restricted to a particular type of group (i.e. class, race, sex, age, etc.) Councils usually deal with specific issues of running the MUD (Code Council, Area Council, Newbie Council, Pkill Council, etc.) This is why councils are usually comprised of immortals. The major difference (and advantage) that a council has, over a Clan, is that councils have an extra field that can be set, called "powers". You can bestow a council with commands that are related to their purpose. For example, You can give the Quest Council the "qpset" command, and any person inducted into the Quest Council will automatically be able to use "qpset", regardless of what level the command was restricted to, and without you having to bestow the command on each person manually. 3.9 I mset a mob's HP, but when it resets, it's much lower. Unlike PC's, you cannot set a mob's permenant hit points, by using mset hp . That will only set that particular mob's hit points, and when it is killed, the next one that repops, will reroll it's hit points, based on SMAUG formula. To get a mob to consistently roll a particular range of hit points, you must set three fields: hitnumdie, hitsizedie, and hitplus. SMAUG uses the same hit point formula that is used in Dungeons and Dragons. That being: (x*y)+z Where: x=the number of 'dice' being rolled (hitnumdie) y=the size of the 'dice' being rolled (hitsizedie) z=a modifier, added to the result of the roll (hitplus) NOTE: hitsizedie should never be set to '0'. Doing so can cause other functions inside the game to not act as they should. Note that only hitsizedie is a randomly generated number (for example, if you set hitsizedie to 10, a random number, between 1 and 10 is generated). Now, let's see it, in action: Let's say I want a mob to have 100-150 hit points, every time it resets. The easiest way to make a range, is this: first I take the lowest number, in the range...in this case, 100. I know that I want this to be a constant (I want the mob to ALWAYS have at least 100 hit points). So this will be assigned as the modifier (hitplus). We know that we will get a value of at least 1, from the others, so we set hitplus at 99 (100-1=99). Now, we need a random number, from 1 to 51 (99+51=150....the max we want the mob to have). The simplest way to do that, is to roll one 51 sided die (hehehe....computers aren't worried about geometry....you can make the die with as many 'sides' as you want). So...we set the number of 'dice' (hitnumdie) to 1...and the number of 'sides' the die has (hitsizedie), to 51. The commands would look like this: mset hitnumdie 1 mset hitsizedie 51 mset hitplus 99 (1 times a random number from 1-51, plus 99) This will cause the mob to always reset, with hit points ranging anywhere from 100, to 150. Now, let's say you want a mob to always have the EXACT same amount of hit points. That's even easier. Remember, only hitsizedie is a randomly generated number. If you set hitsizedie to 1, it will always return 1 (imagine rolling one 1-sided die *grin*....remember, the computer doesn't care). after that, the rest should be easy to figure out. Let's say I want a mob to have 2000 hit points, every time. I simply set hitnumdie and hitsizedie both to 1, and set hitplus to 1999. The commands would look like this: mset hitnumdie 1 mset hitsizedie 1 mset hitplus 1999 (1 times 1 equals 1, plus 1999 equals 2000) Remember to have the mob's prototype flag on, and to save the area. Also, remember that a mob's max hit points are around 32700. If you create a formula that will generate a number higher than that, you could end up with a mob that has negative HP.... 3.10 How do I make a note board into a mail board? Simple. Make a note board, as you normally would, then use the bset command to set the type to 1. That makes it a mail board, and accessable only to mail commands. The command would look like this: BSET TYPE 1 3.11 My shopkeepers will only sell 5 items. Can I raise that? Yes. Go into mud.h, and find a line that says: MAX_TRADE 5 And change it to: MAX_TRADE Then make clean, and recompile. Something worth noting here......technically, you can make this value as high as around 32,000. Of course, you will want to remember that if you give a shopkeeper 100 items to sell, then any player who does "list" is going to get spammed to death. 4. Making it special... (Questions 4.1 - 4.14 are taken from Altrag's original FAQ sheet) 4.1 What am I allowed to do, legally, with SMAUG? 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. 4.2 I run another code base. Can I use SMAUG features? Yes. You may use any part of SMAUG, as long as you follow all of the license agreements as listed in question 4.1. The same license applies for part of SMAUG as it does if you use SMAUG in its entirety. 4.3 I run SMAUG. Can I use features, from other code bases? Again, yes. You must, however comply with the other code base's license as well as those listed in question 4.1. This applies to any code that has been written and released by an author other than yourself. 4.4 Does SMAUG have color capability? SMAUG 1.02a (and possibly 1.02) 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). 4.5 Adding color parsing to act() Open comm.c and find the call to write_to_buffer on line 2740. 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 ); 4.6 Adding color to the entire game. 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). 4.7 Adding color to parts of the game - but not all of it. 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 in 4.5 depending on that boolean. 4.8 Adding color to the initial log-in screen (before players enter their names). 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() in 4.5. ** 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. 4.9 Adding color to the new player log-in sequence. 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 in 4.8. Therefore, the same procedure applies. 4.10 send_to_char_color is outputting two copies of everything. The color version, and the regular version. In comm.c, around line 2302, there should be a line that looks like: write_to_buffer(d, prevstr, (colstr-prevstr)); 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. 4.11 What are all these string macros/functions? In SMAUG, strings have the ability to be hashed, but aren't necessarily. You must not mix up hashed 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. 4.12 Where do I use hashed strings? Unhashed strings? 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). 4.13 What are all these other memory macros? 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. 4.14 What's this LINK / UNLINK / etc. stuff? 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. 4.15 How do I add a command? (1) Add a line for the command in 'skill_name' in tables.c Make sure the command starts with "do_" to keep it easy for other coders to find. Example line: if ( skill == do_mycmd ) return "do_mycmd"; (2) Add a line for the command in 'skill_function' in tables.c Make sure to put this in the proper location in the switch statement. Example line: if ( !str_cmp( name, "do_mycmd" )) return do_mycmd; (3) Add a 'DECLARE_DO_FUN' line for the command function to 'mud.h'. (4) Write the function and put it into an appropriate '*.c' file. (5) Either use 'cedit create' to create the command online, or edit the 'commands.dat' file offline to put the command in the appropriate location. (6) Write a help section for the function. See 'help.are' for the format of help entries. We suggest you start your own file of customized help rather than adding into 'help.are'. This will make it easier for you to upgrade to future releases of SMAUG (which will have upgraded 'help.are' files). SMAUG supports as many help files as you want. 4.16 How do I add a skill? Skills are either automatic (such as 'parry') or manual (such as 'rescue'). Many automatic skills are referenced in 'fight.c'; look at 'multi_hit' for examples of the use of 'gsn_second_attack' and 'gsn_third_attack'. An explicit skill such as 'rescue' has its associated command 'do_rescue'. This command is defined and called in the normal way in interp.c. Within 'do_rescue', 'gsn_rescue' is used to find fields such as 'beats'. To add a new skill: (1) Use the sset command to create a new skill: sset create skill (2) Use the sset command to set the appropriate fields: sset (see 'help sset') (3) You'll probably need a 'gsn'. Declare it in 'mud.h' and 'db.c'. Add a ASSIGN_GSN line into db.c. (4) If the skill is automatic, just use 'ch->pcdata->learned[gsn_new_skill]' in your code. If your skill is manual, you need to write an appropriate command function for it. (5) You may need to increase 'MAX_SKILL' in 'mud.h'. 4.17 How do I add a spell? (1) Find a free slot number. Make sure it's not already used in 'skills.dat'. SMAUG reserves slot numbers below 500 for future expansion. We promise we won't use numbers 500 or above in future SMAUG releases. Thus if you number your spells 500 or above, you will have an easier time upgrading to future releases of the SMAUG base code. (2) Use the sset command to create a new skill: sset create skill (3) Use the sset command to set the appropriate fields: sset (see 'help sset') (3) If this spell is too unique to use spell_smaug, add the 'spell_*' function declaration to the 'DECLARE_SPELL_FUN' section of 'mud.h', and drop the code for the spell function into 'magic.c'. (5) If your spell needs 'AFF_*' bits, create new 'AFF_* bits' in 'mud.h'. (6) You may need to increase 'MAX_SKILL' in 'mud.h', and recompile. 4.18 How do I add a social? Use the 'sedit' command to add a social online (see 'help sedit'), or edit 'socials.dat' offline, if you wish. Variables used in socials: $n : Actor's name (person doing the social) $N : Victim's name (person the actor is doing the social on) $s : His/Hers/Its (applies to actor) $S : His/Hers/Its (applies to victim) $m : Him/Her/It (applies to actor) $M : Him/Her/It (applies to victim) $e : He/She/It (applies to actor) $E : He/She/It (applies to victim) 4.19 How do I add a class? 1). Add one to the MAX_CLASS in MUD.H 2). Add a #define CLASS_(classname) in MUD.H 3). Add a #define Class_(classname) in the npc class part of MUD.H 4). In ACT_OBJ.C add a reference for anti_(newclass) under wear_obj, as a subclass of a main class, unless you have modified the code to allow more bitvectors for obj_flags. 5). Add the new class name to the const npc_class section of CONST.C, using one of the empty pc# slots (i.e. pc9, pc 10, etc. Actually, don't add...overwrite. In other words, delete the next available slot [pc9, for instance], and replace it, with the new class name). 6). Make a new *.class file in the classes directory, and add the skills and spells as needed. (Use an existing .class file as a reference of what to put). Add new skills and spells definately! Nothing sucks more than a "new class" that doesn't have any new spells or skills and is just a new slist of an existing class or two meshed together. 7). In CLANS.C there is a percentage to shove based on Class, you can add to this if you wish to do so. 8). If you want the class to use blood, add an 'or' check for that CLASS_ in IS_VAMPIRE(ch) macro in MUD.h 9). Write a help file for the new class. 4.20 How do I add a race? 1). In MUD.H, change the MAX_RACE by adding one to it for each race you plan to add to the mud. 2). Under the #define RACE_* section in MUD.H, add #define RACE_(racename) (race number). 3). Under the #define LANG_* section in MUD.H, add #define LANG_(racename) and the next BV, and add the LANG_(racename) to the list of VALID_LANGS that directly follows. 4). In ACT_COMM.C add LANG_(racename) before LANG_UNKNOWN in the lang_array[] section, and the long name ex: LANG_GRUNT could be "gruntese" :) into the lang_names[] section, before the "" (which is the UNKNOWN name). 5). In CONST.C add in the data for the race as follows: "name", AFFECT, st,dx,ws,in,cn,ch,lk,hp,mn,re,su, RESTRICTION,LANGUAGE }, ex:"Pixie",AFF_FLYING, -4, 3, 0,-1,-2, 3, 0,-5,40, 0, 0, (1 << CLASS_VAMPIRE)| (1 << CLASS_WARRIOR)| (1 << CLASS_AUGURER), LANG_PIXIE } Where st,dx,...lk are the attribute bonuses, hp is the hp/lvl modifier, mn is the mana per level modifier, re is resist, su is suscept (not sure if those 2 are in), RESTRICTION is the classes it cannot be, and LANGUAGE is the "other" native language it speaks. 6). Add the new race in 'npc_race' in CONST.C, by overwriting one of the empty slots (I believe the empty slots are labled something like "r1", "r2", "r3", etc.) 7). In CLANS.C there is a section for race bonuses to shoving. Add here if you feel it is needed. 8). Write a help file, for the new race. 4.21 How do I increase the maximum number of levels? 1). Using log, or whatever means you like, save the wizhelp list into a text file, so that you have a list of immortal level commands. 2). In MUD.H there is a define called MAX_LEVEL change this from 65 (which is 50 mort levels + 15 imm) to the max mortal level +15 (115, for example, if you want 100 mortal levels). 3). Make clean, and recompile. 4). Edit your Imm Pfile. Change the level to the new max level. 5). Using the wizhelp text file as a refrence, go through, and change the levels of all the immortal level commands to reflect the new immortal levels. You can do this online, via the CEDIT command, or you can do this offline, by editing the 'commands.dat' file directly. 6). Edit all the help files, relating to the immortal level commands to reflect the commands' new levels. You can do this online, via HSET, or change them offline, by editing the 'help.are' file directly. 7). Edit the *.class files to balance out the spells, skills, etc. There is another consideration you need to make. That is how much experience will the higher levels need, to remain consistant with the rest of the MUD? To give you an idea of what you need to consider, along with a possible solution, I will quote an article written by Rjael, of Salt Wind MUD: "1.) (a long int)...has a range from -2,147,yada,yada to 2,147,yada,yada. This means that, in the xp_compute, the maximum number of xp which can be generated by a kill is 2 billion. Similarly, you can also LOSE 2 billion xp with this variable type because of the sign. But, turns out that the int in SMAUG code acts like a long. So every int, declaration is really a declaration of a long variable. So, already you are encountering the xp maxes with using integer operators by just using int. IN order to play around with this, edit a player file of yours to have an xp of 3 billion. Log on, and see how the game converts it to negative something-or-other. Thus, the maximum amount of positive xp a person can have is 2,174... in game terms, you can level upwards to about Anyway, xp required to reach a level is based upona certain formula, which is essentially: (found in handler.h) (level -1)^3 * class_exp_base Where class_exp_base is defined in the *.class files in the classes directory. The highest exp_base in virgin Smaug is the Vampire, set at 1500, so, the highest attainable level is about 112, after which the xp system goes downhill and starts getting into negative numbers. So, 300 seems pretty unreachable as the xp required according to this formula would be 40.5 billion which is more than can be compensated for even in an unsigned long. So, in order to raise your levels to a high plateau, I'd suggest implimenting the following changes. 1.) Divide the xpbase in each class file by a factor of 10 or 100. Remember, these are int variables, so no decimal points allowed. 2.) Then, add an additional operator within the xp_compute functions (found in fight.c in all sorts of places (look for flees too) to divide by the same factor. You'll also ahve to look for where the skills award experience for a job well done, and other experience awards. 3.) Then, within the display coding (do_level, do_score) multiply the xp gained by the same factor, and display that the person got more xp than they did. This will be chessy, cause then your xp will always seem to come around in factors of 10 or 100, but it will work, I think. The best way to code in the factor is to add another varaiable definition in mud.h, make it int and give it the value that will be your division factor. Then, use that variable in all the divides and multiplies. With this method, you'll have to know the code very well, but it will allow you to impliment high levels instead of having to rewrite the entire engine to deal with floating points. With this method: Division Factor Maximum Vampire Level 10 242 50 415 100 523 As you can see, going over 100 as a division factor may be a bit overboard, and it won't gain you too much in the way of levels. Then, its just a matter to set the MAX_LEVEL and go down from there when it comes to immortal levels. WHAT ENDS UP HAPPENING The actual xp value that a vampire needs to reach Lvl 2 is 1^*1500/(factor)10 = 150 A mob which used to spit out 50 xp now only spits out 5. 50/factor But you display xp_needed_to_level * factor = 1500 And you display mob xp * factor = 50 What is kept in the player file is the actual xp, so that you let the function calls do all the work, minimizing the need for more memory. Since all of the variables are int, any lagging decimal places will be cut off. So the net result is that it looks like the player is doing a lot of work, but instead the game is doing most of the work." 5. Misc. stuff.... 5.1 Can you recommend any good books, on C ? Kernighan and Plaugher, _The Elements of Programming Style_ Kernighan and Plaugher, _The C Programming Language_ These two books are by the men that created the C language. You may also want to check out: Brooks, _The Mythical Man Month_ There is also a very good online tutorial, published by Coranado Enterprises which is located at: http://www.swcp.com/~dodrill/ 5.2 I've read the FAQ, but still have questions. There is a mailing list set up for questions about SMAUG. To subscribe, send an e-mail to smaug-request@realms.game.org with the line 'subscribe smaug' (without the quotes) in the body. 5.3 I'm a total lamer, who's life isn't worth living, because I've decided to stop using SMAUG. I feel it is only polite to unsubscribe from the mailing list, before I go commit suicide. How do I do that? (UNSUBSCRIBE) Send an e-mail to smaug-request@realms.game.org (NOTE: NOT to smaug@realms.game.org!) with a blank subject line. In the body, only put the word 'unsubscribe' (without the quotes).