개요
귀하의 애플리케이션에 아주 기본적인 Steam 순위표를 10분 이내에 통합하는 과정을 단계별로 간단히 보여 드리겠습니다.
Steamworks SDK에는 Steam의 모든 기능을 구현해 볼 수 있는
Spacewar라는 예시용 애플리케이션이 포함되어 있어, Steam 기능을 실제로 시험해 볼 수 있는 좋은 기회를 제공합니다. 이 튜토리얼은 최대한 간단한 처리를 위해 Spacewar에서 발견한 정보와
ISteamUserStats내에서 찾은 순위표 API 정보에서 최소한의 필요 정보만을 추출합니다.
1단계 - 게임 순위표 정의하기
통계는 애플리케이션에 따라 다르며 Steamworks 파트너 사이트의
순위표 구성 페이지에서 설정할 수 있습니다.
순위표를 정의하려면 다음 필드를 모두 입력해야 합니다.
- 이름 - 내부 개발팀을 나타내는 적절한 이름을 설정하세요.
- 커뮤니티 이름 - 순위표를 커뮤니티 허브에 표시하려는 경우, 공개할 이름을 여기에 설정하세요. 이름을 입력하지 않으면 순위표가 표시되지 않습니다.
- 정렬 방법 - 순위표를 정렬할 순서를 설정합니다. 위치 기반의 순위표는 오름차순을 사용하세요. 고득점에는 내림차순을 사용하세요.
- 표시 유형 - 순위표에 표시할 데이터의 종류를 결정합니다. 숫자, 초, 밀리 초 중에서 선택하세요.
- 쓰기 - 신뢰함(Trusted)으로 설정하면 클라이언트가 순위표를 설정할 수 없고 오직 SetLeaderboardScore WebAPI를 통해서만 설정이 가능합니다. 기본값은 false입니다.
- 읽기 - 친구(Friends)로 설정하면 사용자의 친구만 순위표를 읽을 수 있고, 모든 점수는 항상 WebAPI를 통해 읽을 수 있습니다. 기본값은 false입니다.
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 번호가 있는지 확인해 주세요.