ACS

ACS is the scripting language that was created for Hexen and has been greatly expanded by ZDoom. ACS enables level makers to script events during gameplay, making the creation of interactive environments even in Doom's archaic engine infinitely more open-ended. With very basic commands, an author can modify the structure of a level in ways such as raising and lowering floors separately, simultaneously, in the same or opposite directions, and to any height or depth. One can even use move walls, given that they meet certain criteria (see Polyobject). Textures displayed on floors and walls can be changed. Monsters &mdash; and any other actors for that matter &mdash; can be inserted, removed, monitored, have many of their properties altered, and even pursue "objectives" through a limited form of AI. The use of ACS opens many possibilities for level design, especially if the person using it is talented, patient, and imaginative.

Somewhat more technically, a scripting language is a limited form of programming language; its code takes the form of a list of commands to be interpreted by a specific engine. ACS is structured much like C/C++ (it is even commentable, as shown in the example below). A script, which is composed in a text editor of some sort, contains commands, variable declarations, and possibly even calls to other scripts (as with subroutines in a programming languages). The top-level items to recognize are scripts and their script types, which are the events that trigger the sequence of commands contained in a given script. A script is started by typing something such as the following:

Note that a script is defined somewhat like a function in C. "OPEN", as used in this example, is a script type that tells ZDoom that the script is to be executed upon starting the level.

Variables are dimensioned, as in many programming languages. Arrays, or variables in which many values can be stored with an index to differentiate between them (e.g. ICanMakeArraysLOL[2] = 9), are valid. A variable intended to be available to all sub-scripts must be declared outside all sub-scripts.

Note also that ACS supports conditional statements, and therefore loops made with conditional statements. It supports most (if not all) C/C++ implementations of conditional statements and loops. Looping a script without a delay will cause ZDoom to automatically terminate the script, however, because it won't give anything else in the map a chance to run. When this happens, a message like the following will be generated:

Runaway script 1 terminated

Randomization
Among notable features, ACS includes a function that allows the map designer to randomize game events. This enabled a new level of replay value to the series of games using the Doom engine as the game content could potentially change between playthroughs. So far, only Heretic's behavior for Firemace placing and the game's implementation of ambient sounds had provided remarkable randomization.

Drawing a single event
By setting up a script variable and assigning it a random value using the proper function (int random;), the mapper can cause a script to run partially. This is completed by dividing the script into cases with the if conditional statement. In the structure, each case practically has an identification number that matches to the values the variable can receive beforehand. Below is an example of a script where randomization is involved. Once the sequence is activated, one of the defined ambient sounds gets played. SCRIPT 2 (void) {  int Select; // This is a script variable Select = random(1,3); if(Select == 1) {    ambientsound("Ambient2",127); // Plays a cricket chirping sound (with full volume) }  else if(Select == 2) {    ambientsound("Ambient5",127); // Frog croaking }  else if(Select == 3) {    ambientsound("Ambient7",127); // Bird singing }  }

The maps in Hexen contain diverse applications of the function. One can be found during the first visit to Guardian of Ice. When the player has hit the switch at the northern end of the level, four columns lower behind it, and eventually an area resembling a sword becomes illuminated in front of one. The sword acts like an arrow showing the column plate which works as a teleporter back to the hub map. By stepping onto the other three plates, the player causes their ceiling to plummet which produces severe damage to him. The puzzle has an example of a script that, during its sole run, is set to randomly choose a single case among many to execute only its commands. The drawn map variable subsequently controls the behavior of the column plates which have a different script assigned to them.

Setting a random order for multiple events
Randomization can also be utilized in scripts which include multiple parts, meant to be activated at separate phases of gameplay. Basically, all command cases of the script can be edited to occur in a random order. With the aid of map variables, the mapper is able to set the system to "memorize" which cases have already been run. If the function later draws a figure of which corresponding contents have been executed for once, an additional test can be used to send the script variable for a redraw. When an unused value is finally found, the test is passed and the value's contents are run. A way to implement such a script is demonstrated below.

int Lock; int Lock2; int Lock3; // These three are map variables SCRIPT 2 (void) {  int Select; Select = random(1,3); if((Lock == Select) || (Lock2 == Select) || (Lock3 == Select)) // || means OR  { restart; }  if(Select == 1) {    ambientsound("Ambient2",127); Lock = 1; }  else if(Select == 2) {    ambientsound("Ambient5",127); Lock2 = 2; }  else if(Select == 3) {    ambientsound("Ambient7",127); Lock3 = 3; }  }

This form of randomization has a significant role in the Hypostyle where the central hall has locked doors in all cardinal points. They seal areas that the player needs to visit. Once he has eliminated a specific Ettin in the hall, one of the four doors is randomly selected to open. Each area has a switch at the end of it. When the player activates such, another door in the hall is chosen to open in a similar way, revealing a new area and a toggle. Once the switch in the fourth area has been triggered, yet two more doors open in the hall and the player can enter either one of them to confront Death Wyvern. Although the script that controls the puzzle has a different structure in comparison with the above example (it uses a do while iteration statement in addition to if statements), the common idea is the same and they both result in their events being executed in a random order.