If you have ideas for improvement, write me to telegram / Issues / pull, I’ll read everything
My Telegram @Alexey_Pe
The game in which I used this addon: Match 3 puzzle, the game has saving/loading
, rewarded/fullscreen advertising
, purchases
, call for feedback
Demo in folder addons/YandexGamesSDK/Demo
Contains simple code with comments
This addon is used by many developers, I added those who don’t mind (write to me to add you)
â„– | Developer | Players |
---|---|---|
1 | RA Games | 1 500 000 + |
2 | Magikelle Studio Yandex | 1000+ |
3 | Legatum Studio | 1000+ |
- When the game starts, the addon automatically calls
initGame()
,getPlayer(false)
,getPayments()
,getLeaderboards()
- For more understanding, you can read YandexGames.gd and sdk documentation
- Add to Project/export/html5/head include:
<script src="https://yandex.ru/games/sdk/v2"></script>
<script>
function get_url(js, size) {
return js(size);
}
</script>
Important
When the game is ready to be shown to the player, call YandexGames.ready()
- for example, after loading the save getData()
, you can call this function.
- You can write this code in your singleton or in any node that will handle loading/saving player data.
func on_initGame():
# Here you can download the player's data, and then confirm that the game is ready to be shown
YandexGames.ready() # inform Yandex that the player has uploaded
func _ready():
YandexGames.connect("on_initGame", self, "on_initGame") # Connect to the sdk initialization signal
if YandexGames.is_initGame: on_initGame() # If for some reason you connected after initialization
- After the release, commercial advertising will work after a few hours. Just wait
- When calling an advertisement, check whether the advertisement is currently called. link to video(bug)
# Interstitial Ads, signal on_showFullscreenAdv(wasShown:bool, ad_name:String)
# ad_name - this argument is not passed to yandex. I added it for signal and match
if YandexGames.current_fullscreen_ad_name == "":
YandexGames.showFullscreenAdv("ad_name")
YandexGames.connect("on_showFullscreenAdv", self, "on_showFullscreenAdv")
# example use signal
func on_showFullscreenAdv(success:bool, ad_name:String):
match ad_name:
"advertising after loading the game":
#your some code when the player closed this ad
if success: pass
else: pass
# Rewarded Ads, signal on_showRewardedVideo(success:bool, current_rewarded_ad_name:String)
# ad_name - this argument is not passed to yandex. I added it for signal and match
if YandexGames.current_rewarded_ad_name == "":
YandexGames.showRewardedVideo(ad_name)
YandexGames.connect("on_showRewardedVideo", self, "on_showRewardedVideo")
# example use signal
func on_showRewardedVideo(success:bool, ad_name:String):
match ad_name:
"open chest for advertising":
#your some code when the player closed this ad
if success: pass
else: pass
- link yandex documentation. For save/load need Player object from getPlayer(bool)
- getPlayer(bool) is called by default in YandexGames._ready() - getPlayer(false)
- getPlayer(true) - to get the player's avatar image, the window will be shown. getPlayer(false) - will not show windows
![](https://private-user-images.githubusercontent.com/70694988/280550315-70b21fec-32b4-434d-b47f-5245911958bf.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQzNzQ0MzYsIm5iZiI6MTcyNDM3NDEzNiwicGF0aCI6Ii83MDY5NDk4OC8yODA1NTAzMTUtNzBiMjFmZWMtMzJiNC00MzRkLWI0N2YtNTI0NTkxMTk1OGJmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODIzVDAwNDg1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWNjMTJjYzBiZDY2NmRjMDllMDU2NGNkMDIyNmQ0Yzc2ZTVlYjBhZGEzZDY1ODM0N2MxN2FhZTc0NWFkODQxNGYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.qWx-YdznUiGHpVPHFfxsG25wLSx-QUsyXO23524zXvg)
![](https://private-user-images.githubusercontent.com/70694988/280550320-51ccfecf-be80-4d66-966b-44a9cb54f011.jpg?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQzNzQ0MzYsIm5iZiI6MTcyNDM3NDEzNiwicGF0aCI6Ii83MDY5NDk4OC8yODA1NTAzMjAtNTFjY2ZlY2YtYmU4MC00ZDY2LTk2NmItNDRhOWNiNTRmMDExLmpwZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODIzVDAwNDg1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTQ0OTgwMmQ4NzRjNzA0NzZlMjMwMDViNGIxMGZlNTk2YjQ4OTg2YTNkZjFkYjhjMjI4NmEzZDcyYmE3NjZjNjUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.b-gwedvnNg0EuWWuI06vhOVOcbhvEkIktqmhw6jJFtI)
# setData(data:Dictionary) to save data on yandex, no signal
YandexGames.setData(data)
# getData() and getData_yield()->Dictionary, signal on_getData(data:Dictionary)
var load_save:Dictionary = yield(YandexGames.getData_yield(), "completed")
# choose the use case that you like best
getData()
YandexGames.connect("on_getData", self, "on_getData")
# Create DataManager.gd signleton
var can_load_data:bool = false
func _ready():
YandexGames.connect("on_getPlayer", self, "on_getPlayer")
func on_getPlayer(player):
can_load_data = true
loadData()
# Example call: a player has entered the game and does not have data, you need to get the data
# loadData is a yield function, when you call it you want to write it like this: yield(DataManager.loadData_yield(self), "completed")
# Why do you need to write yield: this means that you stop executing the code until the Yandex server sends you the data
func loadData_yield(from:Object):
if YandexGames.js_ysdk_player == null: print("DataManager.gd loadData(from:%s) js_ysdk_player == null"%[from]); return
if can_load_data: print("DataManager.gd loadData(from:%s)"%[from]); return
else: print("DataManager.gd loadData(from:%s) !can_load_data"%[from])
var load_save:Dictionary = yield(YandexGames.getData_yield(), "completed")
if load_save.empty(): pass # player logged in for the first time / there were no saves
# here you use the downloaded data from load_save
pass
# Example call: a player upgraded an item by spending currency, you want to save it
func saveData(from:Object):
print("DataManager.gd saveData(from:%s)"%[from])
if YandexGames.js_ysdk_player == null: print("DataManager.gd saveData(from:%s) js_ysdk_player == null"%[from]); return
# setData - overwrites a variable on the yandex server
# Create a dictionary in which you write down all the data that you need to save
# The dictionary will be converted to json, check that your data does not contain classes, you need to convert classes into data that can be stored in json
var data:Dictionary = {"gold":100, "inventory": "your_value", "etc":123}
YandexGames.setData(data)
pass
# example 1
var flags = yield(YandexGames.getFlags_yield(), "completed")
if flags is Dictionary: pass # you code here
# example 2
var flags = yield(YandexGames.getFlags_yield([
{"name":"var_1", "value":"20"},
{"name":"var_2", "value":"33"},
]), "completed")
if flags is Dictionary: pass # you code here
# getFlags_yield() uses the on_getFlags signal
YandexGames.connect("on_getFlags", self, "on_getFlags")
func on_getFlags(response):
if response is Dictionary: pass # flags
else: pass # js error (the error will be printed in the browser console)
- For purchases, you need to create purchases in the draft and add your login - this is enough for tests. (when buying, it will be written that it is a test)
- Before submitting the game for moderation, you need to write a letter to Yandex Games to enable purchases. (You don't need to do this for tests.)
- Yandex calls
on_purchase_then()
only when the player closes the window, keep this in mind. Links to video 1 and video 2 (bugs) - How to solve problem with
on_purchase_then()
- you need to usegetPurchases()
when starting the game.
# In-game purchase, signals on_purchase_then(), on_purchase_catch()
YandexGames.purchase("id")
YandexGames.connect("on_purchase_then", self, "on_purchase_then")
YandexGames.connect("on_purchase_catch", self, "on_purchase_catch")
# example use signals
func on_purchase_then(purchase:YandexGames.Purchase):
match purchase.product_id:
"id which you specified in the console":
# your code
# purchase.consume() - delete a purchase from the getPurchases array
# In short, when a player buys, he must close the window to call on_purchase_then
# Moderators make a purchase without closing the window and refresh the page, which is why on_purchase_then is not called
purchase.consume()
func on_purchase_then(product_id:String):
match product_id:
"1": pass
# Getting the purchases array [YandexGames.Purchase], signals on_getPurchases()
# The array contains only those Purchases for which consume() was not called
YandexGames.getPurchases()
YandexGames.connect("on_getPurchases", self, "on_getPurchases")
# example use signals
# purchases = Array [YandexGames.Purchase] or null
func on_getPurchases(purchases):
if purchases == null: pass # your variant
for purchase in purchases:
match purchase.product_id:
"id which you specified in the console":
# your code
# check the comment on_purchase_then()
purchase.consume()
# YandexGames.gd
class Purchase:
# product_id from Yandex Console (You specify it yourself)
var product_id:String
var _js_purchase:JavaScriptObject
func _init(__js_purchase:JavaScriptObject):
product_id = __js_purchase.productID
_js_purchase = __js_purchase
# consume() for to remove from array YandexGames.getPurchases() (on the Yandex side)
func consume():
YandexGames.js_ysdk_payments.consumePurchase(_js_purchase.purchaseToken)
For a leaderboard, you should have a leaderboard (or several) created in your draft.
You can also select the main leaderboard in the settings ('default'(bool) in the response)
Link to the leaderboard documentation
# setLeaderboardScore(Leaderboard_name:String, score:int)
YandexGames.setLeaderboardScore("Leaderboard_name", 1000)
# getLeaderboardDescription(leaderboardName:String), signal on_getLeaderboardDescription(description:Dictionary)
# description:{appID:String, default:bool, invert_sort_order:bool, decimal_offset:int, type:String, name:String, title:{en:String, ru:String ..}}
YandexGames.getLeaderboardDescription("Leaderboard_name")
# getLeaderboardPlayerEntry(leaderboardName:String)
# signals on_getLeaderboardPlayerEntry_then(response:Dictionary), on_getLeaderboardPlayerEntry_catch(err_code:String)
# response { score:int, extraData:String, rank:int, getAvatarSrc:JavaScriptObject, getAvatarSrcSet:JavaScriptObject, lang:String, publicName:String, uniqueID:String, scopePermissions_avatar:String, scopePermissions_public_name:String, formattedScore:String}
# response, getAvatarSrc and getAvatarSrcSet - is JavaScriptObject(Function maybe?) return String. I didn't understand how to use it
YandexGames.getLeaderboardPlayerEntry("Leaderboard_name")
YandexGames.connect("on_getLeaderboardPlayerEntry_then", self, "on_getLeaderboardPlayerEntry_then")
YandexGames.connect("on_getLeaderboardPlayerEntry_catch", self, "on_getLeaderboardPlayerEntry_catch")
# getLeaderboardEntries(leaderboardName:String), signal on_getLeaderboardEntries(response:Dictionary)
# response { leaderboard:Dictionary, userRank:int, entries:Array}
# leaderboard - getLeaderboardDescription response
# entries - top 20 and 10-20(up/down) players around the player who requested. entries element - getLeaderboardPlayerEntry response
YandexGames.getLeaderboardEntries("Leaderboard_name")
YandexGames.connect("on_getLeaderboardEntries", self, "on_getLeaderboardEntries")
# example use
func on_getLeaderboardEntries(response:Dictionary):
match response["leaderboard"]["name"]:
"best_score": pass
"best_speed": pass
"aaa": pass
# canReview() and on_canReview_yield()->bool, signal on_canReview(can_review:bool)
var can_review = yield(YandexGames.on_canReview_yield(), "completed")
# choose the use case that you like best
YandexGames.canReview()
YandexGames.connect("on_canReview", self, "on_canReview")
# requestReview() automatically calls canReview(), signal on_requestReview(requestReview:bool)
YandexGames.requestReview()
YandexGames.connect("on_requestReview", self, "on_requestReview")
# canShowPrompt() and canShowPrompt_yield()->bool, signal on_canShowPrompt(canShowPrompt:bool)
var can_show_prompt = yield(YandexGames.canShowPrompt_yield(), "completed")
# choose the use case that you like best
YandexGames.canShowPrompt()
YandexGames.connect("on_canShowPrompt", self, "on_canShowPrompt")
# showPrompt() automatically calls canShowPrompt(), signal on_showPrompt(accepted:bool)
YandexGames.on_showPrompt()
YandexGames.connect("on_showPrompt", self, "on_showPrompt")
# getLang() -> String (ru/en/tr/...)
YandexGames.getLang()
# Notifies Yandex that the game is ready
YandexGames.ready()
# Device Info
match YandexGames.js_ysdk.deviceInfo["_type"]:
"desktop": pass
"mobile": pass
"tablet": pass
"tv": pass