순위표를 이용해 플레이어 점수 순위 매기기

에픽게임즈 테크니컬 어카운트 매니저 Rajen Kishna |
2022년 1월 18일
지난주 통계 인터페이스에서는 에픽 온라인 서비스의 순위표(Leaderboards)에 대한 기본 내용을 알아보았습니다. 순위표를 사용하면 수집된 통계의 순위를 매겨, 특정 기간을 기준으로 플레이어에게 순위를 쉽게 노출할 수 있습니다. 오늘은 순위표를 구현하는 법을 자세히 살펴보겠습니다. 주제는 다음과 같습니다.

사용 제한(및 마일스톤)

순위표 기능도 저희가 살펴본 다른 서비스처럼 모든 사용자가 안정적으로 사용할 수 있도록 몇 가지 사용 제한이 적용됩니다. 순위표 작성 시 적용되는 제한 사항은 다음과 같습니다(최신 정보는 이 문서를 확인하세요).
  • 글로벌 순위표의 전체 개수는 사용 가능한 마일스톤에 의해 제한됩니다(다음 참조).
  • 디플로이당 총 마일스톤 최대 100개
  • 순위표당 항목 1,000개(+1,000개 추가분)
    • 에픽게임즈에서는 글로벌 순위표를 전부 추적하지 않으며, 여러분이 (부정행위 등을 이유로) 항목을 삭제할 경우를 대비해 상위 1,000개의 점수와 추가 1,000개의 점수만 계속 추적합니다.

또한 클라이언트 또는 서버 호출과 관련된 API 호출을 대상으로 사용자별 또는 디플로이별 속도 제한이 적용됩니다. 해당 제한은 이 문서에서 확인할 수 있습니다.

글로벌 순위표 개수 제한을 이해하려면 마일스톤의 개념부터 이해해야 합니다. 마일스톤은 통계에 연결되며 어느 한 시점을 나타냅니다. 요약하자면 어떤 순위표든 시작일부터 종료일까지 100개의 고유 타임스탬프로 제한됩니다.

예를 들어 아직 순위표를 만들지 않은 상태에서 시작일이 2022년 1월 18일 오전 9시, 종료일이 2022년 1월 19일 오후 5시로 설정된 순위표를 생성한다고 가정해 봅시다. 이렇게 하면 총 100개의 할당 가능한 마일스톤 중 2개를 차지합니다. 여기에 시작일이 2022년 1월 18일 오전 9시, 종료일이 2022년 1월 20일 오후 5시인 순위표를 추가할 경우, ‘2022년 1월 18일 오전 9시’는 기존에 사용하는 마일스톤이기 때문에 마일스톤을 하나만 더 차지하게 됩니다.

종료일이 미설정된(만료일이 없는) 순위표는 마일스톤을 최대 1개만 차지합니다. 마지막으로 마일스톤은 자신을 참조할 순위표가 더 이상 없으면 자동으로 삭제됩니다.

클라이언트 정책 변경하기

순위표를 사용하려면 클라이언트 정책에 다음 액션을 추가해야 합니다.
  1. https://dev.epicgames.com/portal/
  2. 에서 개발자 포털에 로그인합니다.
  3. 왼쪽 메뉴에서 ‘제품’ > ‘제품 세팅’으로 이동한 후 제품 세팅 화면의 ‘클라이언트’ 탭을 클릭합니다.
  4. 사용 중인 클라이언트 정책 옆에 있는 점 세 개 버튼을 클릭하고 ‘Update Policy’를 클릭합니다.
  5. 아래의 ‘기능’으로 스크롤하여 ‘Leaderboards’ 옆의 토글 버튼을 클릭합니다.
  6. ‘readLeaderboard’ 및 ‘findLeaderboards’ 액션 옆의 박스를 체크합니다.
    • ‘findLeaderboardDefinitons’ 액션을 사용하면 모든 순위표 정의를 쿼리할 수 있으며, ‘findLeaderboardEntries’ 액션을 사용하면 개별 순위표의 순위를 얻을 수 있습니다.
  7. ‘저장 & 종료’를 클릭하여 확인합니다.
