The 2004 runtime in one minute
SCORM 2004 keeps the shape of the 1.2 runtime — a JavaScript API object, string values, explicit commits — but renames and retypes it. The object is API_1484_11; the functions drop the LMS prefix (Initialize, Terminate, GetValue, SetValue, Commit, GetLastError, GetErrorString, GetDiagnostic). The elements that matter most in migration:
| SCORM 1.2 | SCORM 2004 | Change |
|---|---|---|
cmi.core.lesson_status | cmi.completion_status + cmi.success_status | Completion and success are separate; "completed and failed" is reportable. |
cmi.core.score.raw | cmi.score.scaled (−1..1) plus raw/min/max | Scaled score is what sequencing and most 2004 reports use. Set it, not just raw. |
cmi.core.lesson_location | cmi.location, max 1,000 chars | Bigger bookmark. |
cmi.suspend_data (4,096 chars) | cmi.suspend_data (64,000 chars in 3rd/4th Ed.) | See suspend data limits — 2nd Edition is smaller. |
cmi.core.session_time (HHHH:MM:SS) | cmi.session_time, ISO 8601 duration (PT1H30M5S) | Different format; a 1.2-style timespan is a type error. |
| — | cmi.progress_measure (0..1) | Fractional progress, used by video and long-form courses. |
| — | adl.nav.request | The course can request continue / previous / exit — this is how content drives sequencing. |
The activity tree
Sequencing is defined in the manifest, not in content. The <organization> element's nested <item>s form an activity tree; leaf items launch SCOs, parent items exist to group, roll up, and control navigation. Each item can carry an <imsss:sequencing> block. The LMS — not the course — walks this tree, decides which activity the learner may enter next, and computes the course-level result from the leaves. This is the fundamental shift from 1.2: in 1.2 the LMS shows a menu and stays out of the way; in 2004 the LMS enforces the rules you wrote, including the ones you wrote by accident.
Control modes
Set on a parent's <imsss:controlMode>, these decide how its children may be navigated:
| Attribute | Default | Effect |
|---|---|---|
choice | true | Learner may pick children from the menu. Setting it false hides free navigation — and can trap the learner if flow is also false. |
flow | false | "Continue" moves to the next activity automatically. The most common 2004 bug is forgetting to set this true: the course loads to a menu and the Next button does nothing. |
forwardOnly | false | No going back. Combine with care; with a failed post-condition it can dead-end an attempt. |
choiceExit | true | Whether the learner may leave the current activity by choosing another. |
Sequencing rules
Rules live on an activity and are evaluated at fixed points. Each rule is condition(s) plus one action:
| Rule type | Evaluated | Typical actions | Typical use |
|---|---|---|---|
| Pre-condition | Before the activity may be delivered | skip, disabled, hiddenFromChoice, stopForwardTraversal | "Lock module 3 until module 2 is satisfied." |
| Post-condition | After the activity ends | retry, continue, previous, exitParent, exitAll | "On failure, retry the assessment." |
| Exit | When a descendant's attempt ends | exit | End a parent when a child condition is met. |
Conditions test things like satisfied, completed, attempted, attemptLimitExceeded, and objective status — including global objectives shared between activities via <imsss:mapInfo>, which is how a quiz in one module unlocks content in another. Limit conditions (attemptLimit) cap tries; when the limit is hit the activity becomes undeliverable, which is a feature in an exam and a stranding bug anywhere else.
Rollup
Rollup computes a parent's status from its children: by default a parent is complete when all tracked children are complete, and satisfied per its rollup rules. Two controls matter in practice. <imsss:rollupRules> lets you say things like "satisfied if all children satisfied" or weight one child's objective as the course result (the classic pattern: content contributes nothing, the final assessment carries objectiveMeasureWeight). Per-child participation flags (rollupObjectiveSatisfied, rollupProgressCompletion) exclude an activity — an optional resources page, say — from the calculation. If your course "never completes" in a 2004 LMS while every module shows complete, rollup is where to look.
The three mistakes that strand learners
1. Flow left at its default. flow defaults to false. A multi-SCO package with no control mode block delivers nothing when the learner presses Continue on platforms that follow the spec strictly, while more forgiving platforms fake a menu — so the package "works" in testing and fails at the customer.
2. A pre-condition that can never become true. Rules that reference an objective no activity writes, a mapInfo target with a typo'd identifier, or two activities each disabled until the other is satisfied. The symptom is an activity that is visible and permanently disabled. Validate every referenced objective ID against a writer.
3. Choice and flow both false, or forwardOnly plus a retry dead-end. The learner has no legal navigation request left. Strict engines then end the attempt. Any rule combination should be walked through as the failing learner, not the passing one — the passing path almost always works.
Edition differences
"SCORM 2004" is four editions. 2nd Edition (2004) shipped the sequencing model with rough edges and a smaller suspend-data cap; 3rd Edition (2006) fixed ambiguities and raised limits; 4th Edition (2009) tightened conformance requirements and is the edition to target when you have the choice. LMS sequencing engines differ most on 2nd Edition content. When a platform says it supports 2004, ask which edition — and validate the manifest against that edition's schema, which is what the free tester does when it reports "validated against the 2004 4th Ed schema".