This entry is part 4 of 9 in the series SCORM for Developers

SCORM has been around for 20+ years, and the ecosystem has matured to the point where we can make certain assumptions about vendor support.

Commercial course creation tools like Adobe Captivate, Articulate Rise, and iSpring are hyper-focused on broad compatibility with as many LMSs as possible. Acknowledging they couldn’t trust LMSs to provide full SCORM support, the tools were designed to utilize only the most commonly supported SCORM elements, which I refer to as the Safe Parts (hat tip to Doug Crockford). If you limit your course’s use of SCORM to this subset of features, your course will work pretty much anywhere.

Note that my Safe Parts recommendations are based on SCORM 1.2, which has the greatest market share. If you prefer to use SCORM 2004, I consider the SCORM 2004 equivalents safe as well, though there can be some hiccups here and there depending on which version of SCORM 2004 has been implemented.

API Safe Parts

The API, owing to its simplicity, works pretty much as outlined in the SCORM documentation, and doesn’t usually need any special handling.

CMI Data Model Safe Parts

The CMI data model has some truly useful fields. Unfortunately, most course development tools don’t support SCORM’s full CMI data model because of the old chicken or egg conundrum: LMSs don’t consistently support the full CMI data model, so course vendors don’t use it. Since course vendors don’t use it, LMS vendors don’t spend the time and money to implement it.

The following SCORM 1.2 CMI data fields are the closest thing you’ll get to bulletproof in the LMS ecosystem.

  • cmi.core.student_id (read-only)
    • A unique identifier for the learner who launched the course, provided by the LMS.
    • String, 255 characters max.
  • cmi.core.student_name (read-only)
    • Name of learner, as provided by the LMS.
    • String, 255 characters max.
  • cmi.core.lesson_location (read-write)
    • A string that can be used to ‘bookmark’ the learner’s location within a course.
    • String, 255 characters max.
  • cmi.core.lesson_status (read-write)
    • The status of the learner’s progress for the course.
    • Only accepts the following strings: “passed”, “completed”, “failed”, “incomplete”, “browsed”, “not attempted”.
  • cmi.core.score.min (read-write)
    • cmi.core.score.min and cmi.core.score.max establish the range of scoring possible within the course, such as 0-100.
    • Use cmi.core.score.min to specify the lowest possible score.
    • Value must be a number, passed as a string.
      • “A number that may have a decimal point. Examples are ‘2’,’2.2’.” (SCORM 1.2 Run-Time Environment, 3-57)
  • cmi.core.score.max (read-write)
    • cmi.core.score.min and cmi.core.score.max establish the range of scoring possible within the course, such as 0-100.
    • Use cmi.core.score.max to specify the highest possible score.
    • Value must be a number, passed as a string.
      • “A number that may have a decimal point. Examples are ‘2’,’2.2’.” (SCORM 1.2 Run-Time Environment, 3-57)
  • cmi.core.score.raw (read-write)
    • Learner’s current score.
    • Must fall between the values established by cmi.core.score.min and cmi.core.score.raw.
    • Value must be a number, passed as a string.
      • “A number that may have a decimal point. Examples are ‘2’,’2.2’.” (SCORM 1.2 Run-Time Environment, 3-57)
  • cmi.core.exit (write-only)
    • Indicates learner’s reason for leaving the course.
    • Only accepts the following strings: “time-out”, “suspend”, “logout”, “” (empty string).
  • cmi.suspend_data (read-write)
    • Essentially a blank database field for storing anything you might need.
    • Frequently used to store data about the course’s state, such as which pages have been visited and which have not been accessed yet.
    • String, 4096 characters max.
      • LMSs are often lax on the cmi.suspend_data storage limit; some will allow much larger amounts of data. Do not assume if one LMS permits you to store over 4096 characters that other LMSs will follow suit.

Additionally, there are some fields that are likely safe, but should be tested in your LMS if you decide to use them:

  • cmi.core.entry (read-only)
    • Indicates whether the learner is accessing the course for the first time (“ab-initio”) or is returning to an existing session (“resume”).
    • Only returns the following strings: “ab-initio”, “resume”, “”.
  • cmi.core.session_time (write-only)
    • The amount of time the student has spent in the course for the given session, from launch to closing the course. cmi.core.total_time provides a sum of all the individual sessions.
    • String, formatted as HHHH:MM:SS.SS.
      • “Hours have a minimum of 2 digits and a maximum of 4 digits. Minutes shall consist of exactly 2 digits. Seconds shall contain 2 digits, with an optional decimal point and 1 or 2 additional digits. (i.e. 34.45).” (SCORM 1.2 Run-Time Environment, 3-58)
  • cmi.core.total_time (read-only)
    • “Accumulated time of all the student’s sessions in the SCO”. (SCORM 1.2 Run-Time Environment, 3-29)
    • String, formatted as HHHH:MM:SS.SS.
      • “Hours have a minimum of 2 digits and a maximum of 4 digits. Minutes shall consist of exactly 2 digits. Seconds shall contain 2 digits, with an optional decimal point and 1 or 2 additional digits. (i.e. 34.45).” (SCORM 1.2 Run-Time Environment, 3-58)

I hesitate to include cmi.core.session_time and cmi.core.total_time; I’ve seen LMSs that utilize their own codebase to track the learner’s time in the course, ignoring values submitted by the course. Having said that, I do not see harm in using these fields, as long as you don’t rely on them for critical course functionality.

Manifest Safe Parts

In courses produced by commercial tools like Captivate, the manifest is extremely simple. It’s usually just a handful of XML nodes. This is because the course is a monolithic course — a ‘single SCO’ course, meaning it’s completely self-contained, and manages its own internal navigation.

If you were to try to implement SCORM as originally envisioned, the navigation would need to be handled by the LMS, which would require listing every single HTML page in your course, plus navigation instructions (the sequencing and navigation piece). SCORM’s Content Aggregation Model (CAM) took it even further, enabling SCOs (courses) to contain other SCOs and promoting “reusability of learning content across LMSs and repositories“.

A grand vision, never embraced by enterprise LMS vendors.

For our purposes, the safest approach is to emulate commercial course development tools and implement a single-SCO methodology. We will only use the bare minimum, as outlined in this template I posted on GitHub.

<?xml version="1.0" standalone="no" ?>
<manifest identifier="CourseIDHere" version="1"
         xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2"
         xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_rootv1p2"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.imsproject.org/xsd/imscp_rootv1p1p2 SCORM-schemas/imscp_rootv1p1p2.xsd
                             http://www.imsglobal.org/xsd/imsmd_rootv1p2p1 SCORM-schemas/imsmd_rootv1p2p1.xsd
                             http://www.adlnet.org/xsd/adlcp_rootv1p2 SCORM-schemas/adlcp_rootv1p2.xsd">
  <metadata>
    <schema>ADL SCORM</schema>
    <schemaversion>1.2</schemaversion>
  </metadata>
  <organizations default="course-code-here">
    <organization identifier="course-code-here">
      <title>Course Title here</title>
      <item identifier="item_1" identifierref="resource_1">
        <title>Course Title here</title>
      </item>
    </organization>
  </organizations>
  <resources>
    <resource identifier="resource_1" type="webcontent" adlcp:scormtype="sco" href="index.html">
      <file href="index.html" />
    </resource>
  </resources>
</manifest>
Code language: HTML, XML (xml)

A working example will be provided later in this series.

Series Navigation<< The three SCORM components you need to knowA Simple SCORM Example >>

Similar Posts