Einbettungspakete und Simulationen

Überblick

Der Block Code einbetten kann einen Ordner anzeigen, den Sie hochladen: eine index.html samt Ressourcen, die innerhalb der Lektion läuft. Standardmäßig ist dieses Paket eine geschlossene Box. Liefert es zusätzlich ein kleines Manifest und spricht über ein paar Nachrichten mit der Lektion, kann es:

  • der Lektion melden, dass die lernende Person fertig ist (damit die Lektion darauf wartet);
  • seine Höhe mitteilen, damit sich der Rahmen an den Inhalt anpasst;
  • seinen Fortschritt übergeben, damit die lernende Person dort weitermacht, wo sie aufgehört hat;
  • eine Note und jede Entscheidung melden, wodurch es zu einer Simulation wird, die in der Bewertung, in SCORM und in xAPI zählt;
  • Variablen bereitstellen, die bedingte Inhalte lesen können.

Diese Seite richtet sich an alle, die das Paket bauen. Sie lässt sich ohne Blick in den Creator-Code befolgen. Zur Seite der Autorinnen und Autoren (Bedienfeld des Blocks, Bewertung und Hinweise) siehe Inhalts-Bricks.

Alles ist optional. Ein Paket ohne Manifest funktioniert trotzdem: Es wird angezeigt, gilt als abgeschlossen, sobald es gesehen wurde, und hält niemanden auf.

Wie das Paket läuft

Das Paket läuft in einem abgeschotteten Rahmen: Skripte sind erlaubt, aber es hat keinen Zugriff auf die Anwendung (keine Cookies, kein Speicher der Anwendung, kein gemeinsamer Ursprung). Die Lektion hört nur auf Nachrichten, die aus dem Rahmen genau dieses Blocks kommen; nichts anderes auf der Seite kann sich also als Ihr Paket ausgeben. Eine ungültige Nachricht wird stillschweigend ignoriert.

Ein eingebetteter Code, der auf eine externe URL statt auf einen hochgeladenen Ordner zeigt, hat kein Paket: Seine Nachrichten werden immer ignoriert, und er deklariert nie etwas.

Das Manifest: slxd-embed.json

Legen Sie eine Datei namens slxd-embed.json im Stammverzeichnis des Ordners ab, neben der index.html:

{
  "protocol": "slxd-embed",
  "version": 1,
  "capabilities": ["complete", "resize", "state", "result", "interaction"],
  "variables": { "trust": "number", "reused": "boolean" }
}
FeldBedeutung
protocolImmer "slxd-embed".
versionImmer 1; das ist die einzige verstandene Version.
capabilitiesWas das Paket senden wird. Jedes Verhalten funktioniert nur, wenn seine Fähigkeit deklariert ist. Unbekanntes wird ignoriert. Bis zu 32 Einträge.
variablesOptional. Die Variablen von state.vars, die das Paket sendet, mit ihrem Typ (number oder boolean). Bis zu 64. Bedingte Inhalte können nur diese benennen.

Fehlt die Datei, ist das JSON ungültig, die Version eine andere oder die Datei größer als 16 KB, deklariert das Paket einfach nichts.

Das Manifest wird gelesen, wenn Sie den Ordner im Block hochladen. Laden Sie slxd-embed.json zusammen mit dem Rest des Ordners hoch. Ändern Sie das Manifest, laden Sie den Ordner erneut hoch: Ein früher hochgeladenes Paket behält, was es damals deklariert hat.

FähigkeitWas sie ermöglicht
completeDas Paket kann „Ich bin fertig“ melden. Nötig, damit die Sperre des Blocks auf das Paket wartet.
resizeDas Paket kann die Höhe seines Rahmens festlegen.
stateDie Lektion speichert den Fortschritt des Pakets und gibt ihn zurück, wenn die lernende Person wiederkommt.
resultDas Paket kann eine Note senden.
interactionDas Paket kann jede Entscheidung melden (SCORM-Interaktionen und xAPI).

Reservierte Variablennamen

grade, score, maxScore, ending und kind lesen immer das letzte result des Pakets (siehe unten) und können daher nicht zugleich Variablen Ihres Zustands sein. Ein Paket, dessen variables einen davon deklariert, wird beim Hochladen abgelehnt: Der Editor zeigt den Fehler, und der Ordner wird nicht verwendet, bis Sie die Namen ändern. In state.vars wird ein Schlüssel mit reserviertem Namen einfach ignoriert.

Variablennamen beginnen mit einem Buchstaben oder _, setzen sich aus Buchstaben, Ziffern oder _ fort und sind höchstens 64 Zeichen lang. Ein Eintrag mit anderem Namen oder Typ wird ignoriert, ohne den Rest abzulehnen.

Nachrichten

