Anatomy of a Script
By Richard Clark

A ZDoom script, like any programming or batch language, uses its own set of symbols and must follow a certain format in order to be understood by the engine. When Raven created the ACS scripting language, it chose to model the format and syntax after the C programming language. Those familiar with C will see a similar syntax and should be able to readily understand its use. However, even a non-programmer should be able to readily comprehend and use ACS.

Every script file should start with the following command:

#include "zcommon.acs"

The verb "#include" is what is termed a directive and is an instruction to the engine. In this case, it tells the engine to include the file zcommon.acs. This file actually loads three other files and it provides a set of values for the engine that represent various objects in the game. It also allows the script writer to use human readable values instead of cryptic numbers.

The script writer can also include the define directive in a script.

#define pausetime 70

This statement tells the engine to replace all the instances of the word "pausetime" with the number 70. Using the define directive helps create an understandable script as well as localizing any changes. If the script writer finds that the value of delay of 70 is too long, then simply changing the define to another value will automatically update the script.

There is only one variable type in ACS a four-byte integer. The two keywords int and str define their use. INT is used for a number and STR is used for a character string. Variables are simply buckets that store information for use at a later time. Another lesson will be devoted to variables and their use.

A script must follow a certain syntax in order to be understood by the engine. The basic outline for a script is as follows:

    script # [OPEN] [(parameter list)]
    {

        ...commands... ;
    }

The keyword "script" of course defines a script. A script is identified by a number script (1, 50, 100, etc) The number must be unique among all scripts within a map. A script can be defined with either a parameter list, or defined as OPEN. An OPEN script will be executed when the map loads.

The parameter list defines any values that need to be passed to the script. For example, a line identification number can be passed to the script so that the script knows what line to change. If the script doesn't require any parameters, then the script is defined as VOID. This simply means that no parameters are being used.

The meat of the script is contained within the beginning and ending braces { and }. Braces define a set of commands that need to be executed as a group. These outermost braces indicate that the script as a whole needs to be executed as a group. The script writer can also use braces within the script to define sub-groups of commands with the script.

All commands within a script must end with a semicolon (;). This indicates to the engine the end of the command when it is parsed and executed.

The following is a script that doesn't use any parameters and is executed on map load.

    #define mysector 1

    script 1 OPEN
    {
        sector_setcolor (mysector, 255, 255, 0);
    }

The following is a script that has a void parameter list.

    script 2 (void)
    {
        light_changetovalue (1, 180);
    }

The following script uses one parameter to change the blocking on a line. It also uses the human readable value for the on/off parameter.

    script 3 (int line)
    {
        setlineblocking (line, OFF);
    }

The overall basic structure of a script is very straight forward and yet as we shall see, it is a powerful tool for the level designer.