Scripting in articy:draft

articy:draft has its own easy to use expression language called "articy:expresso" and a set of accompanying features to support the designer/writer in the scripting process. You can create, manage and use global variables throughout the project - making it possible to define conditions precisely and change the values of variables via instructions when reaching certain points in your game flow.

Testing Scripts in Simulation Mode

You can test your articy:expresso scripts within articy:draft by using the simulation mode of the presentation view. Please be aware that scripts from template properties are not evaluated in the simulation mode, only scripts that are located in pins and condition / instruction nodes.


Use Built-in Scripting Support

If you want to use articy:expresso and the built-in scripting support, enable the checkbox "Use built-in scripting support" within the project settings under the tab "Flow". This option activates the auto-completion, syntax highlighting and error detection for all pin labels and other script textboxes.



If the scripting support is activated, the auto-completion will offer a list of all matching variable sets or variables when writing in a script textbox. You can select an entry from the list via left-click or via the arrow-keys and ENTER.



Conflicts in the script are visualized by words underlined in red 1 and the conflict icon in the upper right. Hovering over the icon will show a tooltip describing the conflict 2:




articy:expresso Syntax


articy:expresso is an easy to learn expression language, which can help you define conditions and instructions (variable testing and assignment). Its syntax is basically a subset of the C# syntax.

Conditions & Instructions

The concept of articy:expresso centers around conditions and instructions. Conditions are used to test the values of variables and thus to control the game flow. Instructions are their counterpart and are used to modify the values of variables.

If you want to combine multiple variable checks in one condition, you can use the logical operators AND, OR and XOR.

Examples for typical Conditions:
Inventory.key == true

GameState.talkedToGuard == true && Inventory.collectedTokens >= 10


Examples for typical Instructions:
Inventory.key = true

In Instructions multiple assignments must be separated by a semicolon.
Inventory.collectedTokens += 5;
GameState.bossDefeated = true;


Variables

Variables can be of type boolean (true/false), integer (number), or string. They are always addressed in the following notation: VariableSet.Variable.
Example: You created a global boolean variable called "key" that is set to true, if the player finds the missing key. This variable is inside the variable set called "Inventory". To use this variable in conditions or instruction write: "Inventory.key".
isInRange() This method allows to check for a variable range inside a Condition.
isInRange(VariableSet.variable, lower bound, upper bound)
isInRange(Inventory.cards, 40, 60)

Both lower and upper bound are inclusive. In the above example the condition returns a true value if the value of the variable cards is between 40 and 60. Anything below 40 or above 60 will result in the return of false.

Accessing objects, properties and templates via Script

Historically the articy:draft scripting was used together with Global variables. While this was sufficient for a lot of use cases, it can be more useful to store the data alongside the objects directly. Especially given the flexibility our template system, we introduced specialized methods to the scripting system to allow you to access the properties and the template data of objects.
These are the built in methods that you can use to work with object properties:
  • getProp(object, property) returns a value for an object with the given property
    getProp( getObj("Chr_Manfred"), " Player_Character.Morale " ) > 10

    This is an example how getProp() can be used in a condition to test the returned value.
  • setProp(object, property, value) sets the value of a property for an object
    setProp(getObj("Chr_Manfred"), "Player_Character.Morale", 100 )
    setProp(getObj("Chr_Manfred"), "Player_Character.Morale", getProp(getObj("Chr_Manfred"), " Player_Character.Morale ") +10 )

    The first example set the value of the Morale object property to 100, regardless of what is was before. The second example modified the current value by adding 10 to it. Please note that since 3.2 this can be achieved easier with the incrementProp() or decrementProp() methods!
  • incrementProp() / decrementProp() Increments or decrements the value of a property
    incrementProp(getObj("Chr_Manfred"), "Player_Character.Morale", 10)
    decrementProp(getObj("Chr_Manfred"), "Player_Character.Morale", 20)

    The first example increases the value of the Morale property by 10, in the second example we subtract 20 from the current Morale value.
  • getObject(string) returns an object reference via technical name or id
  • print(string) prints a text. Useful as a debug tool when working in the game engine
    print( "Hello World" )
    print( getProp( speaker, "Player_Character.Morale" ) )
  • random(int, int) returns a random number between the first number (inclusive) and the second number (inclusive)
  • isPropInRange() Checks the range of a property. Lower and upper bound are inclusive.
    isPropInRange(getObj("Player"), "Skills.Strength", 5, 10)

    This condition returns true if the value of the Strength property of the Player object is between 5 an 10. Otherwise it returns false.
 
Remember that Conditions are boolean expressions, therefore you can't use print() or setProp() inside a Condition as both methods don't have a return value.

We also added 2 convenient identifier as a substitute for getObject().
  • speaker inside a DialogueFragment this is an automatic reference to the current speaker object.
  • self this references the current object that this script is called on.
setProp(speaker, "Player_Character.Morale", 100 )
incrementProp(speaker, "Skills.Strength", 2)


"How to access object properties with scripting"

"Enhanced scripting with increment and isInRange methods"


Operators

The following relational operators can be used to compare variable or property values.

== Is value equal to...

!= Is value not equal to...

<= Is value less than or equal...

>= Is value greater than or equal...

< Is value less than...

> Is value greater than...



The following logical operators can be used to concatenate comparisons.

&& Logical AND

|| Logical OR



The following arithmetic operators can be used:

+ Add

- Subtract

* Multiply

/ Divide

% The modulo operator computes the remainder after dividing its first operand by its second. (Example 5 % 2 = 1)

++ Pre-/Post Increment (+1)

-- Pre-/Post Decrement (-1)



The following assignment operators can be used to set variable values. Assignment operators can be used in instructions only, not in conditions.

= Set value to...

+= Set value to current value plus...

-= Set value to current value minus...

*= Set value to current value multiplied by...

/= Set value to current value divided by...

%= Sets the value to the remainder after dividing the first operand by the second (modulo).



Short form

Instead of writing "Variable == true" you can also just write "Variable" and instead of writing "Variable == false" you can write "!Variable".

Comments

It's possible to add comments to a script via:
  • // your comment here for a single-line comment and
  • /* your comment here */ for multi-line comments
Comments won't be evaluated and are just a tool to describe the intentions behind an expression.

Script Methods

Scripts inside articy:draft can not only be used to check or modify global variables or property values. They also allow you to call arbitrary methods. While of no use inside articy:draft those methods are much more important inside your game engine project.
Calling custom methods can be combined with isInRange() or isPropInRange()
isInRange(GetTime(), 9, 18)

In this example we have a custom method GetTime() to query the current in game time. With isInRange() we can now for example determine if a shop is open or closed.