Below you’ll find a consolidateD and structured guide that will help you start building up your own game.

Have fun and be creative!

Have fun and be creative!

Introduction #

While Visionaire is a really powerful engine designed originally for 2D point ‘n click adventure games, it is possible since version 5 with the addition of Box2D and the Ilios scripting language to create different genre games, like physics-based platformers. So, welcome to the first Box2d/Ilios scripting tutorial for Visionaire! Let’s try to make a prototype platformer and see how this works 🙂


Some useful reference links: (Box2D) (Ilios)


Feel free to contact us for your comments, ideas and any assistance to your projects! As always, the community’s assistance is also there to help: (Forum) (Discord)

Yes No Suggest edit
0 of 0 users found this section helpful

Project File #

You may download the complete (so far) Visionaire project from here: Sunny Land Visionaire Prototype
Implemented: Character Movement (Keyboard)
  Collectibles (Gems)
Pending: Scrolling
Yes No Suggest edit
0 of 0 users found this section helpful

Prerequisities #

For this tutorial, we will use:


  • The Sunny Land pixel art asset pack which can be found here: . While it can be downloaded for free, we strongly encourage you to support the creator with a donation to allow them to create such nice assets!
  • Visionaire Studio + 


Please note that while programming knowledge is not critical, it is important in order to fully understand the concepts set out in this tutorial. An in-depth of these concepts will not be covered here.


Yes No Suggest edit
0 of 0 users found this section helpful

Setting up the Assets #

Add a Scene #

Currently tiling is not supported in Visionaire so we will use a set scene for the background which includes all layers. There is such an image in assets\PNG\environment\environment-preview.png:


Yes No Suggest edit
0 of 0 users found this section helpful

Add a Character #

Although it’s not necessary for the plaformer, Visionaire needs a character in order for the game to run, so let’s add one:



And ofcourse don’t forget to assign it as the active character in Game Properties:


Yes No Suggest edit
0 of 0 users found this section helpful

Adjust the Resolution #

The background we have defined above is 1456x464px but the view area will be much less, let’s set this to 320 x 240 under Game Properties.



On the same menu, make sure you activate the pixel effect to have a crispy look on the pixel art:



Important note! Depending on your monitor and desktop resolution, 320 x 240 might be quite small. There is a way though to change the resolution window at the game’s Start Action, for this tutorial we have used a 6x magnification factor:


Yes No Suggest edit
0 of 0 users found this section helpful

Action Areas #

Action areas are sections you can draw in and can be used to determine if the engine should perform some actions when the specified – or any – character walks into or out of the action area. You can consider them as triggers. A few example uses:


  • Changing footstep walking sound type
  • Triggering specific events
  • Changing between way systems if you needed to split the scene up into multiple way systems for some reason.


You can create one or more action areas in a scene similarly to Way Borders:



Next step is to draw the action areas. We have to create closed polygons, within which our actions will be triggered (or not)



Final step is to define the relevant actions to be triggered:



  1. Click on the action area you want to edit
  2. Add a new set of actions for this area.
  3. Enter a name for this set of actions.
  4. Set which character triggers the action area. You can also choose ‘any’ character.
  5. Set whether the action area will be triggered upon entering or exiting.
  6. Set whether this action area will be triggered only when the scene is shown or always.
  7. Add your action parts as always!


Action Area Event Handler


You may also register an event handler to listen out for any triggers:


function onActionArea(movement, actionArea, character)
  if movement == "ENTER" then
    -- do something
  elseif movement == "LEAVE" then
    -- do something else

registerEventHandler("actionArea", "onActionArea")

Tip: actionArea == ActionAreas[“example”] (ActionAreas is a table)

Yes No Suggest edit
0 of 0 users found this section helpful

Meanwhile Cutscenes #

There are a few possible ways to display a ‘Meanwhile’  message as per Lucasarts style. The easiest one:
    • Make a new scene with a black (or any other color you like) background.
    • When needed, use ‘Show scene/menu’ action part to show the black scene.
    • Use ‘Display narration text’ with your meanwhile message.


Another option would be to fade the scene brightness instead of using a black background, using the to() tweening function:


game.CurrentScene:to(500, {SceneBrightness = 0}, easeQuintOut) -- easing is optional
Yes No Suggest edit
0 of 0 users found this section helpful

Scrolling #

Visionaire offers scrolling effects for your scenes that are larger than the viewable area along with the possibility to adjust various settings.


Adjust the scroll speed


The basic setting for the scroll speed of your scenes (in pixels / sec) is done through Game Properties:



For a more dynamic adjustment, e.g. if you need to adjust this setting during gameplay, you can use lua as follows:


game.ScrollSpeed = 300 -- scroll by 300 pixels a second

Snap the scroll position of a scene


You can move the camera at any point (this will be top left corner of the camera view) of your current scene using the relevant action part:



or with Lua:


game.ScrollPosition = {x = 300, y = 200} -- important note: x, y is the top left corner of the scroll position!

You can also snap the camera position to a specific object with the relevant action part:



Wait until scrolling finishes


Sometimes you need to wait for scrolling to finish before letting some actions continue. You can achieve this by detecting if the position of game.ScrollPosition changed over the last frame in a main loop: (set as definition script)


local lastScrollPosX = 0

function scrolling()
  if lastScrollPosX ~= game.ScrollPosition.x then
    Conditions["scrolling"].Value = true  -- create a condition 'scrolling' somewhere
    lastScrollPosX = game.ScrollPosition.x
    Conditions["scrolling"].Value = false


You can now use the action part ‘Wait until ‘scrolling’ is false to control your actions flow.


Smooth Scrolling


To start the scrolling smoother (i.e. in the beginning and end of the scrolling), from the Game Properties:


Adjust scrolling triggering by the character


Visionaire uses bounding boxes at the scene edges to monitor when the character goes over them so that the scrolling can be started. These bounding boxes can be adjusted for both the horizontal and vertical axis using the relevant action parts:



Alternatively, with Lua:


game.HorizontalScrollDistance = 300  -- scroll on X axis when character is 300 pixels or less from scene edge (left or right)
game.VerticalScrollDistance = 150 -- scroll on Y axis when character is 150 pixels or less from scene edge (up or down)

For example, to keep the character always at the center of the screen when scrolling horizontally, you can use:


game.HorizontalScrollDistance = game.WindowResolution.x / 2 -- always using 50% of the current window width size

Scroll Scene with the Mouse


By default, you cannot make a scene scroll by hovering the mouse over its edges, but you can enable this in the scene’s properties:


Alternatively, with Lua:


game.CurrentScene.ScrollOnEdges = true

Using Lua, you can also adjust the bounding box size which will trigger the scroll when you hover the mouse over it:


game.CursorHorizontalScrollDistance = 50 -- scroll on X axis when cursor is 50 pixels or less from scene edge (left or right)
game.CursorVerticalScrollDistance = 200 -- scroll on Y axis when cursor is 200 pixels or less from scene edge (up or down)

Limit Scrollable Area


By default, a scene can be scrolled from edge to edge. You can limit this by defining a specific rectangle for the scrollable area:


game.CurrentScene.ScrollableArea = {0, 0, 1920, 1080} -- {x, y, width, height}

Parallax Scrolling


Apart from the scene’s background which always scrolls in the defined scrolling speed, you can set independent scrolling speed for objects to give a nice parallax scrolling effect. This can be applied to any scene object via its effects tab for both axis x and y:



100% will use the defined scene scroll speed while any value <100% will make it slower and 0% will stop it. You can also use Lua to adjust these:


Objects["table"].ScrollFactorX = 50
Objects["table"].ScrollFactorY = 100
Yes No Suggest edit
0 of 0 users found this section helpful

Curves #

There are 3 types of curves:


    • Curve
    • Continuous Curve
    • Curve via control points


Note: the first point of the curve is the starting point (also for the continuous curve)


With Tween Curves you can move a particle system (through an object) on a curve and rotate, or make non-linear animations like flying/swooping bird or wave motion etc.


Step 1 – Create a Curve in a specific scene. Each curve has an index: 1,2,3…


Example 1 – Move a Particle System (through an object)


Step 2.1 – Create a scene object & call it e.g. “moving”
Step 3.1 – Create a particle & link it to the scene object.


Now let’s write a tween loop to make it move around the curve we have created:


startCallBackTween(duration, function(position) --code-- end, easing, loop, pendulum)

duration: the time needed to complete 1 loop
loop: true = infinite loops, false = 1 loop only
pendulum: if loop = true, it will reverse direction each next loop

startCallbackTween(30000, function(x) -- starts loop function that lasts for x time
local pos = game.CurrentScene.Curves[3]:curveAt(x) -- gets current position of linked curve
local direction = game.CurrentScene.Curves[3]:curveDirection(x) - 1.57 -- gets the current direction based on position of curve in the curve
local p = graphics.getParticles(game.CurrentScene.Objects.moving) -- gets the particle belonging to the scene object ["moving"]
p.emissionDirection = {0.0, direction, 0.0, direction} -- updates the angle of the particle = {pos.x,pos.y} -- updates the position of the particle
end, easeLinearIn, true, false)

Example 2 (Move Animation)


startCallbackTween(30000, function(x)
local pos = game.CurrentScene.Curves[3]:curveAt(x)
local direction = game.CurrentScene.Curves[3]:curveDirection(x) - 1.57
ActiveAnimations["animation_name"].AnimationCurrentPosition = {x = pos.x, y = pos.y}
end, easeLinearIn, true, false)

You can create curves in each scene. ‘Curves’ is a linklist; you can access a specific curve in the list using the index, in the above example 3.


The curve object has 3 functions:

curveAt(x) -> position

curveDirection(x) -> degree (rad direction)

curveDerivative(x) -> vector pointing in the direction (tangent)


How to stop curve


If the function(x) returns false, then the startCallbackTween() will stop. Taking into consideration that if you exit a scene that has curves used for animation you will get an error as it will not be able to find the curve or the active animations anymore, use the following format:


startCallbackTween(duration, function(x)
if game.CurrentScene == Scenes["Scene that the curves/anims live"] then
-- do your stuff
else return false end -- it will kill the loop in any other scene (returns false)
end, easeLinearIn, true, false)
Yes No Suggest edit
0 of 0 users found this section helpful

Lightmaps #

Lightmaps allow characters and objects to change brightness or tinting depending on where they are located in the scene so that they follow the light sources in the scene.


Lightmaps maps work based on character / object positions in the scene. Basically the engine:


    1. Checks if a lightmap is assigned to the scene.
    2. Checks the position of the character or object against the lightmap.
    3. Tints the character or object based on the color found at the pixel coordinates of where the character or object is.




    • The entire character or object is tinted.
    • Lightmaps only affect the tint of the characters or objects. If you want one to affect the entire scene you could add them as images inside of scene objects.
    • It’s advisable to add feathering as it allows the character or the object tint to smoothly change from one tint to another.


Especially for objects, you can control which objects will be affected by the lightmap and which not:


Objects["apple"].LightmapAffected = true

Lightmaps are the easiest way to apply tinting, nevertheless you can also use Lua:


Characters["Dragon"].Tint = 0xFF0000 -- format used by Visionaire is 0xBGR (BBGGRR) so this will tint the character blue

Alternatively you could use shaders to directly apply lighting to your scenes which would affect things in a more dynamic way.

Yes No Suggest edit
0 of 0 users found this section helpful

Earthquake Effect #

A nice built in effect to use in your game is the earthquake effect, to simulate such events in your game. You may do so with the ‘Start/Stop earthquake’ action part:



You can control how intense and fast the motion will be. Alternatively, you can use Lua to have even more control, as you have the option to define different forces at x,y axes respectively:


game.Quake = true -- true to start the earthquake, false to stop it
game.QuakeForceX = 0 -- force at x axis
game.QuakeForceY = 5 -- force at y axis
game.QuakeSpeed = 5 -- speed
Yes No Suggest edit
0 of 0 users found this section helpful

Objects #

Get the VS object name (left column of objects in scene)


game.CurrentObject:getName() -- For object under cursor

game.SavedObject:getName() -- For saved object

game.UsedItem:getName() -- For the item at hand

Get the object name as it appears in game.




Change the name of the object as it appears in game.


game.CurrentScene.Objects["obj"]:setTextStr(VObjectName, "string")

Note: if you want to change it in all languages you need to do a for loop through all languages.

