비정형 보상 아이템
아이템이 아닌 다른 뭔가를 보상으로 줄 때 사용할 수 있는 방법을 생각해 봅시다.

지난 포션 아이템을 올바르게 설계하기에서 MMO 게임의 기반을 설계해 나갈 때 쉽게 할 수 있는 실수에 대해 설명했습니다. 처음 개발을 시작하면 게임에 당연히 필요한 여러 기능이 아직 존재하지 않는데 어떤 한 기능을 만들려고 보면 게임의 각 기능은 서로 다른 기능에 의존성이 있어 어디부터 시작해야 할 지 결정하기 어렵게 만듭니다. 소프트웨어를 개발하는 관점에서는 의존성에 기반해 각 단위 기능의 개발 순서를 결정하는 접근이 올바르지만 종종 게임 개발에서는 이런 의존성을 무시한 순서로 개발해야 하는 상황이 일어납니다.
덕분에 이제서야 간신히 캐릭터가 땅 위를 걸어다니기 시작하는 상황에서 당장 퀘스트부터 개발해야 하거나 겉보기에는 캐릭터가 몬스터를 공격해 대미지를 주는 것처럼 보이지만 그렇게 보일 뿐 이를 지탱하는 아무 기능도 없는데 당장 포션부터 만들어야 하는 상황을 겪을 수도 있습니다. 게임 업계의 여러 상위 의사결정자들은 게임 역시 소프트웨어이며 소프트웨어의 각 단위 기능은 서로 의존성을 가지고 있고 한 가지 단위 기능을 개발하기 위해서는 이 기능이 의존하는 나머지 기능을 차례로 개발해야만 한다는 사실을 잘 인식하지 않는 것 같습니다. 때문에 순서가 좀 이상하더라도 이 상황에 맞춰 개발하는 수밖에 없습니다.
순서가 좀 이상하게 느껴지더라도 어쨌든 개발을 진행할 수는 있는데 만약 한 기능이 의존할 다른 기능이 이미 개발되어 있다면 더 간단한 모양으로 무리수를 덜 두며 개발할 수 있겠지만 의존성이 있는 다른 기능이 아직 개발되지 않았고 그 기능이 이번 마일스톤 안에 함께 개발될 계획 조차 없다면 우리는 이 의존성을 무시한 채 이번 마일스톤에 개발할 기능이 독립적으로 동작하는 모양으로 설계해야 합니다. 비록 근미래에 이 기능이 의존할 다른 기능이 개발될 때 이번 마일스톤에 독립적으로 동작하도록 설계해 개발한 기능을 다시 고쳐야 하겠지만 특히 게임 소프트웨어는 각 마일스톤에 걸쳐 완결성 있게 개발되어 그 상태를 회사 내 최상위 의사결정자 분들께 시연해야 하는 경우가 많으므로 이 상황을 받아들이 이에 맞게 설계하고 나중에 수정하기를 반복해야 하기도 합니다. 이러다 보면 종종 MMO 게임의 개체 사이에 일어나는 핵심 상호작용과 그 결과를 기술하는 ‘스킬’과 ‘스킬 효과’가 아직 존재하지 않는 상황에서 당장 포션부터 만들어야 할 수도 있는데 이 때 포션 아이템을 올바르게 설계하기에 설명한 문제가 발생하고 또 이상한 포션 설계를 제안할 수 있습니다. 하지만 개인적으로 의존성이 있는 기능들이 준비되지 않은 상태에서 어쩔 수 없는 개발을 해야 할 때 미래를 고려하지 않은 이상한 설계가 튀어나와도 그리 이상하지 않다고 생각합니다.
다만 이런 상황에서 아이템 데이터에 포션 데이터가 기입되고 아직 스킬 시스템이 없는 상태에서 포션의 효과를 기술하기 위해 아이템 데이터에 이 포션이 채워 줄 체력량이 추가되는 상황을 이 상황이 왜 일어나는지 모른 채 반복하다 보면 시간이 지나 다른 기능을 추가할 때도 이렇게 일차원적인 접근을 통한 설계를 제안하게 될 수도 있습니다. 사실 포션이라는 아이템이 있고 이를 사용하면 사용자의 체력을 올려준다는 요구사항을 스킬 효과 개념 없이 개발한다면 아이템 타입을 ‘포션’으로 구분한 다음 이 타입의 아이템을 ‘사용’할 때 사용자 자신에게 아이템 데이터에 기입 된 체력량 만큼 체력을 올려주도록 개발하면 일단 개체 간 상호작용 기반이 없는 상태에서도 동작하는 포션을 완성할 수 있습니다. 게다가 이 포션은 아이템 데이터에 기반하고 있으므로 아이템의 기초 기능인 인벤토리에 존재하고 이름, 설명, 아이콘 등이 표시되어 적어도 게임 상에서 보기에는 멀쩡해 보일 겁니다. 그런데 종종 커리어 처음부터 이런 상황을 반복해 설계를 반복하다 보면 언젠가 개체 간 상호작용 기능이 준비되었을 때 과거에 만든 포션 기능을 개체간 상호작용의 기능 범위로 편입 시켜야 한다는 사실을 잘 인지하지 못할 수 있습니다. 애초에 포션은 이렇게 동작한다고 생각하면 이미 잘 동작하는 포션 기능을 본격적인 개체 간 상호작용 기능의 범위로 옮길 이유 자체를 이해하지 못하게 됩니다.
그 결과 이미 개체 간 핵심 상호작용 기능인 스킬과 스킬 효과가 준비된 다음에도 포션 기능을 확장할 때 이를 사용하지 않는 설계를 지속적으로 제시할 수도 있습니다. 가령 어느 날 포션에 등급이 생겨 낮은 등급 포션에 비해 높은 등급 포션은 한 번에 더 많은 체력을 회복 시켜 주고 또 어떤 포션은 체력 대신 스태미너를 회복 시켜 주며 또 다른 신기한 포션은 포션을 사용한 사람 주변에 있는 파티원들의 체력도 일부 회복 시켜 줘야 하는 날이 찾아옵니다. 그런데 아직 포션은 아이템 데이터에 별도 타입으로 구분되어 있고 이 포션이 채워 줄 체력은 아이템 데이터를 차지한 한 칼럼에 기입 되어 있는 상태입니다. 요구사항에 대응하기 위해 일단 포션 데이터를 여러 줄 만들고 각 포션에 따라 더 높은 체력 숫자를 집어 넣으면 적어도 체력에 대한 요구사항은 쉽게 달성할 수 있습니다. 하지만 스태미너나 마나를 채워 주는 포션을 만들어야 하고 계속해서 아이템 데이터에 의존한다면 이제 아이템 데이터에는 각 아이템을 사용할 때 올려 줄 체력, 스태미너, 마나를 기입할 새로운 칼럼을 추가해야 합니다. 이 때 ‘그럼 체력과 스태미너 모두 숫자가 들어있으면 어떻게 처리해야 하나요?’ 같은 질문을 받게 될 겁니다. 그래도 여기까지는 아이템 모양으로 어떻게든 대응할 수 있는 수준입니다.
하지만 내가 포션을 사용할 때 주변 파티원들의 체력도 채워 주는 신기한 포션을 만들려면 이제 근본적인 문제가 생깁니다. 지금까지 포션을 아이템으로 해석해 아이템이 일으키는 효과를 아이템 데이터에 기입하는 모양이 이상하지 않다고 생각하고 개발해 왔다면 이제 아이템 데이터에는 아이템이 사용될 때 효과를 적용할 대상을 기입하고 이 대상을 거리에 따라 확정할 일종의 타겟팅 기능이 필요하며 그 안에서도 파티원과 파티원이 아닌 플레이어를 구분하는 개념을 기입할 수 있어야 합니다. 여기 까지 오면 아이템에 대한 요구사항과 이미 개발되어 있을 온라인 게임에서 개체 간의 근본적인 상호작용을 기술하는 스킬과 스킬 효과에 이미 사용하기 편한 모양으로 만들어진 기능과 아주 비슷한 모양이라는 사실을 눈치채지 않을 수 없습니다. 여전히 게임디자인 수준에서 이 사실을 눈치 채지 못했다 하더라도 이를 구현할 엔지니어는 뭔가 상황이 잘못됐다는 사실을 자신이 아이템에 추가하려는 여러 기능이 이미 스킬 시스템에 대부분 만들어져 있다는 점을 보고 눈치채게 됩니다. 근본적으로 의존성을 고려하지 않은 잘못된 개발 순서 때문에 시작된 일이지만 문제를 해결할 수 있는 시점이 됐는데도 문제를 인식하지 못한 결과는 항상 이전 마일스톤에 비해 시각적으로 더 나은 모습을 보이기를 반복해야 하는 게임 프로젝트에 겉으로 드러나지 않는 내부 구조를 대대적으로 수정해야 하는 끔찍한 상황을 겪게 됩니다.
이런 참사의 근본적인 원인은 의존성을 고려하지 않은 개발 순서 때문이지만 그 다음은 이 상황에만 사용할 수 있는 설계를 이 상황이 해소된 다음에도 계속해서 사용해 왔기 때문이기도 합니다. 개체 사이의 상호작용을 기술할 방법이 준비되었을 때 포션 기능은 그 기능을 확장하기 전에 게임 전체에 사용하게 될 표준 상호작용 방법을 사용하도록 정비되었어야 합니다. 하지만 특수한 상황에만 올바른 설계가 그 상황에만 의미 있다는 사실을 깨닫지 못하면 포션 뿐 아니라 이후에 다른 요구사항 역시 게임을 이루는 여러 기능 사이의 의존성을 고려하지 않고 일차원적으로 설계하게 됩니다. 그 사례 중 하나는 아이템 대신 뭔가 다른 요소를 보상으로 줘야 할 때 처음 일어납니다. 지금까지는 던전을 클리어 하면 보상으로 아이템을 줬습니다. 이를 위해 보상 데이터에는 서로 다른 여러 아이템과 아이템 각각의 수량을 기입할 수 있는 모양으로 개발 되었고 이는 오랫동안 잘 동작했습니다. 그런데 게임에 수집 요소가 개발되고 이 수집 요소를 보상으로 주려 할 때, 또 지금까지는 보상으로 준 적 없는 특정 아이템의 경험치, 스킬 포인트, 대도시 뒷골목의 비밀 상점 입장 권한 따위를 보상으로 주려고 할 때 지금까지 사용해 온 아이템 종류와 수량을 기입하는 방식의 보상으로는 대응하기 어렵다는 사실을 깨닫게 됩니다.
이 요구사항을 처음 포션을 만들 때처럼 일차원적으로 생각하면 간단하고 또 그럴듯한 설계를 쉽게 제안할 수 있습니다. 현행 보상 데이터에는 보상으로 줄 아이템 종류와 수량을 여럿 기입할 수 있게 되어 있는데 여기에 아이템이 아닌 항목을 보상으로 줘야 하니 아이템이 아닌 항목 각각의 수량을 기입할 칼럼을 추가하면 됩니다. 가령 수집 요소를 언락 해 줘야 한다면 언락 해 줄 수집 요소 이름을 기입할 칼럼을 만들면 됩니다. 특정 아이템의 경험치를 줘야 한다면 이 경험치 숫자를 기입할 칼럼을 만들면 되고 또 스킬 포인트 역시 마찬가지입니다. 대도시 뒷골목의 비밀 상점 입장 권한 역시 이 권한을 부여할 때 사용할 별도 칼럼을 만든 다음 이 칼럼에 아무 값도 넣지 않으면 권한을 부여하지 않는다는 의미이지만 이 칸에 숫자 1을 넣으면 이 보상이 부여될 때 비밀 상점 입장 권한을 부여하는 의미로 사용할 수 있습니다. 보상 데이터구조가 이전의 아이템과 수량만을 나열하는 모양에서 다양한 항목의 종류와 수량, 보상의 존재 여부를 빈 값과 숫자로 표현하는 좀 더 복잡한 형태로 변하기는 했지만 이 데이터에 집중하면 여전히 이 데이터는 의도를 기입할 수 있고 나아가 개발된다면 요구사항을 달성할 수 있습니다. 물론 이번에도 엔지니어로부터 비밀 상점 입장 권한 같은 보상 요소가 앞으로 게임에 얼마나 더 나올지, 이들을 별도로 관리해야 할지 여부에 대한 질문을 받게 될 겁니다.
그런데 현대 게임 보상은 지금까지 설명한 것과 비교할 수 없을 정도로 복잡해집니다. 아이템과 수량을 기본으로 서로 다른 그룹에 속하는 여러 대상의 언락, 특정 성장 요소에만 적용되는 경험치, 비밀 상점 입장 권한, 아이템과는 달리 취급되는 온갖 종류의 재화, 특정 던전의 입장 횟수 등 간단히 아이템 모양으로만 표현하기 어려운 다양한 형태의 보상이 있습니다. 이런 보상이 추가될 때마다 앞서 포션을 설계했던 것처럼 일차원적으로 접근하고 이 접근이 엔지니어들에 의해 필터링 되지 않는다면 보상 데이터는 점점 더 거대해지고 사용하기 어려워집니다. 새로 온보딩 한 스탭이 보상 데이터를 잘못 만들어 게임을 고장 내거나 고장 나지는 않았지만 의도하지 않은 보상이 집행되는 문제를 일으킬 수 있는데 이런 상황을 완화할 의도로 엑셀 데이터에는 각 칼럼의 동작을 설명하는 행이 추가되고 데이터 컨버터는 이 행을 무시하도록 변경되며 실수를 방어하기 위해 컨버팅 때마다 복잡한 유효성 검사를 통과하게 만듭니다. 하지만 상황은 드라마틱하게 개선되지 않으며 보상 데이터는 좀 더 조심성 많은 소수의 사람들이 편집하게 되는 결과로 이어지기도 하는데 이 분들 중 일부가 휴가를 쓰면 당장 집행해야 할 보상 데이터를 아무도 넣을 수 없어 휴가중인 사람에게 전화를 걸어야 하는 이상한 일이 일어날 수도 있습니다.
앞에서 소개한 포션 사례와 마찬가지로 보상 역시 어느 시점이 되면 미래의 확장을 고려한 모양으로 설계를 변경해야 합니다. 포션 사례에서는 포션이 도입될 때 포션은 그저 아이템일 뿐이었고 또 게임 상에서 개체 간 상호작용을 기술할 방법이 없었기 때문에 어쩔 수 없이 포션 기능이 아이템 데이터를 차지하고 있었지만 개체 간 상호작용 기능이 추가될 시점에 포션은 이를 활용하도록 해야 했습니다. 보상 역시 처음에는 아이템과 수량을 기입하는 모양으로 만들어졌고 잘 동작했겠지만 게임에 다양한 보상 요소가 추가될 때마다 이를 대응할 수 있는 모양으로 수정 되어야 합니다. 이 때 앞서 포션 기능을 확장할 때처럼 아이템 데이터를 늘려 나가는 접근이 바로 위에 설명한 보상 데이터를 늘려 나가는 것과 같은 방식인데 포션에서는 포션 자체는 여전히 아이템 데이터로 존재하되 포션의 동작은 개체 간 상호작용을 기술하는 스킬 시스템으로 편입되어 아이템과 스킬이 연결된 모양이 되었어야 합니다. 보상 역시 계속해서 칼럼을 늘려 가는 대신 서로 다른 보상을 아이템 모양으로 정규화 하되 아이템 타입을 구분해 보상으로 받은 아이템의 동작을 별도로 기술하는 방식으로 접근해야 합니다.
일단 여러 가지 보상을 아이템 모양으로 정규화 해야 하는 이유는 게임 상의 여러 보상 인터페이스가 아이템 모양으로 보상을 줄 것을 가정하고 만들어졌을 것이기 때문입니다. 게임에 따라 보상 화면에서 재화와 아이템을 분리해 보여주기도 하는데 이는 보상을 더 잘 인지하라는 의도도 있지만 아이템과 보상이 분리된 데이터 구조를 사용하기 때문이기도 합니다. 이런 게임은 미래에 보상 종류가 추가될 때마다 데이터를 수정하기도 해야 하지만 동시에 보상을 표시할 모든 인터페이스를 수정해야만 하며 보상 종류가 추가될 때 비용이 높아 이를 잘 시도하지 않게 될 수도 있습니다. 종류에 관계 없이 모든 보상을 아이템 모양으로 정규화 하면 적어도 매번 인터페이스를 반드시 수정할 필요는 없습니다. 인터페이스를 수정하지 않아도 아이템 모양으로 정규화 된 보상은 어쟀든 보상 화면에 표시될 겁니다. 선택적으로 특정 보상을 강조하기 위해, 가령 재화 타입을 별도로 표시할 목적으로 인터페이스를 수정할 수는 있겠지만 이 행동이 필수는 아니게 됩니다. 비밀 상점 입장 권한, 수집 요소 언락 같은 비정형 보상도 일단 아이템 모양으로 표시는 할 수 있습니다.
자. 비정형 보상이 늘어나더라도 데이터구조를 정규화된 아이템 모양으로 유지하라는 건 이해할 수 있지만 그렇다면 아이템 모양으로 표현한 비정형 보상 자체는 어떻게 집행해야 할까요. 이번에는 보상으로 지급하는 아이템 중 비정형 보상을 지급하는 동작을 아이템 데이터에 기술해야 합니다. 아이템 데이터에 비정형 보상의 종류, 비정형 보상이 가리키는 대상을 나타내는 key, value
형태를 기술할 칼럼 하나, 또는 두 개를 추가하고 여기에 비정형 보상의 동작을 기입합니다. 가령 월드 곳곳에 뷰포인트가 있고 뷰포인트에 상호작용 하면 주변 전경을 보여준 다음 수집 요소에서 이 뷰포인트를 언락 하고 또 골드를 조금 주는 보상이 있다고 해 봅시다. 이는 간단히 뷰포인트에 상호작용 하면 보상을 주면 되는데 아이템 모양으로 정규화된 보상은 ‘뷰포인트 언락 아이템'과 ‘골드 아이템’으로 나눠 입력할 수 있습니다. 골드 아이템은 아이템 종류는 골드로, 그 수량에는 골드 수량을 넣으면 끝납니다.
그런데 뷰포인트 언락 아이템이라면 어떨까요. 보상 데이터 관점에서는 뷰포인트 언락 보상 역시 아이템 모양으로 정규화 되어 있으므로 아이템 종류에는 ‘특정 뷰포인트 언락 아이템’으로, 수량은 한 개를 입력하면 됩니다. 이 ‘특정 뷰포인트 언락 아이템’의 아이템 데이터를 따라가 보면 바로 위에서 설명한 이 아이템을 획득할 때 주어질 비정형 보상을 key, value
모양으로 기입하는데 여기서는 ViewPointUnlock, 223
과 같은 형태로 기입할 수 있습니다. 이 아이템을 획득하면 ViewPointUnlock
이라는 동작을 하되 223
번 뷰포인트에 대해 그 동작을 수행하라는 의미입니다. 다만 이 아이템은 인벤토리에서 아이템으로 존재할 필요가 없기 대문에 뷰포인트를 언락하는 동작을 수행한 다음에는 인벤토리에서 제거되거나 애초에 인벤토리에 넣기 전에 아이템 종류를 검사해 동작을 수행한 다음 인벤토리에 넣지 않을 수도 있습니다. 같은 요령으로 앞에서 예를 든 여러 가지 비정형 보상을 아이템 데이터에 정규화된 모양으로 기입할 수 있고 보상 데이터에서는 여전히 여러 비정형 보상이 모두 똑같은 아이템 모양으로 정규화 되어 있기 때문에 비정형 보상 종류가 늘어나더라도 보상 관점에서는 신경 쓰지 않을 수 있습니다.
본격적으로 게임에서 아이템은 인벤토리에 나타나고 이를 기준으로 보상을 지급하며 고객이 인벤토리 인터페이스를 통해 상호작용 할 수 있는 대상이기 때문에 이를 비정형 보상에 사용하도록 확장하려는 발상 자체가 어려울 수 있습니다. 여러 이유가 있겠지만 가장 흔한 이유는 앞서 설명한 포션 사례처럼 요구사항을 일차원적으로 생각해 설계한 다음 이후 게임 기능이 확장되어 가면서 기존의 일차원적인 대응을 게임의 다른 기능에 의존성을 가지도록 확장할 생각에 도달하지 못하기 때문이 가장 크지 않을까 싶습니다. 비정형 보상 역시 처음에 모든 보상은 아이템 모양이었다가 아이템 모양이 아닌 보상이 나타날 때 이들을 아이템 모양으로 정규화 할 생각을 하는 대신 각각의 비정형 보상을 데이터 상에 비정형으로 나타내면 적어도 이를 처음 만들 때는 일차원적으로 이해하기 쉽기 때문일 겁니다. 하지만 쉬울 때는 그 순간 뿐으로 그렇게 만들어진 데이터는 앞으로 이 데이터를 안전하게 입력할 수 있는 사람들을 제한하고 기껏 쉬려고 휴가를 썼는데 회사로부터 걸려온 전화를 받아야 하는 불행한 상황에 처하게 할 수 있습니다.
포션 사례는 이전 포션 아이템을 올바르게 설계하기에서 소개했는데 비슷한 사고 과정을 거치면 비정형 아이템 역시 잘못된 모양으로 설계할 수 있습니다. 포션 사례에서 포션의 동작을 기술할 수 있는 표준 시스템이 도입될 시점에 즉시 이를 활용하도록 기능을 수정해야 하며 이 필요성을 인식해야 합니다. 그리고 비정형 아이템 보상 사례에서 서로 다른 보상을 같은 보상 데이터에 기입하더라도 결국 이들이 앞으로 계속해서 확장될 예정이지만 결국 고객이 보게 될 보상 화면은 아이템의 나열 모양으로 정규화된다는 사실을 인식하는 것이 좋습니다.