runShot (autoplaying = false) {
    if (this.hasActiveRunner) return

    if (!Array.isArray(this.commands) || this.commands.length === 0) {
      this.systems.sound.stopAllSounds()
      return
    }
    this.onPlay()

    this.undoCommands.ignoreUndoCommands = false
    this.mode = FORWARD_MODE

    if (autoplaying) {
      // If this shot is being played from an autoplay node, we need to ensure we
      // autoplay back through the undo.
      this.undoCommands.pushUndoCommand(new SyncFunction(() => {
        this.systems.autoplay.autoplay = true
      }))
    }

    const currentShot = this.commands.shift()
    this.undoCommands.pushUsedForwardCommands([...currentShot])

    this._runShot(currentShot)

    if (this.wasCancelled) {
      this.cancelShot()
    }
  }
Runs the next shot, mutating `this.commands`.