ZScript variables

From ZDoom Wiki
Jump to: navigation, search
Note: This feature is for ZScript only.

ZScript introduces a variety of new variables usable within actors, including structs. These must be defined either inside regular/anonymous functions, or outside the Default {} block, which is used for an Actor class's internal properties only.

NOTE for those with limited programming background: Like C/C++ and unlike ACS, a newly declared variable inside of a function must be initialized or it will take as its value whatever was in its memory space at that time. A numeric variable will not default to zero and must be set to zero explicitly - upon declaration or elsewhere, as long as it is set before it is modified or used.


The following types are available for classes:

  • Arithmetic (bool, double, float, int, int8, int16, uint, uint8, uint16)
  • See this page for more information on what the types are and their aliases. They are defined as shown above, NOT like in C++ (i.e. no unsigned word or underscore).
  • NOTE: There is a difference between double and float. Type double is encouraged over float due to precision loss with the latter.
  • Vectors (Vector2, Vector3)
  • WARNING: Vectors currently CANNOT be used in arrays, but their members can be. However, they can be passed around in functions.
  • Vectors are a container of 2 or 3 doubles respectively, often used with positions, views, velocities, or more.
  • Contains members: x, y. Vector3 includes z and xy.
  • xy is a Vector2. Any changes to it are propagated back to the Vector3 and is provided for convenience to interact with functions or arithmetic made for a Vector2.
  • Has the following functions:
  • double Length(): Returns the length of the vector. Effectively performs sqrt(x*x + y*y) for Vector2, sqrt(x*x + y*y + z*z) for Vector3.
  • Vector# Unit(): Returns a vector with all coordinates multiplied by (1 / Length()) if the length isn't 0, scaling them between range [-1.0, 1.0].
  • Encompassed with double quotes (" "). Case sensitive. Strings are simply compared with <, >, <=, >=, ==, ~== operators.
  • ~== is a case insensitive version of ==.
  • See the link for more detailed information.
  • Names
  • Encompassed with single quotes (' '). Not case sensitive. Operators ==, != are available. Note that ordered comparison currently isn't.
  • Sound
  • Treated similarly to strings.
  • StateLabel
  • Contains the name of a state using double quotes. Can be used for dynamically changing what state an actor is supposed to go to at certain points in their behavior.
  • A special case should be noted with null and "Null", the key difference being using "" around it or not.
  • null should be used if an actor should not perform a jump. Do not use this when performing an action function within an if () statement as it will always fail.
  • "Null" should be used if the actor should be destroyed. Do not confuse this with null. Every actor has this state which will remove them upon making it there. This is safe to use when a jumping function is inside an if statement -- the actor will not be destroyed, since they are treated as booleans instead of actual jumps for testing purposes only.
  • NOTE: StateLabels currently cannot be used in ternary operations, or convert to/from strings and/or names.
  • Color
  • Used to record a a color either defined in the X11R6RGB lump or a hexidecimal surrounded in double quotes, or a directly specified ARGB value.
  • NOTE: Several actor properties can be read only after the mask has been cleared, such as bloodcolor.
Color bl = (bloodcolor & 0xffffff); //Six 'f's, no more, no less!

// Alpha, red, green, and blue from left to right.
// Can also access directly as demonstrated.
Color regrbl = Color(255, 128, 192, 255); 
regrbl.a = 255;
regrbl.r = 255;
regrbl.g = 192;
regrbl.b = 128;
  • Class Casts
  • Used for holding class names and passing said names into places where a function may be expecting a legitimate class for its functionality.
// Ternary operator is basically an if/else statement, short-handed. 
// Left side (between ? and : ) is executed if the statement before the ? is true, right side if false.
bool grenadeChosen = (CountInv("GrenadeToken")) ? true : false;
Class<Actor> proj = "RocketProjectile";

if (grenadeChosen) proj = "GrenadeProjectile";


The following are special types of variables of greater complexity.

  • Similar to their C++ counterpart, contains data of different types. Can also contain functions.
  • State
  • An internal struct which can be used to gather information about an actor's state.


Unlike C++ and DECORATE, ZScript's constant non-arrays do not have a type to be given -- they auto resolve by themselves based on their usage.

const con1 = 1; //int
const con2 = 2.5; //double
const con3 = "Stringify me, cap'n!"; //string (using "")
const con4 = 'A name it is.'; //name (using )


Regular constants cannot be changed by inheriting children, since inheriting states will ignore the new constants and rely upon the previously defined values instead.

Meta variables are like constants, but they can be changed via properties. This effectively makes them replaceable constants for any children.

meta int GibHealth;


Arrays behave like their C++ counterparts, including multi-dimensional support.

Local Arrays

Local arrays can be defined with a set number of index spots, but cannot be initialized until after their declaration. Changing the array's contents must be done inside an anonymous or named function. These can also be declared inside of said functions for temporary existence.

int MyArray[2];
MyArray[0] = 5;
MyArray[1] = 10;

Constant Arrays

Constant arrays are different from normal constants.

  • Can be defined in (anonymous) functions
  • Must have all their fields initialized immediately.
  • Must have a type, and the static word present.
// static const <type> <name>[] =
static const Color SecondaryColor[] =
    "Blue" // Unlike enums, the last member must not have a comma.

See Also