7.1 How do I change the levels on my mud?


Carefully. You need to bear in mind before doing this that simply changing the max_level won't do it..you need to look at how levels affect combat abilities, default mob values and all sorts of subtle facets of the mud. After that, then:
1. In merc.h, change the value of MAX_LEVEL to what you want, and any other defined level value that you need to alter.. eg if you will have 20 imm levels or whatever.
2. Grep your source for any occurrence of the old MAX_LEVEL value..there are a few places this is hardcoded numerically.
3. In the command table in interp.c, look at the commands and see if your imm structure now needs any of the levels changed for commands.
4. The fun part. In const.c, go through the skill_table, and change for every skill the level at which every class now gets the skill/spell. You may not need to do this for all cases, but take careful note of how skills unavailable to a class are set to the lowest imm level..if you now have more mortal levels than this all these values will need to be changed. If you go over 100 levels, make sure to change the value of the 'reserved' slot, as bad things can happen otherwise.
5. Do a clean compilation (delete all .o files and do 'make') and restart the mud.
6. If all is well, this is the basics of adding more levels.. other points you may have to address are:
- if keeping pfiles handling old imms..either advancing by hand, or incrementing your pfile version and handling the change in save.c
. - changing area files, to change mobs stats, obj stats, and generally trying to keep the area re-balanced. Refer to previous note on the combat system.

7.2 How do I add a new class?


1. Increment MAX_CLASS in merc.h
2. Add a entry for the class in the class_table in const.c
3. In the pc_race_table in const.c, add the experience point modifier for each race for the new class.
4. In the group_table? Set up groups of skills/spells for the class
5. In the skill_table in const.c, add a value for the class to each skill/spell to specify which level the class will get that skill at.
6. Add new titles to the title_table in const.c so the class gets a new title each time they level.
7. Clean recompile and reboot.

7.3 How do I add a new race?


1. In merc.h, increment MAX_RACE
2. In const.c, add a new structure to the pc_race_table for the new race
3. In const.c also, add an entry in the race_table for the new race. *make sure it is in the same position as it is in the pc_race_table* Adding It after the last current pc race can help ensure you do this.
4. Clean recompile and reboot

7.4 How do I add a new clan?


1. Increment MAX_CLAN in merc.h
2. In tables.c add a new entry for the clan in the clan_table.
3. Clean recompile and reboot.

7.5 How do I add a new skill or spell?


The procedure for adding a new skill or spell is generally similar, in that you need to write the actual code that actually carries out the skill/spell in question and then also make appropriate definitions to other files so that the addition can be integrated into the existing system.

For skills:
1. Write the function holding the code for the skill, placing it in the most appropriate file, usually act_*.c or fight.c
2. In const.c, put an entry in the skill_table for the skill
3. In interp.c, add a line so the mud knows which command triggers this skill
4. In interp.h, do a DECLARE_DO_FUN( skill_name )
5. Recompile and reboot

For spells:
1. Write the code for the spell, placing it usually in magic.c or magic2.c
2. In const.c, add an entry to the skill_table for the spell
3. In magic.h, do a DECLARE_SPELL_FUN( spell_name ) ;
4. Recompile and reboot

7.6 How does the command table work? How do I add a new command?


The command table holds the required attributes for every command anyone can type, the text they type, the function that holds the code to be executed, the level they can do it at, the position they must be in to do it, how and when to log it and so on.

When input is received from the player, the mud starts at the top of the table and sees if what they have typed can be matched against any of the entries in the table. Thus if they typed 'exam fido', the mud would go through the table, comparing every entry against the word 'exam' either until a match is found, or until the entire table is searched. Two things are of note here. Firstly, for efficiency, the most commonly used commands are first in the list, which is why you see the movement commands before anything else. When adding a new command therefore, think carefully of how often it is used, and try to place it accordingly. You will notice the table is generally grouped into combat commands, informational commands and such, so finding an appropriate place isn't terribly difficult. The second consideration comes from the fact that the mud will allow you to type abbreviations for a command..thus 'n' executes the 'north' command, not 'notell'. Again this requires careful positioning of commands.. it's quite easy to place a command in the table only to realise you've made it so that a frequently used contraction now executes this command instead.

The ROM code as did Merc before it uses a convention whereby all functions that are written to execute a player-typed command are named do_*, such as do_say, do_kill or do_cast. It is important to keep this in mind, as more importantly, all do_ functions must have the same signature, that being
void do_*(CHAR_DATA *ch, char *argument) ;

7.7 Why does the mud crash when I type 'who hjhjkhg'?


