Skip to main content

Setting up a JavaScript Playable for Creative Suite

Creative Suite offers support for JavaScript playables, created outside of the Luna plugin. You can benefit from all of the features such as playable variations, multi-ad network support and playable ad analytics.

This guide outlines the steps necessary to adapt your JavaScript playable ad for us with Creative Suite.

Before continuing with the steps on this page please be sure to have downloaded your HTML5 playable from your provider, or as an export from the game engine being used.

Please note that these steps are also detailed on our community github alongside 2 example folders containing ready-to-upload playables.

Step by step

1. Make sure your html file is named "source.html"

WARNING! Luna will not apply further compression or obfuscation once you have uploaded your files. Please minify and obfuscate your playables prior to uploading.

2. Make sure all the startup functionality is performed in the startGame() function

3. Create 2 json files

The name of these files needs to be luna.json and the other playground.json, these will be necessary for uploading to Creative Suite.

4. Populate your playground.json

Within your playground.json you will need to create a new object with 2 fields; "title" & "icon", and another object within it called "fields".

Example of how this should look below:

{
"title": "Basic Playable",
"icon": "", // Icon next to the playable in Creative Suite, takes a Data URL.

"fields": {} // You can populate this with any settings you wish to be editable in Creative Suite
}

If you would like an example of how to populate the fields object for Creative Suite click here.

5. Within your luna.json add the following:

{
"unity": {
"packages": {
"default": {
"applicationName": "",
"iosLink": "",
"androidLink": "",
"orientation": "unspecified",
"supportedLanguages": ["en"]
},

"ironsource": {
"appID": "",
"assetID": "",
"applicationGenre": "",
"versionName": "",
"apiType": 0,
"playableMode": 0,
"packageType": 0
},

"facebook": {
"assetID": "",
"packageType": 0
},

"tiktok": {
"orientation": 0
}
}
}
}

To learn about what should be entered in each field in your luna.json click here.

6. Add callback events to your playable

To diplay the events when they are triggered, we can create a log function that will show the messages directly in the window.

Let's add some style to the logs by adding the following code in a <style> tag in the <head> of our project.

#log {
position: absolute;
background: black;
display: block;
color: white;
bottom: 0;
height: 30%;
width: 90%;
font-size: 2%;
padding: 5%;
}

Create a container for the debug messages in the <body> of our playable:

<!-- container element for debug messages -->
<label id="log"></label>

Add a <script> tag with the following function:

function log(text) {
document.getElementById('log').innerHTML += text + '<br />';
}

Finally, we can subscribe to the event and have a debug message on our window every time the events is triggered. For example:

// Subscribe to luna:build event – will be fired right after 'load' event of the window.
window.addEventListener('luna:build', function () {
log('Playable is about to start');
});

You can see a list of our callback events by clicking here.

You can find an example of this in our repository.

7. Use the Luna API to direct the user to the app store

The API call needed: Luna.Unity.Playable.InstallFullGame()

8. Extra step if you wish to run on Mintegral or Vungle

If you wish to run on Mintegral or Vungle, please also call the Luna.Unity.LifeCycle.GameEnded() event when the game is complete.

9. Zip your playable & json files

The last step is to zip your 3 files (source.html, luna.json, playground.json). Then drag and drop the resulting zip at the bottom of the playground.lunalabs.io/apps page. (You can also click on the browse text at the bottom of the page, navigate to where the zip is in the opened window and hit open).

images-small

Optional Extra Steps

  1. Update your luna.json file with your app store URLs. (Click here to learn about what to put in each field)
  2. Update your playground.json file with parameters in your game, for quick editing in Creative Suite.
  3. Use Luna Custom Events. (see below)

Custom Events

It is possible to use the Luna Analytics events API for custom events in your playable. Please see here for full documentation of the API, and here for information on Events Settings.

Implementation Example:

window.pi.logCustomEvent('LevelFailed', 1);
window.pi.logCustomEvent('EndCardShown');

luna.json guide

Click the arrow below to see a table comprising all you need to know regarding each field in the luna.json file.

