Why do we need to own our networks?
Have you ever been using TouchDesigner and have no idea why things are happening in your network? Has your output been not what you were expecting? Do you have a bug somewhere or events happening out of order and you have no idea why? This normally happens if you’re just getting started or even if you’re an experienced user working on a really complex project. At a certain point, you can’t keep every single CHOP channel or DAT script memorized in your head. You eventually lose track of things and you start answering yes to the questions I asked above. Over the years, I’ve found a few practices that help me own my networks, regardless of complexity, so that they never escape me. Let’s dive in!
Use a Trail CHOP
An operator I see used so infrequently is the Trail CHOP. This is the easiest thing on the list. Seriously. Using a Trail CHOP will probably solve most of your CHOP related problems! This little operator is extremely helpful in understanding signals passing through your networks. Those signals could be audio signals, MIDI/OSC control signals, or other CHOP signals in your network. What a Trail CHOP does is visualize the input channels over a period of time specified in the parameters. The example below shows a Timer CHOP’s outputs and allows you to visually compare the timer_fraction channel and the cycles_pulse channel.
One trick I always use with the Trail CHOP is to connect multiple inputs and then change the display to show all channels on 1 graph. This is great for comparing different signals and values. I use this especially for debugging if I find certain events are happening out of order. To do this, you have to activate the viewer of the Trail CHOP, right click on the background, go to “Number of Graphs”, and select “All channels on one graph.”
This view can become confusing at times, but if you name your channels before hand, it’s an incredibly useful way of directly comparing the values coming out of different CHOPs.
Leave lots of comments
The first one is what separates good programmers from great programmers. Comments seem like that thing you do when someone asks. Like when your parents used to tell you to clean your room, or if your business partner tells you to clean you desk. As boring as it sounds, leaving lots of comments can turn even the most vicious network full of long Python scripts into a few sentences you can read and understand in seconds. This avoids the huge issue that happens when you might be working on a project/feature, then get side tracked either on a totally unrelated project or you get stuck developing another feature, and after a few days or weeks you come back and try to pick up where you left off. This feeling sucks! Trying to remember where your mind was at in the past is a futile pursuit and is bound to create some bugs that may or may not be easily found.
Not only are comments great for owning your own networks, but they make ownership transfer much easier. No more trying to decipher variable names or trying to mind-meld with another person. You can quickly and easily pick up even complex Python operations as long as they have some decent commenting along the way.
Use Print and Debug statements
I always have print() statements riddling my Python scripts as I’m developing projects. I’m no phenom coder and I suspect most people are in the same boat as me: you learned coding while also learning TouchDesigner. In that case, why would I not constantly print out variables, outputs, inputs, and anything I can along my Python signal path to make sure what’s going in is what is expected and what’s coming out is equally expected? It seems like common sense, but I’ve seen far too many developers write cryptic and long Python scripts with not a single print statement, and then they’re confused when the output is weird and they don’t know where things went wrong. These print() statements shouldn’t stay in the code permanently. Once everything is falling into place and the project is delivering, I usually comment out all the print() statements in the project using the built-in search functionality of TouchDesigner, like below.
A lot of folks also like to use debug() instead of print() for areas where the print() statement may be permanent because it outputs a little bit more information, including which operator is doing the printing to console. So feel free to use both based on your own preference.
It’s always funny talking to colleagues, and we talk about how our networks are really boring because they’re stable, easy to traverse, compartmentalized by functionality, and super simple without crazy tangles of wires everywhere. This is the opposite state you’d expect to get at when you’re starting with TouchDesigner. You see crazy networks with hundreds of operators all wired together in a cacophony of generative design. Those were the days! Now I barely have more than 10 operators ever inside a single network, because if it’s more than 10 operators that means I’m probably building a feature/piece of functionality and it should go inside of a container. Give that container a nice name and either some customer parameters to control it or some inputs & outputs connections and you’ll soon find that no matter how hard you try, your network will always be in control. I know it sounds boring, but staying in control of your network through compartmentalization looks better than anything you could add to your CV when applying for a TouchDesigner development job!
Whether you’re working on a million dollar project or just getting started with TouchDesigner, staying in control of your networks should be a goal always on your mind. The moment when you lose control isn’t always obvious until it’s too late and you have crazy bugs in your network or you end up confused beyond belief. To avoid that situation, you can use a combination of Trail CHOPs, print/debug statements, compartmentalizing, and code commenting to keep things in control for longer than would normally be possible. Happy coding!