Trivia

For a more advanced voting and reward system, Muxy provides a trivia system. Trivia is made up of a series of questions, each of which has multiple answers. Viewers submit their chosen answer to the backend and a correct answer is chosen by the extension administrator. Points are awarded to the individual viewers based on their responses, and an extension-wide leaderboard is updated.

Multiple questions may be asked, one after the other, and the leaderboard will contain a sum of each viewer’s correct answers.

Questions have a numerical order field for organizing question display and a state field which can be set by an administrator to show or hide a question and to enable or disable voting.

This system is currently only available extension-wide, so all channels running an extension will see the same questions and be combined in the same leaderboard.

Administration

First, let’s cover how to create and manage a trivia-style system as an administrator.

Setting Questions and Answers

To begin a Trivia event, an administrator-level account must set one or more questions with associated possible answers. Here we are creating a single question with three options.

NOTE: Currently extensions using the trivia system are limited to 64 questions.

const opts = new Muxy.DebuggingOptions();
opts.role('admin');
Muxy.debug(opts);

const sdk = new Muxy.SDK();
sdk.addExtensionTriviaQuestion({
  id: 'first-question',
  name: 'This is the 1st trivia question',
  short_name: '1st Question',
  description: 'This is the first question viewers will be able to vote on',
  image: 'https://picsum.photos/200/200/?random',
  order: 1
});

sdk.addExtensionTriviaOptionToQuestion('first-question', {
  id: 'first-option',
  name: "The first question's first option",
  short_name: '1st option',
  description: 'This is the first option of the first question',
  image: 'https://picsum.photos/200/200/?random',
  order: 1
});

sdk.addExtensionTriviaOptionToQuestion('first-question', {
  id: 'second-option',
  name: "The first question's second option",
  short_name: '2nd option',
  description: 'This is the second option of the first question',
  image: 'https://picsum.photos/200/200/?random',
  order: 1
});

sdk.addExtensionTriviaOptionToQuestion('first-question', {
  id: 'third-option',
  name: "The first question's third option",
  short_name: '3rd option',
  description: 'This is the third option of the first question',
  image: 'https://picsum.photos/200/200/?random',
  order: 1
});

Them image and order fields are optional.

Updating and Removing Questions and Options

To change a question or option’s values, simply call the add methods above with the same id.

const opts = new Muxy.DebuggingOptions();
opts.role('admin');
Muxy.debug(opts);

const sdk = new Muxy.SDK();
sdk.addExtensionTriviaQuestion({
  id: 'first-question',
  name: 'This is the 1st trivia question',
  short_name: '1st Question',
  description: 'This is the first question viewers will be able to vote on',
  image: 'https://picsum.photos/200/200/?random',
  order: 1
});

sdk.addExtensionTriviaQuestion({
  id: 'first-question',
  name: 'This is the 1st trivia question with correct text',
  short_name: '1st Question Corrected',
  description: 'This is the first question viewers will be able to vote on',
  image: 'https://picsum.photos/300/300/?random',
  order: 1
});

To remove a question or option use the remove methods:

sdk.removeExtensionTriviaOptionFromQuestion('first-question', 'first-option');

sdk.removeExtensionTriviaOptionFromQuestion('first-question');

Transitioning Question State

Every trivia question has a state field that can be used to restrict or allow viewer access to trivia questions by the server. These are enumerated in Muxy.TriviaQuestionState.

Available states:

state value description
Inactive ‘state-inactive’ This question will not be returned to viewers or broadcasters.
Unlocked ‘state-unlocked’ This question will be returned to and accept votes from viewers.
Locked ‘state-locked’ This question will be returned to viewers but any attempted votes will be rejected by the server.
Results ‘state-results’ This question will be returned to viewers and will include vote result values in the response. Votes sent to a question in this state will be rejected by the server.
const opts = new Muxy.DebuggingOptions();
opts.role('admin');
Muxy.debug(opts);

const sdk = new Muxy.SDK();
sdk.setExtensionTriviaQuestionState('first-question', Muxy.TriviaQuestionState.Unlocked);

When transitioning to state Results, you must provide the option id of the winning option. The server will use this information to calculate the vote result percentages and update the leaderboard.

const opts = new Muxy.DebuggingOptions();
opts.role('admin');
Muxy.debug(opts);

