Can anyone help me ?Not working high score

Godot Version

3

not working high score

extends Node2D

# High score variable
var high_score := 0

# Reference to the label node
onready var highscore_node = get_node("/root/Game/Control/Highscore")

# Data storage key
var data_key := "high_score_key"

func _ready():
	# Connect the "data_loaded" signal to the loading function
	if $igbgui:
		$igbgui.connect("data_loaded", self, "_on_data_loaded")
	
	# Ensure data_value is a dictionary
	if !$igbgui.data_value or typeof($igbgui.data_value) != TYPE_DICTIONARY:
		$igbgui.data_value = {}  # Initialize as an empty dictionary
	
	# Initialize the key if it doesn't exist
	if not $igbgui.data_value.has(data_key):
		$igbgui.data_value[data_key] = 0  # Set a default value
	
	# Load data when the game is ready
	$igbgui.data_key = data_key
	$igbgui.load_data = true

func _update_high_score_label():
	# Update the label text
	highscore_node.text = "High Score: " + str(high_score)
	
	# Save the high score to data_dictionary[data_key]
	if typeof($igbgui.data_value) == TYPE_DICTIONARY:
		$igbgui.data_value[data_key] = high_score
		$igbgui.save_data = true
		print("Data saved: ", $igbgui.data_value)  # Print to confirm data saving
	else:
		print("data_value is not a dictionary. Type: ", typeof($igbgui.data_value))

func _on_player_score_increased(new_score: int):
	print("New Score Received: ", new_score)
	if new_score > high_score:
		high_score = new_score
		_update_high_score_label()

# Function called when data is loaded
func _on_data_loaded():
	if $igbgui.data_value and typeof($igbgui.data_value) == TYPE_DICTIONARY:
		if $igbgui.data_value.has(data_key):
			var loaded_value = $igbgui.data_value[data_key]
			if loaded_value != null:
				var str_value = str(loaded_value)
				if str_value.is_valid_integer():
					high_score = int(str_value)
					_update_high_score_label()
				else:
					print("Loaded value is not a valid integer. Value: ", str_value)
			else:
				print("Loaded value is null.")
		else:
			print("Key not found in data_value.")
	else:
		print("data_value is not a dictionary or is null. Type: ", typeof($igbgui.data_value))

— Debugging process started —
Godot Engine v3.5.3.stable.official.6c814135b - https://godotengine.org
OpenGL ES 3.0 Renderer: GeForce GTX 550 Ti/PCIe/SSE2
Async. shader compilation: OFF

current device: desktop
current platform: mock
current language: en
player authorized:False
mouse out
mouse in
data loaded: True
[57]
data_value is not a dictionary or is null. Type: 4
New Score Received: 14
data_value is not a dictionary. Type: 4
mouse out
— Debugging process stopped —…

Seems like your data_value is a string, maybe you are saving string? How is $igbgui scripted?

extends Node
#Instant Games Bridge by Mewton Games, GUI Node by Repin Develop v1.11
#Добавьте данную сцену как дочернюю там где вам необходим функционал IGB.
#Отключение звука при сворачивании, показе interstitial и rewarded происходит автоматически.
#platform
export var game_ready = false #поставте галочу, чтобы отправить сигнал ready в нужной сцене
var vk_only = false #vk games, работает только на платформе vk
var vk_direct_only = false #vk direct only, работает только на мобильной платформе vk direct
var vk_play_only = false #vk play, работает только на vk play
var yandex_only = false #yandex games, работает только на yandex играх
var no_social = false #html5 платформа без интеграции с плагином
#device
var desktop = false #работает только на ПК
var mobile = false #работает только на телефонах
signal app_visible #сигнал при возвращении видимости игры после сворачивания
signal app_hidden #сигнал при сворачивании игры
#advertisement
export var show_banner = false #показать баннер
export var show_interstitial = false #поставьте галочу для показа interstitial, либо вызывайте ее при помощи AnimationPlayer
export var show_rewarded = false #поставьте галочу для показа rewarded, либо вызывайте ее при помощи AnimationPlayer
signal get_reward #используйте сигнал "get_reward" для получения награды
signal ad_open #сигнал при открытии interstitial и rewarded рекламы.
signal ad_close #сигнал при закрытии interstitial и rewarded рекламы.
#social
export var share_app = false #поставте галочу в сцене, где необходимо поделится приложением vk.
export(String) var game_link = "" #ссылка на игру, пример: https://vk.com/app123
export var join_community = false #приглашение в сообщество vk
export(String) var community_id = "" #id вашего сообщества vk, состоит только из цифр, пример: 123
export var vk_donut_check = false #включение проверки подписки на сообщество vk donut через переменную vk_donut_subscriber, так же требуется указать community_id
var vk_donut_subscriber = false #проверка подписки на ваше сообщество через vk donut, true - когда есть подписка и false при ее отсутствии.
export var invite_friends = false #пригласить друга из vk
export var create_post = false #сделать пост на стене vk
export(String) var post_message = "" #текст вашего поста
export(String) var post_attachments = "" #ссылка или номер вложения к посту, например: photo-123 or video-123 etc.
export var add_to_favorites = false #добавить в избранное vk
export var rate = false #оценить приложение в yandex
export var open_catalog = false #открыть каталог игр в yandex
export(String) var catalog_link = "" #ссылка на страницу разработчика, пример: /games/developer?name= Не работает на iOS!
#leaderboard
export var vk_direct_leaderboard = false #доступно только в vk direct, показывает только ваш результат
var vk_direct_result = 0.0 #ваш результат который отобразится в окне vk direct
export var yandex_leaderboard = false #активация доски лидеров yandex
var yandex_result = 0.0 #результат который отобразится на странице игры в yandex играх
export(String) var yandex_leaderboard_name = "" #техническое название лидерборда в который будет осуществляться запись
#storage
export(Array) var data_key #выберете String для создания названия ключа
export(Array) var data_value #выберете любое значение для вашего ключа. ВНИМАНИЕ! Размер массива "data_key", должен совпадать с размером "data_value"
export var save_data = false #сохранение значений
export var load_data = false #загрузка значений
signal data_loaded #проверка загрузки значений
export var delete_data = false #удаление значений