Developer Portal Client Policy Leaderboards
순위표 클라이언트 정책에서 허용된 기능 및 액션

개발자 포털에서 순위표 생성하기

순위표는 개발자 포털에서 생성할 수 있으며, 합계(SUM), 최신(LATEST), 최소(MIN), 최대(MAX) 등 4가지 수집 유형을 기반으로 한 통계에 따라 달라집니다.

참고로 순위표를 최신(LATEST) 수집 유형 통계를 기준으로 할 경우, 매우 불규칙한 결과가 나올 수 있습니다. 예를 들어 레벨 완료 시간을 추적하여 순위표를 설정할 경우, 플레이어는 최신(LATEST) 수집 유형을 사용하여 손쉽게 ‘최고’ 점수를 덮어쓰기 할 수 있습니다. 보통은 아주 상세하게 짠 시나리오에서만 최신(LATEST) 수집 유형을 적용한 통계를 사용해야 합니다.

그리고 순위표의 시작 및 종료 시간 프레임 외부에서 수집한 통계 값은 순위표에 통합되지 않습니다.

이제 최신(LATEST)을 제외한 수집 유형별로 순위표를 정의하여 샘플 앱에서 행동을 확인해 보겠습니다.
  1. 왼쪽 메뉴에서 ‘제품’ > ‘게임 서비스’ > ‘순위표’로 이동합니다.
  2. 여기서 제품에 구성된 각 디플로이의 기존 순위표를 볼 수 있습니다. 샘플 앱에서 사용 중인 디플로이를 선택하고 화면 오른쪽 상단의 파란색 ‘순위표 생성’ 버튼을 클릭합니다.
  3. 순위표 이름에 ‘SumLeaderboard’를 입력한 뒤, 이전에 본 통계 관련 글에서 만든 ‘SumStat(SUM)’을 선택합니다. 이번에는 ‘이 리더보드는 만료되지 않음’ 토글 설정을 활성화하여 절대 만료되지 않는 3개의 순위표를 만들겠습니다. 다만 위에서 설명한 마일스톤 계획에 기반하여 기간을 따로 정의할 수 있습니다.
  4. 파란색 ‘생성’ 버튼을 클릭하여 생성 작업을 마칩니다.
  5. MinStat, MaxStat 통계도 마찬가지로 3단계를 반복하고 각 순위표를 ‘MinLeaderboard’, ‘MaxLeaderboard’으로 명명합니다.
Developer Portal Leaderboards
개발자 포털의 순위표

‘검색’ 버튼의 오른쪽 상단에는 연결 아이콘이 있습니다. 이 아이콘을 클릭하면 어느 순위표 및 업적이 통계에 연결되었는지 조사할 수 있습니다. 지금은 아무것도 없지만 앞으로 연재할 ‘순위표 및 업적’ 글에서 다시 방문할 예정입니다.

마지막으로 주목할 부분은 ‘플레이어 통계 리셋’ 버튼입니다. 이 버튼은 파란색 ‘새 통계’ 버튼 옆에 있습니다. 버튼을 클릭하면 PUID를 기준으로 플레이어를 검색할 수 있는 창이 실행되며, 통계 정의에 영향을 미치지 않고 플레이어별 통계를 리셋할 수 있습니다.

순위표 정의 쿼리하기

