Skip to main content

Adding SpellSync for Defold

SpellSync is an extension for the Defold engine (for version Defold >= 1.4.0). SpellSync is a service for convenient publishing of HTML5 games on various platforms with a single SDK. The service supports local game debugging.

Installation

You can use it in your own project by adding the spellsync git project as a Defold Library Dependency.

Initialization

In the game.project file, you need to add the 'spellsync' section and specify the game id and token, other parameters can be omitted:

[spellsync]
id = game identifier
token = token
description = There are not enough words to describe the awesomeness of the game
image = /img/ogimage.png

Additional parameters: (doc)

To begin, initialize the SDK using the init method:

local spellsync = require("spellsync.spellsync")

spellsync.init(function(success)
if success then
-- initialization was successful
else
-- initialization error
end
end)

To subscribe to an event, you need to define the corresponding method in the callbacks table:

local spellsync = require("spellsync.spellsync")

local function ads_start()
-- turn off sound
end

local function ads_close(success)
-- turn on sound
end

local function ads_reward()
-- give some gold to the player
end

-- event functions can be assigned before SDK initialization
spellsync.ads.callbacks.start = ads_start
spellsync.ads.callbacks.close = ads_close
spellsync.ads.callbacks.rewarded_reward = ads_reward
-- initialize the SDK
spellsync.init(function(success)
if success then
-- show preloader
spellsync.ads.show_preloader(function(result)
-- ad closed, can do something
end)
-- do something else

-- show rewarded video ad
spellsync.ads.show_rewarded_video()

-- show rewarded video ad using a callback
spellsync.ads.show_rewarded_video(function(result)
if result then
-- give the player some crystals
end
})
else
-- initialization error
end
end)

API

See all API method names and descriptions.

Calling native platform methods

To call a native method, get an object, or field, the function call_native_sdk(method, parameters, callback) is intended.

  • method: a string representing the path to the method, object, or field separated by dots. If the path leads to an object or object field, then parameters and callback will be ignored.
  • parameters: the parameter of the called method (string, number, boolean, table). If multiple parameters need to be passed, they should be placed in an array (table). The order of parameters is determined by the index of the array. Passing functions as parameters is not supported!
  • callback: a callback function that needs to be specified if the native method returns a promise. If callback == nil, the function returns the result; otherwise, it returns nil.

The result returned by the function is formatted according to the following rules:

  1. The method parameter refers to an object or object field:

    • If the result is a string, number, boolean, or object, the received data is returned.
    • In case an exception occurs, error data is returned in the form of a table {error = "error description"}.
  2. The method parameter refers to a function:

    • If the result is a string, number, boolean, or object, the received data is returned.
    • If an exception occurs, or if the promise is rejected with an error, error data is returned in the form of a table {error = "error description"}.

callback(result): result - the result of the promise execution. If the promise is rejected with an error, then result = {error = "error description"}.

Advanced actions with promises

There are situations where a promise returns an object with functions that may need to be executed later. For these situations, a mechanism is provided for saving the object at the JS level and using it in subsequent API calls.

In these cases, the format of the method parameter for the call_native_sdk function can take the following forms:

  • var=path1.path2.path3: The object path1.path2.path3 will be saved in the variable var.
  • var:method: Calling a method from a previously saved object.
  • var2=var:method2: Calling a method (which must be a promise) from a previously saved object and saving the result in the variable var2.

Examples of various call scenarios

SDK CallTypeFunction Call and Result
environmentobjectcall_native_sdk("environment")
table
environment.i18n.langstringcall_native_sdk("environment.i18n.lang")
string
envundefinedcall_native_sdk("env")
{error = 'Field or function "env" not found!'}
player.getUniqueID()functioncall_native_sdk("player.getUniqueID")
string
feedback.canReview()functioncall_native_sdk("feedback.canReview", nil, callback)
nil
After the promise is resolved, the callback will be called.
getLeaderboards().then(lb => {})functioncall_native_sdk("lb=getLeaderboards", nil, callback)
nil
After the promise is resolved, the callback will be called.
The result will be saved in a JS variable.
lb.setLeaderboardScore()functioncall_native_sdk("lb:setLeaderboardScore")
After the promise is resolved, the callback will be called.
When the function is called, there will be an access to the previously saved JS variable; if the variable is not found, the function will return {error = "The 'lb' object has not been previously saved!"}

