보상 시스템 설계 (2)
이전 보상 시스템 설계 (1)에서 게임의 나머지 부분에 연결해 사용할 수 있는 간단한 보상 시스템의 요구사항과 요구사항 중 일부를 반영한 구조를 만들어 보았습니다. 단일 보상에는 여러 아이템들이 들어있는데 아이템 각각은 자신이 나올 지 말 지를 결정할 확률을 가지고 있고 수량을 범위로 설정할 수 있습니다. 이런 아이템을 여러 개 설정해 몬스터에 연결하면 이 몬스터를 처치할 때 골드 약간과 장비 약간, 그리고 성장 재료 약간을 제한된 범위 안에서 조금씩 다르게 드랍 할 겁니다.
여기서 용도를 조금 확장해 봅시다. 게임에 따라 서로 다른 클래스 캐릭터가 사냥할 때 클래스에 맞는 장비를 드랍하길 원할 수 있습니다. 플레이어 입장에서는 어떤 클래스를 선택하든 몬스터들이 알아서 그에 맞는 장비를 드랍하니 편리합니다. 반대로 여러 캐릭터를 성장시키기를 원하는 게임은 이와 반대 정책을 펴기도 합니다. 특정 성장 단계에 필요한 장비는 항상 다른 클래스 전용 장비가 드랍 되어 플레이어 스스로가 새로운 캐릭터를 플레이 하기를 요구하거나 거래소가 있다면 이를 통해서 다른 플레이어의 다른 캐릭터가 획득한 장비를 구입해야 합니다. 앞서 만든 보상 시스템으로는 이 목적을 달성할 수 없습니다. 이번에는 이를 반영해 보겠습니다.
단일 보상
아이템 아이디1
클래스[]
검사, 마법사, …
확률 (십만분율로 입력)
수량
수량범위 낮은숫자
수량범위 높은숫자
아이템 아이디2
…
앞서 단일 보상 하위에 아이템이 있고 아이템 각각마다 확률과 수량이 있었는데 여기에 클래스 조건을 추가했습니다. 클래스는 한 번에 여러 개를 입력할 수 있고 현재 캐릭터 클래스가 여기 나열된 클래스 중 어느 하나에 일치하면 이 아이템을 드랍할 클래스 조건을 만족합니다. 처리 순서를 설명해보면 먼저 게임 내 어떤 컨텐츠에서 이 단일 보상을 드랍 하기로 결정합니다. 첫번째 아이템의 두 가지 조건을 검사합니다. 먼저 아이템에 설정된 클래스 조건이 현재 캐릭터 클래스와 일치하는지. 일치하면 확률로 넘어갑니다. 확률에서는 십만분율을 기준으로 드랍할지 여부를 결정합니다. 여기서 이 아이템을 드랍하기로 결정하면 범위 내에서 수량을 결정한 다음 드랍할 아이템에 추가합니다. 이 동작을 모든 아이템에 대해 반복합니다.
다음으로는 어떤 아이템이 적어도 한 가지는 나와야 하는 상황이 있을 수 있습니다. 앞서 몬스터를 처치할 때 성장재료 한 종류와 캐릭터카드 한 종류가 꼭 나와야 한다면 지금은 이를 입력할 수 없습니다. 성장재료가 하나 이상 나오게 하거나 캐릭터카드 역시 하나 이상 나오게 할 수는 있겠지만 운이 좋은 사람은 캐릭터카드 여러 개 중 둘 이상이 나올 수 있습니다. 항상 같은 카테고리 안에서는 아이템이 하나만 나오게 만들고 싶다면 구성을 좀 바꿔야 합니다.
단일 보상
그룹1
확률연산방법: 결합확률 | 독립확률
아이템 리스트:
아이템 아이디1
확률:
그룹 내 결합확률 (그룹 내 합계가 십만이 되도록 입력)
그룹 내 독립확률 (십만분율로 입력. 결합확률을 사용할 때는 항상 십만을 입력.)
클래스[]
검사, 마법사, …
수량
수량범위 낮은숫자
수량범위 높은숫자
아이템 아이디2
…
그룹2
…
이제 단일 보상 내에 아이템을 감싸는 그룹이 필요합니다. 그룹에 속한 여러 아이템들에 대해 어떤 확률 연산 방법을 사용할지 설정합니다. 결합확률은 같은 그룹 안에 있는 아이템 중 하나를 선택합니다. 이 그룹에서는 항상 아이템이 하나만 나옵니다. 독립확률은 그룹에 속한 아이템 각각을 십만분율 기준으로 선택할지 말지를 결정합니다. 그래서 독립확률에서는 같은 그룹에서 아이템이 둘 이상 나올 수도 있습니다. 아이템 각각에 확률을 설정할 때 그룹 내 결합확률은 그룹 내 확률 합계가 10만이 되도록 입력해야 하고 그룹 내 독립확률은 아이템 각각의 확률이 10만이 되도록 입력해야 합니다. 실수가 자주 일어나고 실수가 일어날 때 치러야 할 댓가가 크기 때문에 바쁜 팀에서 다른 데이터 검증은 기계 대신 사람에게 맡기기도 하지만 이 보상 확률만은 기계가 검증하게 만듭니다.
이제 이전에 이야기한 몬스터를 처치할 때 성장재료 한 가지와 캐릭터카드 한 가지가 반드시 드랍되는 시나리오를 위 데이터로 어떻게 표현할지 생각해 보겠습니다. 재화 이름은 디아블로 이모탈 재화구조에서 아무렇게나 가져왔습니다.
단일 보상
그룹1: ‘성장재료’
확률연산방법: ‘결합확률’
아이템 리스트:
아이템1: 빛나는 조각
확률:
그룹 내 결합확률: ‘25000’
그룹 내 독립확률: ‘100000’
수량:
수량범위 낮은숫자: '1'
수량범위 높은숫자: '1'
아이템2: 재활용 재료
… ('아이템1'과 같이 설정)
아이템3: 마력 깃든 가루
… ('아이템1'과 같이 설정)
아이템4: 불가사의한 수정
… ('아이템1'과 같이 설정)
그룹2: ‘캐릭터카드’
확률연산방법: ‘결합확률’
아이템 리스트:
아이템1: 서큐버스 카드
확률:
그룹 내 결합확률: ‘25000’
그룹 내 독립확률: ‘100000’
수량:
수량범위 낮은숫자: '1'
수량범위 높은숫자: '1'
아이템2: 묘실바퀴 카드
… ('아이템1'과 같이 설정)
아이템3: 라쿠니 난도질꾼 카드
… ('아이템1'과 같이 설정)
아이템4: 모래사막늑대 카드
… ('아이템1'과 같이 설정)
아이템5: 해골 약탈자 카드
… ('아이템1'과 같이 설정)
이 사례를 작성하면서 이렇게 아슬아슬하게 만들고 있는 것을 그대로 이야기하기 좀 부끄럽다는 생각을 했습니다. 이 데이터를 편안하게 입력할 수 있는 가상의 도구를 상상해보면 그룹을 추가하고 드랍다운박스에서 확률연산방법을 선택하면 그에 맞는 옵션만 나타난 채로 아이템을 추가할 수 있을 것 같습니다. 그런데 이런 제안은 프로그래머도 싫어하고 이를 입력할 기획자도 싫어하더라구요. 결국 이 구조를 엑셀에 걸쳐서 입력 받다 보니 결합확률은 그룹 내에서 합계가 10만이 되도록, 독립확률은 아이템 각각마다 10만분율로 입력하는 등 데이터구조에 드러나지 않는 규칙을 알고 있어야 데이터를 입력할 수 있는 상태로 만들었습니다.
어지간한 게임의 요구사항을 만족하는 보상 시스템을 알아봤습니다. 여기서 다음 단계로 넘어가면 같은 성장재료 그룹 안에서 저급 성장재료 여럿 중 하나와 고급 성장재료 여럿 중 하나 중에서 하나만 나와야 하는 상황이 생깁니다. 몬스터를 처치하면 보통은 저급 성장재료 중 하나가 나오지만 낮은 확률로 고급 성장재료 중 하나가 나오는데 이때는 저급 성장재료가 나오지 않아야 합니다. 이를 반영하려면 그룹 하위에 또 다른 그룹을 포함할 수 있도록 해야 하는데 여기까지 읽어 오셨다면 이 다음은 비슷한 요령으로, 다만 더 너절하고 복잡해 보이는 구조를 만들기만 하면 되니 여기서는 생략하겠습니다.