Steamworks 문서
단계별 지침: 순위표

개요

귀하의 애플리케이션에 아주 기본적인 Steam 순위표를 10분 이내에 통합하는 과정을 단계별로 간단히 보여 드리겠습니다. Steamworks SDK에는 Steam의 모든 기능을 구현해 볼 수 있는 Spacewar라는 예시용 애플리케이션이 포함되어 있어, Steam 기능을 실제로 시험해 볼 수 있는 좋은 기회를 제공합니다. 이 튜토리얼은 최대한 간단한 처리를 위해 Spacewar에서 발견한 정보와 ISteamUserStats내에서 찾은 순위표 API 정보에서 최소한의 필요 정보만을 추출합니다.

1단계 - 게임 순위표 정의하기

통계는 애플리케이션에 따라 다르며 Steamworks 파트너 사이트의 순위표 구성 페이지에서 설정할 수 있습니다.

순위표를 정의하려면 다음 필드를 모두 입력해야 합니다.
  • 이름 - 내부 개발팀을 나타내는 적절한 이름을 설정하세요.
  • 커뮤니티 이름 - 순위표를 커뮤니티 허브에 표시하려는 경우, 공개할 이름을 여기에 설정하세요. 이름을 입력하지 않으면 순위표가 표시되지 않습니다.
  • 정렬 방법 - 순위표를 정렬할 순서를 설정합니다. 위치 기반의 순위표는 오름차순을 사용하세요. 고득점에는 내림차순을 사용하세요.
  • 표시 유형 - 순위표에 표시할 데이터의 종류를 결정합니다. 숫자, 초, 밀리 초 중에서 선택하세요.
  • 쓰기 - 신뢰함(Trusted)으로 설정하면 클라이언트가 순위표를 설정할 수 없고 오직 SetLeaderboardScore WebAPI를 통해서만 설정이 가능합니다. 기본값은 false입니다.
  • 읽기 - 친구(Friends)로 설정하면 사용자의 친구만 순위표를 읽을 수 있고, 모든 점수는 항상 WebAPI를 통해 읽을 수 있습니다. 기본값은 false입니다.

spacewar_leaderboards

2단계 - 순위표 캡슐화 작업

다음 코드는 게임과 별도로 존재하며 필요에 따라 게임에 추가할 수 있습니다. 클래스는 그 자체로도 작동하지만, 필요에 따라 손쉽게 확장할 수 있습니다. 모든 코드는 Spacewar 샘플 파일 Leaderboards.cpp/h에서 직접 가져온 것입니다.

헤더 파일