Example of working with Yandex platform natively:

local spellsync = require("spellsync.spellsync")

spellsync.init(function(result)
if result then
-- Get Yandex environment variables, equivalent to ysdk.environment
local environment = spellsync.platform.call_native_sdk("environment")

-- Get the language of Yandex.Games interface in ISO 639-1 format, equivalent to ysdk.environment.i18n.lang
local language = spellsync.platform.call_native_sdk("environment.i18n.lang")

-- Get leaderboards tables, equivalent to ysdk.getLeaderboards()
-- the promise returns an object, save it in the variable lb
spellsync.platform.call_native_sdk("lb=getLeaderboards", nil, function(leaderboards)
pprint(leaderboards)
-- Record a new score, equivalent to lb.setLeaderboardScore('leaderboard2021', 120);
-- accessing the lb variable
spellsync.platform.call_native_sdk("lb:setLeaderboardScore", { "leaderboard2021", 120 })
-- Get leaderboard data, equivalent to lb.getLeaderboardEntries('leaderboard2021')
spellsync.platform.call_native_sdk("lb:getLeaderboardEntries", "leaderboard2021", nil, function(result)
pprint(result)
end)

-- Get leaderboard data with parameters
-- equivalent to lb.getLeaderboardEntries('leaderboard2021', {quantityTop: 10, includeUser: true, quantityAround: 3})
local parameters = {
"leaderboard2021",
{ quantityTop = 10, includeUser = true, quantityAround = 3 }
}
spellsync.platform.call_native_sdk("lb:getLeaderboardEntries", parameters, function(result)
pprint(result)
end)
end)
end
end)

The Lua code above is equivalent to JavaScript code:

YaGames.init().then((ysdk) => {
// Get Yandex environment variables
let environment = ysdk.environment;

// Get the language of the Yandex.Games interface in ISO 639-1 format
let language = ysdk.environment.i18n.lang;

// Get leaderboards tables
ysdk.getLeaderboards().then(function (lb) {
console.log(lb);
// Record a new score
lb.setLeaderboardScore('leaderboard2021', 120);
// Get leaderboard data
lb.getLeaderboardEntries('leaderboard2021').then(function (result) {
console.log(result);
});

// Get leaderboard data with parameters
let parameters = { quantityTop: 10, includeUser: true, quantityAround: 3 };
lb.getLeaderboardEntries('leaderboard2021', parameters).then(function (result) {
console.log(result);
});
});
});

Mock for platforms other than HTML

Mock APIs are provided for platforms other than HTML for convenient debugging.

When using functions like:

  • player.get(key)
  • player.set(key, value)
  • player.add(key, value)
  • player.toggle(key)
  • player.has(key)
  • player.to_json()
  • player.from_json(player)

the data will be stored/retrieved locally in/from the file "spellsync.dat" using sys.save()/sys.load() functions (this can be changed).

local mock_api = require("spellsync.mock_api")

-- Set the name for the local data storage file
mock_api.file_storage = "my_storage.dat"

-- Set values for mock API
mock_api["player.name"] = "my player name"
mock_api["player.id"] = 625
mock_api["player.score"] = 500

Each SpellSync API mock function can be represented by data or a function that performs an action and/or returns data. Any functions/data can be overridden for convenience in work/debugging.

Mock for native calls

Mocks for native calls are separated into a separate module. To include it, use the set_native_api function.

--native_api.lua
local M = {}

M["environment"] = {
app = {
id = "app_id"
},
browser = {
lang = "ru"
},
i18n = {
lang = "ru",
tld = "ru"
}
}

return M
local mock = require("spellsync.mock")
local native_api = require("native_api")
local spellsync = require("spellsync.spellsync")

-- Set a mock for native functions
mock.set_native_api(native_api)
-- Access the native function
local result = spellsync.platform.call_native_sdk("environment")
pprint(result)

Author: Megalanthus

Stay in Touch

Other documents of this chapter available Here. To get started, welcome to the Tutorials chapter.

SpellSync Community Telegram: @spellsync.

For your suggestions e-mail: [email protected]

We Wish you Success!