Search code examples
pythonctypesleaderboardsteam-web-apirenpy

Python ctype: argument 2: <class 'Typeerror': wrong type


I use Ren'Py engine and want to implemet Steam leaderboards in to my game. Steamapi has a method SteamUserStats: https://partner.steamgames.com/doc/api/ISteamUserStats#FindOrCreateLeaderboard

Ren'Py uses ctypes-based binding to the Steamworks API: https://github.com/renpy/renpy-build/blob/master/steamapi/steamapi.py

In order to deal with leader board I have to create it in Steamworks interface and then use FindLeaderboard function -> I tried it and this function cannot find created leader board, named "topscores".

I also can use FindOrCreateLeaderboard function to create a leaderboard, but in this case I have an error: "argument 2: <class 'Type error': wrong type"

I have connection to Steam, as other functions, like checking achievements, work. Please advise what I can do. Thanks.

the code I use:

# find my leaderboard
def find_board():
    leaderboard_name = achievement.steamapi.SteamUserStats().FindOrCreateLeaderboard("topscores", 2, 1)
    return leaderboard_name

I expected it to work.


Solution

  • The code is written to take explicit classes for the enumerations. From steamapi.py, FindOrCreateLeaderboard is a method that calls ISteamUserStatus_FindOrCreateLeaderboard:

    def FindOrCreateLeaderboard(self, pchLeaderboardName, eLeaderboardSortMethod, eLeaderboardDisplayType):
        return ISteamUserStats_FindOrCreateLeaderboard(byref(self), pchLeaderboardName, eLeaderboardSortMethod, eLeaderboardDisplayType) # type: ignore
    

    But! ISteamUserStats_FindOrCreateLeaderboard is a C function called by ctypes with these types:

    ISteamUserStats_FindOrCreateLeaderboard.argtypes = [ POINTER(ISteamUserStats), c_char_p, ELeaderboardSortMethod, ELeaderboardDisplayType ]
    

    The second parameter is type c_char_p and corresponds to pchLeaderboardName. A c_char_p needs a bytes object but "topscores" is type str. Use b'topscores' instead.

    The code is also written to take explicit classes for the enumerations, so you may need to use the named enumerations instead. Try:

    from steamapi import k_ELeaderboardSortMethodDescending, k_ELeaderboardDisplayTypeNumeric
    
    # find my leaderboard
    def find_board():
        leaderboard_name = achievement.steamapi.SteamUserStats().FindOrCreateLeaderboard(
            b'topscores',
            k_ELeaderboardSortMethodDescending,
            k_ELeaderboardDisplayTypeNumeric)
        return leaderboard_name