Steam 순위표 API 호출을 모두 래핑하고 Steam 호출 결과 핸들러의 생성을 전담할 헬퍼 클래스를 정의합니다.
class CSteamLeaderboards { private: SteamLeaderboard_t m_CurrentLeaderboard; // Handle to leaderboard public: int m_nLeaderboardEntries; // How many entries do we have? LeaderboardEntry_t m_leaderboardEntries[10]; // The entries CSteamLeaderboards(); ~CSteamLeaderboards(){}; void FindLeaderboard( const char *pchLeaderboardName ); bool UploadScore( int score ); bool DownloadScores(); void OnFindLeaderboard( LeaderboardFindResult_t *pResult, bool bIOFailure); CCallResult m_callResultFindLeaderboard; void OnUploadScore( LeaderboardScoreUploaded_t *pResult, bool bIOFailure); CCallResult m_callResultUploadScore; void OnDownloadScore( LeaderboardScoresDownloaded_t *pResult, bool bIOFailure); CCallResult m_callResultDownloadScore; };

코드 파일

생성자

매개변수 - 해당 사항 없음
반환값 - 해당 없음
기능 - 이 생성자는 멤버 변수를 초기화합니다.
CSteamLeaderboards::CSteamLeaderboards() : m_CurrentLeaderboard( NULL ), m_nLeaderboardEntries( 0 ) { }

FindLeaderboard()

매개변수 - 찾고자 하는 순위표의 문자열 식별자 (예: 'Feet Traveled')
반환값 - 없음
기능 - 이 메서드는 Steam에 해당 순위표의 핸들을 요청하는 비동기 호출인 ISteamUserStats::FindLeaderboard 호출을 래핑합니다. 이 호출을 완료해야 순위표 기록을 가져오거나 기입할 수 있습니다. 이 메서드는 또한 호출 반환 메서드를 지정합니다.
void CSteamLeaderboards::FindLeaderboard( const char *pchLeaderboardName ) { m_CurrentLeaderboard = NULL; SteamAPICall_t hSteamAPICall = SteamUserStats()->FindLeaderboard(pchLeaderboardName); m_callResultFindLeaderboard.Set(hSteamAPICall, this, &CSteamLeaderboards::OnFindLeaderboard); }

OnFindLeaderboard()

매개변수 - 해당 없음
반환값 - 없음
기능 - 이 메서드는 Steam에서 순위표 찾기를 시도할 때마다 호출되는 콜백입니다. 요청한 순위표를 찾으면 해당 순위표 핸들을 현재 순위표로 설정합니다.
void CSteamLeaderboards::OnFindLeaderboard( LeaderboardFindResult_t *pCallback, bool bIOFailure ) { // see if we encountered an error during the call if ( !pCallback->m_bLeaderboardFound || bIOFailure ) { OutputDebugString( "Leaderboard could not be found\n" ); return; } m_CurrentLeaderboard = pCallback->m_hSteamLeaderboard; }

UploadScore()

매개변수 - 현재 순위표에 저장할 값을 나타내는 int32 값.
반환값 - 순위표를 아직 선택하지 않은 경우에는 false, 아니면 true를 반환합니다.
기능 - 이 메서드는 현재 선택한 순위표에 현재 사용자의 점수를 업로드하는 Steam으로의 비동기 호출인 ISteamUserStats::UploadLeaderboardScore 호출을 래핑합니다. 이 메서드는 또한 호출 반환 메서드를 지정합니다. 이 호출은 FindLeaderboard()로 순위표를 선택한 다음에 이루어져야 합니다.
bool CSteamLeaderboards::UploadScore( int score ) { if (!m_CurrentLeaderboard) return false; SteamAPICall_t hSteamAPICall = SteamUserStats()->UploadLeaderboardScore( m_CurrentLeaderboard, k_ELeaderboardUploadScoreMethodKeepBest, score, NULL, 0 ); m_callResultUploadScore.Set(hSteamAPICall, this, &CSteamLeaderboards::OnUploadScore); return true; }

OnUploadScore()

매개변수 - 해당 없음
반환값 - 없음
기능 - 이 메서드는 Steam의 순위표에 점수 업로드를 시도할 때마다 호출되는 콜백입니다.
void CSteamLeaderboards::OnUploadScore(LeaderboardScoreUploaded_t *pCallback, bool bIOFailure) { if ( !pCallback->m_bSuccess || bIOFailure ) { OutputDebugString( "Score could not be uploaded to Steam\n" ); } }

DownloadScores()

매개변수 - 해당 없음
반환값 - 순위표를 아직 선택하지 않은 경우에는 false, 아니면 true를 반환합니다.
기능 이 메서드는 현재 선택한 순위표에서 일련의 항목을 다운로드하는 Steam으로의 비동기 호출인 ISteamUserStats::DownloadLeaderboardEntries 호출을 래핑합니다. 여기서는 현재 사용자 앞의 기록 네 개와 현재 사용자 뒤의 기록 다섯 개를 합쳐 총 열 개를 다운로드합니다. 이 호출을 변경하면 순위표의 어느 위치에서든 원하는 수만큼 기록을 가져올 수 있습니다. 이 메서드는 또한 호출 반환 메서드를 지정합니다. 이 호출은 FindLeaderboard()로 순위표를 선택한 다음에 이루어져야 합니다.
bool CSteamLeaderboards::DownloadScores() { if (!m_CurrentLeaderboard) return false; // load the specified leaderboard data around the current user SteamAPICall_t hSteamAPICall = SteamUserStats()->DownloadLeaderboardEntries( m_CurrentLeaderboard, k_ELeaderboardDataRequestGlobalAroundUser, -4, 5); m_callResultDownloadScore.Set(hSteamAPICall, this, &CSteamLeaderboards::OnDownloadScore); return true; }

OnDownloadScore()

매개변수 - 해당 없음
반환값 - 없음
기능 - 이 메서드는 Steam의 순위표에서 항목 다운로드를 시도할 때마다 호출되는 콜백입니다. 데이터 다운로드에 성공하면 데이터를 항목 모음에 복사합니다. 다운로드한 기록의 개수는 m_nLeaderboardEntries에 저장됩니다.
void CSteamLeaderboards::OnDownloadScore(LeaderboardScoresDownloaded_t *pCallback, bool bIOFailure) { if (!bIOFailure) { m_nLeaderboardEntries = min(pCallback->m_cEntryCount, 10); for (int index = 0; index < m_nLeaderboardEntries; index++) { SteamUserStats()->GetDownloadedLeaderboardEntry( pCallback->m_hSteamLeaderboardEntries,index,&m_leaderboardEntries[index],NULL,0); } } }

3단계 - 게임에 통합하기

다음은 게임 안의 적절한 위치에 통합할 때 필요한 코드 조각의 전체 목록입니다.

정의 및 전역

다음은 순위표를 구축하는 데 필요한 항목과 헬퍼 개체에 대한 전역 포인터를 포함한 목록입니다.
... #include "steam_api.h" #include "SteamLeaderboards.h" // Global access to Leaderboards Object CSteamLeaderboards* g_SteamLeaderboards = NULL; ...

초기화

SteamAPI_Init을 호출하면 Steam 전체가 초기화되므로 가장 먼저 호출해야 합니다. 호출이 성공하면 헬퍼 개체를 생성합니다.
... // Initialize Steam bool bRet = SteamAPI_Init(); // Create the SteamLeaderboards object if Steam was successfully initialized if (bRet) { g_SteamLeaderboards = new CSteamLeaderboards(); } ...

콜백 처리하기

모든 Steam 콜백을 처리하려면 신규 메시지를 규칙적으로 확인해야 합니다. 그렇게 하려면 게임 루프에 다음 호출을 추가하면 됩니다.
... SteamAPI_RunCallbacks(); ...

종료

SteamAPI_Shutdown 호출은 이미 귀하의 코드 안에 있을 것입니다. 이 호출은 Steam을 종료하는 것으로 애플리케이션에서 나가기 전에 호출해야 합니다. 마지막으로, 생성한 모든 헬퍼 개체를 삭제합니다.
... // Steam 종료 SteamAPI_Shutdown(); // SteamLeaderboards 객체 삭제 if (g_SteamLeaderboards) delete g_SteamLeaderboards; ...

4단계 - 테스트 및 문제 해결

이 샘플 코드는 디버그 콘솔에 디버그 정보를 출력하여, 어느 호출이 성공하고 실패하는지 파악하도록 해줍니다. 다음은 일반적인 오류 메시지와 해결 방법입니다.

Steam_api.dll을 찾을 수 없어 애플리케이션을 시작할 수 없습니다. 애플리케이션을 재설치하면 문제가 해결될 수 있습니다.
Steam_api.dll이 실행 파일과 같은 디렉터리에 있는지 확인해 주세요.

[S_API FAIL] SteamAPI_Init() 호출에 실패했습니다. 실행 중인 Steam 또는 로컬 steamclient.dll을 찾을 수 없습니다.
Steam 클라이언트가 실행 중이 아닐 가능성이 높습니다. Steam을 시작하고 로그인해 주세요.

[S_API FAIL] SteamAPI_Init() 호출에 실패했습니다. appID를 찾을 수 없습니다.
Steam_appid.txt 파일이 제자리에 없을 가능성이 높습니다. Steam_appid.txt 파일을 소스 폴더에 넣고 파일에 appID 번호가 있는지 확인해 주세요.