Click or drag to resize

Scripting and how to use it

articy:draft contains support for a script language called "Expresso" and was introduced with articy:access. In articy:draft the script language was most useful when combined with Global Variables and the Simulation mode allowing you to test your flow and your dialogues with logic.

The ArticyImporter plugin imports your scripts into unity and makes sure that you can use them as you seem fit, not only that, but the ArticyFlowPlayer will automatically use the scripts found inside the flow when it will traverse it.

This guide will teach you how you can take advantage of the script functionality inside articy:draft and how to make use of it in unity

Expresso Script Primer

There is a fair chance that you have never worked with scripts inside articy:draft before, so in this chapter we give you a small overview of what you can and can't do with it and how to use it.

The first thing is: In articy:draft are basically 2 types of scripts Conditions and Instructions. Incidentally there are two node types in articy:draft that go by these names.

  • Conditions are used to test if something is allowed, a condition script is a single statement that must resolve to a boolean therefore returning true or false.
  • Instructions are scripts that can be multiple statements, separated with semicolon and usually used to change variables or call methods.

Scripts can be found in 3 different places Pins, specialized Nodes and Script template property. While template and node types are self explanatory, pins need a bit more explanation.

Pins on the left side of a node are called Input Pins and every input pin contains a condition script. In that regard are the pins on the right side called Output Pins and every output pin contains an instruction script.

For more information how to write scripts inside articy:draft check the help about Scripting

Conditions
edit pin

To write a condition you usually just have to form statements that can be evaluated to a boolean, lets look at some simple examples of what are valid condition scripts.

true
GameState.awake
!Inventory.hasKey || Inventory.lockPicks == 0
Resources.woodSupply > 100 && Resources.ironSupply > 50

As you can see conditions are just a single statement that is testing the value of one or more variables. Its important to understand that you cannot use multiple statements in conditions and articy:draft will usually return an error when trying to do that.

Instructions
edit pin instruction

Instructions are rather easy to write, as they are usually just one or more statements changing a variable.

GameState.awake = true;
Resources.woodSupply -= 100;
Resources.ironSupply -= 50;

playSound("forge_build.wav");

You can use instructions to change the variables inside your game and even call custom methods.

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.

There are built in methods that you can use to work with object properties:

  • getObject(string) returns an object reference via technical name or id.
  • getProp(object, property) returns a value for an object with the given property.
  • setProp(object, property, value) sets the value of a property for an object.
  • incrementProp(object, property, value = 1) increments the value of a property for an object.
  • decrementProp(object, property, value = 1) decrements the value of a property for an object.
  • isPropInRange(object, property, lowerBound, upperBound) returns if the property value is the given range (lower and upper bound inclusive).
  • isInRange(value, lowerBound, upperBound) returns if the value is the given range (lower and upper bound inclusive).
  • random(int, int) returns a random number between the first number (inclusive) and the second number (inclusive).
  • print(string) prints a text, you can use parameters similar to String.Format().
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.

Caution note Caution

Remember that Conditions are only boolean statements, therefore you can't use print() or setProp() inside an instruction as both methods don't have a return value.

getObj()

This function is used in conjunction with functions like getProp() or setProp().

You can access an object via its technical or its id

getObj("Chr_Manfred")

getObj("0x01000001000010C6")

And you can specify the instance id to access another clone of the object.

getObj("NPC_Guard", 1)

getProp()

To access a property you just have to call getProp() and get the object, which you can query via getObject() for example. After getting the object you need to supply the PropertyName as a string.

getProp( getObj("Chr_Manfred"), "DisplayName")

The property name is just the C# property name. For example DisplayName, Speaker, BackgroundColor etc.

You can access the template data of the object by writing the feature name and the property name separated via a dot

getProp( getObj("Chr_Manfred"), "Morale.MoraleValue" ) > 10
Here we used getProp() in a condition, testing the returned value.

Remember that you can use the convenient identifier to ease accessing objects:

getProp( speaker, "Player_Character.Morale" ) > 10

setProp()

To change the value of an object, similar to getProp() you have to access the object and supply the property name you also need to supply the new value for the property.

setProp( getObj("Chr_Manfred"), "DisplayName", "Player1" )
You can change pretty much anything of an object.

Changing a template property is equally easy

setProp( getObj("Chr_Manfred"), "Player_Character.Morale", 100 )

And you can of course use the convenient identifier here aswell.

setProp( speaker, "Morale.MoraleValue", 100 )

incrementProp() and decrementProp()

Instead of nesting setProp and getProp to increment or decrement a value, you can use these convenience functions.

incrementProp(getObj("Chr_Manfred"), "Player_Character.Morale", 10)

If no change value is specified, the value will be increased or decreased by 1.

incrementProp(getObj("Player"), "Attributes.Strength")

isPropInRange

A convenience function to check if a prop value is in a specific range.

isPropInRange(getObj("Chr_Manfred"), "Morale.MoraleValue", 50, 100)

isInRange

Similar to isPropInRange(), but not restricted to properties.

It can be used for global variables

isInRange(Resources.ironSupply, 500, 1000)

Or even with custom methods

isInRange(getTime(), 6, 12)

random()

Can be used to work with random values.

incrementProp(getObj("Player"), "Inventory.Gold", random(50, 100));

print()

Useful as a debug tool you can use print() to write into the Unity console log, like Debug.Log().

print( "Hello" )

print( "Number {0}", 42 ) 

print( getProp( speaker, "Morale.MoraleValue" ) )

See Also