Managing Decisions

One of the most intuitive ways to make an interactive video, well, interactive, is by decision points. For example, If we look at Charlie Ruins Buzzfeed on Eko, we see that the viewer decides on how the video continues by selecting one of the choices available (in this case, by clicking on the UI) – the stream will be modified according to it.

This process requires several management abilities related to the stream, the flow of the video and the synchronization between the video stream and the UI layer.

What is a decision?

The common pattern of decision making is as follows:

  1. Define a time frame to allow the user to decide how the story will unfold. This time frame is called Decision Time.
  2. Provide the viewer with UI components that allow selecting what should happen next and provide visual representation of the decision time.
  3. When the decision is made a relevant node is appended to the playlist.
  4. If the decision time had elapsed no decision was made, some node is appended to the playlist. The show must go on!

The decision plugin makes decision handling easy.

Decisions can be implemented using the InterludePlayer and Node APIs. However, we strongly recommend using the decision plugin where applicable. Implemeting decisions using the low level APIs is error prone since there are many pitfalls such as prefetech configurations, cue points handling and UI state management.

Decisions types

When the viewer makes an active interaction that triggers a decision making process it is called an explicit decision.
Sometimes, however, a decision will be made for the user under the hood. A common case is when the decision time ends and no explicit decision was made. This is called an implicit decision.

It is often useful to know, once a decision is made, whether it’s explicit or implicit. The events and reduxState of the decision plugin include a boolean variable called autoDecided. It is set to true when the decision was made implicitly.

Adding decisions

Adding a decision is easy. The decision.add function registers a decision on a node. The following code registers a decision on the question node. The stream will continue to either ‘toBe’ or ‘notToBe’ nodes.

let decision = player.decision.add('question', ['toBe', 'notToBe']);

Adding a decision can be controlled via options. Here is a more common example:

let decision = player.decision.add('question', {
    // viewer can decide to be or not to be
    children: ['toBe', 'notToBe', 'youHaveToChoose'],
    // if no decision was made continue with youHaveToChoose node
    defaults: 'youHaveToChoose',
    // decision time starts 4 seconds after the question node starts playing
    startTime: 4,
    // decision time ends 3 seconds before the question node ends
    endTime: -3
});

Eko Studio adds decisions for each node by default. In most cases you will not be adding decisions yourself. The decision.get API can be used to retrieve decision instances added by the Studio.

Making decisions

The decision.add returns an instance of DecisionInstance. You make an explicit decision by calling DecisionInstance.make with the id of a decision’s child node. For example:

// make the decision 5.25 seconds into the question node
let questionNode = player.repository.get('question');
questionNode.on('timeupdate:5.25', function() {
    let decision = player.decision.get(questionNode);
    decision.make('toBe');    
});

Making a decision takes care of the following:

  1. The child node is pushed to the playlist.
  2. The decision’s state is set to made.
  3. DecisionInstance.made event is triggered.
  4. The redux state is updated.

Decisions can be made only when they are active (e.g. in their decision time).

The decider

The decider function takes care of implicit decisions. An implicit decision is made by calling the make function without a node id or when the decision time ends without any call to the make function.
The decider is called with the active node, array of available children and the options object associated with the decision. It should return the next node to be pushed to the playlist or false to end the stream. Learn more on the decider in the API docs.

The default decider picks a random node from the defaults array. If no defaults were provided the children array is used as defaults.

Use DecisionInstance.decider to override a decision’s decider or decision.decider to override the global decider. In the following example, if no explicit decision is made before the time runs out, the next node that will be pushed to the playlist will match the current time, either day or night.

let decision = player.decision.add('question', ['day', 'night']);
decision.decider = function(node, children, options) {
    let hour = (new Date()).getHours();
    return (hour >= 6 && hour < 18) ? 'day' : 'night';
}

Building decision UI

It is assumed that you are already familiar with the UI development concepts explained in ui for interactive video and state and redux.

It is common to provide the viewer some UI to make explicit decisions. Each child is represented by a button component. When making a choice all the buttons are hidden or moved to some disabled state. It is also a good practice to show the viewer a timer indication of the remaining decision time.

Eko Studio takes care of this for you. The code generated from the Studio includes decisions, buttons and timers. See Customizing Studio UI to learn more.

If you need to build a custom UI from scratch we’ve got you covered as well. The decision plugin provides everything needed in its reduxState. See Create UI From Scratch and Building a Scoring System to learn more. In addition check out the decision plugin API.

Rate this page: X
Tell us more!