XScript Compiler
A modern scripting language and compiler for X3 Farnham’s Legacy — write cleaner scripts, catch errors before they reach the game.
⬇ Download Quick StartOverview
XScript is a high-level scripting language that compiles to the native XML format used by X3 Farnham’s Legacy. Rather than working directly in the game’s built-in editor with its limitations, you write scripts in a clean, readable syntax and let the compiler produce correct, optimised XML output.
XScript adds a number of capabilities that aren’t possible in standard X3 scripts:
Object types are tracked through assignments. Calling a ship method on a sector variable produces a warning.
Use function return values directly as arguments or chain with -> without intermediate variables.
$x += 1, ++$count, $x *= 2 — all translated automatically.
Define reusable constants and parameterised macros with #define.
Variables assigned inside a gosub sub are visible to the calling code via a pre-pass.
Convert existing compiled XML scripts back to readable XScript source.
Download
| File | Description |
|---|---|
XScriptCompiler-0.5.zip | Compiler executable, data builder, and decompiler |
x3fl.xml | XScript definition file — function database, constants, datatypes |
default_data.dat | Pre-built binary data file (requires the game’s Data\ folder to regenerate) |
Quick Start
1. Set up the folder
Place the compiler and data file in a working folder. If you need to regenerate the data file from scratch, your Data\ folder from the game installation must be present:
XScriptCompiler.exe
default_data.dat
x3fl.xml
Data\
0001-L044.xml
TShips.txt
TDocks.txt
TMissiles.txt
... (other game data files)
2. Write a script
Create a .xs file. Here’s a minimal example:
$message = “Hello from XScript”;
incomingMessage($message, PlayerLog::Alert, TRUE);
return null;
3. Compile
The output myscript.xml can be placed directly in your mod’s script folder.
4. Rebuild the data file (optional)
Only needed when x3fl.xml has been updated:
Command Reference
| Command | Purpose |
|---|---|
--load_data <file> |
Load the compiled data file (default_data.dat or x3fl.dat). Required for compile and decompile. |
--compile <file> |
Compile an XScript .xs source file to XML. |
--builddata <file> |
Build the binary data file from x3fl.xml and the game’s Data\ folder. |
--decompile <file> |
Decompile a compiled XML script back to XScript source. |
--out <file> |
Output file path. Required for all commands. |
Language Overview
All statements end with a semicolon. Variables begin with $ and may contain letters, numbers, underscores, and periods. X3 only supports integer values — no floating point.
Variables and Assignment
$my.variable = “hello”;
$ship = PLAYERSHIP;
$array[0] = 42;
Object Methods and Properties
Use -> to call methods or access properties on an object. Properties map to getter/setter functions — no parentheses needed when reading or writing:
$exists = $ship->exists();
$ship->setCommand(null);
// Properties — getter
$name = $ship->name;
$sector = $ship->sector;
// Properties — setter
$ship->name = “My Freighter”;
$ship->commander = PLAYERSHIP;
Nested Function Calls XScript only
Standard X3 scripts require every return value to be assigned to a variable first. XScript allows direct nesting — the compiler generates the temporary variables automatically:
$name = $sector->name;
Conditions
Keywords: if, else, not, while. These can be combined. Unlike standard X3, do if and skip if are not written explicitly — the compiler selects the correct instruction automatically based on block size.
else if ($value > 50) { … }
else { … }
if not $ship->exists() { return null; }
while ($count < 10)
{
$count += 1;
}
Arrays and Tables
Arrays are integer-indexed. Tables accept any datatype as a key — strings, integers, objects, or constants. Both support multi-dimensional access and can appear in any expression or condition.
$array[0] = 42;
$value = $grid[2][3];
// Table — any key type
$table[“name”] = “My Ship”;
$table[PLAYERSHIP] = TRUE;
// Utility functions
$count = arraySize($array);
$keys = tableKeys($table);
Constants
Named constants use the :: namespace separator. Several built-in constants refer to the object the script is attached to — these are null when running globally.
| Constant | Description |
|---|---|
this | The object this script is running on |
ThisSector | The sector of this |
ThisHomebase | The homebase of this |
ThisEnvironment | The environment of this (sector or docking station) |
ThisOwner | The race that owns this |
DOCKEDAT | The station or ship this is docked at |
TRUEOWNER | The true owner race — relevant for disguised ships such as pirates |
PLAYERSHIP | The ship the player is currently piloting |
TRUE / FALSE | Integer 1 / 0 |
NULL | No object |
Labels, Goto and Gosub
$result = $myVar->exists(); // $myVar is known here
return null;
initialise:
$myVar = PLAYERSHIP;
endsub;
gosub target before compiling the calling code, so variables assigned inside a sub are correctly typed in the code that follows the gosub. This is handled automatically.
Compound Assignment and Increment
++$count; $count++; —$count; $count—;
Macros
#define ADD(a, b) a + b
$limit = MAX_COUNT;
$sum = ADD($x, $y);
Error Output
Errors and warnings are printed to stdout with the exact file, line, and column, plus the source line and a caret pointing to the problem:
$result = createSheep(RACE.Argon, $sector, 100)
^
Compile Warning [#2]: [myscript.xs:7:0] – Object ‘$ship’ datatype mismatch
$result = $ship->getSectorName()
^
Errors prevent the output file from being written. Warnings are informational — the script still compiles.
Mod Support
Custom Commands
Third-party mods can add ship commands that aren’t in the base data file. XScript supports these via a prefix notation defined in x3fl.xml. If a DataType has a prefix (e.g. SHIPCOMMAND_), you can reference any command ID directly:
The decompiler also emits these correctly — unknown command IDs are written as PREFIX_id rather than raw integers.
Rebuilding the Data File
If you are maintaining a mod that extends x3fl.xml with new functions, constants, or DataTypes, rebuild the data file after each change:
The Data\ folder from the game must be present in the working directory as it is read for ware type lists and text IDs.
VS Code Integration
A Visual Studio Code extension is included (xscript-x3fl.vsix) providing full editor support for .xs files.
Keywords, operators, constants, variables, and strings are all coloured correctly.
Autocomplete for functions, methods, properties, and constants — with parameter hints and inline documentation.
Hover over any function or constant to see its description, parameters, and return type.
Compiler errors and warnings appear as underlines directly in the editor and in the Problems panel.
Ctrl+Shift+B compiles the active file using your configured compiler settings.
Optionally compile automatically every time a .xs file is saved.
Installing the Extension
- Open Visual Studio Code
- Press Ctrl+Shift+X to open the Extensions panel
- Click the … menu (top right of the panel) and choose Install from VSIX…
- Select
xscript-x3fl.vsixand reload when prompted
Configuring the Extension
Place default_data.dat (or x3fl.dat) in your workspace root folder — the extension loads function definitions and constants from it automatically on startup.
Open Settings (Ctrl+,) and search for xscript to configure the compiler integration:
| Setting | Description |
|---|---|
xscript.compiler.exePath |
Full path to XScriptCompiler.exe. Leave blank to auto-detect in the workspace root or on PATH. |
xscript.compiler.dataFile |
Path to default_data.dat. Auto-detected in the workspace root or next to the exe if left blank. |
xscript.compiler.outputDir |
Where compiled .xml files are written. Defaults to the same folder as the .xs source file. |
xscript.compiler.compileOnSave |
Set to true to compile automatically every time a .xs file is saved. |
Version History
0.5 BETA — Current
- Full XScript language support including arrays, tables, compound assignment, namespace constants, and custom prefix constants
- Two-pass compilation for correct type tracking across
gosub/label boundaries - Object type propagation through assignments and function return values
- Boolean arguments correctly emit
TRUE/FALSEin decompiled output - DataType prefix support for mod-added commands (
SHIPCOMMAND_1000) - Improved error messages with source line and caret indicator
- Property getter/setter support via
->operator - Nested function calls and method chaining