func _ready():
#game ready
	if game_ready:
		Bridge.platform.send_message(Bridge.PlatformMessage.GAME_READY)
#connect states
	Bridge.advertisement.connect("banner_state_changed",self,"_banner_state")
	Bridge.advertisement.connect("interstitial_state_changed",self,"_interstitial_state")
	Bridge.advertisement.connect("rewarded_state_changed",self,"_rewarded_state")
	Bridge.game.connect("visibility_state_changed",self,"_visibility_state")
#get current device
	print("current device: " + str(Bridge.device.type))
#get current platform
	print("current platform: " + str(Bridge.platform.id))
#get current language
	print("current language: " + str(Bridge.platform.language))
#get player authorized
	print("player authorized:" + str(Bridge.player.is_authorized))
#set language
	if OS.get_name() == "HTML5":
		TranslationServer.set_locale(Bridge.platform.language)
#set platform visibility
	if Bridge.platform.id == "vk":
		vk_only = true
	if Bridge.platform.id == "vk" and Bridge.device.type == "mobile":
		vk_direct_only = true
	if Bridge.platform.id == "yandex":
		yandex_only = true
	if Bridge.platform.id == "vk_play":
		vk_play_only = true
	if Bridge.platform.id == "mock":
		no_social = true
#set device visibility
	if Bridge.device.type == "desktop":
		desktop = true
	if Bridge.device.type == "mobile":
		mobile = true
#vk donut check
	if Bridge.platform.id == "vk":
		if vk_donut_check:
			JavaScript.eval("""
			let url = new URL(window.location.href)
			let accessToken = url.searchParams.get('access_token')
			bridge.platform.sdk.send('VKWebAppCallAPIMethod', {
				method: 'donut.isDon',
				params: {
					owner_id: '-"""+str(community_id)+"""',
					v: '5.131',
					access_token: accessToken 
				}})
				.then((data) => { 
					if (data.response) {
						console
						window.vk_donut_subscriber = true
					}
					else {
						window.vk_donut_subscriber = false
					}
				})
				.catch((error) => {
					console.log(error)
				})""")
			yield(get_tree().create_timer(5), "timeout")
			if JavaScript.get_interface("window").vk_donut_subscriber == true:
				vk_donut_subscriber = true
			if JavaScript.get_interface("window").vk_donut_subscriber == false:
				vk_donut_subscriber = false
			if vk_donut_subscriber:
				print("vk donut subscription: true")
			else:
				print("vk donut subscription: false")
		
func _process(_delta):
#advertisement
	if show_banner:
		$anim.play("show_banner")
	if show_interstitial:
		$anim.play("interstitial")
	if show_rewarded:
		$anim.play("rewarded")
#vk social
	if vk_only:
		if share_app:
			$anim.play("share_app")
		if join_community:
			$anim.play("join_community")
		if invite_friends:
			$anim.play("invite_friends")
		if create_post:
			$anim.play("create_post")
		if add_to_favorites:
			$anim.play("add_to_favorites")
#vk direct leaderboard
	if vk_direct_only:
		if vk_direct_leaderboard:
			$anim.play("vk_direct_leaderboard")
#yandex social
	if yandex_only:
		if rate:
			$anim.play("rate")
		if open_catalog:
			$anim.play("open_catalog")
