# Configuration Syntax

All configurations used with Doom Builder follow a specific, structured syntax. The configurations are all in plain text format and can be edited with any plain text editor. Every setting in a configuration is in the following form:

    settingname = value;

Here are a few examples:

    doublesidedflag = 4;
    defaulttexturescale = 1.0f;
    scaledtextureoffsets = true;
    gamename = "Doom";

There are a few rules to the setting names and values:

- The setting name may not contain any spaces, tabs, newlines, dots or (back)slashes.
- The setting name must be unique within the configuration, or within the structure it is in.
- A decimal value must contain a dot and must end with 'f'
- Boolean settings may use the keywords true and false.
- Strings (texts) must begin with a doublequote (") and end with a doublequote. To include a doublequote in the string, prefix it with a backslash (\"). To use a backslash in a string, also prefix it with a backslash.

Some settings do not require a value and their precense or absense alone is enough. Such a case would look like this:

    enablelighting;

C-style comments can be inserted by using double slashes (//) for singleline comments and /* and */ for block comments. These comments will be completely ignored by Doom Builder. You can hide writings about your wildest dreams in configuration files!

## Structures

Configurations can also contain structures. Think of them as a collection of settings that have their own name space. The structure begins with a name and opens with an opening bracket ({). At the end of the structure it closes with a closing bracktet (}). It is common to ident the settings inside the structure with a single tab to make it easier to see that those settings belong in a structure. An example of a structure with settings:

    winningnumbers
    {
    	car = 55;
    	washmachine = 40;
    	tools = 30;
    }

Structures are often used by Doom Builder in cases where multiple collections of settings can be found. The name of a structure can also be just a number, so that a structure can describe information about a specific index number. Here is an example of such a case:

    things
    {
    	1
    	{
    		name = "Player 1 start";
    		color = "green";
    	}

    	2
    	{
    		name = "Player 2 start";
    		color = "green";
    	}

    	138
    	{
    		name = "Hideous monster";
    		color = "red";
    	}
    }

Please note that in some structures, the order of the settings and structures is important.

## Including

Some configurations (such as the Game Configurations) can become very large and complex, while some share the same values in many settings. For example, Eternity is a game engine that inherits features from Doom and Boom and adds on top of that. This is where including pieces from other configuration files becomes interesting. With the include function, we can insert features from Doom, then insert (and possible override) features from Boom and then add the Eternity ones. This saves us rewriting all the Doom and Boom features that already exists in other configurations.
The include function takes two arguments. The first (mandatory) is the filename (path relative to the current file) and the second (optional) is the name of the structure to include. If the second argument is not given, the entire file will be included. Here is an example that shows how such an include functions look like:

    include("commonsettings.cfg");
    include("extras.cfg", "skills");

Below are a few examples that show what the results are when including settings that override settings with the same names among other things. For these examples we will be including a file named "extras.cfg", which contains the following settings:

    maxtexturenamelength = 8;
    skyflatname = "F_SKY1";

    options
    {
    	1 = "Low";
    	2 = "Medium";
    	3 = "High";
    }

This example shows how the include function includes an entire file. This is the most basic include:

    thingflags
    {
    	1 = "Easy";
    	2 = "Medium";
    	4 = "Hard";
    }

    include("extras.cfg");

Result:

    thingflags
    {
    	1 = "Easy";
    	2 = "Medium";
    	4 = "Hard";
    }

    maxtexturenamelength = 8;
    skyflatname = "F_SKY1";

    options
    {
    	1 = "Low";
    	2 = "Medium";
    	3 = "High";
    }

The following example shows how a single structure from extras.cfg is included. Notice how only the contents of the structure are included and not the structure container itsself!

    thingflags
    {
    	1 = "Easy";
    	2 = "Medium";
    	4 = "Hard";
    }

    include("extras.cfg", "options");

Result:

    thingflags
    {
    	1 = "Easy";
    	2 = "Medium";
    	4 = "Hard";
    }

    1 = "Low";
    2 = "Medium";
    3 = "High";

If we want our included settings in a structure, we have to put the include function in the structure where we want our settings included. See the following example:

    thingflags
    {
    	1 = "Easy";
    	2 = "Medium";
    	4 = "Hard";
    }

    options
    {
    	0 = "None";

    	include("extras.cfg", "options");

    	4 = "Ultra";
    }

Result:

    thingflags
    {
    	1 = "Easy";
    	2 = "Medium";
    	4 = "Hard";
    }

    options
    {
    	0 = "None";

    	1 = "Low";
    	2 = "Medium";
    	3 = "High";

    	4 = "Ultra";
    }

The following example demonstrates how values can be overridden by using the same same setting name. It also shows that this does NOT change the order of the items. The first time an item is defined (either by including or because it is written) is where its position will be. See this example:

    thingflags
    {
    	1 = "Easy";
    	2 = "Medium";
    	4 = "Hard";
    }

    options
    {
    	0 = "None";

    	include("extras.cfg", "options");

    	2 = "Average";
    	4 = "Ultra";
    }

Result:

    thingflags
    {
    	1 = "Easy";
    	2 = "Medium";
    	4 = "Hard";
    }

    options
    {
    	0 = "None";

    	1 = "Low";
    	2 = "Average";
    	3 = "High";

    	4 = "Ultra";
    }

Notice how the definition of setting "2" ("Average") does not move the already defined "2" ("Medium"), but instead only changes its value to "Average".