Javascript game loader and API for operators to load and communicate with Nolimit games.
nolimit.js provides a powerful yet simple way to load games, while still putting most of the control in the hands of the operator.
The operator makes all the design and layout, and will only need to provide a target element for the loader to use.
nolimit.js is available with sourcemap and some logging as nolimit-VERSION.js
or as minified as nolimit-VERSION.min.js
at http://nolimitjs.nolimitcdn.com/.
It can also be installed using NPM:
npm install --save @nolimit/nolimit.js
nolimit.js files are packaged as UMD, meaning it can be loaded using CommonJS such as Browserify, AMD such as RequireJS or just standalone with a regular <script>
tag.
When loaded standalone, it will add a global variable window.nolimit
which is used to load the games. See examples below.
var nolimit = require('@nolimit/nolimit.js');
nolimit.init({
operator: 'SMOOTHOPERATOR'
});
define(['nolimit'], function(nolimit) {
nolimit.init({
operator: 'SMOOTHOPERATOR'
});
});
<script src="https://nolimitjs.nolimitcdn.com/dist/nolimit-latest.min.js"></script>
<script>
nolimit.init({
operator: 'SMOOTHOPERATOR'
});
</script>
import * as nolimit from '@nolimit/nolimit.js';
nolimit.init({
operator: 'SMOOTHOPERATOR'
});
For more information on the available methods and options, see the generated JSDOC.
console.log('nolimit.js', nolimit.version);
Create an element, usually a <div>
, that will be replaced by the game's <iframe>
. The iframe will retain styling information such as width
and height
, display
and so on.
var api = nolimit.load({
target: document.querySelector('#game'),
game: gameName
});
api.on('exit', closeGame);
Common use case on mobile, where the game should fill the whole screen and you still want the back button to work.
var api = nolimit.replace({
game: gameName
});
This goes to a completely separate page, so listening to events are not possible. So to specify what to do on exit, deposit or support, it's instead possible to give URLs as parameters:
Exiting will still default to history.back()
which will usually work in the common case.
var api = nolimit.replace({
game: gameName,
lobbyUrl: lobbyUrl,
supportUrl: supportUrl,
depositUrl: depositUrl,
accountHistoryUrl: accountHistoryUrl
});
It's also possible to make a full screen <div>
and use that as target if that fits your flow better. Note though, that you need to make the game element responsive or resize manually in that case.
If you wish to not make use of nolimit.js, but rather construct a URL, this is also possible:
The minimal URL that loads a game looks like: https://partner.nolimitcdn.com/loader/game-loader.html?game=GAME&operator=OPERATOR
To construct this URL manually:
<key>=<value>
and joining them with &
https://<environment>.nolimitcdn.com/loader/game-loader.html?
<environment>
is either 'partner'
for test environments, or the name for a specific production environment that you have gotten from us.Note: nolimit.url(options)
can build this URL for you if you use javascript, and nolimit.replace(options)
can also redirect there.
Some objects can be passed along in the URL, e.g. jurisdiction
. However, this needs to be encoded properly to be accepted. The value is added into to the options structure by decoding in the following way conceptually.
options.value = JSON.parse(decodeURIComponent(value in url))
So when adding the value to the URL first encode it in this way, where {...}
represents the object you need to pass along.
encodeURIComponent(JSON.stringify({...}))
It's not strictly required to call init()
, it's possible to call load()
directly with all the options instead. init()
just provides a way to setup some common defaults and the options will actually be merged before each game load.
The only required options are the operator code for init, the game code for game loading, and the HTMLElement or Window to replace.
Option language defaults to 'en'
.
Some of our supported languages are 'en', 'da', 'de', 'es', 'fi', 'fr', 'is', 'ja', 'ko', 'lv', 'nl', 'no', 'pl', 'ru', 'sv', 'th', 'tr', 'vi', 'zh'
. We support many languages so please talk to us if loading a game in a language you expect to work ends up loading in the default language instead since then either the language code may be wrong or we may not have the language yet.
For playing with real money, a one time token is required, that is generated by the operator. The token will be verified via an API call to the operator's server. If the token is missing, fun mode is automatically enabled. If the token is present, but fails validation, there will be an error inside the game.
Ask environment for some information such as optimal game size and version number. Used internally by game loader and exposed here in case it's useful.
nolimit.info({game: 'SpaceArcade'}, function(info) {
var target = document.getElementById('game');
target.style.width = info.size.width + 'px';
target.style.height = info.size.height + 'px';
console.log('Loading:', info.name, info.version);
});
For more information on the available methods, see the generated JSDOC. Note that replace()
does not return an API connection.
The operator can add callbacks for certain events, such as the player trying to close the game or do a deposit from within the game.
var api = nolimit.load({
game: gameName
});
api.on('intro', function onLoad() {
// ...
});
api.on('ready', function onLoad() {
// ...
});
api.on('exit', function goToLobby() {
// ...
});
api.on('balance', function updateBalance(balance) {
// ...
});
api.on('deposit', function openDeposit() {
// ...
});
api.on('support', function openHelpChat() {
// ...
});
api.on('accountHistory', function openAccountHistory() {
// ...
});
api.on('error', function logError(message) {
console.error('nolimit.js:', message);
});
api.on('info', function logInfo(info) {
console.log('Loading:', info.name, info.version);
});
nolimit.info()
.There may be more specific events for Jurisdictions and other special cases, see those specific parts.
The operator can also control the game using RPC calls:
api.call('refresh');
api.call('pause');
api.call('resume');
window.addEventListener('message', function(e) {
if(e.data) {
console.log(e.data); // busy, idle, ready
}
});
// iframe with the launcher URL
var gameFrame = document.getElementById('game');
gameFrame.contentWindow.postMessage('pause', '*');
gameFrame.contentWindow.postMessage('resume', '*');
// To handle this way, use depositEvent=true and lobbyEvent=true instead of depositUrl and lobbyUrl, see game loading options
gameFrame.contentWindow.postMessage('deposit', '*');
gameFrame.contentWindow.postMessage('lobby', '*'); // this is the same as "exit" in regular api
If the operator has added an event listener for the 'deposit' event, the game will offer the player an option to open this when they run out of money. After a successful deposit, the game can be asked to refresh the balance:
api.on('deposit', function openDeposit () {
showDeposit().then(function() {
// ask the game to refresh balance from server
api.call('refresh');
});
});
The api can listen to events for when the game is busy/idle as well as call pause/resume. Game will usually be in "busy" state when doing a spin (or equivalent).
The usual use case for pausing is to show some operator-specific content. It is recommended to first wait for the game to be in "idle" state, then call "pause" and once done with the custom content, call "resume".
Game cannot be paused in the middle of a spin or other equivalent "busy" state, but will pause once "idle" state is reached. It is recommended to use the events to keep track of this for maximum control.
var busy = false;
api.on('busy', function() {busy = true;});
api.on('idle', function() {busy = false;});
// Pause the game at next possible time
api.call('pause');
// unpause the game
api.call('resume');
Use options.jurisdiction.name=<JURISDICTION CODE>
to override which jurisdiction's license that should be used.
Some of our supported jurisdictions are: "DE", "DK", "LV", "RO", "SE", "UKGC", "MT", "LT". Please talk to us and verify which one you should be using. It is very important you use the correct value for your targeted jurisdiction.
Lotteriinspektionen has three mandatory buttons that must be displayed for play in Sweden. The operator will need to show them on their site without covering the game.
It may help the experience to set the option fullscreen
to false
; default enabled on Android mobile.
At regular intervals (default once per hour), a dialog is shown to the player, listing time elapsed, bets and wins during the game session and an option to close the game.
Interval, message and intial values can all be changed, or it can be completely disabled. See the javascript options for nolimit.init()
. It is also possible to update these values via the server-to-server API, see integration documentation.
For instance, set the initial background color, width/height etc.
Style the original element (probably a <div>
). Note that if you do this with CSS, the tag will be iframe
, so this selector will not work:
div.game {...}
but any of these will:
div.game, iframe.game {...}
.game {...}