Jede Nachricht ist ein einfaches Objekt, das mit postMessage gesendet wird, mit demselben Umschlag:

const send = (type, data = {}) =>
  window.parent.postMessage({ channel: "slxd-embed", version: 1, type, ...data }, "*");

Der Zielursprung ist "*", weil der Rahmen den Ursprung der Lektion nicht kennen kann; in diesen Nachrichten wird nichts Sensibles übertragen.

Vom Paket zur Lektion

typeFelderErfordertWas Creator tut
ready——Senden Sie sie, sobald das Paket geladen ist. Deklariert das Paket state, antwortet die Lektion mit restore.
complete—completeMarkiert den Block als abgeschlossen und hebt seine Sperre auf. In einer Simulation schließt sie diese zusätzlich ab (siehe unten).
resizeheight: Zahl ≥ 0, in CSS-PixelnresizeDer Rahmen übernimmt diese Höhe, begrenzt auf 100 bis 4000 px und aufgerundet. Bis zur ersten Nachricht gilt die im Block eingestellte Höhe.
statestate: JSON-Objekt; done: booleschstateSpeichert state unverändert. done: true bedeutet, dass es ein Ende ist: Es schließt die Simulation ab und schließt den Block ab. Senden Sie sie nach jeder Entscheidung und beim Erreichen eines Endes.
resultscore, maxScore, grade, ending, kindresultAktualisiert nur die Note. Sie kann unvollständig eintreffen, und die letzte gilt. Sie schließt weder den Block noch die Simulation ab.
interactionattempt, n, response, description, result, weightinginteractionErfasst eine Entscheidung. Senden Sie sie nach jeder Entscheidung.

Eine Nachricht, die nicht zu diesen Formen passt, wird vollständig ignoriert, ohne Warnung. Prüfen Sie jedes Feld:

  • state.state: ein einfaches JSON-Objekt (keine Liste, kein Einzelwert) mit höchstens 1024 Zeichen in serialisierter Form. state.done ist Pflicht. Creator behandelt den Zustand als undurchsichtig, bis auf ein optionales Mitglied, vars: ein Objekt aus Zahlen und Wahr/Falsch-Werten, das bedingte Inhalte lesen.
  • result.score: jede endliche Zahl (auch negativ). maxScore: endliche Zahl ≥ 0. grade: eine Zahl von 0 bis 100, die Ihr Paket berechnet; nur sie zählt für die Bewertung. ending: eine Kennung. kind: good, mixed oder bad.
  • interaction.attempt und n (Nummer der Entscheidung im Versuch): ganze Zahlen von 1 bis 9999. response: die Kennung der gewählten Option. description: Text mit höchstens 250 Zeichen, Pflicht (ein leerer Text genügt). result: correct, incorrect oder neutral. weighting: eine Zahl größer als 0 (senden Sie 1, wenn die Entscheidung 0 wert war).
  • Kennungen (ending, response): Kleinbuchstaben, Ziffern und _, beginnend mit einem Buchstaben, bis zu 64 Zeichen.

Von der Lektion zum Paket

typeFelderWann
restorestate: der zuletzt gespeicherte Zustand oder nullAls Antwort auf ready, wenn das Paket state deklariert. Ist null, wenn nichts gespeichert war.
reset—Wenn die Prüfung einen neuen Versuch öffnet. Beginnen Sie von vorn: Gespeicherter Zustand und Note sind bereits gelöscht.

Ein minimales Paket

const send = (type, data = {}) =>
  window.parent.postMessage({ channel: "slxd-embed", version: 1, type, ...data }, "*");

let scene = "s1";
let vars = { trust: 0, reused: false };

window.addEventListener("message", (event) => {
  const msg = event.data;
  if (!msg || msg.channel !== "slxd-embed") return;
  if (msg.type === "restore" && msg.state) {
    scene = msg.state.scene;
    vars = msg.state.vars;
    render();
  }
  if (msg.type === "reset") {
    scene = "s1";
    vars = { trust: 0, reused: false };
    render();
  }
});

function choose(option) {
  vars.trust += option.points;
  scene = option.next;
  send("interaction", {
    attempt: 1,
    n: 1,
    response: option.id,
    description: option.label,
    result: option.points > 0 ? "correct" : "incorrect",
    weighting: Math.abs(option.points) || 1,
  });
  send("state", { state: { scene, vars }, done: false });
  render();
}

send("ready");
send("resize", { height: document.body.scrollHeight });

Abschluss: result vor complete

Eine Simulation wird durch complete oder durch ein state mit done: true abgeschlossen. Ein result schließt sie nie ab. Es zählt die Note aus dem letzten result, das vor dem Abschluss eintraf; nach dem Abschluss werden spätere Ergebnisse ignoriert. Schließt das Paket ab, ohne je ein result gesendet zu haben, ist die Simulation 0 wert.

