Phantasmal MUD Lib for DGD

Phantasmal Site > DGD > Untitled document (index.base.html) > (untitled)

2. Introduction

This tutorial is intended for anyone with a basic knowledge of programming and a will to learn. You don't have to know C very well before you start, and I believe that even true programming beginners might be able to learn how to code. They will, of course, have far more to do. There is much more good material available on the topic of learning C than learning LPC, so it's recommended that novices attempt to learn at least the basics of C before attempting this book.

Experienced coders, including MUD coders, will need to read the tutorial since it explains concepts that are unique to DGD's LPC and to this book. They will be able to skim most of the book and then use it primarily as a reference. The selection of what is and what is not important is left to the reader.

The LPC language in actual application is closely wed to the driver and mudlib it uses. This edition of this textbook is meant for use with the DGD driver. Since the DGD driver includes a mudlib, the Kernel Library, in the standard distribution, and since the Kernel Library is public domain, we choose to include basic information on its use in this volume. The basic information all refers to plain, bare DGD, used with no other mudlib.


i - Acknowledgments

Ronnie:

I'd like to start by thanking Thorsten Lockert and Christian Markus, perhaps better known as Plugh and Olorin, for their help in proofreading this text, suggesting improvements and in general being supportive and providing constructive feedback.

Without them this rather lengthy project would have taken even longer (mind-boggling, but true) to complete and ended up a lot worse.

Angelbob:

I'd like to acknowledge Ronnie, of course, for writing the first, non-DGD edition of this text. I'd like to thank Felix Croes (Dworkin) for producing the excellent DGD driver that made all this possible. And I'd like to thank all the people out there writing MUDs and working on DGD. You've made the work that I do useful and in some cases, possible.


ii - Tutorial Setup

The manual is divided into three progressively more advanced sections. The first part explains the basics of coding and LPC without delving too deeply into specifics.

The second part is aimed at the intermediate audience, explaining many aspects of functions and operators more fully.

The third part handles applications and advanced topics that seemed inappropriate for the first two chapters. In addition to more advanced topics, this includes miscellaneous topics that the more casual programmer may not care about.

If you are a new MUD administrator you may be taken back at the thickness of this tutorial. Nonetheless, it's highly recommended that you read all of it eventually, and that you read at least an intermediate level of proficiency with all functions you commonly use. Bear in mind that in this era of internet security problems and rampant hacking, your MUD may be vulnerable as well. The better you understand your code, the harder it is for hackers and malevolent players or administrators to take advantage.

This manual is fairly extensive, but it's primarily aimed at builders and administrators rather than driver programmers or implementors who write mudlibs from scratch. It's important for those latter categories to know how their work is likely to be used, but the sort of very specific details that their work requires don't age well and require a massive amount of information that simply isn't useful to the more casual MUD administrator or builder. For such implementors working under DGD, I highly recommend the DGD mailing list. This list can be located from a web search engine. As of this writing, it is located at http://list.imaginary.com/mailman/listinfo/dgd. I recommend typing the words "DGD mailing list" into Google, just in case.

A note about gender: throughout the text I've used male pronouns. This is not meant as a statement on female coders, but simply a shorthand to avoid using the phrase "he or she" at every instance.

Chapters that describe functions and macros in detail have a subcaption with the names of the discussed items within brackets. This should make it easy to search for them, for later reference.


iii - History of LPC

LPC is an interpreted language created by Lars Pensjoe for LPMUD. LPMUD, also written by Lars Pensjoe, is an interactive multiuser environment suited for many purposes, games not the least among them. Since its first appearance in 1988 the language has changed dramatically.

Development was taken over around 1990 by other people at Chalmers Datorfoerening, especially Jakob Hallen, Lennart Augustsson and Anders Chrigstroem. They extended and refined the language extensively but LPC still strongly resembles its parent language, 'C'. The main differences lie in the object structure that LPC imposes and several new data types to faciliate fast development. LPC isn't as free-form as 'C', but it's far more suitable for its original purpose - programming in a game environment.

Felix Croes wrote a driver called DGD which uses a variant of the standard LPC language. DGD is far more advanced than most LPC drivers in several ways, although it includes a far smaller standard library of functions. DGD is also different in that it allows commercial licensing for a fee, which other LPMUD drivers do not.


