Difference between revisions of "Scripting"

From The Official Visionaire Studio: Adventure Game Engine Wiki
(Visionaire Object Model)
 
(71 intermediate revisions by 4 users not shown)
Line 1: Line 1:
== General ==
+
Visionaire Studio comes with its own scripting language, which consists of, a combination of: '''Lua script''' and a '''Visionaire object model'''. The object model is used to access the Visionaire data structure in a convenient way. Almost every instance in Visionaire is represented as an object (e. g. scene, character, interface, ...), all of which can be accessed/manipulated through the scripting language.
  
Visionaire 3.0 comes with a Scripting language which is a combination of Lua (http://www.lua.org) and a Visionaire Object Model. The object model is used to access the Visionaire data structure in a convenient way. Almost every instance in Visionaire is represented as an object (e.g. scene, character, interface, ...) which can be manipulated through the scripting language.<br>
 
  
Online documentation about scripting Language:
+
== Lua ==
* Programming in Lua: http://www.lua.org/pil/index.html
+
Visionaire Studio currently uses Lua version 5.4.0.
* Reference Manual: http://www.lua.org/manual/5.1/
 
  
== Visionaire Object Model ==
+
If you want to learn more about the language, you may refer to the official online documentation on the Lua website or have a look at some tutorials:
 +
<div style="float:right;margin:20px 0 30px 30px">[[File:Lua-logo.png]]</div>
 +
* Reference Manual: https://www.lua.org/manual/5.4/
 +
* Programming in Lua: https://www.lua.org/start.html
 +
* Lua tutorial: https://www.tutorialspoint.com/lua/index.htm
 +
* Learn Lua in 15 Minutes: https://tylerneylon.com/a/learn-lua/
  
All objects can be accessed and manipulated through the scripting language. All objects of the same type (e.g. scene or button) are stored in one table. The properties of an object can be accessed by defined fields for the specific table. All objects and its fields are documented in [[Data_Structure|Visionaire Data Structure]].
 
  
The field types of the data structure are mapped to Lua types in the following way:
+
Our community member ''AFRLme'' wrote a basic Lua introduction which you can find in this wiki:
 
+
* [[Basic_lua:_Index|Basic Lua: AFRLme's guide to Lua script]]
{| class="ts"
 
|-
 
! style="text-align:left" | Field Type
 
! style="text-align:left;width:80%" | Description
 
|-
 
|-
 
| valign="top" |
 
t_link
 
| valign="top" |
 
userdata ([[#VisionaireObject|VisionaireObject]]) or string which describes the object path. See [[#Accessing_an_object|object access]] for description of the object path.
 
|-
 
| valign="top" |
 
t_links
 
| valign="top" |
 
table (array) with Visionaire Objects (userdata or string, see t_link above) entries, each entry referencing one Visionaire Object.
 
|-
 
| valign="top" |
 
t_int
 
| valign="top" |
 
number (integer)
 
|-
 
| valign="top" |
 
t_float
 
| valign="top" |
 
number
 
|-
 
| valign="top" |
 
t_bool
 
| valign="top" |
 
boolean
 
|-
 
| valign="top" |
 
t_point
 
| valign="top" |
 
table (with entries "x" and "y")
 
|-
 
| valign="top" |
 
t_rect
 
| valign="top" |
 
table (with entries "x", "y", "width" and "height")
 
|-
 
| valign="top" |
 
t_string
 
| valign="top" |
 
string
 
|-
 
| valign="top" |
 
t_text
 
| valign="top" |
 
table with entries "text", "sound" (relative path to sound file for speech output) and "language" (language id).
 
|-
 
| valign="top" |
 
t_path
 
| valign="top" |
 
string
 
|-
 
| valign="top" |
 
t_sprite
 
| valign="top" |
 
table (with entry "path" and optional entries "x", "y", "cutting" (t_rect) and "transparent" (t_point))
 
|-
 
| valign="top" |
 
t_vint
 
| valign="top" |
 
table with number (integer) entries
 
|-
 
| valign="top" |
 
t_vfloat
 
| valign="top" |
 
table with number (float) entries
 
|-
 
| valign="top" |
 
t_vpoint
 
| valign="top" |
 
table with t_point entries
 
|-
 
| valign="top" |
 
t_vrect
 
| valign="top" |
 
table with t_rect entries
 
|-
 
| valign="top" |
 
t_vstring
 
| valign="top" |
 
table with string entries
 
|-
 
| valign="top" |
 
t_vtext
 
| valign="top" |
 
table with t_text entries
 
|-
 
| valign="top" |
 
t_vpath
 
| valign="top" |
 
table with t_path entries
 
|-
 
| valign="top" |
 
t_vsprite
 
| valign="top" |
 
table with t_sprite entries
 
|}
 
  
== Exported objects ==
 
  
The following objects are exported to the Lua scripting environment:
+
== Visionaire object model ==
* currentAction: a visionaire object which represents the action where the current script was called from.
 
* emptyObject: an empty visionaire object.
 
* game: the game object. This is the same as calling getObject("Game") but faster and easier to use.
 
  
== Exported constants ==
+
Each Visionaire project is saved in a hierarchical [[Data_Structure|data structure]]. Every instance of an object of that data structure is a "VisionaireObject" (TVisObj). All objects of the same type (e.&nbsp;g. scene or button) are stored in one table (called e.&nbsp;g. "Scenes" or "Buttons").
  
The following contants are exported to the Lua scripting environment:
+
The properties of an object can be accessed by defined fields for the specific table. These fields can contain single values (e.&nbsp;g. integers, strings) or tables of values as well as links to other VisionaireObjects or tables of links to VisionaireObjects. All objects and their fields are documented on the [[Data_Structure|data structure]] page. The different [[#Field types|field types]] are listed below.
* all fields which are used to reference attributes of visionaire objects. The fields are all listed in the [[Data Structure|Visionaire Data Structure]] documentation. To reference a field use a 'V' and the field name. E.g. VDialogPartAvailable to reference the field DialogPartAvailable.
 
* all visionaire tables. These constants start with an 'e' and then the plural table name. E.g. for the table Action the constant is eActions.
 
* DIVIDING_POINT: a table with entries '''x''' and '''y''' which specifies a point which is used to separate multiple polygons. Usually a point list (t_vpoint field) can contain multiple polygons (e.g. ObjectPolygon which is used for the object boundaries). In this point list a point which is equal to DIVIDING_POINT marks the end of the current polygon.
 
* localAppDir: directory where the savegames (in the sub directory savegames), the messages.log file and possible dumps are written to. This directory is also used for the config.ini in case the project file is given as command line parameter for the player.
 
  
== VisionaireObject ==
 
  
Every instance of an object of the visionaire data structure is a VisionaireObject. With this object it is possible to read and manipulate the attributes of all objects.
+
=== Accessing objects and fields ===
  
The following methods are supported on a VisionaireObject (in alphabetical order):
+
The data structure tables are globally accessible. Object instances within the tables are usually accessed by their name, but it is also possible to use the table index. The "game" object is not contained in a table but directly accessible.
 +
<syntaxhighlight lang="lua">
 +
-- Examples of accessing a VisionaireObject by (a unique) name
 +
local char = Characters["hero"]
 +
local coins = Values["coins"]
  
=== clearLink ===
+
-- The following syntax is also possible, but be aware that it only works for object names which don't contain
 +
-- special characters or whitespaces (only A-Z, a-z, 0-9 and underscore allowed) and start with a letter
 +
local char = Characters.hero
  
Removes a link from the visionaire object. This is only a convenient method and has the same effect as calling setValue with emptyObject as value.
+
-- Access a VisionaireObject by table index: get the first object in the "Characters" table
 
+
local char = Characters[1]
Lua Syntax:
+
</syntaxhighlight>
<syntaxhighlight>clearLink(number)</syntaxhighlight>
 
*Arguments
 
;number
 
The field which specifies a link to be cleared. The field type must be t_link.
 
 
 
=== getBool ===
 
 
 
Lua Syntax:
 
<syntaxhighlight>getBool(number)</syntaxhighlight>
 
*Arguments
 
;number
 
The field which specifies a boolean value. The field type must be t_bool.
 
*Return Values
 
;boolean
 
Current value of specified field.
 
 
 
Example:
 
<syntaxhighlight>local allowSkipText = game:getBool(VGameAlwaysAllowSkipText)</syntaxhighlight>
 
 
 
=== getFloat ===
 
  
Lua Syntax:
 
<syntaxhighlight>getFloat(number)</syntaxhighlight>
 
*Arguments
 
;number
 
The field which specifies a number value. The field type must be t_float.
 
*Return Values
 
;number
 
Current value of specified field.
 
  
=== getFloats ===
+
Object properties are accessed through their fields:
 +
<syntaxhighlight lang="lua">
 +
-- Example of accessing a property of a VisionaireObject
 +
local char = Characters["hero"]
 +
local pos = char.Position
  
Lua Syntax:
+
-- This leads to the same result
<syntaxhighlight>getFloats(number)</syntaxhighlight>
+
local pos = Characters["hero"].Position
*Arguments
 
;number
 
The field which specifies a number list. The field type must be t_vfloat.
 
*Return Values
 
;table
 
Table with t_float entries representing the specified field.
 
  
=== getId ===
+
-- Get the integer value ("Int" field) of the "Value" object called "coins"
 +
local num_coins = Values["coins"].Int
  
Lua Syntax:
+
-- The "game" object is directly accessible
<syntaxhighlight>getId()</syntaxhighlight>
+
local scr_pos = game.ScrollPosition
* Return Values
 
;table
 
A table with the fields '''tableId''' and '''id''' returning the table id and object id of the VisionaireObject.
 
 
 
Example:
 
<syntaxhighlight>
 
-- writes to the log file if the animation with the name 'animname' (must be set before)
 
-- is a character animation
 
local anim = getObject("Animations[" .. animname .. "]")
 
if anim:getParent():getId().tableId == eOutfits then
 
  print(animname .. " is a character animation")
 
else
 
  print(animname .. " is not a character animation")
 
end
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== getInt ===
 
 
Lua Syntax:
 
<syntaxhighlight>getInt(number)</syntaxhighlight>
 
*Arguments
 
;number
 
The field which specifies a number value. The field type must be t_int.
 
*Return Values
 
;number
 
Current value of specified field.
 
 
Example:
 
<syntaxhighlight>local direction = getObject("Characters[Mother]"):getInt(VCharacterDirection)</syntaxhighlight>
 
 
=== getInts ===
 
 
Lua Syntax:
 
<syntaxhighlight>getInts(number)</syntaxhighlight>
 
*Arguments
 
;number
 
The field which specifies a number list. The field type must be t_vint.
 
*Return Values
 
;table
 
Table with t_int entries representing the specified field.
 
 
=== getLink ===
 
 
Lua Syntax:
 
<syntaxhighlight>getLink(number)</syntaxhighlight>
 
*Arguments
 
;number
 
The field which specifies a link. The field type must be t_link.
 
*Return Values
 
;userdata (VisionaireObject)
 
The linked object or an empty object if no object is linked for this field.
 
  
=== getLinks ===
+
If other VisionaireObjects are linked in an object property, you can specify the complete object path to access them. This is especially helpful, if you have non-unique object names which cannot be accessed purely by their name:
 +
<syntaxhighlight lang="lua">
 +
-- Let's say each character has a value property called "coins"; it is not possible to use 'Values["coins"]'
 +
-- because the name is not unique; now access the different values by using the object path
 +
local hero_num_coins = Characters["hero"].Values["coins"].Int
 +
local villain_num_coins = Characters["villain"].Values["coins"].Int
 +
local cur_num_coins = game.CurrentCharacter.Values["coins"].Int
  
Lua Syntax:
+
-- Object paths can be even longer
<syntaxhighlight>getLinks(number)</syntaxhighlight>
+
local door_state = Scenes["kitchen"].Objects["door"].Conditions["door_closed"]
*Arguments
 
;number
 
The field which specifies a link list. The field type must be t_links.
 
*Return Values
 
;table (list of VisionaireObject)
 
Table containing all linked visionaire objects.
 
  
=== getName ===
+
-- If the condition name "door_closed" is unique in the project, the following leads to the same result
 
+
local door_state = Conditions["door_closed"]
Lua Syntax:
 
<syntaxhighlight>getName()</syntaxhighlight>
 
* Return Values
 
;string
 
The internal name of the visionaire object. This is the name which is used to access the object and also shown in the editor. This name is not shown to the user in the game - therefor always a language dependent text is used.
 
 
 
=== getObject ===
 
 
 
Lua Syntax:
 
<syntaxhighlight>getObject(string)</syntaxhighlight>
 
* Arguments
 
;string
 
Path to a Visionaire Object. The path has to start with a dot '.' and then a field name (field type must either be t_link or t_links). For t_links fields you must specify an object name in brackets ('[',']'). For t_link fields there are no brackets. The path is relative to this object. See [[Scripting#Accessing_an_object|object access]] for description of the object path.
 
* Return Values
 
;userdata (VisionaireObject)
 
The found visionaire object or an empty object if no object was found.
 
Example:
 
<syntaxhighlight>
 
local scene = getObject("Scenes[Bedroom]")
 
local deskCond = scene:getObject(".SceneObjects[Desk].ObjectCondition")
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== getParent ===
 
 
Lua Syntax:
 
<syntaxhighlight>getParent()</syntaxhighlight>
 
* Return Values
 
;VisionaireObject
 
The parent object for this object. An object has always a parent which contains it - only the game object has no parent.
 
 
=== getPath ===
 
 
Lua Syntax:
 
<syntaxhighlight>getPath(number)</syntaxhighlight>
 
*Arguments
 
;number
 
The field which specifies a path value. The field type must be t_path.
 
*Return Values
 
;string
 
Current value of specified field. The path will be returned in unix format ('/' for directories) and relative to the .ved file.
 
 
=== getPaths ===
 
  
Lua Syntax:
+
Writing a field value is just as easy. However, not all fields of the data structure can be changed through script. Please refer to the [[Data_Structure|data structure]] page:
<syntaxhighlight>getPaths(number)</syntaxhighlight>
+
<syntaxhighlight lang="lua">
*Arguments
+
-- Lower the brightness of a scene to 80%
;number
+
Scenes["kitchen"].Brightness = 80
The field which specifies a path list. The field type must be t_vpath.
 
*Return Values
 
;table
 
Table with t_path entries representing the specified field.
 
  
=== getPoint ===
+
-- Make the villain the playable character
 +
game.CurrentCharacter = Characters["villain"]
  
Lua Syntax:
+
-- Set a condition to true
<syntaxhighlight>getPoint(number)</syntaxhighlight>
+
Conditions["door_closed"].Value = true
*Arguments
 
;number
 
The field which specifies a point value. The field type must be t_point.
 
*Return Values
 
;table
 
A table representing the value of the specified field. The table contains the entries '''x''' and '''y'''.
 
  
=== getPoints ===
+
-- Change the integer value of a "Value" object
 
+
Characters["hero"].Values["coins"].Int = 47
Lua Syntax:
 
<syntaxhighlight>getPoints(number)</syntaxhighlight><br/>
 
*Arguments
 
;number
 
The field which specifies a point list. The field type must be t_vpoint.
 
*Return Values
 
;table
 
Table with t_point entries representing the specified field.
 
 
 
Example:
 
<syntaxhighlight>
 
-- let's get the x, y position of an animation ...
 
getAnimPos = getObject("ActiveAnimations[anim_name]"):getPoints(VAnimationCurrentPosition)
 
 
 
-- let's print it to the log file!
 
print("current position of x=" .. getAnimPos.x)
 
print("current position of y=" .. getAnimPos.y)
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== getRect ===
 
  
Lua Syntax:
+
=== Common VisionaireObject fields ===
<syntaxhighlight>getRect(number)</syntaxhighlight>
 
*Arguments
 
;number
 
The field which specifies a rectangle value. The field type must be t_rect.
 
*Return Values
 
;table
 
A table representing the value of the specified field. The table contains the entries '''x''', '''y''', '''width''' and '''height'''.
 
  
=== getRects ===
+
The following fields are available for all VisionaireObjects. They are read-only (except "name" which can be written with the "setName" method):
 +
* <span class="inlinecode">id:</span> The internal id of the object (integer).
 +
* <span class="inlinecode">name:</span> The internal name of the object as defined in the editor (string). Not to be confused with the "Name" property (with capitalized "N") which is available for some objects and contains the multi-language object name used in the game.
 +
* <span class="inlinecode">parent:</span> Returns the parent object (TVisObj).
 +
* <span class="inlinecode">tableId:</span> The id of the data structure table the object is part of (integer).
  
Lua Syntax:
 
<syntaxhighlight>getRects(number)</syntaxhighlight>
 
*Arguments
 
;number
 
The field which specifies a rectangle list. The field type must be t_vrect.
 
*Return Values
 
;table (list of table with '''x''', '''y''', '''width''' and '''height''' entries)
 
Table with t_rect entries representing the specified field.
 
  
=== getSprite ===
+
=== Field types ===
  
Lua Syntax:
+
The field types of the data structure are mapped to Lua types in the following way:
<syntaxhighlight>getStr(number)</syntaxhighlight>
 
*Arguments
 
;number
 
The field which specifies a sprite value. The field type must be t_sprite.
 
*Return Values
 
;table
 
A table representing the value of the specified field. The table contains the entries '''path''', '''x''', '''y''', '''cutting''' (t_rect) and '''transparency'''.
 
  
=== getSprites ===
+
{| class="ts"
 
+
|-
Lua Syntax:
+
! style="width:10%" | Field Type
<syntaxhighlight>getSprites(number)</syntaxhighlight>
+
! style="width:5%" colspan="2" | Lua type/Structure
*Arguments
+
! Description
;number
+
|-
The field which specifies a sprite list. The field type must be t_vsprite.
+
| '''t_bool'''
*Return Values
+
| colspan="2" | boolean
;table
+
| true or false
Table with t_sprite entries representing the specified field.
+
|-
 
+
| '''t_int'''
=== getStr ===
+
| colspan="2" | number
 
+
| integer
Lua Syntax:
+
|-
<syntaxhighlight>getStr(number)</syntaxhighlight>
+
| '''t_float'''
*Arguments
+
| colspan="2" | number
;number
+
| decimal
The field which specifies a string value. The field type must be t_string.
+
|-
*Return Values
+
| '''t_string'''
;string
+
| colspan="2" | string
Current value of specified field.
+
|
 
+
|-
=== getTexts ===
+
| '''t_path'''
 
+
| colspan="2" | string
Lua Syntax:
+
| file path
<pre>getTexts(number)</pre>
+
|-
*Arguments
+
| rowspan="2" | '''t_point'''
;number
+
| rowspan="2" | table
The field which specifies a text languages value. The field type must be t_vtext.
+
| style="width:15%" | x (int)
*Return Values
+
| x coordinate
;table
+
|-
Table with t_text entries representing the specified field.
+
| y (int)
 
+
| y coordinate
=== getTextStr ===
+
|-
 
+
| rowspan="4" | '''t_rect'''
Lua Syntax:
+
| rowspan="4" | table
<pre>getTextStr(number, <languageId>)</pre>
+
| x (int)
*Arguments
+
| x coordinate of top left corner
;number
+
|-
The field which specifies a text languages value. The field type must be t_link to Text.
+
| y (int)
;languageId (optional)
+
| y coordinate of top left corner
The text will be returned for the language with this id. If parameter is missing then the text will be returned in the currently active language.
+
|-
*Return Values
+
| width (int)
;string
+
| width of rectangle
Text string in given language.
+
|-
* Example:
+
| height (int)
local button = getObject("Buttons[Talk]")
+
| height of rectangle
local langEn = getObject("Languages[English]")
+
|-
local langDe = getObject("Languages[German]")
+
| rowspan="5" | '''t_sprite'''
-- print name of talk command in current language
+
| rowspan="5" | table
print(button:getTextStr(VButtonName))
+
| path (str)
-- print English name of talk command
+
| relative path to image file
print(button:getTextStr(VButtonName, langEn:getId().id))
+
|-
-- print German name of talk command
+
| position (t_point)
print(button:getTextStr(VButtonName, langDe:getId().id))
+
| sprite offset in case sprite is used in an animation
 
+
|-
=== isAnyObject ===
+
| transparency (int)
 
+
|
Lua Syntax:
+
|-
<syntaxhighlight>isAnyObject()</syntaxhighlight>
+
| transpcolor (int)
* Return Values
+
| transparent color
;boolean
+
|-
true if the object represents any object (isEmpty would return true because the object does not represent an object of the data structure). This is needed for actions where the user can set "[Any item]" for actions which should be executed in case an item was used.
+
| pause (int)
 
+
| pause value in milliseconds in case sprite is used in an animation
=== isEmpty ===
+
|-
 
+
| rowspan="3" | '''t_text'''
Lua Syntax:
+
| rowspan="3" | table
<syntaxhighlight>isEmpty()</syntaxhighlight>
+
| text (str)
* Return Values
+
|
;boolean
+
|-
true if the object is empty, i.e. the VisionaireObject does not reference an object of the visionaire data structure.
+
| sound (str)
 
+
| file path to a sound file for this text
=== setName ===
+
|-
 
+
| language (int)
Sets the internal name of the visionaire object.
+
| id of the language of this text object
 +
|-
 +
| '''t_link'''
 +
| colspan="2" | string
 +
| a link to a VisionaireObject (TVisObj); the object will be returned on access; the link can be set with an object
 +
|-
 +
| '''t_links'''
 +
| colspan="2" | table
 +
| a list of VisionaireObject (TVisObj) links, can be iterated with numbers and names of the objects
 +
|-
 +
| '''t_vint'''
 +
| colspan="2" | table
 +
| table with number (integer) entries
 +
|-
 +
| '''t_vfloat'''
 +
| colspan="2" | table
 +
| table with number (float) entries
 +
|-
 +
| '''t_vstring'''
 +
| colspan="2" | table
 +
| table with string entries
 +
|-
 +
| '''t_vpath'''
 +
| colspan="2" | table
 +
| table with t_path entries
 +
|-
 +
| '''t_vpoint'''
 +
| colspan="2" | table
 +
| table with t_point entries
 +
|-
 +
| '''t_vrect'''
 +
| colspan="2" | table
 +
| table with t_rect entries
 +
|-
 +
| '''t_vsprite'''
 +
| colspan="2" | table
 +
| table with t_sprite entries
 +
|-
 +
| '''t_vtext'''
 +
| colspan="2" | table
 +
| table with t_text entries
 +
|}
  
Lua Syntax:
 
<syntaxhighlight>setName(string)</syntaxhighlight>
 
*Arguments
 
;string
 
The new internal name.
 
  
=== setValue ===
+
=== The old-fashioned "longhand notation" ===
  
Sets a field of the visionaire object. Note that only fields which are marked as 'Scriptable' in the [[Data_Structure|Visionaire Data Structure]] documentation should be modified. If the field is not marked as scriptable then changes to this field are often not recognized (or sometimes not immediately). Further changes to these fields will usually not be stored in savegames for performance reasons.
+
While the syntax described in the chapter "Accessing objects and fields" is recommended, there is another way of accessing VisionaireObjects. It dates back to the early days of scripting in Visionaire and you may come across script examples which still use this old-fashioned way. It is usually referred to as the "longhand notation" - in contrast to the much simpler "shorthand" from above.
  
Lua Syntax:
+
Use the global [[Global Command: getObject|getObject]] command to access a VisionaireObject and [[VisionaireObject Commands|object commands]] to get and set property fields:
<syntaxhighlight>setValue(number, VARIANT, {flags=1, index = number})</syntaxhighlight>
+
<syntaxhighlight lang="lua">
* Arguments
+
-- Example of accessing a VisionaireObject by (a unique) name
;number
+
local char = getObject("Characters[hero]")
Data field which will be set.
 
;VARIANT
 
Value to set. The type of the value must match the type of the field. E.g. if the field type is t_int then the value type must be a number (int). If the field type is t_rect then the value type must be a table with the entries "x", "y", "width" and "height".
 
* Flags
 
;index
 
If specified then an existing list element at the given index will be modified. In this case the field type must be of a list-type (t_vint, t_links, ...).
 
  
Examples:
+
-- Example of accessing a VisionaireObject by passing a tuple:
<syntaxhighlight>
+
-- get the object with id=1 from the table with id=0 (characters table).
-- set character "Tom" to position x(100), y(300)
+
local char = getObject("(0,1)")
local tom = getObject("Characters[Tom]")
 
tom:setValue(VCharacterPosition, {x=100,y=300})
 
</syntaxhighlight>
 
 
 
 
 
<syntaxhighlight>
 
-- set condition "TV is on" to true
 
local cond = getObject("Conditions[TV is on]")
 
cond:setValue(VConditionValue, true)
 
</syntaxhighlight>
 
  
 +
-- Note that in the object path, VisionaireObject names need to be prefixed with the (singular) table name
 +
local door_state = getObject("Scenes[kitchen].SceneObjects[door].ObjectConditions[door_closed]")
  
<syntaxhighlight>
+
-- If you want to get/set a field you need the appropriate object method and have to use the field constants.
-- let the "dog" follow the current character
+
-- A field constant starts with a "V" followed by the field name (including the aforementioned table prefix)
local dog = getObject("Characters[dog]")
+
local is_closed = door_state:getBool(VConditionValue)
local currentCharacter = getObject("Game.GameCurrentCharacter")
+
door_state:setValue(VConditionValue, true)
dog:setValue(VCharacterFollowCharacter, currentCharacter)
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Accessing an object ==
 
 
Use the [[GetObject|getObject]] command to access a visionaire object. Pass an object path to the command to get the visionaire object.
 
 
Examples:
 
<syntaxhighlight>local mother = getObject("Characters[Mother]")</syntaxhighlight>
 
 
 
<syntaxhighlight>local cond = getObject("Scenes[Forest].SceneObjects[Tree].ObjectCondition")</syntaxhighlight>
 
 
Whenever an object path is needed you can specify it the following way:<br>
 
1. start with a Table (as is shown in the table column of the Visionaire Data Structure).<br>
 
2. if this table is not "Game" (this table has only one object) then you have to write the name of the object inside bracktes ('[' and ']').<br>
 
3. either goto 7. or continue with 4.<br>
 
4. write a dot '.' and then a fieldname of this object (the field type must either be t_link or t_links).<br>
 
5. if the field type is t_links then goto 2., else goto 6.<br>
 
6. either goto 7. or goto 4. (access another link)<br>
 
7. done. A valid object is specified.<br>
 
 
Examples:
 
<syntaxhighlight>Game.CharacterLinks[Tom]</syntaxhighlight>
 
 
 
<syntaxhighlight>Scenes[Room].SceneObjects[start].SceneConditions[game started?]</syntaxhighlight>
 
 
 
<syntaxhighlight>Characters[Tom].CharacterInterfaces[Tom-MI3]</syntaxhighlight>
 
 
Alternatively, you can also access an object by its table-id and object-id. It can be specified by a tuple:<br>
 
(table-id,object-id)<br>
 
 
Example:
 
<syntaxhighlight>(0,6)</syntaxhighlight>
 
 
Selects the object with id 6 from table 0 (characters).
 
 
== Commands  ==
 
  
* [[VisObjectCmds|Object access]]
+
== Add a script ==
  
=== Commands for Visionaire Player only ===
+
[[File:Script.png|thumb|250px|Scripts section]]
 +
Scripts are generally added in the "Scripts" section of the editor. Each script has to be declared a <span class="inlinecode">Definition script</span> or an <span class="inlinecode">Execution script</span> by (un)checking the option above the script editor (see image). A definition script is automatically run at game start, while an execution script has to be explicitly called.
  
* [[Player_Commands|Player commands]]
+
In your actions you can make use of scripts by using the [[Action_Parts#Call_script|Call script]] and the [[Action_Parts#Execute_a_script|Execute a script]] action parts, with the first one allowing you to select from your list of execution scripts and the second one expecting Lua code. You can use the [[Action_Parts#If_Lua_result|If Lua result]] action part to build an "if…else" query using Lua code. Besides that, a Lua query can also be part of a [[Conditions_and_Values#Conditions|Combined condition]].
 +
{{toc}}

Latest revision as of 12:54, 16 January 2024

Visionaire Studio comes with its own scripting language, which consists of, a combination of: Lua script and a Visionaire object model. The object model is used to access the Visionaire data structure in a convenient way. Almost every instance in Visionaire is represented as an object (e. g. scene, character, interface, ...), all of which can be accessed/manipulated through the scripting language.


Lua

Visionaire Studio currently uses Lua version 5.4.0.

If you want to learn more about the language, you may refer to the official online documentation on the Lua website or have a look at some tutorials:

Lua-logo.png


Our community member AFRLme wrote a basic Lua introduction which you can find in this wiki:


Visionaire object model

Each Visionaire project is saved in a hierarchical data structure. Every instance of an object of that data structure is a "VisionaireObject" (TVisObj). All objects of the same type (e. g. scene or button) are stored in one table (called e. g. "Scenes" or "Buttons").

The properties of an object can be accessed by defined fields for the specific table. These fields can contain single values (e. g. integers, strings) or tables of values as well as links to other VisionaireObjects or tables of links to VisionaireObjects. All objects and their fields are documented on the data structure page. The different field types are listed below.


Accessing objects and fields

The data structure tables are globally accessible. Object instances within the tables are usually accessed by their name, but it is also possible to use the table index. The "game" object is not contained in a table but directly accessible.

-- Examples of accessing a VisionaireObject by (a unique) name
local char = Characters["hero"]
local coins = Values["coins"]

-- The following syntax is also possible, but be aware that it only works for object names which don't contain
-- special characters or whitespaces (only A-Z, a-z, 0-9 and underscore allowed) and start with a letter
local char = Characters.hero

-- Access a VisionaireObject by table index: get the first object in the "Characters" table
local char = Characters[1]


Object properties are accessed through their fields:

-- Example of accessing a property of a VisionaireObject
local char = Characters["hero"]
local pos = char.Position

-- This leads to the same result
local pos = Characters["hero"].Position

-- Get the integer value ("Int" field) of the "Value" object called "coins"
local num_coins = Values["coins"].Int

-- The "game" object is directly accessible
local scr_pos = game.ScrollPosition


If other VisionaireObjects are linked in an object property, you can specify the complete object path to access them. This is especially helpful, if you have non-unique object names which cannot be accessed purely by their name:

-- Let's say each character has a value property called "coins"; it is not possible to use 'Values["coins"]'
-- because the name is not unique; now access the different values by using the object path
local hero_num_coins = Characters["hero"].Values["coins"].Int
local villain_num_coins = Characters["villain"].Values["coins"].Int
local cur_num_coins = game.CurrentCharacter.Values["coins"].Int

-- Object paths can be even longer
local door_state = Scenes["kitchen"].Objects["door"].Conditions["door_closed"]

-- If the condition name "door_closed" is unique in the project, the following leads to the same result
local door_state = Conditions["door_closed"]


Writing a field value is just as easy. However, not all fields of the data structure can be changed through script. Please refer to the data structure page:

-- Lower the brightness of a scene to 80%
Scenes["kitchen"].Brightness = 80

-- Make the villain the playable character
game.CurrentCharacter = Characters["villain"]

-- Set a condition to true
Conditions["door_closed"].Value = true

-- Change the integer value of a "Value" object
Characters["hero"].Values["coins"].Int = 47


Common VisionaireObject fields

The following fields are available for all VisionaireObjects. They are read-only (except "name" which can be written with the "setName" method):

  • id: The internal id of the object (integer).
  • name: The internal name of the object as defined in the editor (string). Not to be confused with the "Name" property (with capitalized "N") which is available for some objects and contains the multi-language object name used in the game.
  • parent: Returns the parent object (TVisObj).
  • tableId: The id of the data structure table the object is part of (integer).


Field types

The field types of the data structure are mapped to Lua types in the following way:

Field Type Lua type/Structure Description
t_bool boolean true or false
t_int number integer
t_float number decimal
t_string string
t_path string file path
t_point table x (int) x coordinate
y (int) y coordinate
t_rect table x (int) x coordinate of top left corner
y (int) y coordinate of top left corner
width (int) width of rectangle
height (int) height of rectangle
t_sprite table path (str) relative path to image file
position (t_point) sprite offset in case sprite is used in an animation
transparency (int)
transpcolor (int) transparent color
pause (int) pause value in milliseconds in case sprite is used in an animation
t_text table text (str)
sound (str) file path to a sound file for this text
language (int) id of the language of this text object
t_link string a link to a VisionaireObject (TVisObj); the object will be returned on access; the link can be set with an object
t_links table a list of VisionaireObject (TVisObj) links, can be iterated with numbers and names of the objects
t_vint table table with number (integer) entries
t_vfloat table table with number (float) entries
t_vstring table table with string entries
t_vpath table table with t_path entries
t_vpoint table table with t_point entries
t_vrect table table with t_rect entries
t_vsprite table table with t_sprite entries
t_vtext table table with t_text entries


The old-fashioned "longhand notation"

While the syntax described in the chapter "Accessing objects and fields" is recommended, there is another way of accessing VisionaireObjects. It dates back to the early days of scripting in Visionaire and you may come across script examples which still use this old-fashioned way. It is usually referred to as the "longhand notation" - in contrast to the much simpler "shorthand" from above.

Use the global getObject command to access a VisionaireObject and object commands to get and set property fields:

-- Example of accessing a VisionaireObject by (a unique) name
local char = getObject("Characters[hero]")

-- Example of accessing a VisionaireObject by passing a tuple:
-- get the object with id=1 from the table with id=0 (characters table).
local char = getObject("(0,1)")

-- Note that in the object path, VisionaireObject names need to be prefixed with the (singular) table name
local door_state = getObject("Scenes[kitchen].SceneObjects[door].ObjectConditions[door_closed]")

-- If you want to get/set a field you need the appropriate object method and have to use the field constants.
-- A field constant starts with a "V" followed by the field name (including the aforementioned table prefix)
local is_closed = door_state:getBool(VConditionValue)
door_state:setValue(VConditionValue, true)


Add a script

Scripts section

Scripts are generally added in the "Scripts" section of the editor. Each script has to be declared a Definition script or an Execution script by (un)checking the option above the script editor (see image). A definition script is automatically run at game start, while an execution script has to be explicitly called.

In your actions you can make use of scripts by using the Call script and the Execute a script action parts, with the first one allowing you to select from your list of execution scripts and the second one expecting Lua code. You can use the If Lua result action part to build an "if…else" query using Lua code. Besides that, a Lua query can also be part of a Combined condition.