Teletype 3.+ feature requests and discussion



DEL ops copy the I value from their calling script when they are queued. so currently a DEL.X command would queue each delayed command with the same I value.

source code wise it would be possible to add functionality similar to L with I being incremented on each subsequent delay command. maybe we could add a DEL.L op for that functionality?


Perhaps so! I guess if it were DEL.L, you’d want DEL.L x y z with x, y, z respectively start, end, time? A couple use cases I thought of. The original one is probably in the sequential switching family:

DEL.L 2 4 500: TR.TOG I

You could create stair stepped wave forms:

DEL.L 1 10 200: CV 1 * I V 1

You could create something that sounds like a feedback delay, but switching oscillators for each echo:

DEL.L 1 4 250: TR.P I

Would DEL.L exhibit the ratcheting style behavior where the first is immediate?

I’m sure there are others use cases, but thought I’d throw a few ideas out to see if others think it would be useful. Thoughts?


Testing TELETYPE 3.0.0 4FFDD58

J RRAND 1 100
K RRAND 1 100
$ 2


Watching the variable display, X and Y update to random values between 1-100 when a trigger is received on 1. Would we expect X and Y to stay at 0 when a trigger is received on 1? Right now J and K seem to behave like globals in this test case.

Or is this intended behavior since script 1 called script 2? J and K effectively serving as parameters.

Some nominal testing on DEL.X and DEL.R they seem to work as expected so far!


likely it’s replicating the behaviour of I variable - when a script is called from another script, its I value gets set to what it is in the calling script so you can do things like L 1 5: SCRIPT without having to assign the current I value to one of the global variables (if you need to use it in the script being called).

there is definitely a benefit of having local variables that are not affected in such manner, so you can use them to store values between calls. but i’d worry about introducing special cases… perhaps it’s okay in this case as I is already special since it gets modified by the loop op.

for delays and stack there is a question of whether you want a variable value to be “frozen” at the moment of defining a delay (or adding to stack). i can see both frozen and live behaviour to be useful, but not sure how would we indicate that. maybe another variation of DEL and S to make the choice explicit?

we can’t do that right now as # is treated as a special character when saving presets to usb, so that would need to be changed (in a way that would make it backwards compatible).


In my test scene above though, firing a trigger into 2 in this case should show X and Y = 0, right? In which case I still think something might be not quite as expected here, Tripping input trigger number 2 leaves X and Y unchanged from their current state.

Edit, I think you’re right @scanner_darkly. A simplified test:

J 1

J 2


Pressing F1, F2, F3 all result in X = 0.

I think I kind of like it this way then. If you call a script from another, you get two input parameters. In a way that destination script becomes kind of like a function (with the exception that it doesn’t return anything, though it could still set globals or pattern values). But having inputs to pass seems pretty useful/powerful.


one important point is - if a script is not called from another script, it will not initialize local variables to zero when you run it from a trigger or manually.

i agree it’d be nice to be able to pass additional parameters into called scripts, but being able to use them as temp storage without worrying about them getting overwritten by a caller script is super useful imo. also, you might not always want to pass all 3.

maybe a separate op for SCRIPT that would allow passing additional parameters might be a good alternative.


what values is it using for local variables then?

edit: also from what I can tell J & K seem to be working properly so far yes?


Right now it seems like it is initializing J and K when triggered manually or by Fx keys.

For example:

J + J 1

J + J 1

J + J 1
$ 4


Triggering scripts 1 - 3 results in X = 1, even repeated presses. Triggernig script 4 results in X = 0.

I think so, depending how you’re expecting them to behave! :slight_smile: If I substitute I instead of J in the scripts above, it behaves the same way.


i would expect it to keep values between calls actually…

it could initialize it with 0s when a scene is loaded and then keep values between calls.


I does behave the same way. Keeping values between calls could definitely be useful.


well my understanding of the source code is that a new execute state is created each time, but I isn’t initialized to zero. so it’s just creating a new execute state in the same memory location, therefore retaining values between calls?


it wouldn’t be the same memory location necessarily though. in any case if we want to keep values between calls we would need to store them in the scene state and initialize from that when a new execute state is created (if i understand that part correctly, i need to look at that code)


right it’s not intentional, but that’s the cause of this behavior if I understand correctly.

on your second point I think that could work something like LAST with the values being stored in the scene_script_t.


the behaviour is that it resets it to 0 on each call, according to @EqualTemperament’s test.

yeah, basically store it in the scene state and init it to 0 when a scene is loaded.


So to summarize the favored implementation is:

  • J and K are initialized to 0 in each script on scene load, and are not reset to 0 when the script is called. Instead they retain their stored value within the script. So J and K effectively represent 20 new variables (J and K * 10 scripts)
  • When a script is called from another script, I in the called script gets set to I from the calling script (this is the current behavior)
  • When a script is called from another script, J and K in the called script do not get set from the calling script, and instead retain their current value stored in the called script (this is not the current behavior)
  • Potentially an additional new to-be-named SCRIPT op could pass I, and also J and K to the called script

Does that sound right? Thought I’d type it out for clarity, since that and testing are all I can contribute here.


yep, this sounds right, thanks for the summary!


perfect! testing is a huge help don’t downplay it.

I’ll start working on this if it’s the agreed upon behavior then.


Sticking this in here as it seems like the best place for it for now:

I’ve rebased and merged:

However GitHub is have a “bad day”, so the PR hasn’t shut, nor have I been able to making any comments on the PR.

I’ll come back to it in a few hours and check that the merge really did happen and hasn’t been rolled back.


Here’s another idea. As usual, I offer it without regard for dev complexity or performance impacts because I don’t know. I could see where this would be high for both.

The idea would be to create a kind of flow control that doesn’t exist today - to execute a command when an expression evaluates to true. I think it would fit nicely as additional stack ops:

S.COND: [expr]
S.C: [expr]

So essentially it would set up a watch condition for the specified expression that is evaluated as often as possible without impacting performance. When the condition evaluates to true, it would execute the equivalent of S.POP.

There could also be flavors to pop the entire stack, or maybe even a set number of LIFO stack entries.

S.C.ALL: [expr]
S.C x: [expr]

where x is the number of stack entries to pop. Might also need:

to remove the watch condition.

I don’t use the stack all that much. For me, I think this would add a lot of use cases.


I can see the appeal of this - but wouldn’t it break the event-based paradigm to watch continuous changes in the background?