Compiler Directives#
Compiler directives are statements whose purpose is to directly interface with the compiler in some way. They have a variety of uses.
Importing Files#
Using the import
or #include
directive, you can include other ZScript
code files in your project by specifying the path to the file as a
string literal. Normally, only the script buffer of a
quest is compiled- but each of these statements adds a file to be compiled.
Generally, including the same file multiple times has no ill effects- unless you change the HEADER_GUARD option.
#include "std.zh"
Including the standard library.
Note
When typing the string literal parameter, escape characters have no effect,
and \
characters can be inserted normally. This is due to \
being common
in file paths, and all strings worked this way in older versions of the
program, so import path strings continue to act this way for compatibility
purposes.
Related: Include Paths
#include
vs import
There is one difference between #include
and import
.
#include
will check for the file in each of the include paths
first, THEN check from zscript.exe
.import
checks for it from zscript.exe
first, THEN the include paths
.Conditionally Including Files#
The #includeif()
directive takes two parameters; a compile-time constant bool
expression, and a string in the same format as #include
.
The file indicated by the string will be included, IF the bool
evaluates to true
.
const bool USE_TANGO = true;
#includeif(USE_TANGO, "tango.zh")
Checking Imported Files#
The IS_INCLUDED()
directive takes a single parameter, a string
in the same format as #include
. It evaluates to a compile-time constant bool
,
with a value of true
if the specified file has been included.
if(IS_INCLUDED("tango.zh"))
{
// code here to show a tango message
}
else Screen->ShowMessage(5); // show a non-tango message
Including Paths#
In ZScript->Compiler Settings
in the editor, you can set a set of include paths
.
Every time a file is included, the compiler will search for the file both as a relative
path to the zscript.exe
file, AND relative to every include path
.
Additionally, the #includepath
directive can be used to add a path to the
include paths
. It takes a string the same as #include
, except to a
directory rather than a file.
#includepath "../MyQuestScripts/"
Note that the include paths
set in the editor apply to all quests;
using the #includepath
directive can allow you to set per-quest paths.
Changing Options#
Using the #option
directive allows you to change compiler options
per-scope. More details.
Repeating Code#
The repeat()
directive can be used to duplicate code, similarly
to a loop. However, it acts as though you actually wrote out
the code multiple times. For example, repeat(5) Trace(2);
is
the same as typing out
Trace(2);
Trace(2);
Trace(2);
Trace(2);
Trace(2);
The number passed to the repeat()
directive must be compile-time constant.
Custom Errors#
You can cause compiler errors yourself. This can be useful for some cases, such as setting up an error in a script you intend others to use, which triggers if they have something set up incorrectly.
This is done using the CONST_ASSERT()
directive, which as the name might
imply, relies on compile-time constants. It requires a compile-time constant boolean expression as its
first parameter. It can optionally take a string literal as a second
parameter, which will be output as part of the error message.
#include "std.zh"
CONFIG BLANK_COMBO = -1;
CONST_ASSERT(BLANK_COMBO >= 0 && BLANK_COMBO <= MAX_COMBOS,
"BLANK_COMBO must be set to a valid combo ID!");
gives the compile error Error C082: Assert Failed! BLANK_COMBO must be set to a valid combo ID!
If no string is specified, the message is simply Error C082: Assert Failed!
.
Suppression while editing#
You may want to send your script to others in a state where these errors would occur, such that they are forced to set the constants properly before being able to compile (ex. set an appropriate blank combo, in the above example). But, this may make it harder to edit your script, requiring you to first making such changes yourself before attempting to compile to even be able to see real compile errors.
If you edit with VSCode, there is an Ignore Const Assert
setting
in the extension settings. By toggling this on, the compiler in the
extension will entirely ignore all CONST_ASSERT()
based errors,
allowing you to edit and only see actual errors in your script.