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:

alt text

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:

alt text

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

alt text

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():

alt text

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":

alt text

Inside this network, however, we can have a Lua-based setup with input and output nodes exposing specific values to the external ports:

alt text

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.