Die richtige Reihenfolge bei einem Ende ist daher:

send("result", { score: 8, maxScore: 10, grade: 80, ending: "agreement", kind: "good" });
send("state", { state: { scene: "end", vars }, done: true }); // oder: send("complete")

Ein state ohne done nach einem Ende ist ein neues Spiel: Die vorherige Note wird vergessen.

Ein Paket, das als Bewertet markiert werden soll, muss daher complete oder state deklarieren; sonst ließe sich seine Note nie abschließen.

Was Creator mit jedem Punkt macht

Sperre des Fortschritts. Der Block „Code einbetten“ hält standardmäßig niemanden auf. Aktiviert die Autorin oder der Autor die Sperre (im Block oder in den Theme-Einstellungen für eingebetteten Code), wirkt sie nur bei einem Paket, das complete deklariert: Die lernende Person kann erst weitermachen, wenn die Nachricht eintrifft, ohne Zeitlimit und ohne Entsperr-Schaltfläche. state und result heben sie nicht auf. Ein Paket ohne complete und jede externe URL gelten als abgeschlossen, sobald sie gesehen wurden. Der Editor warnt, wenn die Sperre aktiv ist, das Paket sie aber nicht einhalten kann.

Höhe. Der Rahmen folgt dem letzten resize (zwischen 100 und 4000 px). Bis zum ersten verwendet er die im Block eingestellte Höhe.

Zustand bei der Rückkehr. Der Zustand der Simulation wird unter ihrer Simulationskennung gespeichert, pro Inhalt. Lädt das Paket und sendet ready, erhält es restore mit dem letzten Zustand. In einem SCORM-Export überdauert der Zustand die Sitzungen (er reist in den Suspend-Daten des LMS); in der Vorschau, bei Freigabelinks und im Review gilt er nur für die Sitzung. Passt der Zustand nicht in den Platz des LMS, kürzt Creator das Nötigste in fester Reihenfolge: zuerst Simulationen, die weder zählen noch von bedingten Inhalten gelesen werden, dann den Zustand der übrigen, wobei deren Variablen und Noten möglichst lange erhalten bleiben.

Note. Damit die Simulation zählt, gibt die Autorin oder der Autor dem Block eine Simulationskennung (im Inhalt eindeutig), markiert ihn als Bewertet und vergibt ein Gewicht; das Paket muss result deklarieren, außerdem complete oder state. In einer Prüfung zählt die Simulation neben den Fragen: Jede Simulation ist ihr Gewicht mal grade / 100 wert, und die Prüfung schließt erst, wenn alle zählenden Simulationen abgeschlossen sind. In einem Inhalt ohne Prüfungen ist die Note des Inhalts der gewichtete Durchschnitt seiner bewerteten Simulationen, sobald alle beendet sind, gemessen an der Bestehensgrenze des Inhalts (auf der Exportseite angezeigt). Bewertete Simulationen neben benoteten Prüfungen zählen nicht; der Editor warnt.

Interaktionen in SCORM. In einem SCORM-Export wird jede interaction zu einem Eintrag in cmi.interactions vom Typ choice, mit der ID <Simulationskennung>-<Versuch>-<n>, der gewählten Option, dem Ergebnis (correct, wrong/incorrect oder neutral) und der Gewichtung; SCORM 2004 speichert zusätzlich die Beschreibung. In der Vorschau gibt es kein LMS, daher wird nichts erfasst.

xAPI. Wo xAPI aktiv ist, wird jede interaction als „beantwortet“ auf einer Entscheidungsaktivität gemeldet (mit Beschreibung, gewählter Option und success für correct und incorrect; neutral trägt keines), und beim Abschluss der Simulation trägt ein einziges „Punktzahl erreicht“-Statement die zählende Note, mit Ende und Art als Erweiterungen. Ein unvollständiges result sendet nichts. Ein neues Spiel erlaubt das Statement erneut. Die Autorin oder der Autor kann xAPI für den Block abschalten.

Grenzen auf einen Blick

WasGrenze
slxd-embed.json16 KB, nur Version 1
Fähigkeitenbis zu 32 Einträge
Variablenbis zu 64, number oder boolean
stateJSON-Objekt, ≤ 1024 Zeichen
Rahmenhöhe100–4000 px
Beschreibung einer Entscheidung≤ 250 Zeichen
attempt, nganze Zahlen 1–9999
Kennungen[a-z][a-z0-9_]*, ≤ 64 Zeichen
Gespeicherter Fortschritt (SCORM)gemeinsames Budget von 4096 Zeichen für den ganzen Inhalt

Nächste Schritte

Einbettungspakete und Simulationen