XScript Compiler

Version 0.5 BETA

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 Start

Overview

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:

Type checking

Object types are tracked through assignments. Calling a ship method on a sector variable produces a warning.

Nested calls

Use function return values directly as arguments or chain with -> without intermediate variables.

Compound assignment

$x += 1, ++$count, $x *= 2 — all translated automatically.

Macro defines

Define reusable constants and parameterised macros with #define.

Sub variable tracking

Variables assigned inside a gosub sub are visible to the calling code via a pre-pass.

Decompiler

Convert existing compiled XML scripts back to readable XScript source.

Download

Beta release — XScript 0.5 is functional but under active development. Some edge cases may not compile correctly. Please report any issues.
FileDescription
XScriptCompiler-0.5.zipCompiler executable, data builder, and decompiler
x3fl.xmlXScript definition file — function database, constants, datatypes
default_data.datPre-built binary data file (requires the game’s Data\ folder to regenerate)

⬇ Download XScript 0.5 BETA

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:

// myscript.xs — shows a message to the player
$message = “Hello from XScript”;
incomingMessage($message, PlayerLog::Alert, TRUE);
return null;

3. Compile

XScriptCompiler.exe –load_data default_data.dat –compile myscript.xs –out myscript.xml

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:

XScriptCompiler.exe –builddata x3fl.xml –out default_data.dat

Command Reference

CommandPurpose
--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

$count = 0;
$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:

// Methods
$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:

Standard X3 (3 lines)
$sector = getSectorByCoord(22, 3);
$name = $sector->name;
XScript (1 line)
$name = getSectorByCoord(22, 3)->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.

if ($value > 100) { … }
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
$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.

ConstantDescription
thisThe object this script is running on
ThisSectorThe sector of this
ThisHomebaseThe homebase of this
ThisEnvironmentThe environment of this (sector or docking station)
ThisOwnerThe race that owns this
DOCKEDATThe station or ship this is docked at
TRUEOWNERThe true owner race — relevant for disguised ships such as pirates
PLAYERSHIPThe ship the player is currently piloting
TRUE / FALSEInteger 1 / 0
NULLNo object

Labels, Goto and Gosub

gosub initialise;

$result = $myVar->exists(); // $myVar is known here
return null;

initialise:
    $myVar = PLAYERSHIP;
endsub;
Sub variable pre-pass — the compiler scans each 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 += 1;    $count -= 1;    $count *= 2;    $count /= 2;
++$count;    $count++;    $count;    $count;

Macros

#define MAX_COUNT 100
#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:

Compile Error [#5]:   [myscript.xs:12:4]  – Unknown function ‘createSheep’
    $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:

$cmd = SHIPCOMMAND_1000;  // mod-added command with ID 1000

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:

XScriptCompiler.exe –builddata x3fl.xml –out default_data.dat

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.

Syntax highlighting

Keywords, operators, constants, variables, and strings are all coloured correctly.

IntelliSense

Autocomplete for functions, methods, properties, and constants — with parameter hints and inline documentation.

Hover docs

Hover over any function or constant to see its description, parameters, and return type.

Error squiggles

Compiler errors and warnings appear as underlines directly in the editor and in the Problems panel.

Compile shortcut

Ctrl+Shift+B compiles the active file using your configured compiler settings.

Compile on save

Optionally compile automatically every time a .xs file is saved.

Installing the Extension

  1. Open Visual Studio Code
  2. Press Ctrl+Shift+X to open the Extensions panel
  3. Click the menu (top right of the panel) and choose Install from VSIX…
  4. Select xscript-x3fl.vsix and 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:

SettingDescription
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/FALSE in 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