XStart Quickstart


The best way to learn XStart is to look at the example scripts that are included. Look at the examples in the “examples” folder or open the shortcut in the Windows start-menu. If you have some experience with scripting languages like Javascript or Lua it is likely that you can start almost immediately, learning XStart in the progress.

Variable Scope

In XStart variables and functions should be declard as global or local to specify their scope. If ommited it is assumed that the scope is local. If access from everywhere is wanted, the global keyword should be used. To set a previously declared global variable in another scope (function) to a new value, again the global keyboard must be specified, otherwise a new local version is created.

global A = 1;
log("A is "+A);
function ChangeA(newA) { global A = newA; }
log("A is "+A);

Native Types

Native types do not create an object when declared. They can only hold a single value of the given type. GM-Script knows the following native types:


Converting from one type to the other is possible by using a method call as follows:



In GM-Script a function definition is like an object creation and assignment to a variable:

global MyFunction = function(a,b) { return a+b; };

You can see, that a function is an object, and the function-object is assigned to a variable named “MyFunction” in this example. Also you may have noticed that you must put a semicolon (;) at the end of the definition.

But there is also a shortcut for this that mimics a common semantics of other languages:

global MyFunction(a,b) { return a+b; }

Also note, in this example, we made the functions global, this way they are accessible in another scopes.


Pointing to the object itself in a method (object member function) can be done with the “this”-keyword.

global function NewObject(name) {
        local o = Object();
        o.name = name;
        o.PrintName = function() { log("My name is " + this.name); };
        return o;

global MyObject = NewObject("Alf");


Every object in XStart has a table to store functions and variables. Also build-in variables and functions can be overwritten.

To set custom or build-in variables or functions, the bracket operator or the dot operator is used:

object["url"] = "http://www.xstart.io/";
object.url = "http://www.xstart.io/";

Both methods are equivalent, same for reading:

local url = object["url"];
local url = object.url;

Method Chaining

Some build-in object functions (methods) are simple enough that they do not need return a result of the call, instead they return the object itself. This allows method chaining.

global FRAME = Frame("Example", 50, 50, 800, 600, "#6080060").toggle().cursor(true);

To see which methods can be chained, look in the reference documentation for functions that return “[this]”.


There are three container classes in Xstart: Array, List and Map. They should explain itself pretty much.

For now, look into the reference-documentation:

Array List Map


XStart has no support for native threads and all operations are blocking. This does not mean that XStart does not use native threads to accelerate some operations. For example, expensive image operations use OpenMP to increase their performance.

In the script however, the execution is sequential. This gives the benefit of not having to deal with multithrading issues. XStart scripting is not build to compete with the fastest languages but to give a tool for rapid development and prototyping.

However, what XStart does support are coroutines by using the thread() keyword in the scripting language.

function LogAlive(text) {
        while(true) {

thread(function() { sleep(1.0); log("hello"); });
thread(function() { sleep(2.0); log("world"); });
thread(function() { sleep(3.0); log("!!!"); });
thread(LogAlive, "alive!");

Scene Graph

For tools and automation tasks XStart can be used without a window or rendering context. If however graphics and a user interface is needed, the build-in scene graph is a simple to use but powerful tool. First thing needed is a Frame, every Frame object has a default root scene-node where the tree begins rendering. Adding a scene-node to the table of another scene-node will add it to the graph tree.

global FRAME = Frame("Scene Graph", 50, 50, 800, 600, "#608060").toggle().cursor(true);
FRAME.root["image"] = Texture("images/button.png"), 200, 200);

while(FRAME.render()) {


Every scene-node and the frame do receive input events. For now, look at the example and the reference-documentation.