Forum Discussion

RobertLoverin-f's avatar
RobertLoverin-f
Community Member
6 months ago

Data listed in cmi.interactions.x.id

We're using Docebo to deploy a course built in Storyline. During a test, I pulled the interaction data for some of our questions. 

The cmi.interactions.25.id, for example, lists the correct scene/slide, but that doesn't tell an independent reviewer which question someone answered. 

I know that cmi.interactions.x.description lists the question stem, but our course has a pre-test and knowledge checks that reuse the question stem and answers. So, the stem would display twice for different interactions (as expected) . 

Is there a way to update cmi.interactions.x.id within Storyline? I'd love to have the pre-test version and knowledge check version more clearly delineated.

Here's the data I have for one interaction:

 cmi.interactions.24.objectives.0.success_status: unknown

cmi.interactions.24.objectives.0.completion_status: unknown

cmi.interactions.24.objectives.0.id: Course Name

cmi.interactions.24.timestamp: 2024-09-10T11:00:13.0-04>

cmi.interactions.25.id: Scene18_Slide10_MultiResponse_0_0

cmi.interactions.25.type: choice

  • Hi RobertLoverin-f I haven't come across a way on the forums to change this information. Completely agree that the data isn't very useful in isolation like this, as it does not include the question in the ID. I know in the past I have always used the ID to include as much of the question as possible for reporting purposes, but there really isn't an easy way to achieve this in Storyline.

    It would be possible, but you would have to include script in your project to intercept the calls to the SCORM API and then replace the interaction IDs with a value you have defined, for example:

    cont scormIdMatrix = {
    "Scene18_Slide10_MultiResponse_0_0" : "which_is_the_largest_continent_in_the_world",
    "Scene18_Slide11_MultiResponse_0_0" : "which_of_the_following_cities_is_the_capital_of_australia",
    }

    Not impossible, but could be a maintenance issue, for example if a question changes location, it's interaction ID is likely to change.

    If you have JavaScript developers within your organisation they would be able to help you out with this. If not, and it's an important issue, I'd be happy to chat more and give you an idea of cost.

    • RobertLoverin-f's avatar
      RobertLoverin-f
      Community Member

      Thanks Sam. I don't think I'm ready to manually manipulate SCORM packages or find someone that can script this each time. 

    • AdityaChettri's avatar
      AdityaChettri
      Community Member

      Hello SamHill I have a good grasp of Javascript and also have used it inside Storyline for some interactivity etc. however I am having to deal with a similar issue being described and also somehow recording additional variable along with the interaction info, e.g. for a recent project the requirement was to capture attempt wise responses for a quiz. I scoured the community, and went through the SCORM file and used all kinds of hacks, but the project failed massively and I am back to square one. 

      I however am able to do this with a custom SCORM created from scratch by sending appropriate cmi.exit and adl.nav.requests etc. However, all our existing projects being on Storyline, this is a much desired info which needs to be captured for quiz. I am hoping with what you are saying, "replacing the interaction IDs", I can add some data to the ID which gives me an indication of which attempt it was. 

      Your inputs are highly appreciated. Thanks

      • SamHill's avatar
        SamHill
        Super Hero

        Hi AdityaChettri unfortunately their isn't a cmi.interaction element that you can use to count the users attempt at a question, but Storyline does already change the ID to include the attempt number, but this attempt number is "per session".

        For example, a True/False question I have defined with unlimited attempts may record an ID like this if I attempt the question multiple times. I've highlighted the digit at the end of the ID to indicate the attempt:

        • Scene1_Slide1_TrueFalse_0_0
        • Scene1_Slide1_TrueFalse_0_1
        • Scene1_Slide1_TrueFalse_0_2

        The problem is, if I then exit the module and then relaunch, and have three more attempts at the question, the ID starts from zero again, and does not continue from 2.

        • Scene1_Slide1_TrueFalse_0_0
        • Scene1_Slide1_TrueFalse_0_1
        • Scene1_Slide1_TrueFalse_0_2

        Your LMS would have to be capable of adding all of these up to arrive at a total (6 attempts).

        I think the best field to use to track an attempt number might be the cmi.interactions.n.description as Storyline just adds a brief description of the question, and it's a flexible field. For example, for a T/F question, the description is "True or False". 

        SetValue('cmi.interactions.3.description', 'True or False')

        You could therefore hijack that data field, and log your attempt how you would like to.

        SetValue('cmi.interactions.3.description', '{attempt:6}')

        The challenge you have with tracking attempts, is keeping track of those attempts, as Storyline does not keep track. You would therefore need a variable for each question, to track the number of attempts the user has had at the question, and use that value.

        const player = GetPlayer();
        const attempt = player.GetVar('Q1Attempts');
        SetValue('cmi.interactions.3.description', `{attempt:${attempt}}`)
        

        This is just a very rough idea, but you would have to hook into the function that is writing the interactions to the LMS and then hijack the part that is writing the description to the LMS. Then you have the challenge of pulling that data from the LMS into a report. That will depend on how much control you have over the LMS and how flexible the reporting tools are.

        The function in scormdriver.js that you would have to hijack is SCORM2004_RecordInteraction.

        You could assign that function to another function, e.g:

        // Assign original function to new function name (allows us to hijack the function)
        super_SCORM2004_RecordInteraction = SCORM2004_RecordInteraction
        // And then re-define SCORM2004_RecordInteraction so you can override description
        function SCORM2004_RecordInteraction(strID, strResponse, blnCorrect, strCorrectResponse, strDescription, intWeighting, intLatency, strLearningObjectiveID, dtmTime, SCORM2004InteractionType){
            // override the strDescription variable
           const player = GetPlayer();
            // You have a global Storyline variable, questionAttempt,  that you set with the current attempt number
           strDescription = `{attempt: ${player.GetVar('questionAttempt')}}`;
           // Call the original function
           return super_SCORM2004_RecordInteraction(strID, strResponse, blnCorrect, strCorrectResponse, strDescription, intWeighting, intLatency, strLearningObjectiveID, dtmTime, SCORM2004InteractionType);
        }