XS Scripting: A Programmer's Reference¶
Written by: Alian713
This is the most short and precise guide for XS Scripting that you will find, it does not give any introductions to programming topics and cuts right to the chase, if you are a programmer then this is perfect for you. If you are not a programmer fear not! Refer to the For Beginners section of this guide instead.
1. Using an XS Script¶
To use an XS script:
-
Navigate to the folder
C:\Program Files (x86)\Steam\steamapps\common\AoE2DE\resources\_common\xs
-
There should be 2 files in this folder already, called
Constants.xs
andxs.txt
. In here, create a new file with any name ending with.xs
. For example, the file can be calledfilename.xs
default0.xs
There may be an additional file called
default0.xs
. Never write code in this file as this is a temporary file and can be overwritten by the game.Constants.xs
The file
Constants.xs
contains a list of constants that can be used in any XS Script directly, without needing to use an include statement.VSC Plugin for XS
A VSC Extension for syntax highlighting and code auto completion for AoE XS Scripting can be found here
-
To begin with using XS, write this basic code in the file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// this is a comment /* this is a multiline comment */ void main() { int a = 10; int b = 20; // the variables cannot be declared by separating them with commas // unlike java or python. // chats to the screen xsChatData("a+b = "+(a+b)); }
1.1. In a Custom Scenario¶
- Open the scenario in the editor
- Under the
Map
tab, type the name of the XS Script that you created in theScript Filename
field without the.xs
at the end. For example, if your file is calledfilename.xs
then you will writefilename
in this field. - Now, under the
Triggers
tab in the editor, add a new trigger, then add a new effect. (If you do not know what a trigger/effect is, please go through theCustom Scenarios: Triggers: Trigger Basics
section of this guide) - From the
Effects List
selectScript Call
. - You can now use the functions in the XS Script in the message box using a normal function call. Keep in mind, only those functions that do not take any parameters work here!
- The
main()
function that we made above is automatically run when the scenario is played. - If there are no errors in the code, clicking the
E#0: Script Call
effect will turn it green. If there is an error in the script, an error message will be shown. - Testing the scenario now will run the
Script Call
effect in the trigger defined above, which in turn will run themain()
function in the XS Script and30
will be shown in the chat.
1.2. In an RMS¶
- Open the RM Script in a text editor
- At the very top, type
#includeXS filename.xs
. Here,filename.xs
is the name of the file that you created above. - The
main();
function is automatically called when a map is generated using the RMS. - To test, load the RMS in a single player (or multi player) lobby and start the game.
- It is recommended that you use a custom scenario to test XS Scripts, as it is easier to debug them in the editor.
1.3. In an AI¶
- Open the AI per file in a text editor.
- Use
(inlcude "filename.xs")
at the top of the file to load an XS script. - Use
xs-script-call "function name"
inside adefrule
to call an xs function. - We will use
xs-script-call "main"
to call the function we created above. - To test, load the AI in a single player (or multi player) lobby and start the game. When the map is generated, the
main()
function in the XS Script will run and30
will be shown in the chat. - It is recommended that you use a custom scenario to test XS Scripts, as it is easier to debug them in the editor.
- Note: Each AI runs its XS code separately, and they are executed on the computer of the host (AIs behave as if the host controls them)
Now that you have set up an XS file with a main()
function inside, you can type code inside this function to do different things! We'll be walking through all of the different things that are known to be possible one by one:
2. Variables Data Types¶
There are a total of 5 data types supported by XS, they are:
Data Type | Syntax |
---|---|
int |
int a = 10; |
float |
float a = 3.1; |
string |
string a = "string"; |
bool |
bool a = true; |
vector |
vector v = vector(1.2, 2.3, 3); |
Refer to the Vector Manipulation section of this guide for all the different functions that can be used on vectors.
No Vars in Vector Initialisation
Variables cannot be used in vector initialisation. For example: vector v = vector(x, y, z);
does not work. Here x
, y
, z
are floating point values. Use vector v = xsVectorSet(x, y, z);
instead.
Constants, Statics and Scope
-
Constant Variables
Syntax
const int a = 10;
orconst float PI = 3.1415;
will declare an immutable variable. -
Static Variables
Syntax
static int counter = 0;
will declare a static variable. -
Scope of a Variable
The concept of local and global variables applies to XS.
3. Operations¶
3.1. Arithmetic Operations¶
Operation | Syntax |
---|---|
Addition | a+b |
Subtraction | a-b |
Multiplication | a*b |
Division | a/b |
Modulo | a%b |
Refer to the Mathematical Operations section of this guide for useful mathematical functions.
Unary Negative
There is no unary negative operator in XS
1 2 3 4 5 6 7 8 9 |
|
3.2. Prefix and Postfix Operations¶
Operation | Syntax |
---|---|
Postfix increment | a++ |
Postfix decrement | a-- |
Prefix operations are not supported by XS.
3.3 Shorthand Assignment Operations¶
Shorthand Assignment operations are not supported by XS.
3.4 Bitwise Operations¶
Bitwise operations are not supported by XS.
3.5. Relational Operations¶
Operation | Syntax |
---|---|
Less Than | a < b |
Greater Than | a > b |
Less Than or Equal To | a <= b |
Greater Than or Equal To | a >= b |
Equal To | a == b |
Not Equal To | a != b |
Relational Operators on Strings
These relational operators also work on strings, for example a < b
tells you if a
lexicographically preceeds b
.
3.6. Boolean Operations¶
Operation | Syntax |
---|---|
AND | a && b |
OR | a || b |
Negation is not supported by XS.
DataType of Result of Operation
Due to a bug at the moment, the data type of the answer of any operation is determined by the first operand. This means that 9*5.5
evaluates to 49
instead of 49.5
. However, 5.5*9
will correctly evaluate to 49.5
.
4. Flow Control Statements¶
The following flow control statements are supported by XS:
-
if else if
construct:Example Syntax:
1 2 3 4 5 6 7 8 9 10 11 12
void main() { int a = 10; float b = 20; int c = 30; float max = 0; if(a > b && a > c) max = a; else if(b > c && b > a) max = b; else max = c; }
-
switch-case
construct:Example Syntax:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
void main() { int a = 10; switch(a) { case 1 : { // do stuff } case 2 : { // do stuff } case 3 : { // do stuff } default : { // do stuff } } }
-
while
loop:Example Syntax:
1 2 3 4 5 6 7
void main() { int a = 0; while(a < 10) { xsChatData("a = "+a); a++; } }
-
for
loop:Syntax:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
void main() { // this loops a from 0 to 10 for(a = 0; < 10) xsChatData("a = "+a); // this loops a from 10 to 0 for(a = 10; > 0) xsChatData("a = "+a); // unlike java, you do not need to specify an increment or decrement // the for loop takes care of that // step sizes unfortunately cannot be changed. }
5. Functions¶
Syntax:
1 2 3 4 |
|
Example Syntax:
1 2 3 4 5 6 7 8 9 10 11 |
|
An XS Script can import other XS Scripts using the following syntax:
1 |
|
6. Arrays¶
Refer to the Array Manipulation section of this guide on how to use arrays.
Standard syntax like int a[] = new int[10];
or a[2];
is not supported by XS.
7. Type Casting¶
int
, float
and bool
data types can be implicitly casted into each other. All of them can be implicitly casted into strings by doing string a = "this would work "+5.6;
. However, string a = 5.5;
will not work, instead use: string a = ""+5.5;
.
It is unknown if XS supports proper explicit type casting
8. Rules¶
A rule is a block of code that can be set to repeatedly execute at set intervals throughout the duration of the game. A rule is always initialised outside of a method. Its usage looks like:
Syntax:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Example:
1 2 3 4 5 6 7 8 9 10 11 |
|
There are a lot of built in XS functions that can interact with rules. Check the Rules Section of this guide.
The variable cActivationTime
, when used inside the block of a rule, gives the time of activation of the rule in seconds.
With that, you now know everything that is currently known to work with XS Scripts. Good luck and have fun creating awesome maps!