You have an incorrect value for either MAX_CLASS, MAX_RACE, or MAX_CLAN in merc.h. If one of these values is larger than it should be, someone typing 'who jhhjhgk' will have the mud go searching into places it shouldn't go, with predictably dire results.

7.8 My players are levelling from 1 to hero after one kill..what's going on?

You haven't set the exp modifier for their class in the pc_race_table. Because this is declared as an array, forgetting to do it for a new class will effectively mean they need 0 xp per level. One kill therefore, will take them to the maximum level achievable by killing mobs.

7.9 Why do my mobprogs suddenly stop working?


If you are using the mobprogs by Newt, there is an error checking routine that can sometimes cause all mobprogs to stop working until the next reboot. In program_flow(), there is a variable used to detect the level of call nesting of mobprogs, which is intended to stop mobprogs which call each other in an infinite loop. This variable is increased once the function is entered, and decreased at the end of the function, but the problem lies in the routes taken through the function by a bad mobprog. If the function detects a problem with the mobprog, and returns from it without reaching the end, the variable isn't decremented, and once this happens 5 times all mobprogs mud-wide cease being executed. If you see an error in your log file of the format:
Mobprog: max_call_level exceeded
Then this is indicitive of this problem.

The solution is to go through the program_flow() function, and add a
call_level-- ;
Before anywhere where there is a 'return' statement. You probably want to do this instead of just disabling the check as someone will build looping mobprogs if you do.

7.10 How do I add more flags past 'ee'?

You can't simply just start defining 'ff', 'gg' and so on. The flags in Rom are held in 32 bit variables, so trying to assign values larger than a 32 bit number can hold isn't going to work very well. Note that 64 bit machines may not suffer this limitation, it will depend on what the compiler allocates for the variables.

There are a number of solutions to the problem, ranging from redefinition as 'long long', restructuring the flag variables as bit arrays and the most common, which is to simply add a new field for the additional flags. In this way, you will have a new field in the appropriate structures for 'act2', 'affect2' or whichever you need. You will need to add new functions for setting and checking these new variables, but it is largely an exercise in copying what is already there. If you're careful you can add as many new fields as you need and keep it totally transparent to players, imms and builders alike. There is at least one snippet for this available, and searching the Rom archives should yield a few past discussions.

7.11 Why don't objects reset to the room?

To stop players simply staying in an area and collecting vast amounts of loot through object resets, 'o' and 'p' resets will not function to the room if the area has any players in it. Thus, if a 'o' reset is set to load a pile of gold into a treasure room and a player picks it up, no matter how long the player waits in the area, area resets will not repop that object to the room. Once the player leaves the area, the object will repop on the next area reset. This check can be removed in the reset code in db.c if you feel it is sufficiently necessary.

7.12 How do I increase my number of possible vnums?

Firstly, do you really need to? Rom as is gives you 32k vnums, and there are precious few muds with that many rooms, mobs or objects. If you do need this though, it will require a fair amount of code changing, all of which though is the simple act of changing the declaration of the 'vnum' field in the structures that have it to a 'long'. This will give you a few billion vnums. You will also need to change those functions that directly access vnums, as they may assign a vnum to a local variable whose type will also need changed.

7.13 Why can't I see much while switched into a mob?

After adding mobprogs, some people find that when switched into a mob they don't see a lot of the mud text, most notably communications channels. The cause of this is the code added to the 'act' function, to check for an ACT trigger on a mob. The code returns from the function if the mob doesn't have such a trigger, but doesn't take account for a switched imm. Add a clause to the 'if' check to return only if the mob has no descriptor and this problem should go away.

7.14 How do I add additional colours?

In short, you don't. The ANSi colour codes used to display colour on terminals specify only eight colours, with bold versions of each, and a number of other control sequences. You cannot simply add a bunch of new codes, the standard does not support it. You will even find massive variations in how different terminal programs handle the 'official' codes, so even by using these you are not guaranteed to have them display correctly on every users screen.

7.15 What areas can or can't I remove?

[by Gabrielle Taylor, blame her]

