SCORM 1.2 and xAPI
Both packages are the standalone HTML player
plus a launch wrapper and an imsmanifest.xml, zipped. They are for the
training market and for every LMS that speaks SCORM 1.2 or xAPI.
What is in the zip
Section titled “What is in the zip”The_Ferry_at_Dusk-scorm12.zip├── index.html the standalone player + the SCO wrapper (head script)└── imsmanifest.xml single-organization, single-SCO manifestThe xAPI variant is the same two files with an additional emitter script in
index.html. Both files sit at the zip root, as SCORM requires.
SCORM 1.2
Section titled “SCORM 1.2”On launch the wrapper finds the API object by walking parent windows,
calls LMSInitialize, and sets cmi.core.lesson_status to incomplete.
It subscribes to the player with whenComplete (so a scenario short enough
to finish during boot is still reported), and on completion sets:
| Element | Value |
|---|---|
cmi.core.score.raw | 0–100, per the scoring rule below |
cmi.core.score.min / max | 0 / 100 |
cmi.core.lesson_status | passed / failed when a score variable is used; completed / incomplete otherwise |
then LMSCommit and LMSFinish. The manifest carries
<adlcp:masteryscore>80</adlcp:masteryscore>.
The scoring rule
Section titled “The scoring rule”Written into the manifest as a comment, verbatim, so an LMS administrator can read it without opening the code:
- If a numeric score variable is available — a project variable
literally named
score— the run scores its final value normalised onto 0–100 from the variable’s declared range (itsMin/Maxcustom fields, defaulting to 0 and 100), clamped. Status ispassedat or above the mastery score (80),failedbelow. - Otherwise: reaching an ending scores 100; an abandoned run scores the
proportion of the project’s playable nodes it visited. Status is
completedwhen an ending was reached,incompleteotherwise.
So to grade a scenario, declare a variable named score (with Min and
Max custom fields if the range is not 0–100) and set it from the nodes:
Variable["score"] = Variable["score"] + 25The example manifest uses rule 2 because
the example has no score variable.
The xAPI package keeps the SCORM wrapper and adds an emitter that sends
statements to the LRS named in the launch URL’s query string — endpoint
and auth (required; with neither present the emitter stays silent so the
same package still works as a plain SCORM upload), and actor as a JSON
agent (an anonymous account agent is used when absent):
| Verb | When | Result |
|---|---|---|
initialized | On launch | — |
responded | Each choice, as it is taken (the player fires onChoice before traversal runs, so order is preserved) | response: the choice text; the choice’s node as a sub-activity of the scenario |
completed | When the run ends | score raw 0–100 and scaled 0–1, success at or above the mastery score, completion when an ending was reached |
The activity ID is the manifest identifier (CM_<Title>). Every statement
sent is also kept on window.chatmapperXapi.sent for inspection.
Testing without an LMS
Section titled “Testing without an LMS”Unzip and open index.html: with no API object present the wrapper stays
inert and the scenario plays normally — an LMS that is missing or refuses to
initialise is never a reason to break the course. For a real conformance check use SCORM Cloud or your LMS’s sandbox
— the package is a plain single-SCO 1.2 course with nothing exotic in it.
Limits
Section titled “Limits”- One SCO per package: one scenario, one score. Split a course into several scenarios if you need several scores.
- The player is text-only; a training package with audio should use the LearnBrite or engine route instead, or a wrapper you build around the player’s API.
- SCORM 2004 is not produced; every 2004-capable LMS also imports 1.2.