#yandexleaderboard
		if yandex_leaderboard:
			$anim.play("yandex_leaderboard")
#storage
	if load_data:
		$anim.play("load_data")
	if save_data:
		$anim.play("save_data")
	if delete_data:
		$anim.play("delete_data")
	
func _finished(anim_name):
#advertisement
	if anim_name == "show_banner":
		Bridge.advertisement.show_banner()
		show_banner = false
	if anim_name == "interstitial":
		Bridge.advertisement.show_interstitial()
		show_interstitial = false
	if anim_name == "rewarded":
		Bridge.advertisement.show_rewarded()
		show_rewarded = false
#vk social
	if vk_only:
		if anim_name == "share_app":
			Bridge.social.share(Bridge.ShareVkOptions.new(game_link))
			share_app = false
		if anim_name == "join_community":
			Bridge.social.join_community(Bridge.JoinCommunityVkOptions.new(community_id))
			join_community = false
		if anim_name == "invite_friends":
			Bridge.social.invite_friends()
			invite_friends = false
		if anim_name == "create_post":
			Bridge.social.create_post(Bridge.CreatePostVkOptions.new(post_message,post_attachments))
			create_post = false
		if anim_name == "add_to_favorites":
			Bridge.social.add_to_favorites()
			add_to_favorites = false
#vk direct leaderboard
	if vk_direct_only:
		if anim_name == "vk_direct_leaderboard":
			Bridge.leaderboard.show_native_popup(Bridge.ShowNativePopupVkOptions.new(vk_direct_result,true))
			vk_direct_leaderboard = false
#yandex social
	if yandex_only:
		if anim_name == "rate":
			Bridge.social.rate()
			rate = false
		if anim_name == "open_catalog":
			JavaScript.eval("window.open('https://yandex."+str(Bridge.platform.tld)+str(catalog_link)+"')")
			open_catalog = false
#yandex_leaderboard
		if anim_name == "yandex_leaderboard":
			Bridge.leaderboard.set_score(Bridge.SetScoreYandexOptions.new(yandex_result,yandex_leaderboard_name))
			print("leaderboard " + str(yandex_leaderboard_name))
			yandex_leaderboard = false
#storage
	if anim_name == "load_data":
		load_data()
		load_data = false
	if anim_name == "save_data":
		save_data()
		save_data = false
	if anim_name == "delete_data":
		delete_data()
		delete_data = false
#ad state and audio mute in advertisement
func _banner_state(state:String):
	print("banner ",state)
func _interstitial_state(state:String):
	if state == "opened":
		AudioServer.set_bus_mute(0, true)
		emit_signal("ad_open")
		print("interstitial opened")
	if state == "closed":
		emit_signal("ad_close")
		AudioServer.set_bus_mute(0, false)
		print("interstitial closed")
	if state == "failed":
		emit_signal("ad_close")
		AudioServer.set_bus_mute(0, false)
		print("interstitial failed and closed")
func _rewarded_state(state:String):
	if state == "opened":
		emit_signal("ad_open")
		AudioServer.set_bus_mute(0, true)
		print("rewarded opened")
	if state == "rewarded":
		emit_signal("get_reward")
		print("get reward")
	if state == "closed":
		emit_signal("ad_close")
		AudioServer.set_bus_mute(0, false)
		print("rewarded closed")
	if state == "failed":
		emit_signal("ad_close")
		AudioServer.set_bus_mute(0, false)
		print("rewarded failed and closed")
			
#audio mute in minimizing
func _visibility_state(state:String):
	if state == "visible":
		AudioServer.set_bus_volume_db(0,0)
		emit_signal("app_visible")
		print("game visible")
	if state == "hidden":
		AudioServer.set_bus_volume_db(0,-80)
		emit_signal("app_hidden")
		print("game hidden")
#audio mute in mouse focus out
func _notification(what):
	match what:
		MainLoop.NOTIFICATION_WM_MOUSE_ENTER:
			if OS.get_name() == "HTML5":
				AudioServer.set_bus_volume_db(0,0)
			print("mouse in")
		MainLoop.NOTIFICATION_WM_MOUSE_EXIT:
			if OS.get_name() == "HTML5":
				AudioServer.set_bus_volume_db(0,-80)
			print("mouse out")
#storage func and status
func load_data():
	Bridge.storage.get(data_key,funcref(self,"_load_data_completed"))
func save_data():
	Bridge.storage.set(data_key, data_value, funcref(self,"_save_data_completed"))
func delete_data():
	Bridge.storage.delete(data_key)
	
func _load_data_completed(success ,data):
	print("data loaded: " + str(success))
	if success:
		print(data)
		data_value = data
		emit_signal("data_loaded")
	else:
		print("empty")
