무관련자

문서 및 도움말
Steamworks 문서
통계 및 도전과제

영어로 된 새 버전이 있습니다.

이 페이지가 번역된 이후에 영어 버전이 새롭게 업데이트되었습니다.\r
여기를 클릭하여 이 페이지의 영어 버전을 확인하세요.

개요

Steam 통계 및 도전 과제는 귀사의 게임에서 사용자의 도전 과제와 통계를 지속적으로 로밍해 추적할 수 있는 방법을 제공합니다. 사용자의 데이터는 Steam 계정과 연결되어 있고 각 사용자의 도전 과제와 통계는 각자의 Steam 커뮤니티 프로필에서 구성 및 표시될 수 있습니다.

좋은 점

도전 과제는 게임에서 가치가 높은 보상을 제공하는 것 이외에도 팀협동이나 플레이어 상호작용에 대해 보상하고 이를 더욱 권장하는 도구로 매우 유용합니다. 이는 게임에 다각적인 목적을 부여할 수 있으며 게임에서 시간을 더 소비하는 사용자에게 보상을 더 제공할 수도 있습니다.

통계는 플레이 시간, 사용된 팝업 수 등 자잘한 정보를 추적합니다. 게임 내부 데이터를 추적하는 데만 통계를 사용할 수도 있습니다. 예를 들어, 사용자가 여러 개의 컴퓨터에서 플레이한 여러 개의 게임 플레이 세션 통계를 기초로 도전 과제를 허용할 수 있습니다.

구현 개요

귀사의 게임 통계 및 도전 과제 정의

도전 과제는 Steamworks 파트너 사이트에서 애플리케이션별로 설정됩니다. 앱 관리자 페이지도전 과제 구성 페이지에서 직접 확인해 주세요.

게임이 저장할 수 있는 통계에는 세 가지가 있습니다.
  • INT - 32비트 (서명된) 정수(예: 플레이한 게임 수)
  • FLOAT - 32비트 부동 소수점 값(예: 운전한 킬로미터 수)
  • AVGRATE - 이동 평균. 참고: AVGRATE 통계 형식

Steamworks 파트너 웹사이트는 귀사의 게임 통계 및 도전 과제를 정의하고 업데이트할 수 있는 인터페이스를 제공합니다. 이 인터페이스로 다음과 같은 작업을 할 수 있습니다.
  • 초기 통계 및 도전 과제를 정의할 수 있습니다.
  • 추가적인 통계 및 도전 과제를 더할 수 있습니다.
  • 도전 과제 이름과 설명, 아이콘을 업데이트할 수 있습니다.
  • 통계 매개 변수 및 제약 조건(최댓값 및 최솟값, 이동 평균 윈도우 크기 등)
통계에는 다음과 같은 속성을 가집니다.
  • ID - 각 통계에 대해 자동 생성된 숫자 ID.
  • Type - 해당 통계의 종류 - INT, FLOAT, 또는 AVGRATE.
  • API Name - 해당 API를 사용해 해당 통계에 접근할 때 사용된 문자열.
  • Set By - 통계를 수정할 수 있는 사람을 설정합니다. 기본 설정은 클라이언트입니다. 자세한 내용은 게임 서버 통계 문서를 참고해 주세요.
  • Increment Only - 설정할 경우, 시간이 지남에 따라 값이 증가하는 것만 허용합니다.
  • Max Change - 설정할 경우, 통계 값이 하나의 SetStat 호출에서 다음 SetStat 호출로 넘어갈 수 있는 양에 대한 한계를 설정합니다.
  • Min Value - 설정할 경우, 해당 통계가 취할 수 있는 최솟값입니다. 기본 설정으로, 최솟값은 기본 숫자 형식의 최솟값입니다(INT_MIN 또는 -FLT_MAX).
  • Max Value - 설정할 경우, 해당 통게가 취할 수 있는 최대 숫자 값입니다. 기본 설정으로, 최댓값은 기본 숫자 형식의 최댓값입니다(INT_MAX 또는 FLT_MAX).
  • Default Value - 설정할 경우, 해당 통계가 새로운 사용자에게 초기화될 때 설정하는 기본값입니다. 설정하지 않으면 기본값은 0입니다.
  • Aggregated - 설정할 경우, Steam에서 해당 통계에 대한 전체 총계를 보관합니다. 전체 통계에 대한 자세한 정보는 아래를 참고해 주세요.
  • Display Name - Steam 커뮤니티에서 표시되는 해당 통계의 이름입니다. 지역화 가능합니다.