iv - Driver vs Mudlib

The distinction between driver (also called the "gamedriver") and mudlib is very simple in concept. The driver is the program that runs on the host computer. It is a language interpreter with an object management kernel, almost a small operating system in its own right. It defines the LPC language, interprets it and executes the instructions given to it through the LPC objects in the game.

Since the driver defines the LPC language, different LPC drivers define subtly different dialects of LPC. That's the reason for the specific DGD edition of this text. DGD's dialect includes some language features found in almost no other languages, and exports a very limited set of functions from the driver.

The mudlib is the collection of LPC objects that make up the basic game environment. It defines the "laws of physics" of the gameworld, or the program being used if it's not a game. For instance, DGD is used for Yahoo Chat. Therefore, there is somewhere a Yahoo Chat library for DGD. That's an example of a very unusual mudlib. More-standard mudlibs include GurbaLib, Phantasmal, Melville, and the LPMUD 2.4.5 library which has been adapted for use with DGD. Each of those mudlibs independently decides how its rooms, verbs, creatures and other defining characteristics work.

While the mudlib defines the standard objects and the commands a game uses, there is also code and data specific to an individual game. For instance, if you run an Old West game where the players can go into the Bar None Saloon, the code that makes the Saloon special is the domain code -- how the bartender acts, the mannerisms that the waitresses have, all of this is specific to an individual game, and usually kept separate from the mudlib code. This is called domain code and domain data.


v - Administrative Setup

The domain code and data is produced by administrators or builders of a game. A MUD also often calls these people wizards or immortals. Different games refer to them differently. This book will call all game staff "administrators". "Builder" denotes someone that produces domain code or domain data for the game.

Sub-areas of a MUD are also often called domains. The other common name for them is zones. This book will refer to them as zones to avoid confusion with the terms "domain code" and "domain data". Each zone will usually have a player in charge of it, one who regulates building within that area. Some zones will have only a single player in charge who will be the only builder of that zone.

While zones will be interconnected to some extent, usually they are kept as separate as the game allows. This prevents any conflict between the builders of the different areas over code or in-game objects.

If you're a new administrator or builder on an LPMUD, you'll want to find a zone to become part of, or start your own zone. Talk to the head administrator or builder of the MUD to find out how new builders are usually integrated into their MUD. Some MUDs like to start new builders on their own private area while others like to have them help out for awhile on existing areas.


vi - Writing code

Formatting code properly makes it easier to read, easier to use and generally more pleasant for all involved. This section describes some fairly standard code formatting conventions as well as why they may be worth the trouble.

Here are some good arguments for making the effort:

  • It makes the code much more readable, not only for others, but also for yourself, particularly if you have to read or alter the code six months after you produced it.
  • Since it is easier for others to read, it's also easier for them to understand what you have done. That means it'll be easier for them to help you debug your code if you have problems. It can be very difficult to find people to help you debug badly-formatted code.
  • Writing code properly actually makes it better, believe it or not. The reason for this is simply that writing code badly makes it easy to miss simple errors that get hidden in the hard-to-read code.

What follows here are some guidelines about how to format your code. Read it even though you might not fully understand what is being discussed, then go back and re-read it later after having learned the skills necessary. That way you won't pick up any bad habits and have to unlearn them.

