Online Subsystem Write to Leaderboard

Hello, I’m trying to implement Leaderboard using OnlineSubsystem Leaderboards Interface. And it’s not working for me.

Steam is properly integrated in to my game - Achievements and online Sessions work perfectly fine.

I’ve created the Leaderboard on Steam (image below)

This is the code I’m trying to use to write to the Leaderboard.

		IOnlineLeaderboards* Leaderboards = OnlineSubsystem->GetLeaderboardsInterface().Get();
		if (Leaderboards != nullptr)
		{
			const FUniqueNetIdPtr NetId = RetrievePlayerUniqueNetId(PlayerController); // works fine for achievements
			FOnlineLeaderboardWrite NewLeaderboardInfo = FOnlineLeaderboardWrite();
			NewLeaderboardInfo.DisplayFormat = ELeaderboardFormat::Number;
			NewLeaderboardInfo.SortMethod = ELeaderboardSort::Ascending;
			NewLeaderboardInfo.UpdateMethod = ELeaderboardUpdateMethod::KeepBest;
			NewLeaderboardInfo.LeaderboardNames = TArray<FName> { FName("TestLeaderboard") };
			NewLeaderboardInfo.RatedStat = "BestLap";
			NewLeaderboardInfo.SetIntStat("BestLap", 140);


			const bool Result = Leaderboards->WriteLeaderboards(NAME_GameSession, *NetId.Get(), NewLeaderboardInfo);
		}

The error I get is this:

[2023.05.26-18.14.05:926][544]LogOnlineLeaderboard: Warning: STEAM: Failure to write key value pair when uploading to Steam TestLeaderboard_BestLap=140
[2023.05.26-18.14.05:928][544]LogOnline: Warning: OSS: Async task 'FOnlineAsyncTaskSteamUpdateStats bWasSuccessful: 0 User: Bojan [0xSOME_NUMBER]' failed in 0.622502 seconds
[2023.05.26-18.14.05:942][545]LogOnline: Warning: OSS: Async task 'FOnlineAsyncTaskSteamUpdateLeaderboard bWasSuccessful: 0 Leaderboard: TestLeaderboard Score: 0' failed in 0.638273 seconds

What am I doing wrong? Do I need to add Leaderboards in DefaultEngine.ini in the same way I have added Achievements? If yes, what is the syntax for that? Maybe I should do some additional work on Steamworks side? If yes, what should I do?

Thanks in advance

Anyone has any idea? I’m sorry for bringing it up, but I really need this one :slight_smile:
I forgot to mention, I’m running the game using BAT file.

OK, so I managed to figure it out.

If you create Leaderboard named Jynkyard01, you also must go to stats and create stat named Jynkyard01_Jynkyard01

Then, you can do this in code to submit to leaderboard, and it should work just fine

void YourClass::SubmitLeaderboardScore(APlayerController* PlayerController, FName StatName, int32 StatValue)
{
	FOnlineLeaderboardWrite WriteObject;
	WriteObject.LeaderboardNames.Add(StatName);
	WriteObject.RatedStat = StatName;
	WriteObject.DisplayFormat = ELeaderboardFormat::Milliseconds;
	WriteObject.SortMethod = ELeaderboardSort::Ascending;
	WriteObject.UpdateMethod = ELeaderboardUpdateMethod::KeepBest;
	WriteObject.SetIntStat(StatName, StatValue);
	bool Successful = DoWriteLeaderboardObject(PlayerController, WriteObject);
	if (Successful)
	{
		// Do success logic	
	} else
        {
        // Do fail logic
	}
}
bool YourClass::DoWriteLeaderboardObject(APlayerController* PlayerController, FOnlineLeaderboardWrite& WriteObject)
{
	if (APlayerState* PlayerState = (PlayerController != NULL) ? PlayerController->PlayerState : NULL)
	{
		FUniqueNetIdPtr UserId = PlayerState->GetUniqueId().GetUniqueNetId();
		if (UserId.IsValid())
		{
			if (IOnlineSubsystem* const OnlineSub = IOnlineSubsystem::IsLoaded() ? IOnlineSubsystem::Get() : nullptr)
			{
				IOnlineLeaderboardsPtr Leaderboards = OnlineSub->GetLeaderboardsInterface();
				if (Leaderboards.IsValid())
				{
					bool bResult = Leaderboards->WriteLeaderboards(PlayerState->SessionName, *UserId, WriteObject);

					bool bFlushResult = Leaderboards->FlushLeaderboards(PlayerState->SessionName);

					return bResult && bFlushResult;
				}
				else
				{
					FFrame::KismetExecutionMessage(TEXT("WriteLeaderboardObject - Leaderboards not supported by Online Subsystem"), ELogVerbosity::Warning);
				}
			}
			else
			{
				FFrame::KismetExecutionMessage(TEXT("WriteLeaderboardObject - Invalid or uninitialized OnlineSubsystem"), ELogVerbosity::Warning);
			}
		}
		else
		{
			FFrame::KismetExecutionMessage(TEXT("WriteLeaderboardObject - Cannot map local player to unique net ID"), ELogVerbosity::Warning);
		}
	}
	else
	{
		FFrame::KismetExecutionMessage(TEXT("WriteLeaderboardObject - Invalid player state"), ELogVerbosity::Warning);
	}

	return false;
}
1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.