AVGRATE 통계는 다음과 같은 속성을 가집니다.
  • Window - 귀사의 데이터를 평균 내는 데 사용되는 '슬라이딩 윈도우'의 크기.
AVGRATE 통계 하나는 Steam애서 자동으로 평균값을 계산한 것입니다. 자세한 정보는 아래 AVGRATE 섹션을 참고해 주세요.

도전 과제는 다음과 같은 속성을 가집니다.
  • ID - 각 통계당 자동으로 생성된 숫자 ID 하나.
  • API Name - 해당 API를 사용해 해당 도전 과제에 접근할 때 사용된 문자열.
  • Progress Stat - 해당 도전 과제에 대해 커뮤니티에 표시되는 진행률 막대에 사용하는 통계를 지정합니다. 통계가 잠금해제에 해당하는 값에 도달하면 도전 과제가 자동으로 잠금해제됩니다.
  • Display Name - 클라이언트 알림 팝업이나 커뮤니티에서 표시되는 도전 과제 이름입니다. 지역화 가능합니다.
  • Description - 해당 도전 과제에 대한 설명으로 커뮤니티에 표시됩니다. 지역화 가능합니다.
  • Set By - 도전 과제를 잠금해제할 수 있는 사람을 설정합니다. 기본 설정은 클라이언트입니다. 자세한 내용은 게임 서버 통계 문서를 참고해 주세요.
  • Hidden - 참인 경우, 'hidden' 도전 과제는 사용자의 커뮤니티 페이지에 전혀 표시되지 않습니다. 도전 과제를 달성할 경우에만 표시됩니다.
  • Achieved Icon - 도전 과제를 달성하면 표시되는 아이콘입니다.
  • Unachieved Icon - 아직 달성하지 못한 도전 과제를 표시하는 아이콘입니다.

다음은 Steamworks API Example Application (SpaceWar)에 있는 도전 과제 목록입니다.
achievements_spacewar.png

사용 방법

게임 안에서 통계 및 도전 과제에 접근하기:

AVGRATE 통계 형식

이 형식의 통계는 독특하고 유용한 기능을 제공하는데 좀 더 자세한 설명이 필요한 부분이 있으므로 말씀드리겠습니다.

'시간당 획득 점수'와 같이 특정 평균 통계를 추적하고자 하는 경우가 있습니다. 먼저, INT 'TotalPoints'와 FLOAT 'TotalPlayTimeHours', 두 가지의 통계를 가지고 점수를 시간으로 나누어 시간당 점수를 계산하는 방법이 있습니다.

이러한 구현 방법의 단점은, 플레이어가 상당히 긴 플레이 시간을 가지고 있는 경우 평균이 변동되는 속도가 극도로 느리다는 것입니다. 사실, 사용자가 게임을 더 오래 플레이할수록 평균이 덜 반응하는 결과가 생깁니다. 사용자가 해당 게임을 100시간 플레이한 경우 계산되는 평균은 50시간 플레이한 만큼 지연됩니다. 사용자가 스킬을 향상하는 경우, 시간당 점수가 기대하는 것만큼 높아지지 않는 것을 확인하게 됩니다.

AVGRATE 통계 형식으로 평균에 '슬라이딩 윈도우' 효과를 구현할 수 있습니다. 예를 들어, 최근 몇 시간의 게임 플레이만을 활용함으로써 통계가 플레이어의 현재 스킬 레벨을 더욱 정확하게 반영할 수 있습니다.