social.are is required, but you can edit the socials in it as you please. Certain help related areas (rom.are, help.are, group.are) should not be removed unless you're positive that you've copied out the helps required by license (help rom, help merc, help diku) and have your versions of help newbie and help greeting in another file. (There may be other helps automatically called by the code that I'm not sure of.)

limbo.are, midgaard.are, school.are, immort.are, air.are, and gangland.are all contain mobs, objects or rooms that the code calls. Also note that removing a single area may cause other areas to break. You may accidentally remove rooms, mobs or objects that are linked to, or reset in, other areas. Always do this on a backup.

The #defined names of all required objects, mobs or rooms are provided here for your convenience. They are all located in merc.h.

limbo.are is required for the creation of corpses, body parts, money, and some spell related objects. It also contains the rooms that link dead characters drift into.

Only edit or remove it if you're sure of what you're doing.

OBJ_VNUM_SILVER_ONE           1
OBJ_VNUM_GOLD_ONE             2
OBJ_VNUM_GOLD_SOME            3
OBJ_VNUM_SILVER_SOME          4
OBJ_VNUM_COINS                5
OBJ_VNUM_CORPSE_NPC          10
OBJ_VNUM_CORPSE_PC           11
OBJ_VNUM_SEVERED_HEAD        12
OBJ_VNUM_TORN_HEART          13
OBJ_VNUM_SLICED_ARM          14
OBJ_VNUM_SLICED_LEG          15
OBJ_VNUM_GUTS                16
OBJ_VNUM_BRAINS              17
OBJ_VNUM_MUSHROOM            20 (create food spell)
OBJ_VNUM_LIGHT_BALL          21 (continual light spell)
OBJ_VNUM_SPRING              22 (create spring spell)
OBJ_VNUM_DISC                23 (floating disc spell)
OBJ_VNUM_PORTAL              25 (portal and nexus spells)
ROOM_VNUM_LIMBO               2 (where link dead characters go)

air.are is required for the create rose spell. It is safe to copy obj #1001 from air.are into limbo.are, change the vnum to any unused number between 25 and 99, and change this define in merc.h, should you wish to remove air.are. (Note that this will probably be done in a Rom release after June 19/98)

OBJ_VNUM_ROSE              1001
midgaard.are is required for the newbie map, the donation pit, the recall room and the altar room. It is safe to either redefine these values to existing vnums in your world, or to slash midgaard.are down to only containing these vnums.

OBJ_VNUM_MAP               3162 (map of Thera)
OBJ_VNUM_PIT               3010 (donation pit)
MOB_VNUM_FIDO              3090 (used in save.c)
ROOM_VNUM_TEMPLE           3001 (recall room for non-clan)
ROOM_VNUM_ALTAR            3054 (recall room for Loners)

school.are is required for newbie items, gained on login or on executing the outfit command. It is safe to either redefine these vnums to existing vnums in your world, or to slash down school.are to only contain these.

OBJ_VNUM_SCHOOL_MACE       3700
OBJ_VNUM_SCHOOL_DAGGER     3701
OBJ_VNUM_SCHOOL_SWORD      3702
OBJ_VNUM_SCHOOL_SPEAR      3717
OBJ_VNUM_SCHOOL_STAFF      3718
OBJ_VNUM_SCHOOL_AXE        3719
OBJ_VNUM_SCHOOL_FLAIL      3720
OBJ_VNUM_SCHOOL_WHIP       3721
OBJ_VNUM_SCHOOL_POLEARM    3722
OBJ_VNUM_SCHOOL_VEST       3703
OBJ_VNUM_SCHOOL_SHIELD     3704
OBJ_VNUM_SCHOOL_BANNER     3716
ROOM_VNUM_SCHOOL           3700 (where newbies log in to)

immort.are is required for room 1200, which is where immortals are placed if they were in rooms that no longer exist. It is safe to either redefine these vnums to existing vnums in your world, or to slash down immort.are to only containing one room.

ROOM_VNUM_CHAT             1200

gangland.are contains mobs and one object that are called in spec_troll_member, spec_ogre_member and spec_minotaur in special.c. If you remove this area, be sure to disable, remove, or rewrite these specials.

MOB_VNUM_PATROLMAN         2106
GROUP_VNUM_TROLLS          2100
GROUP_VNUM_OGRES           2101
OBJ_VNUM_WHISTLE           2116

7.16 How do I add a new wear location to my mud?


[no longer available]

7.17 Why do act and plr bits seem to be set in the same place?


As you may see, the act flags and plr flags are both set and checked for in the act field of CHAR_DATA. This is not a bug, nor a problem. It is merely a case of efficiency, act flags are only ever used by mobs, and plr flags only by players, so you should *never* have a char who needs both set.

You should be careful though, because of this setup it is vital that you use an IS_NPC to check whether the char in question is a mob or a player before ever setting or checking an act bit.

7.18 What does the number_bits function do?


This function is used to get a random number. The number generated will be between 0 and (2^arg) -1, where arg is the value passed to the function. Some examples follow.


number_bits(3) -- Return random number between 0 and 7 (2^3 is 8)
number_bits(4) -- Return random number between 0 and 15 (2^4 is 16)

7.19 How do I add new data elements to my players without having to wipe all my pfiles?


All player files have a version number, and you can use this as a mechanism for safely extending the data structures that hold player information without having to delete all your player files.

The problem is this- if you add say a new stat called charisma, the obvious thing to do is to write it to the player files with the other stats, therefore the lines involving stats will then have 6 as opposed to 5 numeric values. You will also change the player loading routine to read 6 stat values from each player file. However, any players created before this change were saved with only 5 stats, and the new code will choke when trying to read that extra stat.

The solution is that when you make this kind of change or addition, to increment the version number stored in each player file and check for versions lower than this in your loading routines. In the above example, if your original version was 5, you would increment this so that all player files saved in the new way are given version 6. Additionally, in the loading routines, you would check for the player version. If it was 6 or greater, read in 6 stats. If 5 or lower, read in 5 stats and then set the new stat to some default value. When this player saves out again, their file will be in the new version.

Note that this principle can also be applied to areas. If you find yourself adding new fields that need saved in the area files, it can be at best time consuming to convert all existing areas to conform to this new format. The procedure is easier if you have an OLC, but still not precisely fun. If you give your areas a version number, then additions and changes can be made in the same way as above. It can lead to slightly ugly loading routines, with lots of 'if (pArea->version < 4)' and such, but it does make the extension easier and allows you to retain the ability to read in older areas.

7.20 How does nanny and the connected states work?


When a player is connected, from being at the initial name prompt to being in the midst of combat, any input he sends must be processed, according to both what he typed and his character's status. The function nanny, in comm.c is vital to this process.

If the player is in the game, then the game simply needs to determine if what was typed was a valid command and if so execute it. If the player is either logging on or creating, then things aren't quite so straightforward. This is where nanny comes in.

Each character, or more accurately each connection from a player to the mud has a value, the connected state that indicates where in the creation/logging/playing process the player currently is. This is an element of the DESCRIPTOR_DATA structure. All the possible values for this are defined in merc.h, and the names are pretty self-explanatory. CON_PLAYING is for players fully in the game and playing normally, CON_GET_PASSWORD is for someone who is at the password prompt.

If a player is in a state other than CON_PLAYING, then nanny is called when the mud receives input from them, the arguments sent to it being the players descriptor and the text they have typed. Note that it is the descriptor and not the character itself which is sent as some of the possible states such as CON_GET_NAME get input from the player before the mud has loaded their character.

The heart of nanny is a large switch statement, which looks at the connected state of the descriptor and acts accordingly. Generally, this action will involve some validation of the input, some output to the player, and then the setting of the connected state to the next stage the player should progress to. For example, say a player has connected, and is at the name prompt. This means they have entered nanny with their connected state set to CON_GET_NAME. The branch of the switch statement in nanny for CON_GET_NAME will firstly try to load a player file of that name, and if it finds one, needs then to prompt the player for his password. So, nanny loads the player file, sets the connected state to CON_GET_OLD_PASSWORD and returns. When the player then types his password, they will be brought back into nanny, but this time enter the switch limb for the CON_GET_OLD_PASSWORD state, where passwords are checked.

If there was no player file of the name the player typed, then the mud must instead prompt the player if this is the name they want for a new char. The mud prints such a message to them, and sets their connected state to CON_CONFIRM_NEW_NAME. When the player types something else in this situation, they again are brought into nanny, and this time the code for the switch limb for CON_CONFIRM_NEW_NAME is executed.

The bottom line is that nanny handles the processing of your char through all the possible stages involved in both normal login and creation. If you look at any one stage and compare it to how that stage acts when you are logging on you should see the correlation. What can confuse some is that each stage can set the players connected state to a few different values depending on the input, and things can even get circular. Think of how creation works and this isn't all that surprising. If you mistype your password confirmation the mud has to backtrack to the start of the password entering process. If you choose to customise then you enter customisation, otherwise you skip that stage. At every stage the mud will check your input and inform you if it was invalid, and will then put you back through that stage.

There are two common reasons for wanting to add additional connected states. The first is simply if you are changing your creation or login process in a way that requires input not normally needed in stock Rom. To do this you need to define a new state in merc.h, and add a new limb to the switch statement in nanny. You will need to make sure that the stage before the new one sets the player's connected state to the new state so that the new stage is entered, and that you correctly pass the player to the proper stage depending on their input. Usually this will either be to display an error message and keep them at this stage if their input was invalid, or to do some processing of their input and pass them to the next stage.

The other situation for a new connected state is if you want the ability within the mud to prompt a player for input. Possibilities here are menu driven OLC or note systems, confirmation of irreversable commands such as pkillon or remort and such. The principle is the same though, you define the new state, and add to the switch in nanny. You will process their input, and then either return them to normal playing, send them to another additional connected state, or keep them at this state if the input was invalid.


Main Rom Page Index 1 2 3 4 5 6 7 8