func _save_data_completed(success):
	print("data saved: " + str(success))
	

Thats my igbgui script

Try printing your data_key see what you get, I am not sure how Bridge.storage works. Looks like you have a variabled named save_data and a function named the same save_data I am surprised this isn’t outright a scripting error and highly recommend changing their names to be different.

I tried to change it but i asked about that the plugin developer and he said dont change anything in the scene code.I will try now

I tried and thats what i got:
— Debugging process started —
Godot Engine v3.5.3.stable.official.6c814135b - https://godotengine.org
OpenGL ES 3.0 Renderer: GeForce GTX 550 Ti/PCIe/SSE2
Async. shader compilation: OFF

current device: desktop
current platform: mock
current language: en
player authorized:False
Data Key:high_score_key
mouse out
mouse in
data loaded: True
[57]
Data loaded: [57]
data_value is not a dictionary or is null. Type: 4
New Score Received: 0
New Score Received: 11
data_value is not a dictionary. Type: 4
mouse out
— Debugging process stopped —

which part of this is the data_value?

i think this data_value is not a dictionary or is null. Type: 4

4 means it’s a string. Can you show me print(data_value)

1 Like
func _on_data_loaded():
	print("Data loaded: ", $igbgui.data_value)
	if typeof($igbgui.data_value) == TYPE_DICTIONARY:
		if $igbgui.data_value.has(data_key):

Then it’s printing this? “[57]” doesn’t bode well, I have to guess the Bridge.storage.set doesn’t accept dictionaries or serializes them in a very destructive way. I’m also seeing data_value and data_key are expected to be arrays?

That seems way off, I am sure it’s worth it to re-write this script, or at least remove the Array type.

You should try to serialize the data yourself then use the Bridge.storage.set, JSON is a good target, especially for web based games.

func save_data():
	var as_string = JSON.print(data_value) # convert data to a string
	Bridge.storage.set(data_key, as_string, funcref(self,"_save_data_completed"))

func _load_data_completed(success ,data):
	print("data loaded: " + str(success))
	if success:
		print(data)
		data_value = JSON.parse(data) # convert string back to data
		emit_signal("data_loaded")
	else:
		print("empty")

I can tell what says that plugin creater:

Open the data_value array
In the code, $igbgui.data_value[0] = value, etc
This is when saving
To load connect signal data loaded
And in the function that will be created already write
your_variable = $igbgui.data_value[0]

And you have set the key names
In data_key?
You have it loading then by key name

You should have the name of the key you are loading or saving specified
Each key corresponds to a value

and i try to create a code like this but i dont know am i right ?

It’s certainly off, keys are strings or ints, not data containers like Array. Values can be Arrays or Dictionarys but converting them to a string is common practice.

I would try re-writing them as pure functions, without either data_value or data_key variables stored in the node. Then use the function arguments and signal to send data.

# remove:
#export(Array) var data_key
#export(Array) var data_value
signal data_loaded(value_got)

func load_data(key: String):
	$anim.play("load_data") #also wants to animate?
	Bridge.storage.get(key, funcref(self,"_load_data_completed"))

func save_data(key: String, value):
	$anim.play("save_data")
	var value_str = JSON.print(value)
	Bridge.storage.set(key, value_str, funcref(self,"_save_data_completed"))

func delete_data(key: String):
	$anim.play("delete_data")
	Bridge.storage.delete(key)
	
func _load_data_completed(success: bool, data_str):
	print("data loaded: " + str(success))
	if success:
		var data = JSON.parse(data_str)
		emit_signal("data_loaded", data)
	else:
		print("empty")

Then in your script you would keep track of high_score with your high_score variable, only calling $igbgui to save and load.

func _ready():
	# Connect the "data_loaded" signal to the loading function
	if $igbgui:
		$igbgui.connect("data_loaded", self, "_on_data_loaded")
		$igbgui.load_data(data_key)

func _update_high_score_label():
	# Update the label text
	highscore_node.text = "High Score: " + str(high_score)
	$igbgui.save_data(data_key, high_score)

# Function called when data is loaded
func _on_data_loaded(new_value):
	print("Got loaded value: ", new_value)
	high_score = new_value
1 Like

I get this


maybe thats only for godot 4 ?

Maybe so, you can remove the : Variant type definition

yes thats worked but this ?

remove that line as well, left over, this function does not have a “data” varible.

I think you are pasting this into the wrong script too.

then were i need to ?


but i think yes…

Here I am recommending you change the bridge/storage functions, they are attached to the igbgui node.


This section is refering to your highscore/game script.

Okay i understand but i think if i change it would not work because last time i changed that function because there were same names and it crashed :confused:
And maybe try another way ?That igbgui is an animations player and has this animation but i dont understand how to use it maybe try with animation to not get that problem with code ?