Check if a string value is not empty (zero length)


string.len(game.CurrentObject:getTextStr(VObjectName)) ~= 0

How to clear/unlink an object value?


Using the ‘emptyObject’, e.g.:

Characters["Tom"].FollowCharacter = emptyObject

Item at hand


The currently used item, either with the ‘Set item’ action part or dragged item:


Hide an Object


Objects["bottle"].Visibility = 0

Note: it hides only the image, not the interaction polygon.


Get the Sprite position of an object


Objects["name"].Sprite.Sprite -- holds a table with information about the sprite path, position , etc

Get the position of the sprite


Objects["name"].Sprite.Sprite:getPosition().y -- for the y-axis position

Move or Check if an object has moved to another position (x,y)


Yes No Suggest edit
0 of 0 users found this section helpful

Object Areas #

All the object areas are made of polygons which are defined by points. Practically polygons are a collection of points which are joined together. An object can have multiple polygons.


You can also access the points of an object’s polygon with Lua:


for i = 1, #Objects["big-door"].Polygon do


Yes No Suggest edit
0 of 0 users found this section helpful

Duplicate Objects #

You can create a new object from an existing one:


local obj = game.CurrentScene.Objects.["table"]:duplicate("duplTable") -- duplicate object is created and then stored into a variable

You can delete this new object with:




Yes No Suggest edit
0 of 0 users found this section helpful

Setting up a Menu #

Checking if a scene is a menu


Yes No Suggest edit
0 of 0 users found this section helpful

New Game Button #

The best way for having a new game functionality is to create an autosave the first time you launch a new game (e.g. just before your intro starts). Then every time you click the ‘New Button’ you can query if the autosave exists, if it does then load that; if it doesn’t then create it. Note: You have to be on a regular scene not a menu scene type for autosave to work. As a good practice, use autosave #1 only for your new game functionality.


So for example in your New Game button add the following actions:


If autosave #1 exists
  Load autosave #1
  Show scene 'Intro'
Εnd if

Now when your intro starts, at the beginning of scene just include at the very top:


If condition '1st-play' is true
  Change condition '1st-play' to false
  Pause for 1 second
  Execute autosave 
End if

Above we have created the ‘1st-play’ condition which is true by default because we want to create the autosave at the very first play. Note also that we added 1 second pause before executing the autosave to allow the scene to fully load first.


You could also try using the Lua replaceGame() function when you click on the ‘New Button’  but it restarts the game from the very beginning like you have just launched it.



Replace “data” with whatever you called the vis file when you export/compile the game. For testing via Visionaire Studio editor just enter your project’s ved or veb file instead.


Also note that old save files cause conflict issues when you have added new content/data to your game since it was created. While you are working on your game it is a good practice to check if an autosave exists and delete it. This will generate a fresh autosave each time you launch the game.


If autosave #1 exists
 Delete autosave #1
End if
Yes No Suggest edit
0 of 0 users found this section helpful

Save / Load Menu #

Characters #

Positioning of a character in a scene


To position the character above an object in a scene, you must set a YChar in the scene as follows:


YChar > YObjCenter [r], where YChar = YChar Actual + YAnim Center


So you basically need to set the YAnimCenter = YChar – YCharActual


Example: I want to place a character with YActual = 344 above an object with YAnim Center = 650, therefore I set YChar = 651, which means than i have to change YAnimCenter  = 651 – 344 = 307


To be able to work with characters, the first thing to do is to retrieve their object and store it in a variable.


Get current character object


local cisco = game:getLink(VGameCurrentCharacter)

Get any character object


local kosmos = getObject("Characters[kosmos]")

Now, you can do anything with your character.


Get the position (x,y) of a character


local pos = cisco:getPoint(VCharacterPosition)

Set the position (x,y) of a character


kosmos:setValue(VCharacterPosition, {x = pos.x, y = pos.y})

Get the Direction of a character


local direction = cisco:getInt(VCharacterDirection)

Set the Direction of a character


cisco:setValue(VCharacterDirection, 0)
Characters["Cisco"].Direction = 0 --shorthand 
game.CurrentCharacter.Direction = 0 -- for current character

Note: 0 = right, 90 = top, 180 = left, 270 = bottom


