This guide is based on the Ilios Scripting Guide by Chris Tikkos (Dionous Games) and is published here with his permission. Example projects and images are by Dionous Games.
Before you get started
Visionaire Studio was originally designed for 2D point and click adventures. Since version 5, Box2D physics and the Ilios scripting language make other genres possible too, for example physics based platformers. This guide walks you through your first Ilios scripts and the physics setup of a small platformer prototype.
Useful references:
Prerequisites
- Visionaire Studio 5.1.9.2 or newer
- The Animated Pixel Adventurer asset pack by rvros. It is free, but please consider supporting the artist with a donation.
- The background image used in the physics example
You do not need deep programming knowledge, but the basics of object oriented programming (classes, functions, variables) will help a lot. This guide does not teach programming in general, it shows how these concepts work in Visionaire.
Code vs. visual scripting
Visionaire offers two ways to write Ilios scripts:
- Code: classic typed code
- Blocks: visual scripting
Open Visual Scripting in the top bar, create a new script and choose the editor you prefer:

Both kinds can be mixed in one project, so some scripts can be written as code and others with blocks.
Your first Ilios script
Ilios brings a component based approach to Visionaire. You write behaviours, which are classes, and attach them to objects, characters, scenes, interfaces, buttons or the game itself via the Components tab.
1. Create a script block
Go to the Visual Scripting tab and create a new entry. It will hold your behaviour class. Code and blocks offer the same functionality, so it is a matter of taste. This example uses blocks first, the code version follows at the end of the section.

2. Create a behaviour class
Click on the canvas to open the block list, choose New Class and confirm with a double click.

Name your class and assign a behaviour superclass. A superclass already contains the basic behaviour of a Visionaire entity. Your class inherits it, you can override its functions, and you can attach your class to the matching entity as a component.
Available behaviour superclasses:
GameBehaviourObjectBehaviourCharacterBehaviourSceneBehaviourButtonBehaviourInterfaceBehaviour
For this example, create an object behaviour, so choose ObjectBehaviour:

Click OK. The class node now appears on the canvas:

3. Create a function
The + sign adds connection points (yellow dots) for functions, variables, states and more. Drag a connection point onto the canvas and release it to see the list of nodes you can connect.

Here you can also override functions of the ObjectBehaviour superclass, for example FixedUpdate, which runs at a fixed rate of about 50 times per second:

The FixedUpdate block is yellow, which marks it as a function:

Now call a method that prints text: Debug.Print(). Click on the canvas, search for debug and double click Print(string) of the Debug class:

The block looks like this:

Inputs are on the left side of a block, outputs on the right. The purple dot is a string input. You can either connect a string to it or type the text directly into the small box next to the dot:

4. Connect the execution flow
The print block does nothing until it is part of the execution flow, the white line between blocks. Execution starts at a function, follows the line and runs all blocks in order.

Drag the small white arrow of FixedUpdate onto the Debug.Print block. The hint add exec appears. Release it, and your first script is ready:

5. Attach the behaviour to an object
The new behaviour is now available in the Components tab of your object (here test-player):

Run the game and open the console with Tab. Under Lua Execute you see the output of Debug.Print, about 50 times per second, because it sits inside FixedUpdate.

6. Using function arguments
Now print the name of the object as well. The key is the this argument of the update function:

this refers to the object the behaviour is attached to. Drag this onto the canvas:

You now have access to all properties of the object. Drag the blue output dot onto the canvas and choose Name from the list:

The Name node has a purple output, so it delivers a string:

Connect it to a second Debug.Print block:

Finally connect both print blocks with the execution line so they run one after the other:

The console shows both lines:

The same script as code
class TestClassCode : ObjectBehaviour
{
override void FixedUpdate()
{
Debug.Print("Hello World! -Code Version-");
Debug.Print(this.Name);
}
}
The class has a different name, so you can switch between the block version and the code version in the components dropdown:

Example project: quickstart.veb (Dionous Games)
Three ways to use Ilios scripts
- As a component that gives an object, scene, character, button, interface or the game a behaviour
- As a static class with functions that every other script can use
- As a data type, a template for data that other scripts use
Script components
To attach a script to an entity, its class must inherit from the matching superclass:
| Entity | Superclass |
|---|---|
| Object | ObjectBehaviour |
| Scene | SceneBehaviour |
| Button | ButtonBehaviour |
| Interface | InterfaceBehaviour |
| Character | CharacterBehaviour |
| Game | GameBehaviour |
Components are instances: you can add the same script several times, and each instance keeps its own data. To use one from another script, you need a reference to that instance.
Visionaire calls certain functions of a component automatically, for example Awake and FixedUpdate. That is how your code connects to what happens in the game:
class PlayerMoveC : ObjectBehaviour
{
// called once before the first update
override void Awake()
{
// initialization code
}
// called at a fixed rate
override void FixedUpdate()
{
// code that updates the object
}
}
Something only happens if a component reacts to a trigger: input, a collision, a call from another script, or a regular call like FixedUpdate or Update.
Static classes
Static classes are not attached to anything. They exist once in the project, and every script can use them directly by their class name, without a reference. That makes them useful for helper functions that many scripts need.
Example: a helper class that calculates the distance between two points:
class MathUtils
{
// distance between two points
static float CalculateDistance(vec2 pointA, vec2 pointB)
{
float distance = vec2.Distance(pointB, pointA);
return distance;
}
}
Call it from anywhere like this:
MathUtils.CalculateDistance(new vec2(0,0), new vec2(3,4))
To test it, use the action part Run ilios script and print the result in the console:
Debug.Print(MathUtils.CalculateDistance(new vec2(0,0), new vec2(3,4)).ToString());
Debug.Print() only accepts strings, so .ToString() converts the float result first.
Custom data types
Scripts can also define your own data types: structs, plain classes, enums or interfaces. You use them throughout the game as a type of data or as a template, see Constructors below.
Variables and outlets
A simple example with two variables:
class Player : ObjectBehaviour
{
outlet float playerHealth;
outlet bool isDead;
void Damage(float dmg)
{
playerHealth -= dmg;
if(playerHealth < 0)
{
// the player has died
isDead = true;
}
}
void AddHealth(float health)
{
playerHealth += health;
if(playerHealth > 100)
{
// health is full
playerHealth = 100;
}
}
}
The keyword outlet shows the variable in the editor, so you can adjust its value there. Add the Player component to an object to see it:

Setting up the player's physics
Preparing the player
- Create the player object, for example test-player.
- Create an idle animation, add its frames and set it to infinite loops:

- Position the animation on the canvas, for now at (40,90):

- Set the idle animation as the default animation of the player:

When you run the game, the player appears with its idle animation. Because the pixel art is very small, these settings improve the display:
- Set the game resolution to 320 × 240 pixels.
- Enlarge the window with a script in the start action:

- Activate the pixel effect for crisp pixels:

Body and fixture
Visionaire uses Box2D for physics and adds it to objects through components. A working Box2D object needs a Body and a Fixture:

The body holds the properties you cannot see or touch:
- mass: how heavy it is
- velocity: how fast and in which direction it moves
- rotational inertia: how much effort it takes to start or stop spinning
- angular velocity: how fast and which way it rotates
- location: where it is
- angle: which way it faces
Add a body to the player:

Box2D knows three body types:
- dynamic: affected by forces and reacts to collisions, like our player
- static: not affected by forces and cannot be moved, like walls or the ground
- kinematic: moves with a set velocity but ignores forces, like a moving platform. When the original guide was written, Visionaire did not support this type yet.
Body settings:
- Static: leave it unticked, the player is a dynamic body.
- Fixed Rotation: prevents rotation, for example after a collision. The player needs this.
- Linear Damping: reduces the linear velocity.
- Angular Damping: reduces the angular velocity.
- Gravity Scale: weakens or strengthens gravity. 1 is normal gravity, -1 reverses it, 0 turns it off.
A body alone has no shape and cannot collide. Size, shape and material come from fixtures. A body can have several fixtures, and their arrangement affects its center of mass. When two bodies collide, their fixtures decide how they react. Fixture properties:
- sensor: a sensor detects collisions but does not react to them. The player is not a sensor.
- friction: how slippery it is
- restitution: how bouncy it is
- density: how heavy it is in relation to its area
- shape: polygon or circle
Visionaire offers three fixture shapes: rectangle, circle and edge (free form). For the player, choose the box:

The red rectangle is the collision border of the player. Run the game: the player falls off the screen because of gravity. So add the background image and a ground object with a static body and its own fixture:

Run the game again. The player now stands on the ground: your first collision works.
Example project: player-setup.zip (Dionous Games)
Constructors
A constructor is a special function that runs automatically when a new instance is created. It initializes the data of the new instance.
Create a new block and, in the code tab, a class for weapons with a constructor:
class Weapon : object // inherits from the object superclass
{
string wpnName;
int dmg;
float fRate;
// constructor, must have the same name as the class
Weapon(string weaponName, int damage, float fireRate)
{
this.wpnName = weaponName;
this.dmg = damage;
this.fRate = fireRate;
Debug.Print("Created ${this.wpnName} with Damage ${this.dmg} and Fire Rate ${this.fRate}");
}
}
- Such classes inherit from the internal
objectsuperclass. They describe data, not behaviour, so they cannot be attached to Visionaire entities. - The constructor has the same name as its class, here
Weapon. thisrefers to the instance that is being created.
The equivalent script in visual scripting (click to enlarge):

To create a constructor in the block editor, create a normal function block and choose Constructor:

Using the constructor
In this example the weapons are created once when the script loads, so they are created in Awake(). The script is attached to the player object, so its superclass is ObjectBehaviour:
class MainPlayer : ObjectBehaviour
{
override void Awake()
{
Weapon axe = new Weapon("Axe", 7, 3);
Weapon sword = new Weapon("Sword", 5, 4);
}
}
The same as blocks:

Run the project and open the console: both weapons are created.

Constructor overloading
A class can have several constructors with different signatures, that is, different parameters in the parentheses. Besides Weapon(string weaponName, int damage, float fireRate) you could add Weapon() without parameters and Weapon(string weaponName) with only a name. Then a weapon can be created in different ways, for example new Weapon("Spear") or new Weapon().
Example projects (Dionous Games): constructors.veb (blocks) and constructors-code.veb (code)
Next step: build a level for this player in the platformer tutorial with Tiled and Box2D.
More on constructors, destructors and static constructors is in the Ilios reference.