Sending simulation results to Storyline variables

You can embed a BranchTrack simulation in an Articulate Storyline 360 course and let your course know what the learner does in it: the scene on screen, the character's emotion, the score, and when the learner finishes. Storyline saves this in its own variables, so you can react with ordinary Storyline triggers, for example unlock the Next button or show the score. You paste one ready script; you don't write any code yourself.

What you can build

  • Keep the Next button locked until the learner finishes the simulation.

  • Mark the course complete in your LMS when the simulation is finished.

  • Show the score in Storyline, on the same slide or later in the course.

  • Show different slides based on the result. For example, learners with a high score skip ahead, and the others get a review first.

Set it up

You need Storyline 360 and a published simulation. In BranchTrack, copy the simulation's embed code (Publish → Live Link) and take the address from it: the part in quotes after src=.

  1. Add the simulation. In Storyline, choose Insert → Web Object, paste the address, and choose to display it on the slide.

  2. Create the variables you need. In the Variables window, add the ones from the table below. You only need the ones your course uses. The names must be exactly as in the table.

  3. Paste the script once. Open View → Slide Master, select the top master slide, and add a trigger: Execute JavaScript when the timeline starts. Paste the whole script from the section The script at the end of this article. From now on, the variables update by themselves.

  4. Use the variables in normal triggers. For example: Jump to next slide when bt_status changes, if bt_status = finished. To show the score, type %bt_score% in a text box.

  5. Publish to test. Storyline's Preview doesn't run scripts. Publish to Review 360, the web or your LMS to see it work.

Variables

Variable Type What it holds
bt_status Text not started, started or finished
bt_saved True/False True once the result is saved in BranchTrack
bt_project Text Name of the simulation being played
bt_scene Number Number of the scene on screen, as shown in the editor
bt_emotion Text happy, normal, puzzled, unhappy or angry
bt_score Number Total score so far
bt_score1, bt_score2, bt_score3 Number Up to three separate scores, if you use multiple scoring. A score appears here only after the learner earns points in it, so check the matching name variable to see which score it is.
bt_score1_name, bt_score2_name, bt_score3_name Text Names of those scores, such as Empathy
bt_choices_made Number How many choices the learner has picked
bt_last_choice Text Text of the last choice picked
bt_last_choice_to Number Scene the last choice leads to (0 when it ends the simulation)
bt_free_text Text The learner's last typed answer in a free text scene
bt_path Text Scenes visited, such as :1:3:7:
bt_minutes Number Minutes it took to finish
bt_attachments_opened Number How many attachments the learner opened
bt_last_attachment Text Name of the last attachment opened

Tip: to check whether the learner visited scene 7, use the condition bt_path contains :7:. Use both colons, so scene 17 doesn't count.

Good to know

  • It works in one direction. The simulation tells Storyline what happens. Storyline can't tell the simulation what to do, for example jump to a scene.

  • The simulation must be on the slide as a web object. If it opens in a new browser window, Storyline doesn't get the data.

  • Replay resets the variables. When the learner clicks replay, bt_status goes back to started and the scores start from zero.

  • One simulation at a time. The variables always describe the simulation the learner is playing now. In a course with several simulations, copy each result into your own variable when it finishes, for example: Set sim1_score to bt_score when bt_status changes to finished.

  • Not only Storyline. The same data reaches any web page that embeds a BranchTrack simulation: Adobe Captivate, Lectora, iSpring, your intranet or your own app. If your developers need the technical details, contact BranchTrack support.

The script

Copy everything below, from the first line to the last, and paste it into the Execute JavaScript trigger on the master slide. You don't need to change anything in it.