Hide/Show a character


Characters["cisco"].CharacterActive = false / true

Set the size of a character


Characters["unicorn"].Size = 50 -- in %

Disable character scaling


Characters["franco"].Size = 100 -- First set him to 100%

Characters["franco"].CharacterScale = false

Disable Interaction during animation state of the current Character


You can do this from the game properties but it is possible with lua also


game.DisableInteractionDuringAnim = eDisableInteractionAlways

Possible options:


    • eDisableInteractionAlways 2
    • eDisableInteractionCharacterAnim 1
    • eDisableInteractionNever 0


Get the animation state of a Char


You can actually listen to the animation state of a char by using the following



Where AnimState can be:


eCharacterAnim 4

eStandingAnim 3

eTalkAnim 2

eWalkAnim 1

eNoAnim 0

eRandomAnim 5




if Characters["grocery-elf"].AnimState == 2 -- (or == eTalkAnim) then 
  -- do something

So for example, you want to check when a character is talking, possible options:


    • Use a mainLoop to listen out for animation state change.
    • textStarted & texts linked to characters
    • Insert a play animation action part into the first frame of each of your talk animations. There is also a ‘Wait until a character stops speaking’ action part.
    • Use the action part hook:


local SHOW_TEXT = 23

system.registerActionPartHook(SHOW_TEXT, "charTalk")

function charTalk(actionPart)
  if actionPart.Link:getName() == "Tom" then
    -- do something

Prevent Character from Moving


game.LeftClickBehaviour = eMouseActionBehaviourDoNotSendCharacter -- Disable left click from updating/setting destination

game.LeftClickBehaviour = eMouseActionBehaviourSendCharacterToCursor -- Enable left click update/set destination

Character talking and walking


Switch to an outfit where the character’s face/mouth isn’t drawn on. Create a secondary character that has the same canvas height &amp; character center position as the actual character but only contains the face/mouth. Use a script to make sure that the position &amp; alignment of the actual and the secondary characters match. Secondary character to do the talking.


Alternative Option (no lip sync is possible in this case though)


Switch to an outfit where the character also includes a talk animation with the walk animations. Set the spoken text as background (text can move with moving char)


Access current character animation



Empty the inventory of a character

Yes No Suggest edit
0 of 0 users found this section helpful

Character Texts #

You can control what happens when a character text starts or stops by registering textStarted / textStopped event handlers:


function txtStart(text) -- this function handles actions when the char text starts
  local owner = text:getLink(VTextOwner)
  if owner:getId().tableId == eCharacters and owner:getName() == 'cisco' then
    -- start any actions here

function txtEnd(text) -- this function handles actions when the char text finishes
  local owner = text:getLink(VTextOwner)
  if owner:getId().tableId == eCharacters and owner:getName() == 'cisco' then
    -- start any actions here

-- * initialize text event handlers * --
registerEventHandler("textStarted", "txtStart")
registerEventHandler("textStopped", "txtEnd")

Getting the text position of the character talking:


Yes No Suggest edit
0 of 0 users found this section helpful

Dialogs #

Start a dialog or a dialog layer


Use the relevant ‘Start dialog/dialog-layer’ action part.



To start a dialog from the beginning (i.e. 1st layer or super layer), choose one under ‘Characters’



You can also start a specific dialog layer/part (these are the ones that have children dialogue options) by choosing ‘Dialog Parts’.



Use a Dialog Part only once


You can have a dialog part to be selected only one time and then to be removed:



The limitation to the above is that you can only delete the dialog part being selected at a time. If you want to delete a dialog part from any other place, you need to do it with LUA, e.g.:


Characters["townhall-elf-right"].Dialogs.townhall.DialogParts[4].DialogPartAvailable = false -- this will remove the dialog part with ID 4

Access Dialog Parts


You can loop through the dialog if you want; you can access them by directly by name:



Generally, if you have unique texts/naming you can search them directly:



or via table/Array number:



Checking for availability:


Characters[1].Dialogs[1].DialogParts[1].Available == true

Disable a dialog option


Sometimes you want to disable a dialog option and not delete it, e.g. for testing. Just set False to an empty condition:


Switch to 1st dialog level


