JS API

showQuestion and answerResult should only be used by developers given permission to use the Question Overlay.

Legends of Learning Platform: JavaScript API

The LoL Game API is implemented as a sequence of asynchronous calls between an iFrame parent and child. Use the browser's built in window.postMessage to send outgoing messages, and window.addEventListener("message", message => {...}) to receive messages. Details on each method are linked below.
Direction
Category
Message Name
Added
LoL => Game
Lifecycle
ready
V2
Game => LoL
Lifecycle
start
V2
LoL => Game
Data Payload
language
V2
Game => LoL
Lifecycle
loadingProgress
V1
Game => LoL
Progress
progress
V2
Game => LoL
Speech
speakText
V2
Game => LoL
Lifecycle
complete
V1
Game => LoL
Questions
showQuestion
V4
LoL => Game
Questions
answerResult
V4
Game => LoL
State
saveState
V5
Game => LoL
State
loadState
V5

Sending Messages

function LoLApi (messageName, payloadObj) {
parent.postMessage({
message: messageName,
payload: JSON.stringify(payloadObj)
},
'*')};

Receiving Messages

window.addEventListener("message", function (msg) {
// Message name and JSONified payload
const { messageName, payload } = msg.data;
}

Messages

gameIsReady

Sent by the game to indicate it is ready to receive data.
LoLApi('gameIsReady', {
aspectRatio: "16:9",
resolution: "1024x576",
});

start

Sent from the gameframe (following receipt of gameIsReady) to initialize gameplay (with optional lastGameProgress payload).
// payload received (JSON stringified)
{
"languageCode": "en",
"lastGameProgress": {
score: 10,
maxScore: 11,
gameProvidedPayload: "{\"developerProvidedPayload\": true}"
}
}

language

// payload received (JSON stringified)
{
"welcome": "Welcome!",
"readyToPlay": "Are you ready to play?",
"greatJob": "Great job!",
"pressContinue": "Press the next button to continue.",
"onePlusOne": "One + One = Two"
}

loadingProgress

LoLApi('loadingProgress', { progress: 0.56 });

progress

LoLApi('progress', { alternativeId: 1 });

speakText

LoLApi('speakText', { key: 'welcome' });

saveState

LoLApi('saveState', {data: {key: 'welcome'}});

loadState

window.addEventListener("message", function (msg) {
// Message name and JSONified payload
const { messageName, payload } = msg.data;
if (messageName === 'loadState') {
// Your STATE handler here
break;
}
});
parent.postMessage({
message: 'loadState',
payload: '*'
},
'*');

saveState with progress data

LoLApi('saveState', { currentProgress: 3, maximumProgress: 10, data: {key: 'welcome'}});

loadState and restore progress data

window.addEventListener("message", function (msg) {
const { messageName, payload } = msg.data;
if (messageName === 'loadState') {
const previousState = JSON.parse(payload);
const currentProgress = previousState && previousState.currentProgress
const maximumProgress = previousState && previousState.maximumProgress
LoLApi('progress', {currentProgress, maximumProgress});
// do something with the data inside payload
break;
}
});
parent.postMessage({
message: 'loadState',
payload: '*'
},
'*');

complete

LoLApi('complete', {});

Code Example: Receiving Messages

const EVENT = {
RECEIVED: {
PAUSE: 'pause',
RESUME: 'resume',
QUESTIONS: 'questions',
LANGUAGE: 'language',
START: 'start',
INIT: 'init',
STATE: 'loadState'
}
};
window.addEventListener("message", function (msg) {
console.log('[PARENT => UNITY]', msg)
switch (msg.data.messageName) {
case EVENT.RECEIVED.PAUSE:
// Your PAUSE handler here
break;
case EVENT.RECEIVED.RESUME:
// Your RESUME handler here
break;
case EVENT.RECEIVED.QUESTIONS:
// Your QUESTIONS handler here
break;
case EVENT.RECEIVED.LANGUAGE:
// Your LANGUAGE handler here
break;
case EVENT.RECEIVED.START:
// Your START handler here
break;
case EVENT.RECEIVED.STATE:
// Your STATE handler here
break;
case EVENT.RECEIVED.INIT:
break;
default:
console.log('Unhandled message: ' + msg);
}
});