Forum Discussion
Can you show storyline quiz score as a percentage?
We've build a game show quiz with Articulate Storyline with 3 stages, 5 question in each stage with a total of 15 questions. For every correct answer, the user gets 100 point and the aim of the course is to get as much of a high score as possible. We are having issue reporting the course/quiz on the LMS we are using. We tried to run a report on our LMS to report on percentage using the field 'SCORM 2004 Quiz Data - Quiz score' but its not showing the correct percentage score. For example, one result was 1400 points (14/15) so the percentage score should show 93% but its shows 33%. Below is a screenshot showing this:
All the relevant quiz setting have been selected to score on, we have a 'submit score' trigger on the final slide when the timeline starts. Is there anything we are missing that is causing the score to show incorrectly.
Hi Nathan,
Happy to help!
Can I ask if you've tested the behavior on a different LMS to see if the scoring issue is specific to your LMS? If you haven't yet, here's a helpful article on testing courses in SCORM Cloud.
If you are able to replicate the scoring issue in SCORM Cloud, would you be willing to share a copy of your project file here or in private by opening a support case so we can take a closer look at what's happening? We'll delete it when we're done testing!
- ScottMaxwell-95Community Member
You can do this using JavaScript and xAPI statements and queries.
I'll show you the code I use.// Sends the users' answer choices and results */function sendAnswered(object, objectId, responseVar, success) {
const player = GetPlayer();
const uNamejs = player.GetVar("uName");
const uEmailjs = player.GetVar("uEmail");
const userResponse = player.GetVar(responseVar);
const uScorejs = player.GetVar("uScore");
const maxScorejs = player.GetVar("maxScore");
const scaledScore = uScorejs / maxScorejs;
let finalDuration = convertToIso(slideSeconds);
const statement = {
"actor": {
"name": uNamejs,
"mbox": "mailto:" + uEmailjs
},
"verb": {
"id": "http://adlnet.gov/expapi/verbs/answered",
"display": {"en-us": "answered"}
},
"object": {
"id": objectId,
"definition": {
"name": {"en-us": object},
"description": {"en-us": "Question in the Quiz"},
"type": "http://adlnet.gov/expapi/activities/question"
},
"objectType": "Activity"
},
"result": {
"duration": finalDuration,
"response": userResponse,
"score": {
"min": 0,
"max": maxScorejs,
"raw": uScorejs,
"scaled": scaledScore
},
"success": success
}
}
const result = ADL.XAPIWrapper.sendStatement(statement);
}
// Function to send passed result and user score to the LRS (Learning Record Store)function sendPassed(object, objectId) {
// Get references to Storyline variablesconst player = GetPlayer();
const uNamejs = player.GetVar("uName");
const uEmailjs = player.GetVar("uEmail");
const uScorejs = player.GetVar("uScore");
const maxScorejs = player.GetVar("maxScore");
const scaledScore = uScorejs / maxScorejs;
// Format the course duration as ISO 8601let finalDuration = convertToIso(courseSeconds);
// Define the xAPI statement to sendconst statement = {
"actor": {
"name": uNamejs,
"mbox": "mailto:" + uEmailjs
},
"verb": {
"id": "http://adlnet.gov/expapi/verbs/passed",
"display": {"en-us": "passed"}
},
"object": {
"id": objectId,
"definition": {
"name": {"en-us": object},
"description": {"en-us": "NGTS Network Overview"},
"type": "http://adlnet.gov/expapi/activities/assessment"
},
"objectType": "Activity"
},
"result": {
"duration": finalDuration,
"score": {
"min": 0,
"max": maxScorejs,
"raw": uScorejs,
"scaled": scaledScore
},
"success": true
}
};
// Converts the time to ISO standard readable in JavaScriptfunction convertToIso(secondsVar) {
let seconds = secondsVar;
if (seconds > 60) {
if (seconds > 3600) {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
seconds = (seconds % 3600) % 60;
return `PT${hours}H${minutes}M${seconds}S`;
} else {
const minutes = Math.floor(seconds / 60);
seconds %= 60;
return `PT${minutes}M${seconds}S`;
}
} else {
return `PT${seconds}S`;
}
}
Then you would want some placeholders within your storyline file for the usernames and scores.
firsUser and firstScore
These are pretty typically used placeholders after Devlin Peck published how to develop a leaderboard using xAPI. So, I'll use his example in this reference so you can follow along with his instructions if you get stuck.
I have added to the code to include debugging to help you find any errors when viewing the console log (F12 when you are viewing the exported html).// Function to populate Storyline leaderboard using the project variables for users and scoresfunction populateLeaderboard() {
// Create parameters for querying xAPI statements
const parameters = ADL.XAPIWrapper.searchParams();
parameters["verb"] = "http://adlnet.gov/expapi/verbs/passed";
parameters["activity"] = "http://example.com/NGTSNetworkOverview";
// Query the LRS for xAPI statementsconst queryData = ADL.XAPIWrapper.getStatements(parameters);
// Sort the statements by scaled score in descending orderconst statements = queryData.statements;
statements.sort(function(a, b) {
return b.result.score.scaled - a.result.score.scaled;
});
// Update Storyline Player Project Variables with sorted user names and scores as percentagesconst player = GetPlayer();
player.SetVar("firstUser", statements[0].actor.name);
player.SetVar("secondUser", statements[1].actor.name);
player.SetVar("thirdUser", statements[2].actor.name);
player.SetVar("fourthUser", statements[3].actor.name);
player.SetVar("fifthUser", statements[4].actor.name);
// Debugging: Log the scaled scores and user scores as percentagesconsole.log("Scaled Scores:", statements.map((stmt) => stmt.result.score.scaled));
console.log("User Scores (Percentages):", statements.map((stmt) => stmt.result.score.scaled * 100 + "%"));
// Set user scores as percentages in Storyline variablesplayer.SetVar("firstScore", statements[0].result.score.scaled * 100 + "%");
player.SetVar("secondScore", statements[1].result.score.scaled * 100 + "%");
player.SetVar("thirdScore", statements[2].result.score.scaled * 100 + "%");
player.SetVar("fourthScore", statements[3].result.score.scaled * 100 + "%");
player.SetVar("fifthScore", statements[4].result.score.scaled * 100 + "%");
}
Please let me know if this helped you or not. Happy to chat about it via LinkedIn when you have time.
Scott