최근 게임 플레이의 20시간에 대한 값만 반영된 '시간당 점수'를 구현하는 AVGRATE 통계를 설치해 보겠습니다. 다음 작업이 필요합니다.
  • 주의: 해당 평균은 '시간당'을 계산하는 것이므로 해당 통계와 관련된 시간 매개변수에 있는 모든 시간 단위는 '시간'이 됩니다. 이것은 통계 자체의 Window 속성에 적용되며 아래 UpdateAvgRateStat에 전달되는 'dSessionLength' 매개 변수에도 적용됩니다.
  • 'AvgPointsPerHour'라는 이름으로 AVGRATE 통계 하나와 Window 속성 20.0(시간)을 생성합니다.
  • 게임 중 적절한 시점에 다음과 같은 매개 변수와 함께 ISteamUserStats::UpdateAvgRateStat 함수를 호출합니다.
    • pchName - 'AvgPointsPerHour'
    • flCountThisSession - 최근 마지막으로 UpdateAvgRateStat을 호출한 이후 플레이어가 획득한 점수.
    • dSessionLength - 최근 마지막으로 UpdateAvgRateStat을 호출한 이후 플레이어가 플레이한 게임 시간. 단위는 Window 속성에 있는 단위와 같아야 합니다. 여기서는 '시간'입니다.
  • 예를 들어, 플레이어가 지난 라운드에서 0.225시간(13.5분)을 플레이하고 77점을 획득했다면, SteamUserStats()->UpdateAvgRateStat( 'AvgPointsPerHour', 77, 0.225 )가 됩니다.
위 예에서, Steam은 현재 라운드 평균을 시간당 342.2점으로 계산하고(77을 0.225로 나누기) 이전 값과 함께 섞습니다. 그 결과는 플레이어가 지난 20시간 동안 플레이한 전체 평균을 반영합니다. 이 통계가 현재 사용자에게 처음으로 업데이트되는 통계인 경우 현재 값은 342.2가 됩니다.

해당 예시는 '시간'을 시간 단위로 사용했지만 다른 시간 단위를 선택할 수도 있습니다. 선택한 단위는 'SessionLength'와 Window 속성에서 일관되게 사용해야 한다는 점을 기억해 주세요.

다른 사용자에 대한 통계 확보

ISteamUserStats::RequestUserStats 함수를 사용해 다른 사용자에 대한 통계를 얻을 수 있습니다. 그리고 나서 ISteamUserStats::GetUserStat, ISteamUserStats::GetUserAchievement, ISteamUserStats::GetUserAchievementAndUnlockTime 함수를 사용해 해당 사용자의 데이터를 가져올 수 있습니다. 이 데이터는 해당 사용자가 새로운 통계를 업로드할 때 자동으로 업데이트되지 않습니다. 데이터를 새로고침하려면 ISteamUserStats::RequestUserStats 함수를 다시 호출하면 됩니다.

메모리를 절약하기 위해 '오래전에 사용한 항목'(LRU) 캐시가 유지되고 다른 사용자의 통계가 경우에 따라 언로드됩니다. 이 작업이 이루어질 때 ISteamUserStats::UserStatsUnloaded_t 콜백이 자동으로 전송됩니다. 이 콜백이 전송되고 나면 지정된 사용자의 통계는 ISteamUserStats::RequestUserStats 함수를 다시 호출할 때까지 사용할 수 없게 됩니다.

오프라인 모드

Steam은 통계 및 도전 과제에 대한 로컬 캐시를 보관해 오프라인 모드에서도 API가 정상적으로 사용될 수 있도록 합니다. 커밋되지 못한 통계는 모두 다음에 사용자가 온라인으로 접속할 때 저장됩니다. 하나 이상의 기기에서 수정된 사항이 있는 경우, Steam에서는 자동으로 도전 과제를 병합하고 진행률이 높은 통계를 선택합니다. Steam에서 통계 데이터에 대한 로컬 캐시를 보관하기 때문에 게임에서 디스크에 데이터에 대한 로컬 캐시를 따로 보관할 필요가 없습니다. 이러한 캐시는 종종 대립하기 때문에 이를 실행할 경우 사용자에게는 진행 상황이 이전 상태로 돌아간 것으로 보이므로 좌절감을 줄 수 있습니다.

게임 서버 통계

