Nox Script
3.0
|
Welcome to Nox Script 3.0! This language is inspired by Pawn which is a scripting language with a C-like syntax. If you are familiar with C, then this will be very familiar to you.
There are four exposed types in Nox Script:
The int
and float
types are the same as C. The string
type refers to a string in the string table. Lastly, the object
type is used as an opaque type. It does not refer to an object in Nox! Types are strictly enforced to prevent errors.
In Nox Script, Nox objects are always referred to by their in-game ID which is an int
. In addition, there are two keywords, self
and other
, that refer to the caller of the script and target of the script, respectively. In the API Reference, these will be referred to as SELF and OTHER.
The most common usage of the object
type is when you are dealing with groups and waypoints. While these are technically integer IDs, Nox Script uses an opaque type for basic type checking and preventing you from performing operations on them. The only allowed operations are assignment (=
), is-equal (==
), and is-not-equal (!=
).
All of the standard arithmetic and comparison operators are supported on both int
and float
types. Bitwise operators are only allowed on int
types. Additionally, string
types support comparison operators, concat (+
), and concat-assign (+=
). Below is a complete list of operators and supported types:
Assignment | = | int, float, string, object |
---|---|---|
Concat Assignment | += | string |
Arithmetic Assignment | += -= *= /= | int, float |
Bitwise Assignment | &= |= ^= <<= >>= | int |
Modulo Assignment | %= | int |
Concatenation | + | string |
Arithmetic | + - * / | int, float |
Modulo | % | int |
Bitwise | & | ^ = << >> | int |
Logical | && || | int |
Equality | == != | int, float, string, object |
Comparison | < > <= >= | int, float, string |
There are three types of literals: ints, floats, and strings. The syntax is similar to C.
An int-literal is either a decimal, hexadecimal, or octal number. A hexadecimal number starts with 0x
, and a octal number starts with 0
. There are additionally the keywords true
and false
, which are treated as 1
and 0
respectively.
A float-literal is a number of the form: 1.0
or 1.0e2
. It must contain a dot, otherwise it may be interpreted as an int-literal, which may cause a type mismatch.
A string-literal is a C quoted string: "hello world". It may contain the usual C escape characters, for example: "This is a quote: \".". All string literals will be added to the string table during compilation.
Like C, all variables are statically typed when they are declared. In addition, a variable name must not conflict with any other name that is within scope. Variables that are declared outside of a function have a global scope, and they can be modified or used from any function. Variables inside a function have a block scope.
The basic syntax for variable declaration is: type name;
.
You can also immediately assign a value using: type name = value;
. If you assign a value to a global variable at declaration, then it must be a constant expresssion (e.g. it does not use any functions or variables).
Declaring a variable can only be done as a statement. It cannot be inside of an expression.
Arrays are also supported: type name [length];
. The length must an integer number greater than 1. Arrays must be subscripted when they are used: name[index]
.
Functions are defined in the global scope and their names must not conflict with variable names or built-in names. Functions can have an return type and parameters. If a function does not return anything, then its return type must be the void
keyword. Function parameters can be used just like normal variables.
The function declaration syntax is similar to C: type name(type paramName1, type paramName2, ...)
.
You can call functions and pass in arguments like C: name(arg1, arg2, ...)
. If a function returns a value, a function can be called in an expression. This syntax also applies to calling a built-in. Argument types are checked against the expected parameter types.
Some built-ins take a function as a parameter. This is the only situation where you can use a function as a value.
The standard control flow constructs are present: if statements, for loops, and while loops. Additionally, you can use a goto statement and labels if necessary, but this is heavily discouraged.
An if statement can have an optional else statement. You can chain these to produce an else-if statement:
A for loop has 3 parts, each is optional. The initialization happens before any loop code. It must be an expression (e.g. it cannot be used to declare a variable). The condition is checked, and exits the loop if false. And the afterthought is performed every time the loop ends and repeats.
A while loop has a condition that is checked, and exits the loop if false. The condition is required.
Both for loops and while loops can be controlled by keywords. A break;
will exit the loop immediately. A continue;
will cause the loop to repeat immediately.
A goto statement can be used to immediately start executing from a label. Labels have function scope, so you can only goto a local label. Using a goto is heavily discouraged.
A return statement is used to immediately exit the current function. It is also required when the function has a return type.
Use builtins.h to find the function you are interested in. These functions have been renamed from previous versions:
Below are some examples inspired by scripts in official Nox maps. These are just snippets, so they are not sufficient by themselves.