Tscript
TouchDesigner Scripting Languageedit
Tscript is TouchDesigner's original built in scripting language, now alongside the Python language. A side-by-side list of common tasks in both languages can be found here.
Tscript is similar to C-Shell in its syntax and structure. TouchDesigner's Expression language is also used heavily in Tscript. As a result, when learning Tscript, don't focus solely on Tscript itself, but look at Expressions too.
Tscript Commands and Tscript Expressionsis a complete reference of Tscript.
The Order of Expansionedit
Expansion of a TouchDesigner command follows the C-shell expansion standards very closely. There are some subtle differences.
Lexical Structureedit
TouchDesigner splits input lines into words at space characters, except as noted below. The characters ; < > ( ) =
form separate words and TouchDesigner will insert spaces around these characters except as noted below. By preceding a special character by a backslash (\
), its special meaning can be suppressed.
Evaluation of Quotesedit
Strings enclosed in a matched pair of quotes forms a partial word. Within double quotes ("
), expansion will occur. Within single quotes ('
) expansion will not be done. Within back-quotes (`
) the enclosed string will be evaluated as a TouchDesigner expression and the result will be considered to be a partial word. Inside a matched pair of quotes, the quote character may be protected by preceding the slash with a backslash.
Backquotes are evaluated with a higher priority than double quotes. This means that if a double-quoted argument encloses a back-quoted string, the back-quoted string may contain double quotes without terminating the initial double quote delimiter. For example, the string:
foo'ch("/obj/geo1/tx")'
will be parsed as a single argument.
Note: As a general rule, do not include spaces between your "back" quotation marks and what lies between them. TouchDesigner may not evaluate them if there are extra spaces.
Commentsedit
The character #
introduces a comment which continues to the end of the line. This character can be protected by a backslash (\
) or by enclosing the character in quotes.
Multiple Commandsedit
Multiple commands can be specified on the same line by separating them with semicolons (;
).
Expansionedit
Expansion is done in the following order: History substitution, Macro expansion, Variable & Expression expansion.
History substitution is not as sophisticated as the csh history mechanism. The supported substitutions are:
!!
- Repeat last command!str
- Repeat last command matching str!num
- Repeat command "num
" from the history list!-5
- Repeat the command run five commands previous
With the !!
substitution, characters following the !!
are appended to the command. The resulting command is displayed in the Textport before the command is run.
Variable and expression evaluation are done at the same time and have equal precedence. Variables are delimited by a dollar sign ($
) followed by the variable name. A variable name must begin with letter or an underscore (_
) followed by any number of letters, numbers or underscores. As well, the variable name may be delimited by curly braces ({}
) in which case the contents of the curly braces is expanded before the variable name is resolved. This allows for pseudo array operations on variables.
For example:
touch -> set foo1 = bob touch -> set foo2 = sue touch -> for i = 1 to 2 > echo ${foo${i}} > end bob sue
Expression evaluation is done on the string contained within matching backquotes ( `
). Inside the backquotes, expression expansion is performed as opposed to command line expansion. The expression is evaluated, and the resulting string is used to replace the expression on the command line. If the expression evaluates to a type other than a string, the result is cast to a string and this is the value used.
Command Expressionsedit
These differ from general TouchDesigner expressions, though TouchDesigner expressions can be used inside of command expressions. The command expressions are used in the "while
" and "if
" commands. The order of operations in a command expression is as follows:
()
- Parentheses== != < > <= >=
- Equal, Not Equal, Less Than, Greater Than, Less Than or Equal, Greater Than or Equal&& ||
- Logical AND and Logical OR
Expressions can be enclosed in parentheses for clarity, but this is not necessary.
Variablesedit
There are many types of Variables in TouchDesigner. Script variables are variables that are set within a script using the set
command. They are local to the script and exist only for the duration of the script. When the script terminates, these variables will automatically be unset.
All variables created by loops are considered local script variables (i.e. the "for
" loop will use script variables).
Pattern Matchingedit
Many parameters allow patterns to specify multiple sources to be selected or acted upon. CHOPs, channels, DATs, Geometry COMPs are examples of things that some parameters may allow multiple of. The Render TOP allows for multiple lights, geometry COMPs and cameras. The Join CHOP and Composite TOP accept multiple sources. These patterns allow wild cards which will match all or parts of strings. Patterns are also used in various Python methods such as ops()
, to allow specifying more than one OP by a single string.
Multiple patterns can be specified, separated by spaces. The patterns will be ORed together, so a source that matches any of listed patterns will be selected.
*
- Match any sequence of characters?
- Match any single character^
- Do not match.[alphaset]
- Match any one of alphabetic characters enclosed in the square brackets. In TouchDesigner, the[a-g]
format is not currently supported, the characters must be listed as[abcdefg]
.[num1-num2]
or[num1-num2:increment]
- Match any integer numbers enclosed in the number range, with the optional increment.[num1,num2,num3]
- Match the specific integers given.@groupname
- Expands all the items in the group. Since each group belongs to a network, you can specify a path before the@groupname
identifier.
NOTE: The opposite of pattern matching is Pattern Expansion, takes a short string and generates a longer string from it. See also Pattern Replacement.
Pattern matching is also often used to match channel names. It uses the following kinds of patterns to select existing channels in an input CHOP, used in CHOPs like the Select CHOP and the Math CHOP's Scope parameter, where you only want to affect certain channels and leave the rest as-is.
Pattern matching is used to match object names in the Render TOP, and OPs/channel names in the Select CHOP.
Examplesedit
chan2
|
Matches a single channel name |
chan3 tx ty tz
|
Matches four channel names, separated by spaces |
chan*
|
Matches each channel that starts with "chan " and ends with anything
|
*foot*
|
Matches each channel that has "foot " in it, with anything or nothing before or after
|
t?
|
The ? matches a single character. t? matches two-character channels starting with t , like the translate channels tx , ty and tz
|
r[xyz]
|
Matches channels rx , ry and rz . that is, "r " followed by any character between the [ ]
|
blend[3-7:2]
|
Matches number ranges giving blend3 , blend5 , and blend7 . (3 to 7 in steps of 2)
|
blend[2-3,5,13]
|
Matches channels blend2 , blend3 , blend5 , blend13
|
t[uvwxyz]
|
[uvwxyz ] matches characters between u and z , giving channels tu , tv , tw , tx , ty and tz
|
See Alsoedit
Command Loopsedit
There are three different looping constructs in Tscript:
for
for variable = start to end [step increment] ... end
foreach
foreach variable ( element_list ) ... end
while
while ( expression ) ... end
The for
loop will loop from the start
, up to and including the end
.
The foreach
loop will cycle through every element in the element_list
assigning the variable value to be a different element each iteration through the loop.
All variables in the for
and foreach
loops are local variables. To export the variable to other scripts simply set a global variable using the rvar
or the cvar
Command inside the loop.
Example
You can use a loop to perform repetitive tasks for you. For example, if you wanted to wanted to merge 255 SOPs, it would be faster to write a short script than to do all that wiring manually.
For example, if you named your SOPs consistently, like: model_0
, model_1
, model_2
... model_255
, then you could execute the following script in a Textport:
for i = 0 to 255 opwire model_$i -$i merge1 end
If you haven't been consistent with naming, you could also do it with a foreach
.
Terminating a Long or Endless Scriptedit
If TouchDesigner looks like it is hanging, you may have scripted an endless loop by mistake and may want to kill the script. In this case, you can hit Ctrl-Break to interrupt, halt and terminate script execution. It may take a few seconds for TouchDesigner to respond, break from the script and stop processing. You can view messages on which scripts were stopped in the Textport.
Conditional Statementsedit
The "if
" command provides the ability for a script to check a condition and then execute one set of commands if the condition is true or an alternate set of commands if the condition is false. It should have an endif
to signify the end.
if ( expr ) [then] ... else if (expr2) [then] ... else ... endif
Arithmetic Expressionsedit
Arithmetic Operations
^ - not + - add - - subtract * - multiply / - divide % - mod
Logical Operations
== - equal to != - not equal to < - less than <= - less than or equal to > - greater than >= - greater than or equal to
&& = AND || = OR ! = NOT
Macros and Multiple Commandsedit
Some frequently used commands can be represented with a single word, a Macro.
Example
touch-> macro greet echo hello world touch-> greet hello world touch-> macro mine "opset -d off * ; opset -d on geo1" touch-> mine
This will execute the string attached to the macro "mine
" and turn off the display of all the objects then turn on object geo1
.
The next two commands list, then undefine, a macro:
touch-> macro greet hello world mine opset -d off * ; opset -d on geo1 touch-> macro -u greet
TouchDesigner accepts several commands on the same command line separated by a semicolon ( ;
). This does not apply to semicolons embedded in quotes. Macros can contain commands embedded in quotes.
Redirecting Command Output to DATsedit
Redirect to a DAT (clearing the DAT first) with the echo
Command:
echo "abc" > text1
appending a line to the DAT:
echo "abc" >> text1
If the DAT does not exist, TouchDesigner will create a Text DAT and place the new text in it.
It doesn't matter if there is a space after the >
or >>
.
You can append to a pre-existing table, which adds a new row to the table.
There are two syntax forms to put things in different columns. First by putting \t
in your text string:
echo abc\tdef\tghi >> table1
and with quotes around it you need to put actual tab characters in the string:
echo "abc def ghi" >> table1
where the spaces above are actual tab characters (not \t
).
Redirecting Command Output to Filesedit
To redirect the output to a file in the filesystem, use FILE:
as a destination prefix. Examples:
echo "hello world" > FILE:abc.txt # relative to current disk folder on current drive echo "hello world" > FILE:Map/README.txt # relative path, into subfolder Map echo "hello world" > FILE:C:/abc.txt # absolute path echo "hello world" > FILE:$TOUCH/test.txt # new file using Built-in Variable for the path to your project. echo "hello world" >> FILE:$TOUCH/test.txt # this appends text
Note the quotes are optional in the above examples.
Also note >>
can be used to append to existing text, instead of replacing it.
If no prefix is given, a DAT node path is assumed. This can also be specified with the DAT:
prefix, though this is redundant.
Using Arguments in Scriptsedit
When calling a script with Tscript run
or include
Command, arguments can be passed to the script. These arguments are set to TouchDesigner script variables so that they can be used by the script.
Example
Assuming the current TouchDesigner component contains repeatscript
(see Tscript pc
and cc
Command):
touch-> run repeatscript 1 10 2 blockhead
where repeatscript
contains:
echo Hello, my name is $arg4 for i = $arg1 to $arg2 step $arg3 echo I said, my name is $arg4 end
Note that there are four variables in the script: arg1
, arg2
, arg3
and arg4
. These are set to the arguments 1
, 10
, 2
and blockhead
respectively.
$arg0
- name of the script
You can get the name of the script being run from $arg0
.
For example: run myscript 1 4.5 7 balloon will come into the script with
$argc
=5
$arg0
=myscript
$arg1
=1
$arg2
=4.5
$arg3
=7
$arg4
=balloon
This allows usages such as:
if $argc != 5 then echo USAGE: cmdread $arg0 numclowns clownsize numtoys toytype exit endif
$argc
- number of arguments passed to script
The number of arguments passed to the script can be retrieved with the variable $argc
.
For example, from the lookat script:
# USAGE: lookat eyeobject focusobject if $argc!= 2 then echo USAGE: source lookat eyeobject focusobject exit endif
Examplesedit
Question: How would I get all the container level parameters of the master component and reapply them to a clone?
set master = $arg1 set clone = $arg2 opparm $clone `run("parmls /$master")`
The problem is that you will loose spaces, so any par("tx")
will end up as par(tx)
, which produces an error. The following script seems to work better, but hasn't been tested very much.
set master = $arg1 set clone = $arg2 foreach p (`noevals(run("parmls $master"))`) if (`arg("$p",1)` !="") opparm $clone $p else opparm $op `arg("$p",0)` "" endif print "" end