Be aware also that the specifics of how a piece of code should be formatted is a very individual topic among programmers. Where and when whitespace should be added and the number of spaces in an indent are frequently disagreed on. If you're joining an existing MUD, find out if they have policies on code formatting. If you're starting your own, make sure to spell out your own policies on the topic.

  1. A new indent level is started at the beginning of each block.
  2. The closing curly-brace is in the same column as the first letter of the opening statement. Many people like to put the opening curly-brace in this column as well.
    if (this)
    {
        statement;
    }
    else if (that)
    {
        another_statement;
    }
    else
    {
        default_statement;
    }
            
    
    The important thing is to make sure to indent new blocks, and to make sure you do it by the same amount everywhere you do it. If you're modifying an existing piece of code, use the same number of spaces that they do for indentation.
  3. Several arguments on a line separated by a comma have a space following the comma. Operators that can take multiple arguments (like + and -) have a space both before and after the operator.
    int a, b, c;
    
    for (a = 0; a < 10; a++)
    {
        b = function_call(a, b * 2);
        c = b * 3 / 4;
    }
    
  4. If a loop statement has no body, put the ending ; on a separate line.
    while (!(var = func(var)))
        ;
            
    
    If you put it on the same line then it's very easy for a reader to miss actual mistakes like this one:
    for (i = 0 ; i < 100 ; i++);
    {
        <code that gets executed only once, but always>
    }
            
    
  5. In general, all #define and #include statements should be placed at the top of the file, or in a header file. The compiler allows you to spread them through the file but that will often cause confusion.
  6. The same goes for prototypes and global/static variables used in the file. Put them all at the top of the file with a proper comment header. The compiler will also let you spread these throughout the file and it's a bad idea to do so for the same reason as above.
  7. Break long lines of code in proper places so that they don't use more than 80 columns. This helps people using an 80-column terminal window and anybody trying to print out the code. Note: we'll be breaking this one in the HTML version of this textbook. Sorry!
  8. The file should begin with a proper header. For instance:
    /*
     * <filename>
     *
     * <Short description of what the file does, no more than 5-7 lines.
     * ...
     * ... >
     * 
     * Copyright (C): <your name and year>
     *
     */
            
    
    You should also include a brief note about the license on the code you've written unless you have and retain all rights to all of it. But if you're writing for a MUD, you need to grant them the right to use the code. That's either done implicitly by the license for the MUD or explicitly by getting you to sign over the rights they need. Talk to your MUD administrators about this if you don't understand. The MUD should have a license for any code and content that you submit to them.
  9. It's good to start every function with a header documenting what it does, who wrote it, what inputs and outputs it takes and what its side effects are. For instance:
    /* 
     * Author:        <Your Name<
     * Function name: <Function name>
     * Description:   <Short description of what the function does,
     *                 usually no more than three lines.
     * Arguments:     <A list of all arguments, one per line
     *                   arg1 - description no longer than the line.
     *                   arg2 - next argument, etc. >
     * Returns:       <What the function returns>
     */
            
    
    If the function doesn't take any arguments, or doesn't return anything, simply remove those lines in the header.
  10. Put suitable comments in the code here and there when doing something that might look a bit obscure. Remember that while you and the MUD administrators might be pretty competent, you'd like your code to be debuggable by anybody. Some day you might be gone from the MUD or hit by a bus (or just too busy to help with the problem), and you'd like the next person who looks at the code to be able to handle it rather than replacing all your hard work with something easier to debug.
  11. There are two common ways to write function and variable names. One is to use all lowercase characters and separate as necessary with underscores. The other is to use mixed case characters and use a capital letter only at the beginning of a new word. If you wanted your variable to be named "the quick brown fox", you might write it as either the_quick_brown_fox or TheQuickBrownFox in those two styles. Determine which capitalization scheme the MUD you're writing for uses. Use it.
  12. Constants and functions using #defines should be written in capitals (e.g. #define AMOEBA "one celled creature"). Doing this makes it easy to see what kind of symbol is being handled at all times. Functions that use #define are also called macros, or macro functions.

One of the easiest ways of getting a good editor is to use the emacs editor, set up to use a modified c++ mode. The c++ mode understands most LPC operators but needs a few hints on indentation. Some example lines of code for your .emacs file:

;; emacs lisp script start

(setq auto-mode-alist (append '(
  ("\\.l" . my-c++-mode)
  ("\\.y" . my-c++-mode)
  ("\\.c" . my-c++-mode)
  ("\\.h" . my-c++-mode))
    auto-mode-alist))

(defun my-c++-mode () (interactive)
  (c++-mode)
  (setq c-indent-level 4)
  (setq c-brace-offset 0)
  (setq c-label-offset -4)
  (setq c-continued-brace-offset -4)
  (setq c-continued-statement-offset 4))

  ;; emacs end
    

An added advantage of using emacs is that you can correct another coder's indention by typing 'M-<', 'M->', 'M-x indent-region'.

If you have no clue what emacs is you can look it up on a web search engine or simply continue to use your favorite text editor. Some MUDs will require you to use a specific editor or submit code in specific ways, which may also affect your choice of editor.