const sdk = new Muxy.SDK();
sdk.setExtensionTriviaQuestionState('first-question', Muxy.TriviaQuestionState.Results, 'first-option');

Viewers

Now that we have questions and answers in our system, your viewers can request the current list and begin voting on unlocked questions.

Getting a List of Questions

You can request the list of current questions at any time. The response will change depending on what access rights your user has. For example, viewers will not see trivia questions that are listed as inactive, but admins will. Also the results field of each question will contain vote information for the current user, and winner information if a winner has been chosen by the admin.

const opts = new Muxy.DebuggingOptions();
opts.role('viewer');
Muxy.debug(opts);

const sdk = new Muxy.SDK();
sdk.getExtensionTriviaQuestions().then(response => {
  console.log(`Found ${response.questions.length} questions`);
  response.questions.forEach(q => {
    console.log(q.name);
    q.options.forEach(o => {
      let optionStr = `\t- ${o.name}`;
      if (q.results) {
        // If the current viewer sent a prediction for this
        // question, it will come back in the `you` field of
        // the `results` object. This field will be `undefined`
        // if no prediction was sent.
        if (q.results.you && q.results.you === o.id) {
          optionStr += ' (your vote)';
        }

        // If an admin has set a winning option, the id of the
        // winning option will be returned in the `winner` field.
        if (q.results.winner && q.results.winner === o.id) {
          optionStr += ' !winner!';
        }
      }

      console.log(optionStr);
    });
  });
});

For the examples above, this script may output:

This is the 1st trivia question
  - The first question's first option (your vote)
  - The first question's second option !winner!
  - The first question's third option

Predicting a Winner

Viewers can predict the winner for a given question as long as voting for that question is open. Multiple votes from the same user will only count once, with their last sent vote being used.

const opts = new Muxy.DebuggingOptions();
opts.role('viewer');
Muxy.debug(opts);

const sdk = new Muxy.SDK();
// Current user is voting for the second option of the first question.
sdk.setExtensionTriviaQuestionVote('first-question', 'second-option');

Trivia “Teams” and Leaderboard

One common use of the trivia system is to pit broadcasters against each other. To make this easier, we provide optional team information in all trivia endpoints.

A viewer is assigned to a team the first time they successfully submit a prediction. The team is set to the channel they are viewing when the prediction is sent. After this point, they can submit votes from any channel, but their predictions (and any associated leaderboard points) will count towards their original team. It is not possible for a viewer to change their team.

Broadcasters always cast votes for their own channel and are returned in results as the special broadcaster_correct field.

In the past we have gated this feature, by showing a dialog to the viewer when they submit their first vote and confirming that they want to join the team of the current channel they are watching.

This feature is entirely optional and can be safely ignored if you are not interested in using it.

Leaderboard

At any time, an admin may request the current status of a prediction leaderboard. However, the leaderboard values only update when a winner is declared for a new question.

const opts = new Muxy.DebuggingOptions();
opts.role('admin');
Muxy.debug(opts);

const sdk = new Muxy.SDK();
sdk.getExtensionTriviaQuestions().then({ questions } => {
  sdk.getExtensionTriviaLeaderboard().then({ leaderboard } => {
    console.log('Current Leaderboard');
    console.log('-------------------');

    leaderboard.forEach(team => {
      console.log(`\nTeam's Twitch ID: ${team.team_id}`);
      console.log(`Current Score: ${team.combined_score}`);
      team.questions.forEach(results => {
        console.log('* ' + questions.find(q => q.id === results.question_id).short_name);
        console.log(`\t - Broadcaster was ${results.broadcaster_correct ? 'correct' : 'incorrect'}`);
        console.log(`\t - Team had ${Math.floor(results.team_participation * 100)}% participation`);
        console.log(`\t - And were ${Math.floor(results.percent_correct * 100)}$ correct`);
        console.log(`\t = There were ${results.team_votes} total votes`);
      });
    });
  });
});

An example response from the above script:

Current Leaderboard
-------------------

Team's Twitch ID: 123456
Current Score: 100000
* This is the 1st trivia question
  - Broadcaster was correct
  - Team had 83% participation
  - And were 68% correct
  - There were 372 total votes

Team's Twitch ID: 654321
Current Score: 82983
* This is the 1st trivia question
  - Broadcaster was incorrect
  - Team had 49% participation
  - And were 38% correct
  - There were 2760 total votes