// BranchTrack → Articulate Storyline bridge
// ---------------------------------------------------------------------------
// Copies everything a BranchTrack simulation reports into Storyline variables,
// so the rest of your course can use ordinary, no-code Storyline triggers.
//
// Setup
// 1. In Storyline, create the variables listed below (names are case-sensitive;
//    create only the ones you need — the rest are skipped).
// 2. Open View > Slide Master, select the master slide, and add a trigger:
//    Execute JavaScript, when the timeline starts. Paste this whole file.
//    (The master runs on every slide, so the bridge is on even when a learner
//    resumes mid-course. It installs itself only once.)
// 3. Insert your simulation with Insert > Web Object, using its embed link.
// 4. Publish (to Review 360, the web or your LMS) to test: Storyline's
//    Preview does not run JavaScript.
//
// Variables                   Type        Value
// bt_status                   Text        'not started' → 'started' → 'finished'
// bt_saved                    True/False  true once the finished run is saved in BranchTrack
// bt_project                  Text        title of the simulation being played
// bt_scene                    Number      number of the scene on screen (as in the editor)
// bt_emotion                  Text        happy | normal | puzzled | unhappy | angry
// bt_score                    Number      total score so far
// bt_score1 … bt_score3       Number      running total of the 1st, 2nd and 3rd score
// bt_score1_name … _name      Text        names of those scores, e.g. 'Empathy'
// bt_choices_made             Number      choices picked in this run
// bt_last_choice              Text        text of the last choice picked
// bt_last_choice_to           Number      scene the last choice leads to (0 = it ended the run)
// bt_free_text                Text        last answer the learner typed on a free-text scene
// bt_path                     Text        scenes visited, e.g. ':1:3:7:' — test with "contains :7:"
// bt_minutes                  Number      minutes from start to finish
// bt_attachments_opened       Number      attachments opened in this run
// bt_last_attachment          Text        title of the last attachment opened

(function () {
  if (window.branchtrackBridge) {
    return;
  }
  window.branchtrackBridge = true;

  var player = GetPlayer();
  var choicesMade = 0;
  var attachmentsOpened = 0;

  function set(name, value) {
    if (value === undefined || value === null) {
      return;
    }
    try {
      player.SetVar(name, value);
    } catch (e) {
      // variable not created in this course: skip it
    }
  }

  function setResults(results) {
    if (!results) {
      return;
    }
    if (typeof results.score === 'number') {
      set('bt_score', results.score);
    }
    (results.scores || []).slice(0, 3).forEach(function (score, i) {
      set('bt_score' + (i + 1) + '_name', score.name);
      set('bt_score' + (i + 1), parseInt(score.total_score, 10) || 0);
    });
    set('bt_path', results.path_indexes);
  }

  function reset() {
    choicesMade = 0;
    attachmentsOpened = 0;
    ['bt_score', 'bt_score1', 'bt_score2', 'bt_score3', 'bt_scene', 'bt_choices_made',
      'bt_last_choice_to', 'bt_minutes', 'bt_attachments_opened'].forEach(function (name) {
      set(name, 0);
    });
    ['bt_last_choice', 'bt_free_text', 'bt_path', 'bt_last_attachment'].forEach(function (name) {
      set(name, '');
    });
    set('bt_emotion', 'normal');
    set('bt_saved', false);
  }

  window.addEventListener('message', function (event) {
    var data;

    try {
      data = typeof event.data === 'string' ? JSON.parse(event.data) : event.data;
    } catch (e) {
      return;
    }
    if (!data || data.provider !== 'branchtrack') {
      return;
    }

    var details = data.details || {};

    switch (data.type) {
      case 'branchtrack:player:start':
        reset();
        set('bt_project', details.project && details.project.display_title);
        set('bt_status', 'started');
        break;

      case 'branchtrack:player:scene':
        set('bt_scene', details.scene.index);
        set('bt_emotion', details.scene.emotion || 'normal');
        setResults(details.results);
        break;

      case 'branchtrack:player:choice':
        choicesMade += 1;
        set('bt_choices_made', choicesMade);
        set('bt_last_choice', details.choice.content);
        set('bt_last_choice_to', details.choice.to_node_index || 0);
        set('bt_free_text', details.choice.custom_content);
        break;

      case 'branchtrack:player:attachment':
        attachmentsOpened += 1;
        set('bt_attachments_opened', attachmentsOpened);
        set('bt_last_attachment', details.title || (details.attachment && details.attachment.filename));
        break;

      case 'branchtrack:player:finish':
        setResults(details.results);
        if (details.results && details.results.started_at && details.results.finished_at) {
          var ms = new Date(details.results.finished_at) - new Date(details.results.started_at);
          set('bt_minutes', Math.max(1, Math.round(ms / 60000)));
        }
        // last, so triggers watching bt_status already see the final score
        set('bt_status', 'finished');
        break;

      case 'branchtrack:player:finish:success':
        set('bt_saved', true);
        break;
    }
  });
})();

See also

Emotion meter colors for WCAG AAA
Copilot capabilities