Keeping Time in TouchDesigner

Time in TouchDesigner is a strange thing. Especially when it comes to the context of building projects that have time-based triggers or actions or scripts. Do you lock things to the timeline? Do you run Python scripts on delay? Do you lean into Timer CHOP? This is precisely the problem! There are so many different ways to count time in TouchDesigner that it can be overwhelming to know which is best. In this post, I talk through the most common strategies for keeping time and give you advice on when to use each of them.

DAT Time

This one is one of the easier ways to approach time. What I mean by DAT time is specifically delaying execution of scripts when using the run() method. You might see this in other peoples projects or tools as a Python line like this:

op('some_script').run(delayFrames = 5 * me.time.rate)

To break this down quickly:

op('some_script') gets us to the script we want to run.

.run() tells TouchDesigner to run the script we just targeted.

The secret here is delayFrames = 5 * me.time.rate which tells TouchDesigner’s engine to delay execution of some_script by a certain number of frames. While frames might not be intuitive, there’s a quick bit of math were we can use me.time.rate to get the project frame rate and then multiply that by the number of seconds we want to wait.

So in this case, we’re waiting 5 seconds before running the script.

The benefit of this method is that there aren’t a lot of moving parts that could get tripped up. We can essentially put a timed event into the TouchDesigner Python queue and know that it’ll run on time. In the other methods we’ll mention, like using CHOPs, if the system starts dropping frames then CHOP channels could get timesliced or skipped entirely and there is a chance that you might miss your moment of execution! It’s great because it is easy to quickly and programmatically say “Do something after X seconds” and you won’t have to worry about it any further.

This can be especially intuitive if you’re already working with Python a lot either in scripts or extensions. You don’t have to go through the trouble of having your script trigger a timer, and then have the timer trigger another script. You can cut that whole overhead out by leaning into the delayFrames argument of the run() method.

CHOPs timers

There are many different ways to keep track of time with CHOPs so I’ll break them down individually here.

Timer CHOP

This is the most common way you’ll see most professionals count time in their projects if they aren’t using the DAT method mentioned above. Timer CHOP is fantastic. I remember back in the day when Timer CHOP wasn’t in TouchDesigner! Those were hard times! Timer CHOP is fantastic way to keep time because it is so feature rich out of the box. It has different ways it can keep time, different types of outputs, ways to turn on and off cycling of the timer, Python callbacks that can be triggered at certain state changes in the timer, and more! It’s pretty bulletproof and easy to use. You just have to set the parameters of the CHOP however you want, and hit start! Not much more to say about this other than it’s heavily used.

Constant CHOP + Speed CHOP

Before the days of Timer CHOP this was one of the main ways to count time! You would connect a Constant CHOP to a Speed CHOP and set the Constant CHOP value to 1. This essentially creates a seconds timer inside of TouchDesigner. From here there were different ways you could parse out the timer into some triggers. You could for example use a Logic CHOP and set the Convert Input parameter to Off When Outside Bounds to create a trigger based on the time value. If you want the 0 to 1 trigger to happen after 60 seconds you can set the bottom boundary to 60 and the top boundary to 61. Then once your Count CHOP counts up to 60 you’d get a quick 0 to 1 trigger you can use to run scripts or change other elements of your network. This method is less common now because of the Timer CHOP’s popularity and feature set, but it can still be useful for a few things.

One benefit this has is that you can count time without knowing how much time you want to count. When you use the Timer CHOP or DAT delayFrames, you have to set the timer length or delayFrames value before you start the timer and changing that in mid-flight can be very difficult. For the Constant CHOP + Speed CHOP combo, you can essentially just start counting time and always refer back to how much time has elapsed since you started it. You can loop the timer if you want in the parameters of the Count CHOP or you can let it run forever (within reason!) and just check it’s value periodically. This can be great for driving shaders or other generative art pieces that need a time counter to drive animations in them.

JOIN THE INTERACTIVE & IMMERSIVE HQ PRO

Want to take your TouchDesigner career to the next level?

The HQ PRO is the only comprehensive TouchDesigner training resource available.

If I’d had access to the tutorials, workshops, coaching and community found in the HQ PRO when I first started with TouchDesigner, I would have hit my career goals years sooner

Clock CHOP + Schedule CHOP

When it comes to keeping time, scale is really important. If wanted to keep track of how many days have passed since my installation has been active I wouldn’t lean into DAT time or Timer CHOPs. Instead I would turn to Clock CHOP. Clock CHOP gives you access to the system clock and gives you CHOP channels that represent the day of the week, the current hour, whether it’s AM or PM, what day of the month it is, and more. These can be a great way to keep track of time at a larger scale. You can take the outputs of the Clock CHOP and plug them into Count CHOPs or CHOP Execute DATs to run triggers and script as the days change or the hours change. It’s extremely useful when it comes to permanent installations and having certain things happen over the course of the day or having the piece change over the day.

Another way to approach larger time scales is to the use the Schedule CHOP. This is a custom operator made by Richard Burns that takes aspects of the Clock CHOP and expands on them. You can download it from Richard’s GitHub repo and you can learn more about it on the Derivative Community page here. It’s a great resource to check out if you’re building triggers into your system built on larger periods of time passing or anything related to the system clock.

Wrap up

Time is a strange concept in general. Especially in TouchDesigner there are so many different ways to keep track of time and count time. Between DAT/Python methods and all the CHOP methods you should be able to find an appropriate way to keep time for your project. I’d recommend experimenting with all these different methods to find the strengths and weaknesses of each and also to see what works best with your project structure and preferred techniques to use in the project. At the end of the day, you have lots of methods and I hope this post helps you explore a method you weren’t aware of before!