Chapter 2

Navigating the Code Tree

The real nature of this cosmic tree cannot be known here, nor its beginning, nor end, nor foundation.
--Bhagavat Gita

The previous chapter was a quick introduction to give you a taste for DM programming. This and the next few chapters will cover the same basic ideas in greater detail.

A DM program begins at the root of the tree and descends along multiple branches. Each branching point (or node) is given a name to distinguish it from the other branches at the same level. Names are case-sensitive (so apple and Apple are different). They may be any length and may contain any combination of letters, numbers, and underscores as long as they do not start with a number.

Consider the following code:

turf
   trap
      pit
      quicksand
      glue

Several types of traps are defined (though no instructions have been included to actually make them work). Here, each type of object is on a line by itself and indentation is used to define the relationships between them. The three siblings pit, quicksand, and glue are all children of trap, which is in turn derived from turf, the map terrain object.

1. Formatting Code

DM provides some flexibility in the way code is formatted. For example, blank lines may be inserted between other lines without effect. This may help code from getting too dense and unreadable.

To compress code that is overly spread out, a semicolon may be used in place of a newline. In this way, several children may reside on the same line. To put a parent and child on the same line, a slash is used. It is equivalent to a newline followed by an additional level of indentation.

The following code is equivalent to the previous example:

turf/trap
   pit; quicksand; glue

In addition, braces may be used to mark the beginning and ending of a node's children. C, C++, and Java programmers may feel more at home using this style. With the compiler checking both braces and indentation, it is hard for simple mistakes to slip through unnoticed. Sometimes it is the simple spelling and typesetting errors which are the hardest to see.

Here is yet another encoding of the same objects, this time using braces:

turf/trap
{
   pit
   quicksand
   glue
}

You may use either tabs or spaces in any number to indent your code. The only requirement is that you be consistent. Each block of code must use the same type of indentation throughout. In general, DM provides enough freedom to format your code the way you like without so much freedom that mistakes are likely to slip through unnoticed.

2. Compilation Errors

While we are on the subject of mistakes, you may as well make one now on purpose so you know what is going on later when it's not on purpose. Remove one of the braces from the above code and try compiling it. You should get a compilation error. If you double-click on it, the cursor will jump to the line in the code where the compiler ran into trouble. You can correct the problem and then try recompiling.

Often, you will need to think less like a human and more like a machine to see what is wrong. Forget about what the code is trying to do and focus more on its form: the grammar, the spelling, and little fussy details that only a computer would care about.

The more frequently you compile your code, the less trouble you will have in locating problems. Also realize that if there are many compilation errors, some of the later ones may just be confusion caused by earlier ones. Try fixing the first few and recompiling if the rest don't make any sense.

3. Paths in the Tree

You have already seen how to use a slash to make code more compact. It is used to separate a parent and a child node, for example turf/trap. This notation is known as a path because it tells the compiler how to get from the current position in the tree to some other point by enumerating the branches to take along the way. If a given branch doesn't exist, it will be created.

Paths have several uses. Sometimes indentation can get so deep that it becomes hard to read. You can use paths instead to get deep down inside the tree without indenting so much to get there. Another time to use a path is when you want to branch off of existing objects from somewhere else in the code.

The following example adds some variation to the basic pit that was already defined.

turf/trap/pit
   tar
   lava
   bottomless

You could place this code at the bottom (or even the top) of the same file or in another file. (You will see how to use multiple files in chapter 19.)

Finally, there are a few rare cases in which you may want to use an absolute path--that is, a path starting with a slash. This allows you to derive something from the root even if you are not currently at the root. Now does not happen to be one of those rare cases; using an absolute path would only make the code more confusing.

If you think you know how things work, take a look at this:

turf {
   trap {pit; /turf/trap/quicksand}
   /turf/trap/glue
}

If you guessed that this is yet another encoding of the same three traps, you have passed obfuscation level one.

4. Code Comments

When you start writing code as confusing and tangled as the last example, it would be a good idea to leave a few clues behind. Otherwise you may find it incomprehensible the next time you visit, a rather embarrassing situation. There are two ways to write comments in the code. One is for multi-line comments and the other is for single line ones. Example:

/*
  This is a multi-line comment.
  You can put whatever you want inside of it.
  The compiler just skips right over.
  Some of you may recognize it as a C style comment.
*/

//This is a single-line comment.
//Some people know of it as the C++ style comment.

Comments can occur anywhere in the code--at the end of lines, on lines by themselves, or wherever. They are often used to make statements of intent or purpose. It frequently takes only a very short note to make code much easier to read.