Ground ZERO codebase document - last updated 8/1/99. By Cory Hilke shadow_0x01@hotmail.com Legal: There is no warranty expressed or implied that this software can or should be used for any purpose whatsoever. It is offered free of charge in compliance with the original shareware license. Further, by agreeing to use this software, you waive the right to seek damages from the author(s) resulting from any use of this software. You are also bound by Diku, Merc, and ROM license agreements which are found in license.doc, license.txt, and rom.license respectively. Ok, things seem to be working. I am going to try to structure this document for a wide range of audiences, so some of you will have to bear with me for a while as I try to provide useful information for everyone else. So here is the structure of this doc: 1. What is this I have just downloaded? 2. I know how to program, tell me about programming a MUD. 3. I have programmed MUDs before, tell me about this codebase. This is going to be written somewhat like a FAQ, with me providing the obvious questions and the answers to them. ***What is this I have just downloaded?*** This is a watered down version of the code for a game called Ground ZERO. This is intended to be used as a codebase for warfare MUDs. The codebase is written entirely in C. What is a codebase? A codebase is a collection of code to get you started that will make your task of developing a warfare MUD much easier because many of the common things you would want to do in such a game have been implemented for you already (by me). I don't know anything about coding, or codebases, etc but I want to be able to understand what I have here and potentially modify it. How would I learn such things? Some people spend their lives and make their career around programming. However, this doesn't mean that you have to jump in completely in order to understand this code in a rudimentary way and even make some simple modifications. The first thing you need to do in this process though is get a book on C programming. C++ is fine too, but Ground ZERO and this codebase are written entirely in straight C. What is C/C++? C and C++ are programming languages. Further detail about these is beyond the scope of this document - get a book like I said above if you want to learn more about these. Is this codebase based on a codebase as well? Yes, this code is based on ROM2.3 which in turn was based on MERC which was based on DIKU. All of these are free software, but the license is such that you cannot use any of code to make a profit for yourself. This is VERY IMPORTANT to remember. ***I know how to program, tell me about programming a MUD*** Fundamentally, of course, a MUD is no different than anything else you might, but there are some characteristics that are common to DIKU-based MUDs. What is a good high-level place in the code to look first? The game continues in one big loop called game_loop_unix. Here it looks for data on every descriptor (telnet connection) and sends pending output to any descriptors that have any. Also, in this loop the game checks the time of day and launches various autonomous actions (actions that occur in the game no matter what, like hitpoint regeneration and object decomposition). How do commands get processed? There is a big table in interp.c that provides a mapping between the strings that players type in and the game functions that are called. By convention, all game functions are called do_whatever. For example if a player types "get", then the table is consulted and the string get is found and the function column in the table has do_get, so the function do_get is called. By convention hat function will be found in one of the act_ files (act_obj.c in this case). *** I have programmed MUDs before, tell me about this codebase*** This codebase is special in a couple of ways, but the most glaring difference is in how we handle areas. Why are areas handled differently? The requirements for areas are not the same in warfare MUDs as they are in other games. We don't need to have complex areas that defy the laws of geometry (in other muds, you may notice sometimes you go east and then west and you aren't in the same room you started in, this is the simplest example of this). What we need instead is a very quick way to tell the distance between rooms in the game, and quickly check the contents of a room with arbitrary coordinates. So how is the area design different? Instead of having each room have a pointer to the rooms neighboring it in each direction, we instead just have a big two-dimentional array of rooms. If you want to see what is in the room 10,7, you need only dereference the array to [10][7] and you have a pointer to the room. A grenade goes off, who hears it? Go through the list of characters in the game and see if the room they are in has a coordinate that is within 5 of the x and y value of the grenade explosion. Any who do, send them the message "you hear a grenade explode." How are the walls randomized? This is done in randomize_level in db.c. Basically we go through and randomly put a certain number of walls in. Then when we're done we call connect_level which verifies with a recursive algorithm that every part of the maze can be accessed from every other part. In other words, we make sure that there aren't any areas that are completely walled in with no way out. How are levels handled? Levels are stacked on top of eachother like pizza boxes. And moved so that there is a mapping between each level. In other words imagine you had 3 pizza boxes. You put one on top of another and then drove a nail through the two to hold them in place. That's how the levels are, at the beginning a random reference point is generated for level 0 and another for level 1. These are the points that our imaginary nail is driven through. So if the reference points were 5,2 on level 0 and 16, 14 on level 1, then if you went through a down on level 0, at 5, 2 you would be at 16,14 on level 1. The same process is repeated for level 1 and level 2. Tell me what happens when you pull a grenade? First take a look at do_pull. What does this function do? Other than messages, most of what it calls is pull_obj, which other than messages does 2 things. First it sets the owner of the object, next it sets the timer to 10 (seconds). The owner needs to be set so that when the grenade explodes we know who pulled it - that's how they get credit for their kill. When the timer reaches zero, the grenade will explode. Why does it explode? Well, if you set the timer on pants, then when it reached zero it would say they fall apart. But grenades don't go away quietly like that. Take a look at obj_update which calls bang_obj on objects who's timer has reached zero. In bang_obj, it checks what extract-flags it has. If it has none, then it just falls apart, if it has the EXPLODE_ON_EXTRACT flag then it blows up like the grenade, BLIND_ON_EXTRACT gives you flash grenade type explosion, etc. There is one for a smoke bomb making darkness, sonic grenade dazing people, etc. You can add your own, and if there are multiple flags it will do all of these. What happens when it explodes? There are several issues that make it more complicated than I'm saying and they are in comments in the code, but most of what it does is calculate the damage that it is going to do and then apply it to the characters and objects - which sometimes results in other objects exploding which adds further complexity. You shouldn't have to change this code, so why's it matter? ;) How do guns work? Guns are containers. They can only contain a single item at a time, and that is their ammo. Guns don't do damage, the ammo does. Each gun can only take a specific type of ammo, if you look at the ammo_obj.boot file you will see the ammo types listed at the top after the ] symbol (comment symbol for the boot files). The ammo has a certain number of rounds in it, when that reaches zero, the ammo is recycled and you'll have to reload your gun to shoot more (obviously). How are items repoped? Items are NOT repop'ed. Instead, they are recycled. Every time an object is extracted in the game, it comes down on a parachute somewhere else in the game. You will notice there are 2 different imm commands purge and destroy. Purge will recycle all the objects on the floor of the room, while destroy will remove them and not recycle them back into the game. That's how we ran droid quests, we'd just create lots of droid contruction sets and type purge and they showed up randomly all over the game. Who is this MR. SELF-DESTRUCT fella? Well it's a NiN song . . . Other than that though it's the default name in the code when do_ commands are called with a NULL pointer for the character, in other words, when the game does actions itself. Like when it saves everything every 5 minutes you'll see MR SELF-DESTRUCT: 253 objects and 17 characters were saved on the imm net. How does the game reboot and have people come back linkdead? Every 5 minutes the function do_save_all is called causing the game to be saved. This writes a file called fullsave.txt. If the game crashes, or you reboot, this file is moved to startfile.txt. If that file exists as the game is starting up, it will read the file, which contains all the people who were in the game and the items they had, their hp, etc and it will pre-load them into the game, so that when they connect it will be like they were in the game linkdead and nothing has changed. How does the account system work? The file account.boot will contain all the accounts. The command newaccount will create an account for a player, delaccount will delete the account, disable will disable the account of a player, and apass will change the account password. We always required people to send mail and used the email name as the account name, but this is general purpose and you could use whatever you wanted as the account name. The purpose of this system was to prevent people from constantly coming on and mining around their own base or blowing up their teammates, etc, which ruined the whole concept. So we made it so without an account you couldn't use explosives at all and if you did have an account and acted like that, it was easy to pinpoint who you were and who your other characters were. How do I make myself an imm/imp? 2 important files: gods.boot and comm.c gods.boot is where all the imms go. You can figure out the format of this by looking at how it is loaded in load_gods in db.c. comm.c is where you put yourself and other imps (max-trust gods). Take a look at imp_table and replace the entry for someimp and add as many other entries as you like. Why is it done this way? Don't you just feel safer knowing you have to recompile the code in order to change who the imps are? Is there any way to turn on and off being a god so that you can test things as an imm and player more easily? YES, but this is also dangerous. There is what is called a backdoor in the code as released. Log in as any player and simply type backdoor You will see the typical Huh?! But you will suddenly have the max-trust in the game - ie you are super-imm. This trust will only last that single session, this does not make you an imm forever. This is a great thing because it allows you to be an imp and type trust self 0 making you a mortal, and then just type the backdoor password and your an imm again, and if you use a better password than "backdoor" you might even want it up when open to the public so that you can tell your lesser imms that if they really really need to they can use this password to get maximum trust and shut the game down, etc. Whenever it is used it is logged, so you will know if someone abuses this. Either way though, you want to change the password from something as simple as backdoor.