게임 서버에 대해서는 ISteamGameServerStats 함수가 ISteamUserStats 함수의 역할을 합니다. Steam 게임 서버 통계는 클라이언트와 같은 방법(위에서 설명)으로 통계를 얻을 수 있습니다. 또한, 통계 및 도전 과제 보상을 설정할 수 있지만 'Set by'가 GS(게임 서버) 또는 Official GS로 설정되어야만 가능합니다. 게임 서버와 공식 서버의 차이는 공식 서버는 귀사가 호스트하고 통제하는 서버라는 것입니다. 공식 게임 서버를 사용해 통계를 설정하면 부정행위에 대비한 보안이 더 향상됩니다. 사용자가 게임 서버가 되면 자신의 게임 서버를 수정할 수도 있고 스푸핑할 수도 있습니다. 공식 게임 서버를 정의하려면 서버의 IP 범위를 여기에서 입력하세요.

게임 서버가 설정하는 통계와 도전 과제는 클라이언트가 설정할 수 없습니다. 게임 서버는 현재 해당 서버에서 플레이하고 있는 사용자에 대한 통계와 도전 과제에 대해서만 설정할 수 있습니다. 사용자가 서버를 떠나면 마지막 통계를 잠깐 설정할 수 있는 시간이 주어지지만 새로운 업로드는 거부됩니다. 이는 일관성을 유지하고 악의적인 게임 서버가 아무 때나 사용자의 통계를 설정하는 것을 막기 위한 것입니다. 이러한 제약 사항을 고려했을 때, 통계는 라운드가 끝나기 전에 설정하는 것이 중요합니다. 통계를 지속적으로 설정하여 사용자가 게임을 종료할 때 바로 저장할 수 있도록 하세요.

클라이언트는 게임 서버의 통계가 변경되면 자동으로 업데이트됩니다. 하지만, 클라이언트와 마찬가지로 다른 사용자에 대해 서버에서 업로드된 통계는 자동으로 새로 고침 되지 않고 만료될 수 있습니다.

통계 재설정

개발 단계에서 테스트를 위해 전체 계정이나 하나의 계정에서 통계 및 도전 과제를 완전히 삭제하기를 원하기도 합니다. 하나의 계정에서 통계를 삭제하려면 bAchievementsTooISteamUserStats::ResetAllStats 함수를 호출해 으로 설정하고 도전 과제까지 삭제합니다. 호출 시 통계와 도전 과제를 반복 수정하고 귀사의 인게임 통계 메모리를 재설정하세요. 모든 사용자의 통계와 도전 과제를 한 번에 완전히 삭제하는 방법은 없습니다. 그 이유는 전체 삭제를 진행한다 하더라도 이미 진행 중인 게임을 삭제 사실을 인지하지 못하고 메모리값을 다시 작성할 것이기 때문입니다. 다행히도, 전체 삭제 시스템을 게임에 설치하는 간단한 방법이 따로 있습니다. 다음을 실행하세요.
  • 'Version'과 같은 이름으로 통계를 정의합니다.
  • 하드코드로 된 통계 버전 숫자를 게임에 넣습니다.
  • 통계가 모두 로드되면 'Version' 통계를 귀사의 하드토드 버전 숫자와 비교합니다.
  • 두 숫자가 서로 일치하지 않으면 ISteamUserStats::ResetAllStats 함수를 호출하고 'Version' 통계를 하드코드된 숫자로 설정합니다.
이렇게 하면 전제 삭제를 하고자 할 때마다 하드코드된 통계 버전 숫자만 변경하면 됩니다. 사용자가 새 빌드를 설치할 때마다 전체 삭제가 실행됩니다. 전체 삭제 코드가 최종 빌드와 함께 출시되지 않도록 주의해 주세요.

통계 일관성

어떻게 서로 관련된 통계들이 일관성을 잃을 수 있는지에 대해 생각해 볼 필요가 있습니다. 예를 들어, 'GamesWon', 'GamesLost', 'GamesPlayed', 이렇게 세 가지의 통계가 있습니다. 아무리 최선을 다한다 해도 통계들 간에 불일치가 발생할 수 있습니다. 이 경우, 이긴 게임과 진 게임을 합친 수가 플레이한 총 게임 수와 일치하지 않을 수 있습니다. 'GamesPlayed' -'GamesWon'으로 컴퓨팅하지 않고 'GamesLost'를 삭제해 문제를 해결한다면, 불일치가 발생하여 'GamesLost'가 마이너스가 될 수 있습니다. 이 경우, 'GamesPlayed' 통계를 버리고 'GamesWon' + 'GamesLost'로 계산하는 것이 좋습니다.