The dialog options allow you to switch to the previous dialog level but not the first one. To achieve this, just use the execute action and restart the dialog by adding a Start Dialog action part.


Greyed-out Dialog Options


It is possible to make dialog options that have already been chosen/used by the player to stand out, e.g. greyed-out etc. You can have different active/inactive fonts for these but adjusting the relevant option under Character’s Properties Tab:



You can also change the status of a dialog option to used or not with Lua (useful when you want to have full control over this, e.g. in nested or quit dialog options):


DialogParts["10. I'm going back to bed now."].Used = false // it will reset this back to non-used option

More Control over the Selection of Dialog Parts

With Lua you have some more control over which dialog parts can be selected which might be useful for example when you want to control this with keyboard or gamepad:


system.dialogScrollPosition = 0 -- it detects/sets the scroll position of the dialog
system.dialogActiveOption = 0 -- it detects/sets the currently hovered dialog option
system.dialogSelect() -- it selects the current dialogActiveOption (so make sure you set system.dialogActiveOption first)
Yes No Suggest edit
0 of 0 users found this section helpful

Outfits #

Query the Outfit of a Character


if game.CurrentCharacter.CurrentOutfit == Outfits["sad"] then ... end

if Characters["potion-man"].CurrentOutfit == Outfits["tied"] then ... end

Play a Character Animation




Set Character Speed


game.CurrentCharacter.CurrentOutfit.OutfitCharacterSpeed = 400

Random Animations


Played whenever a character is idle (i.e. doesn’t move and no animation is played) for a certain period (between 10 and 30 seconds). The animation, which is going to be played, is chosen by chance. Note: Random animations do not play also when there is text displayed on screen and a dialog is active.


You can change above times with Lua:


Characters["cisco"].CurrentOutfit.RandomMinTime = 1500 
Characters["cisco"].Outfits["Surprised"].RandomMinTime = 1500 -- choose a specific outfit

-- Changing the random times for all character's outfits

for i = 1, #Characters["cisco"].Outfits do
 Characters["cisco"].Outfits[i].RandomMinTime = 1500
 Characters["cisco"].Outfits[i].RandomMaxTime = 5000
Yes No Suggest edit
0 of 0 users found this section helpful

Spine Animations #

Spine is a great tool to create 2D Skeletal animations. You can actually import your Spine animations into Visionaire and use them in your game.


You can try importing Spine’s standard example, called ‘spineboy’ into Visionaire to play around:


    • Download the spineboy zip from here.
    • Open it in spine, go to export and extract the spineboy.atlas, spineboy.png and spineboy-ess.json to a subdirectory of your project.
    • Rename the spineboy-ess.json to spineboy.json, the names need to match.
    • Add the spineboy.json to the Spine files of an outfit.
    • Click on one animation and on the cog wheel select an animation on the right (if the right one seems selected you need to reselect it). It should now be shown in the preview.
Yes No Suggest edit
0 of 0 users found this section helpful

3D Character Models #

Using 3D character models is beneficial in many cases as it could save time from designing all character’s animation frames. Visionaire will use the 3D model to display the character in the proper angle automatically.


Note: This guide was made using Blender 2.91.0. You can also download a ready .blend model for testing from here (check video description).


Exporting from Blender


Before you export your character model, it’s suggested to rename your animations in Blender’s Outliner panel to help you assign them to the character after importing to Visionaire:



Under File -> Export -> Collada (Default) (.dae)


From the settings, you only need to adjust the axis orientation to match Visionaire orientation system, as follows:



Finally click EXPORT COLLADA button. This will create your .dae model file. If your model uses textures, the separate file for the texture will also be exported.


Importing to Visionaire


Under your character’s outfit, load the file and adjust any other settings as you wish:



Then, create a new animation under each section (walk /standing / talk etc) – you don’t have to create one for each direction, that’s the good thing with 3d models! – and then select the animation to be played (the name we set in Blender before) and adjust the speed (1 = the normal anim speed)



Now you can assign your character in the scene as you would do normally.

Yes No Suggest edit
0 of 0 users found this section helpful

Lip Sync #

Rhubarb is a Lip Sync software that is supported by Visionaire. Download it from here. It generates single files from a .wav file in “tsv” format. Basically text files with start time -> phoneme.