CLICK ME
SectionField NameData TypeDescription
defaultapplicationNameStringYour playable's name
defaultiosLinkStringYour iOS App Store link
defaultandroidLinkStringYour Android App Store link
defaultorientationStringCan be one of: "unspecified", "portrait" or "landscape"
defaultsupportedLanguagesArray of StringsList the languages your playable supports via listing the corresponding language codes (formatted like this: "en", "fr", ...)
ironsourceappIDStringOptional
ironsourceassetIDStringOptional
ironsourceapplicationGenreStringOptional
ironsourceversionNameStringOptional
ironsourceapiTypeintEnter either 0 or 1: 0 for DAPI, 1 for NUCLEO
ironsourceplayableModeintEnter either 0 or 1: 0 for PA, 1 for IEC
ironsourcepackageTypeintEnter either 0 or 1: 0 for Inline, 1 for CDN
facebookassetIDStringOptional
facebookpackageTypeintEnter either 0 or 1: 0 if your are submitting using a ZIP file (5Mb limit), or 1 for a single inlined HTML file (2Mb limit)
tiktokorientationintEnter 0, 1 or 2: 0 for "responsive", 1 for "portrait" or 2 for "landscape"

Fields example

Click the arrow below to view an example of how to populate the fields object for Creative Suite.

CLICK ME
"fields": {
"ShapeController": {
"shapeColor": {
"title": "shapeColor",
"type": "color",
"defaultValue": [
1,
0,
0,
1
],
"section": "",
"order": 1,
"localization": 0,
"options": {}
},
"shape": {
"title": "shape",
"type": "enum",
"defaultValue": 1,
"section": "",
"order": 2,
"localization": 0,
"options": {
"0": "CUBE",
"1": "SPHERE",
"2": "CYLINDER"
}
},
"someBoolean": {
"title": "someBoolean",
"type": "boolean",
"defaultValue": 1,
"section": "",
"order": 3,
"localization": 0,
"options": {}
},
"someInt": {
"title": "someInt",
"type": "int32",
"defaultValue": 100,
"section": "",
"order": 4,
"localization": 0,
"options": {}
},
"someVector3": {
"title": "someVector3",
"type": "vector3",
"defaultValue": [
0,
1,
0
],
"section": "",
"order": 5,
"localization": 0,
"options": {}
},
"someString": {
"title": "someString",
"type": "string",
"defaultValue": [
"This is a string"
],
"section": "",
"order": 6,
"localization": 0,
"options": {}
},
"mySlider":{
"title": "mySlider",
"type": "int32",
"defaultValue": 10,
"constraints": {
"value_min":1,
"value_max":15,
"value_step":1
}
},
"myVec3Array":{
"title": "myVec3Array",
"type": "vector3[]",
"defaultValue": [
[2,4,6], [1,3,5]
],
"constraints": {
"array_min_length":0,
"array_max_length":3
}
}
}
},
}

Callback Events

A list of the callback events available

// Subscribing to luna:build event – it is going to be fired right after 'load' event of the window.
window.addEventListener('luna:build', function () {
log('Playable is about to start');
});

// Subscribing to luna:unmute event – the playable can play sounds once it is fired.
window.addEventListener('luna:unmute', function () {
log('Playable needs to be unmuted');
});

// Subscribing to luna:mute event – the playable must mute all the sounds once it is fired.
window.addEventListener('luna:mute', function () {
log('Playable needs to be muted');
});

// Subscribing to luna:pause event – the playable must pause rendering and sound playaback.
window.addEventListener('luna:pause', function () {
log('Playable needs to be paused');
});

// Subscribing to luna:pause event – the playable must resume rendering and sound playaback.
window.addEventListener('luna:resume', function () {
log('Playable needs to be resumed');
});

// check if Luna is defined in global namespace
if ('Luna' in window) {
// it is - nothing to do, the startGame() will be invoked when needed
log('window.Luna is set - startGame() will be called automatically');
} else {
// it is not - probably a development build, invoke startGame() manually
startGame();
}