A mostly reasonable approach to Touch Designer Development
this document was started and heavily inspired by the Gamemakin ue-style guide
TD stands for Touch Designer. A platform for visual thinking.
The word toe
or patch
is used interchangeably to refer to the entire Touch Designer project contained within a specefic repo
this can be made up of any combination of external scripts, tox modules, assets, e.t.c
the word tox
refers to a submodule within a larger TD patch. Toxes can be made from containers by right clicking and selecting save as external tox.
TD allows for any COMP to have a custom python class added to it to extend it's functionality. This allows containers for a bunch of neato tricks that helps to make the final touch designer project a little less fragile and easier to version control.
A comp is a container operator. these are gray operators in the network pane and usually contain other nodes
There are a few different ways you can CaseWordsWhenNaming
. Here are some common casing types:
Capitalize every word and remove all spaces, e.g.
DesertEagle
,StyleGuide
,ASeriesOfWords
.The first letter is always lowercase but every following word starts with uppercase, e.g.
desertEagle
,styleGuide
,aSeriesOfWords
.Words can arbitrarily start upper or lowercase but words are separated by an underscore, e.g.
desert_Eagle
,Style_Guide
,a_Series_of_Words
.
If you are working on a project or with a team that has a pre-existing style guide, it should be respected. Any inconsistency between an existing style guide and this guide should defer to the existing.
Style guides should be living documents. You should propose style guide changes to an existing style guide as well as this guide if you feel the change benefits all usages.
Try not to argue to much about cases. As long as it's consisitent it truly doesn't matter.
1.2 All structure, assets, and code in any TD project should look like a single person created it, no matter how many people contributed
Moving from one project to another should not cause a re-learning of style and structure. Conforming to a style guide removes unneeded guesswork and ambiguities. This is especially true in large scale TD driven installations, where there might be many patches that span multiple rooms or activations. Similary, mainting and enforcing a TD style at the organization level ensures that when patches are revisted for remounts or reactivations there is a minimum amount of re-learing or re-remembering of which specefic style was used at this part of the project. This is especially crucial in the many segments in which TD is appropriate given the sometimes limited time frames for a project
Following a consistent style is also helpful if you are revisting a past patch that you made for a project four years ago. It means that it will take less time to get up to speed with what past you was trying to accomplish with a specefic patch. This will make things easier and you can get to upgrading to the latest coolest sensor without having to remember where you put that render module.
it's a nice thing to do to mention or leave a comment if possible if you're adapting or implementing a specefic technique that you picked up from watching a YouTube tutorial or read about in the forums. You never know who might open your patch one day.
All Network operators should have a unified case. this can either be snake case. as in select_raster_config
or camel as in selectRasterConfig
The organization or team should pick a style and stick with it.
This guide thinks that using snake_case
for operators is a slightly more optimal approach. Extensions and User Parameters in TD are required to start with a Capital Letter
thus it's easy for other team members to quickly visualy identify potentially interesting or added parameters. Consider op.config.IsStart
vs op('movie_file_in').par.file
Knowing that the project uses snake case the TD author can assume that the property IsStart
is a custom element added by a team member.
In general one should try to rename most operators in a chain to give a reader the sense of what they do. This is helpful because when another developer is looking at an expression or a reference in a seperate part of your network they can get a sense of your intentions. This is especially true of null
operators at the end of a chain. Consider the difference between seeing a reference to ../../../config/null5
in a select CHOP vs op.config.op('computed_rasters')
External files that are used as the source code for extensions should be prefixed with the project abbreviation and titled in CamelCase
For example a source file that makes a container behave like a Movie Player for a project called BlueParadox
might be called BPMoviePlayerEXT.py
or BPMoviePlayer.py
External files as the source code for glsl or geo shaders should follow the same syntax as the operator that it's referencing so a glsl top called particles_velocity_update
might have a shader associated with it called particle_update.glsl
There are multiple ways to organize a content project directory structure. This guide uses a style that emphasizes clear visibility when viewing the project if the file explorer and in the repository. In general this structure provides the following benefits:
- provide an unambigous entry point to the project
- easily searchable based on asset type
- general compatibility with folder dats
- makes source control via git less of a pain
|-- Project Name |-- .gitignore |-- main.toe |-- subprocess1.toe |-- subprocess2.toe |-- setup.bat |-- config.json |-- src | |-- scripts | | |-- py | | | |-- SomeExtensionNameEXT.py | | |-- glsl | | | |-- particles_update.frag | |-- tox | | |-- raster_template.tox |-- assets | |-- binaries | | |-- dlls | | |-- exe | |-- mov | |-- img | |-- ref | |-- data
The main entry point of the TD project should be clearly delinated at the project directory level. This file should be the first one a new developer opens when getting started with the project. On all projects we like to use main.toe
as the top level file name. Backups in TD should be either disabled (this is what version control is for ) or should be configured to be saved into a Backup folder.
HAP
or NOTCH
files are great for playback. Unfortuneatly, these files can get VERY large. Ideally you should use .gitignore to ignore all files in the mov
directory to keep them out of the project. On cloning the repo a combination of .bat scripts and or manual copying from seperate distro links should be use to get the file up to speed. Ideally the projects README.md
will have project and or organization specefic guidelines on how a new developer can go about getting content files.
If the project is planned for multiple deployments with machine specefic variables it's good practice to use a config.json
file to store these configurations on a per-machine basis. Ideally the team will combine this with 3.1 to make deployment onto production hardware a little less painful. An incomplete list of some of these variables might entail:
- external server IPs - Serial port designations - monitor configuration - Spout sender and receiver names - Hardware identifiers - e.t.c.
Ideally this file is ignored in version control and it's the responsibility of main.toe
to create one if it doesn't exist. This can combine with #4.1
to allow for machine specefic calibration during the deployment phase.
Sometimes it's necessary to split certain parts of a TD patch out into an external subprocess to be launched from main.toe
with the addition of the Engine COMP
in newer version of Touch this has become less neccessary when dealing with certain IO considerations. However, if your project reliese on more than one TD process these toe
files should be stored in the top level of the project to make sure that references to external assets and source files don't break.
This is important. By default many TD modules will store external scripts in memory. This will make source control extremely difficult. Externalize large project specefic modules, extensions, shaders, and scripts early and reference them using relative paths. i.e. src/scripts/py/SomeGreatEXT.py
not C:\Users\Dave\Touch\PROJECT\script
By enforcing this early and often the team or organization will benefit from conventional source control tools. Some easy canididates for externalization include
- any and all extensions - mission critical material and glsl TOP sources - Script CHOP,TOP,and DAT sources - modules and module libs - http DAT or TCP dat callbacks
Obvs this is not a hard and fast rule. If you're dropping a one liner into a TimerChop
callback that you probably don't need to externalize it. If you're writing what's essentially a webserver based on a HTTP callback then you might think about it. In theory you could also consider putting that logic into an Extension
Related to 1.5 and 3.1 The team should try and keep all top level toxes externalized and version controlled. This will essentially allow different team members to work in tandem on different aspects of the project without the fear of overwriting each other's work when it comes to merge time. Tops can be externalized via the Common
tab. Use a relative path here to prevent deployment hell
Many projects will rely on a set of external assets to function properly. All assets referenced by main.toe
should be kept in a sub folder called assets
and referenced with relative paths. This will prevent missing files when the patch is migrated from the developers local environment to production hardware. see 3.3 for a detailed discussion of file import practices.
This section will focus on the internal composition of TD Networks and their internals.
- All operators, scripts, and networks should compile with zero warnings and zero errors. If a script or TOX throws a compile error it should be corrected or mitagated as quickly as possible, regardless of whether or not it effects the functionality of the patch,
- do not submit networks, toxes, or scripts to source control. When another developer opens the patch they will not be able to know for certain if the broken error is mission critical or has been ignored due to loose code style requirements
The top level of a network is the first thing a new developer or user sees when they open your patch. Where possible the top level of a TD project should contain only containers
or bases
that have been clearly named based on its function.
This allows the next developer to quickly gain a high level understanding of the core functions of your patch and allows them to get up to speed on their tasks quickly. If possible, each of these top level containers should be an external tox and stored in version control
related to the above. Every container at the top level of the project can and should be assigned a global operator shortcut.
This will cut down greatly on references breaking over the course of developement and allow for some neat tricks. For example: a container that is responsible for running some post processing effects on a raster generated by a
render
network start it's chain with aSelectTOP
that uses an expression with the referenceop.render.op('final')
this allows multiple developers to work in tandem on different aspects of the project without the added burden of merging top level networks or worse, having networks over written by conflicting versions of the same project.
All variables referenced in many different places in the networks should be stored in a top level base named config
While the specefic type of variables will vary by project some good canidates for this technique include:
- project resolution. - server uris - replicator counts - content folder paths - specefic asset dimensions
When referencing the project level config
top use expressions
to keep your networks clean. global operator shortcuts
can configured in the Common
pane of the network operator.
This allows you to reference the project configuration anywhere in the project without having to break your references.
both approaches can lead to the correct project resolution. However, if this variable is hard coded into multiple operators accross many different networks this can lead to unexpected behavior in the case of updates or scope changes.
Creative reviews are a special case in TD development. It may be desireable for the developer or development team to make spot changes based on the requests of the creative team in situ. This guide suggests that before each creative review a spererate branch is checked-out with git checkout -b review-0.X release-0.X
where X
represents the release number that will be reviewed
After the review and changes made by the team can then be merged back into the release-0.X
branch and pushed to VC.
Don't Panic! Try to follow some version of these instructions. It will make everything easier later
If a hotfix is neccessary during the install or shuowrun process the first thing you should do is not panic.
The second thing you should do is use source control to checkout a new branch on production with the prefix hotfix
and increment the release number by a decimal point.
then you should fix the bug
if you're in show run conditions take a breath and ensure that the rest of the show operates normally
once showrun