이제 순위표 정의를 쿼리할 코드를 구현해 봅시다.
  1. Views 폴더에 LeaderboardsView라는 이름의 새로운 사용자 컨트롤을 생성합니다.
  • 순위표 UI에 두 개의 ListViews를 작성해야 합니다. 전자는 모든 정의를 표시하고, 후자는 선택한 순위표의 모든 항목(또는 순위)을 표시합니다. 지금은 UI의 일부를 차지하는 순위표 하나만 추가한 상황입니다.
  1. LeaderboardsView.xaml.cs를 열어 ViewModel을 어태치하고 자리표시자 SelectionChanged 이벤트 핸들러를 설정합니다.
  1. LeaderboardsViewModel.cs 클래스를 ViewModels 폴더에 추가합니다.
  1. 레퍼런스를 ViewModelLocator.cs의 LeaderboardsViewModel에 추가합니다.
  1. LeaderboardsService.cs 클래스를 Services 폴더에 추가하여 정의 쿼리 로직을 설정합니다.
  1. LeaderboardsQueryDefinitionsCommand.cs 클래스를 Commands 폴더에 추가합니다.
  1. LeaderboardsViewModel.cs를 열어 다음 명령을 선언하고 인스턴스화합니다.
  1. 연결 인터페이스를 통해 로그인한 뒤에만 순위표 API를 호출할 수 있도록 다음 명령줄을 ViewModelLocator.cs의 RaiseConnectCanExecuteChanged() 메서드에 추가합니다.
  1. 마지막으로 LeaderboardsView를 MainWindow.xaml의 TabControl에 추가합니다.
이제 앱을 실행하고 인증 및 연결을 통해 인증한 다음, Leaderboards 탭에서 Query definitions 버튼으로 순위표 정의를 쿼리할 수 있습니다.
App Leaderboards QueryDefinitions
쿼리된 순위표 정의

순위표 순위 쿼리하기

이제 순위표 정의를 쿼리하고, 순위표마다 개별 항목(혹은 순위)을 가져올 수 있습니다.
  1. LeaderboardsView.xaml를 열고 두 번째 ListView를 이전 </ListView> 태그 바로 밑에 추가합니다.
  1. LeaderboardsViewModel.cs를 열고 다음 컬렉션을 순위표 밑에 선언하여 순위를 설정합니다.
  1. LeaderboardsService.cs를 열고 다음 메서드를 추가하여 순위 쿼리 로직을 설정합니다.
  1. LeaderboardsQueryRanksCommand.cs 클래스를 Commands 폴더에 추가합니다.
  1. LeaderboardsViewModel.cs를 열어 다음 명령을 선언하고 인스턴스화합니다.
  1. LeaderboardsQueryDefinitionsCommand.cs를 열어 정의 값을 얻을 때 순위를 제거합니다. LeaderboardsService.QueryDefinitions() 호출 위에 있는 Execute() 메서드에 다음을 추가합니다.
  1. 순위표를 선택해야 순위를 쿼리하도록 만들기 위해, LeaderboardsView.xaml.cs를 열고 LeaderboardsListView_SelectionChanged 이벤트 핸들러에 다음 명령줄을 추가합니다.
이제 앱을 재실행하고 Query definitions 버튼으로 순위표 정의를 얻을 수 있습니다. 이후 각 순위표를 선택하고 Query ranks 버튼을 클릭하여 순위를 얻을 수 있습니다. 순위가 보이지 않을 경우 이전 글에서 구현한 통계 기능으로 통계를 수집해야 합니다.
App Leaderboards QueryRanks
쿼리된 순위표 순위

코드 다운로드

아래에서 이 연재글에 쓰인 코드를 확인할 수 있습니다. 다운로드한 코드를 GitHub 저장소의 사용 지침에 따라 설정하세요.
다음 연재글에서는 통계에 기반해 자동으로 잠금해제하거나 API를 통해 수동으로 잠금해제할 수 있는 에픽 온라인 서비스의 업적을 알아보겠습니다.

이 연재글 시리즈의 전체 목록은 시리즈 참조를 확인하세요. 피드백이나 질문은 커뮤니티 포럼을 방문해 주세요.

    여러분의 성공이 곧 에픽의 성공입니다

    에픽은 통합되고 열려 있는 게임 커뮤니티를 지향합니다.
    에픽은 이러한 온라인 서비스를 모두에게 무료로 제공함으로써, 더 많은 개발자들이 자체 플레이어 커뮤니티에 서비스를 지원할 수 있도록 하는 것을 목표로 합니다.