RevLearning¶
A lightweight learning-runtime abstraction for Unity.
RevLearning gives your content a consistent API for talking to learning standards, so your code depends on RevLearning rather than on any one LMS: SCORM 1.2 and SCORM 2004 behind ILmsRuntime / IScormDataModel, plus a parallel IXApiRuntime for xAPI statement delivery. Your content decides what happened; RevLearning reports it; the LMS records it.
RevLearning is not a learning system. It is a bridge between your content and the LMS. See
RevLearning_Mental_Model.md.
Features¶
- One API per family — SCORM 1.2 and SCORM 2004 behind
ILmsRuntime/IScormDataModel, so content written once runs under either standard; xAPI alongside them throughIXApiRuntime. - Editor stub runtime — develop and test learning flows without an LMS; the stub is used automatically in the Editor and on non-WebGL platforms.
- Learner state helpers — status, score (incl. SCORM 2004 scaled score), bookmarks, completion, objectives, and interactions via extension methods.
- Safe suspend data — automatic JSON storage against the standard's
suspend_datalimits, compressed to fit; a payload that still will not fit is refused and reported rather than trimmed, because a trimmed one will not deserialize and would destroy the last save that did. - Resumable sessions — exit/resume control (
SuspendAsync,LmsExit). - Resilient xAPI delivery — FIFO queue with exponential-backoff retry and persistence (PlayerPrefs / IndexedDB on WebGL).
- Packaging workflow — single-SCO
imsmanifest.xmlbuilder, post-build packaging, an LMS validator window, and a page helper that commits learner progress when the tab closes. - Error visibility —
ILmsRuntime.LastErrormirrors the SCORMGetLastError/LMSGetLastErrorvalue.
Requirements¶
- Unity 6000.3 or newer (see Compatibility for 2021.3)
- WebGL build target for LMS deployment (Editor/standalone use the stub runtime)
Installation¶
Unity Package Manager → My Assets → RevLearning → Import.
It lands in Assets/RevLearning, where the sample scenes are visible in the Project window rather than behind an Import button — they are the panels the conformance run was driven through, and they are worth opening. See Where It Installs for why Assets/ rather than Packages/, and what you can delete.
Keep your own scripts, prefabs and scenes outside Assets/RevLearning. Do that and an update is uneventful; put them inside it and an update becomes a merge.
RevLearning is an Extension Asset: one licence per seat. See LICENSE.md.
Quickstart¶
using System;
using UnityEngine;
using RevGaming.RevLearning;
public sealed class CourseRunner : MonoBehaviour
{
private ILmsRuntime _runtime;
private async void Start()
{
// Version comes from the synchronized runtime config asset.
var config = Resources.Load<RevLearningRuntimeConfig>("RevLearning_RuntimeConfig");
var version = config ? config.defaultVersion : LmsVersion.Scorm2004;
_runtime = await RevLearningRuntime.InitializeAsync(version);
if (_runtime?.Cmi == null)
return; // not connected — handle gracefully
// Report learner state. Your content decides these values.
_runtime.Cmi.LessonLocation = "Module1/Scene1";
_runtime.Cmi.ScoreMax = 100;
_runtime.Cmi.ScoreRaw = 85;
_runtime.Cmi.LessonStatus = LessonStatus.Completed;
_runtime.Cmi.SessionTime += TimeSpan.FromSeconds(30);
// Commit returns false when the LMS refused to persist. Every refused
// write is already logged with the decoded LMS error, so a course only
// needs to react to the ones it cares about.
if (!await _runtime.CommitAsync())
Debug.LogError($"[Course] progress was not saved: {_runtime.DescribeLastError()}");
}
}
LastError reflects the most recent call only, so check it after the write you care about rather than once at the end of a batch:
_runtime.Cmi.ScoreRaw = 85;
if (_runtime.LastError != LmsError.None)
Debug.LogError($"[Course] score rejected: {_runtime.DescribeLastError()}");
A write that RevLearning blocks before it reaches the LMS — after FinishAsync, or outside a live session — does not refresh LastError, because the LMS was never asked. Those are reported as warnings in the console instead. So a single LastError check after several writes can read None precisely when writes are being discarded, which is why the quickstart above checks the commit result.
See the Samples folder for complete SCORM and xAPI examples (QuickstartExample, QuickstartResumeExample, XApiQuickstartExample).
Documentation¶
- Mental Model — how to think about RevLearning.
- FAQ — integration, configuration, and LMS behaviour.
- Changelog
Compatibility¶
Unity¶
The declared floor is 6000.3, because that is the version CI holds. Every commit runs the full EditMode suite, the JavaScript suites and the package validator on 6000.3.5f2, and the release was cut on a green run.
2021.3 LTS almost certainly works, and is not claimed. It was exercised by hand during development and the whole chain passed on 2021.3.45f2 — 377/377 EditMode tests, a WebGL player, and a SCORM package at 23/23 on Tests~/tools/validate-package.py, recorded in Tests~/CONFORMANCE.md with its date. Nothing in the package uses a Unity API newer than 2020.2 or a C# feature above version 9, so static compatibility is not in doubt either.
What is missing is automation. Unity licence activation fails on 2021.3 in CI with the same credentials that activate on 6000.3, so there is no 2021.3 leg to hold that result on the next commit — and a claim held by a memory is not a support commitment. Buying it once is not buying it.
The practical consequence: on 2021.3 the Package Manager shows a compatibility warning and you install deliberately. If that matters to you, say so — lowering a declared floor is an additive, non-breaking change, and restoring the claim with a real CI leg behind it is the right shape for a later release.
WebGL is the build target for LMS deployment; the Editor and other platforms use the stub runtime.
LMS platforms¶
RevLearning is LMS-agnostic and targets any LMS that can host SCORM or xAPI content.
Both standards have been run end-to-end on SCORM Cloud: import, initialization, score, completion and success, objectives, interactions including incorrect answers, suspend and resume, exit modes, commit and terminate. That includes commit-on-tab-close — the guarantee with no automated equivalent — confirmed by closing the tab with unsaved state and finding it intact on the next launch.
The most recent run found a defect serious enough to invalidate the run. Reading any numeric element back from SCORM Cloud returned nothing: that platform answers GetValue with a JavaScript number where SCORM specifies a string, and the WebGL bridge measured it as empty. Scores read back as null, objective enumeration came back empty, and records could overwrite one another. Writes were never affected, which is why it survived an earlier pass that checked the LMS rather than the readback. It is fixed, both halves are covered by tests that fail without the fix, and the checklist has been re-run end to end on both standards against the corrected build. Every step passes bar the one that platform's player makes unreachable.
The step-by-step results are recorded in Tests~/CONFORMANCE.md: which rows are now held provisional and why, the defects each run found, the one step that platform's player makes unreachable, and two places where the checklist itself turned out to be wrong about SCORM 2004. The checklist is there too, so you can repeat the whole thing on your own platform.
An earlier validation on Thrive LXP is not claimed here: it predates a correctness pass that deliberately changed how completion, success, exit modes and interactions are reported, so it no longer describes this code.
Platforms differ in how they interpret completion, success, attempts and bookmarking, and those differences are not always documented. Validate against the LMS your learners will actually use before you rely on it.
Cmi.PassingScore is null for packages built by the in-box packer: the manifest carries no mastery score, and there is no setting to add one, so the LMS has nothing to report. Decide pass and fail in your content.
Not covered: multi-SCO packages, sequencing and navigation, attempt management, and the xAPI State and Profile APIs. See the FAQ for the full list and for CORS and hosting-header guidance, which are the two most common deployment failures.
License¶
© 2026 RevByDesign (RevGaming). Governed by the Unity Asset Store EULA; one licence per seat. See LICENSE.md. For terms outside the standard EULA, write to contact@revbydesign.studio.