전체 통계

통계를 관리자 페이지에서 집계됨으로 표시해 Steam이 모든 사용자의 통계 값에 대한 전체 총합을 보관하도록 할 수 있습니다. 이것은 게임 경제에 있는 총금액, 총 킬 수, 선호 무기, 선호 맵, 승률이 높은 팀에 대한 데이터를 얻는데 사용될 수 있습니다. 반면에, 이것은 'MostKills'와 같은 통계에 대해 사용해서는 안 됩니다. 여러 사용자의 값을 더하는 것은 무의미하기 때문입니다. 통계는 사용자의 손에 달려있으므로 이 데이터는 조작이 가능합니다. 따라서 집계된 통계를 사용할 때에는 최솟값과 최댓값, 증가 전용(적절한 경우), 최대 변경에 대한 제약을 잘 설정하는 것이 중요합니다. 최대 변경은 집계된 통계에 대해 특별한 의미를 가집니다. 새로운 값이 업로드되면 변경되는 전체 값은 최대 변경 값을 초과하지 않습니다. 이러한 방법으로 부정 행위자가 전체 총 통계에 영향을 주는 것에 제한을 가합니다.

전체 총 통계에 접근하려면 ISteamUserStats::RequestGlobalStats 함수를 호출하고, 각 부분에 대한 전체 통계는 ISteamUserStats::GetGlobalStat 함수를 호출합니다. 또한, ISteamUserStats::RequestGlobalStats 함수를 호출하여 히스토리에서 특정 기간에 대한 통계에 접근할 수 있습니다. 히스토리는 매일 변하는 통계의 총량입니다. ISteamUserStats::GetGlobalStatHistory 함수를 사용해 접근할 수 있습니다.

또한, 클라이언트에 전체 도전 과제 완료 퍼센트를 요청할 수 있습니다. 먼저 ISteamUserStats::RequestGlobalAchievementPercentages 함수를 호출합니다. 그리고 나서 ISteamUserStats::GetMostAchievedAchievementInfo 함수와 ISteamUserStats::GetNextMostAchievedAchievementInfo 함수를 호출해 가장 많이 완료된 도전 과제에서 가장 적게 완료된 도전 과제 순으로 반복 수정합니다. 또한, ISteamUserStats::GetAchievementAchievedPercent 함수를 호출해 특정 과제에 대한 완료 퍼센트를 얻을 수 있습니다.

Steam 커뮤니티

게임이 출시되면 개별 도전 과제 및 전체 도전 과제 진행률에 대한 정보가 Steam 커뮤니티에 표시됩니다. 각 플레이어의 프로필에는 자신이 달성한 도전 과제와 아직 잠금해제되지 않은 도전 과제를 볼 수 있는 페이지로 연결되는 링크가 표시됩니다.
참고: 귀사의 도전 과제는 해당 앱이 커뮤니티에 어딘가에 노출되기 전까지는 표시되지 않습니다.

각 도전 과제는 적절한 아이콘과 이름, 설명과 함께 나열되며 이는 Steamworks 컨트롤 패널에서 설정합니다. 도전 과제 이름과 설명이 사용자가 선택한 언어로 지역화된 경우에는 해당 언어로 표시됩니다.

또한, 이 페이지에 있는 링크와 귀사의 게임의 메인 Steam 페이지에 있는 링크를 사용해 게임에 대한 전체 도전 과제 통계 집합으로 이동할 수 있습니다. 이 페이지에서는 해당 게임을 플레이하는 사용자의 몇 퍼센트가 각 도전 과제를 달성했는지 가장 흔한 도전 과제부터 희귀한 도전 과제까지 순서대로 보여줍니다. 플레이어 입장에서는 이것을 들여다보는 것이 재미있고, 개발자 입장에서는 굉장한 자료로서 역할을 합니다. 게임의 도전 과제가 달성하기 너무 쉽지는 않은가? 아니면 너무 어렵진 않은가? 관련 정보는 Steamstats 파트너 사이트에 있습니다.

더 궁금하신 점이 있나요?

통계 및 도전 과제 토론 게시판에서 질문해 주세요.