Stroke Sequence AyvaScript

For use with Ayva Stroker Lite.

This script plays a sequence of strokes. The exact sequence and the parameters of each stroke are at the top of the script and can be customized to your liking.

A video demonstration with the default parameters is available here.

The JSON file you can use to import this routine directly into Ayva Stroker Lite:
stroke-sequence.json (1.6 KB)

When this script is randomly selected in Free Play mode, Ayva will transition smoothly into the sequence and relinquish control after the sequence finishes (smoothly transitioning into the next random stroke or script selected). If activated manually the sequence will smoothly repeat itself indefinitely.

Customizable Parameters:

  • strokes: List of strokes you want included in the sequence. Each entry is an array with the name of the stroke, the bpm, how long to perform the stroke in seconds, and optionally how long it takes to transition into the stroke.
  • defaultTransitionSeconds: Exactly what it says :blush:. This value is used when a stroke entry doesn’t specify a transition time.

Default Sequence (composed of Library Patterns):

  • short-high-roll-forward: Strokes the top half with a small amount of pitch motion 90° out of phase.
  • tease-up-down-circle-right: Strokes the top third while pitched back, and with some sway and roll motion 90° out of phase.
  • short-low-roll-backward: Strokes the bottom half with a small amount of pitch motion 90° out of phase.
  • grind-circular: Grinding motion at the base (sway, pitch, roll).

The source code is included at the end of this post for your convenience (you can also view the source in Ayva Stroker after importing as well).

To learn more about AyvaScripts and how to create or use them, see the AyvaScript Documentation.

If you like my work, please consider supporting me through Patreon :blush:.

Thank You and Happy Stroking! :heart:

Stroke Sequence Source Code:

 * Customizable Parameters
const strokes = [
  // These are the strokes you want to include in the sequence.
  // Each entry is an array with the following data:
  //   0 - name of the stroke (or config).
  //   1 - bpm of the stroke
  //   2 - how long to perform the stroke in seconds
  //   3 - (optional) how long it takes to transition into the stroke.
  ['short-high-roll-forward', 60, 3],
  ['tease-up-down-circle-right', 30, 4, 5],
  ['short-low-roll-backward', 140, 5, 5],
  ['grind-circular', 45, 2],

  // Add any additional stroke entries here...
const defaultTransitionSeconds = 2;

 * Setup
this.currentStroke = this.currentStroke || GLOBALS.input;

 * Stroke Sequence Loop
for (let [stroke, bpm, seconds, transitionSeconds] of strokes) {
  let secondsOffset = 1; // Offset to add to the duration to account for transition time.

  if (!this.currentStroke) {
    this.currentStroke = new TempestStroke(stroke, bpm).bind(ayva);
    yield* this.currentStroke.start();
  } else {
    secondsOffset = transitionSeconds ?? defaultTransitionSeconds;
    this.currentStroke = this.currentStroke.transition(
      stroke, bpm, secondsOffset

  const duration = new VariableDuration(seconds + secondsOffset);

  GLOBALS.output = this.currentStroke;

  while (!duration.complete) {

 * End the sequence if we're in free play mode.
if (GLOBALS.mode === 'freePlay') {
  this.complete = true;