The real nature of this cosmic tree cannot be known here, nor its beginning, nor end, nor foundation.
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.
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:
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:
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.
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.
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.
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:
If you guessed that this is yet another encoding of the same three traps,
you have passed obfuscation level one.
1. Formatting Code
turf/trap
pit; quicksand; glue
turf/trap
{
pit
quicksand
glue
}
2. Compilation Errors
3. Paths in the Tree
turf/trap/pit
tar
lava
bottomless
turf {
trap {pit; /turf/trap/quicksand}
/turf/trap/glue
}