samsface / godot-steam-api

Godot Steam integration using GDNative.
400 stars 16 forks source link

Godot 3.6 SteamAPI Asset issue with leaderboards #47

Closed mojoyup1528 closed 3 months ago

mojoyup1528 commented 3 months ago

For some reason,, I can update a leaderboard from one scene, but not another. I have this that sets my leaderboards right now:

func _ready():
    #SETTING LEADERBOARD VALUES
#   Steam.set_leaderboard_score('Longest_Dominoe_Streak', 10)
#   Steam.set_leaderboard_score('Most_Colorful_Creation', 3)
#   Steam.set_leaderboard_score('Most_Games_Played', 12)

    #GETTING USER LEADERBOARD VALUES
    var players_longest_dominoe_streak_score = yield(Steam.get_leaderboard_scores("Longest_Dominoe_Streak", 0, 0, Steam.LeaderboardDataRequest.GlobalAroundUser), "done")
    var players_most_colorful_score = yield(Steam.get_leaderboard_scores("Most_Colorful_Creation", 0, 0, Steam.LeaderboardDataRequest.GlobalAroundUser), "done")
    var players_games_played_score = yield(Steam.get_leaderboard_scores("Most_Games_Played", 0, 0, Steam.LeaderboardDataRequest.GlobalAroundUser), "done")

    #GETTING TOP 10 LEADERBOARD VALUES
    var top_10_global_longest_dominoe_streak_scores = yield(Steam.get_leaderboard_scores('Longest_Dominoe_Streak', 0, 10), 'done')
    var top_10_global_most_colorful_scores = yield(Steam.get_leaderboard_scores('Most_Colorful_Creation', 0, 10), 'done')
    var top_10_global_most_games_played_scores = yield(Steam.get_leaderboard_scores('Most_Games_Played', 0, 10), 'done')

    #GETTING USER AND ONE USER UP AND ONE USER DOWN ON LEADERBOARD VALUES
    var player_rivals_longest_dominoe_streak_scores = yield(Steam.get_leaderboard_scores("Longest_Dominoe_Streak", -1, 1, Steam.LeaderboardDataRequest.GlobalAroundUser), "done")
    var player_rivals_most_colorful_scores = yield(Steam.get_leaderboard_scores("Longest_Dominoe_Streak", -1, 1, Steam.LeaderboardDataRequest.GlobalAroundUser), "done")
    var player_rivals_most_games_played_scores = yield(Steam.get_leaderboard_scores("Most_Games_Played", -1, 1, Steam.LeaderboardDataRequest.GlobalAroundUser), "done")

    #SET LEADERBOARD NAMES AND VALUES
    for i in range(10):
        var mgp_label_name = Label.new()
        mgp_container_names.add_child(mgp_label_name)
        var mgp_label_value = Label.new()
        mgp_container_values.add_child(mgp_label_value)

        var lds_label_name = Label.new()
        lds_container_names.add_child(lds_label_name)
        var lds_label_value = Label.new()
        lds_container_values.add_child(lds_label_value)

        var mcc_label_name = Label.new()
        mcc_container_names.add_child(mcc_label_name)
        var mcc_label_value = Label.new()
        mcc_container_values.add_child(mcc_label_value)

    populate_labels(mgp_container_names, mgp_container_values, top_10_global_most_games_played_scores)
    populate_labels(lds_container_names, lds_container_values, top_10_global_longest_dominoe_streak_scores)
    populate_labels(mcc_container_names, mcc_container_values, top_10_global_most_colorful_scores)

func populate_labels(container_names, container_values, scores):
    for i in range(min(scores.size(), 10)):
        container_names.get_child(i).text = scores[i].persona_name
        container_values.get_child(i).text = str(scores[i].score)

and if you notice the commented out parts, those are just from the API for set_leaderboard_score. THOSE actually work but I dont need to do it there. When I play the game, I have another script after loading everything that tries to update the Most_Games_Played leaderboard score. BUT it wont do it there, though it works by uncommenting it out here (which is a scene no longer in the tree when playing so I cant do it from here, this is ONLY for the menu leaderboard).

SO, in the other script, I have this:

func _ready():
    Engine.time_scale = 2
    Engine.iterations_per_second = 60

    viewport.fxaa = Configurations.fxaa
    viewport.msaa = Configurations.msaa
    viewport.sharpen_intensity = Configurations.sharpen
    fader.get_node("AnimationPlayer").play("fade_to_clear")
    yield(get_tree().create_timer(1.5), "timeout")
    fader.queue_free()

    #SET GET STEAM ACHIEVEMENTS

    # check if player already unlocked this achievement
    var unlocked_achievement:bool = Steam.get_achievement("Welcome_to_the_game!")
    if unlocked_achievement == false:
        Steam.set_achievement("Welcome_to_the_game!")

    # Set initial window position
    OS.center_window()
    SaveLoad.update_leaderboard_score("Most_Games_Played", 1) 

where in my SaveLoad script as an autoload, it calls this:

func update_leaderboard_score(leaderboard_name, increment):
    var players_score = yield(Steam.get_leaderboard_scores(leaderboard_name, 0, 0, Steam.LeaderboardDataRequest.GlobalAroundUser), "done")

    if players_score.size() > 0:
        var score = players_score[0]["score"]
        print("Current score: ", score)

        var updated_score = int(score) + increment
        print("Updated score: ", updated_score)

        Steam.set_leaderboard_score(leaderboard_name, updated_score)
    else:
        print("No scores found for ", leaderboard_name)

BUT even if I dont use the SaveLoad pass, or even if I directly set it using just a number typed in the script, it will not update the leaderboard score. I can even do exactly this in the game ready function: _Steam.set_leaderboard_score('Most_GamesPlayed', 12) and it wont do it, but it will update it in the first script. It SHOULD be a global thing as Steam is global as an API, and its already a game on Steam so its set up correctly I promise that.

Any thoughts?

samsface commented 3 months ago

Don’t see any issues with the code. You should be able to call Steam from anywhere globally.

Some ideas:

Is there any error being printed in the console?

If you step through set_leaderboard in the debugger, is there anything different happening compared to your first script that’s working?

How are you confirming the leaderboard is updated? Through the steamworks page or the api?

mojoyup1528 commented 3 months ago

Ill probably get ahold of them then because there are zero errors in Godot. It seemed like a timing issue even though I was testing with yields as well but weird thing is, sometimes it worked and sometimes it didnt after that so if the code looks fine, Im pretty sure its a Steam issue. Thank you for responding!

samsface commented 3 months ago

One thing is that Steam rate limits leaderboard updates. Could of been that.

mojoyup1528 commented 3 months ago

So I contacted them, and they told me that I have to force an update on the leaderboards if I don't have 'trusted' resources for updating as the leaderboards set everything to default regardless of the API calls when a game is published.

SO, I found in your API, the Steam.LeaderboardUploadScoreMethod.ForceUpdate. I just use that as the last argument in the API call and that seems to work..so far lol! :) :) I know I closed this BUT I figured an 'answer' might help others so hope that is ok!

I just need to find a way to encrypt it in the gdscript so no one can backtrack the calls somehow since values are shown in the code, unless you dont think that would be an issue :P