Lua Basics - martin-pr/possumwood GitHub Wiki
Possumwood is intended to be easily extensible by enabling easy integration of C++ libraries into dependency graph nodes, and allowing them to be wired into new setups providing new functionality. Sometimes, however, it is necessary to do a bit of "data wrangling" to achieve a particular functionality, which in common DCCs is achieved using an embedded scripting language.
To this end, Possumwood integrates Lua - a simple scripting language well suited to wrapping custom data types. Using Lua, it is possible to create networks with arbitrary inputs and outputs,
This tutorial introduces basic concepts of Lua integration in Possumwood, on an example of a simple addition node.
The Script Node
At the core of the Lua integration is the lua/script
node. Apart from the source
input, containing the Lua source code (editable via the Editor panel), it contains a context
input and a state
output:
The Context input contains the environment the script is to be executed in. This can include additional variables, types and modules injected into the environment before scripts evaluation.
The State output contains the state of the environment after evaluation. Any changes to the environment inside script, such as defining new variables or changing the values of existing ones, are contained in this state and can be extracted for further use in the dependency graph.
Extracting a value from a State
After creation, the script
node contains the following source code:
variable = 10
This code creates a new global variable, and sets its value to 10. This value exists inside the output state
of the node.
By connecting the state to a lua/extract/float
node, we can make the value of the variable accessible as a port in the node graph:
This node is typed - it is only able to extract a value of "float" type. By filling-in the name
attribute, we can connect this node to a particular variable instance; the output then contains the extracted value.
Injecting a value to a Context
A Context instance contains the environment to run the script in. It is constructed using a chain of lua/inject
nodes, each adding an additional variable to the context.
As an example, we can inject a time value from time
node, by connecting it through lua/inject/float
node (while changing the name
attribute to "time") into the context input of the lua/script
node, and change the source code to assign this value to our variable
:
variable = time
Using this setup, any changes to the current time (i.e., moving the time axis below the viewport) changes the output value.
Using Modules
Modules allow to extend a script environment by adding new functionality. For example, the math
module (from lua/modules/math
) allows us to use additional Lua maths functions, such as math.sin()
:
Warpping it up
Lua provides a powerful mechanism for extending the functionality of Possumwood. However, its setups can be quite verbose - the number of nodes required to provide a more complex functionality can be quite high.
An easy way to work around this problem is to wrap the whole setup into a network. For example, a simple "addition" node could look like this from the "outside":
Inside this network, however, we can have a Lua-based setup with input
and output
nodes exposing specific values to the external ports:
To open a network setup of this kind, simply double-click any network (a node with blue background), or use the tree view on the left to explore its internal nodes.
Most setups accessible via a toolbar button hide their internal complexity in similar manner. An addition and multiplication node implemented in this manner (together with other nodes) are accessible from the Lua
toolbar.