겹치지 않는 UID를 수동 생성하는 요구사항
'로직을 데이터 모양으로 표현한 간단한 스킬 시스템'에 게임 프로젝트에서 엑셀을 어떤 식으로 사용하는지 이야기한 적이 있습니다. 엑셀 데이터를 프로젝트 전반에 걸쳐 사용하는데 비해 프로젝트에 따라 엑셀 데이터에 접근하는 방식은 저마다 상당히 다릅니다. 어떤 프로젝트에서는 게임이 읽어들일 모든 엑셀 워크시트는 첫 열 첫 행이 반드시 ID
여야만 하기도 하고 어떤 프로젝트에서는 Id
에 최대 열 자리 숫자만 사용할 수 있기도 하며 또 어떤 프로젝트에서는 Id
에 문자열을 사용해 사람이 알아보기 쉬운 모양을 사용할 수 있기도 합니다. 또 어떤 프로젝트는 워크시트 첫 행에 모든 값 이름을 한 줄로 나열해야만 하기도 하고 또 다른 프로젝트에서는 값 이름에 계층 구조를 만들 수 있기도 하고요.
이런 차이에 따라 프로젝트마다 아이디를 만드는 규칙도 조금씩 달랐는데 어떤 사람들은 아이디를 구성하는 숫자에 아무 의미도 부여하지 않고 1부터 차례로 증가 시키는가 하면 또 다른 사람들은 아이디의 각 자리에 의미를 부여해 항상 모든 자리를 다 사용하는 아이디 체계를 만들기도 했습니다. 1부터 증가하는 숫자는 이해하기 쉬웠지만 여러 사람이 함께 작업하는 환경에서 겹치는 숫자가 나타나기도 하고 모든 자리에 의미를 부여한 번호는 종종 할당된 대역의 모든 숫자를 다 사용해 새로운 대역을 정의해야 해서 의미 파악을 어렵게 만들거나 각 자리의 의미가 모든 작업자들에게 전달되고 또 숙지하지 않아 엉뚱한 숫자를 사용해 종종 각 자릿수의 의미에 따라 데이터를 처리하던 프로그램에 오류를 일으키기도 했습니다.
어떤 방법이 옳다고 말하기는 어렵지만 개인적으로 선호하는 방법은 있습니다. 먼저 엑셀 워크시트의 처음 부분은 값을 계층 구조로 쓸 수 있어야 합니다. 항상 2차원으로 펼쳐진 엑셀 데이터에만 익숙해져 있다면 조금 생소할 수도 있지만 몇몇 데이터는 값이 너무 많아져 가로 방향으로 늘리다 보면 테이블을 다루기 어렵게 만들고 또 값 이름 각각은 네임스페이스를 따로 정의하지 않아 세월이 흘러 여러 사람 손을 거친 데이터는 값 이름만 봐서는 동작을 추측하기 어려워지곤 합니다. 반면 값에 따라 중첩된 형태를 허용하면 값의 역할에 따라 계층구조를 만들 수 있어 어떤 사람들에게는 익숙하지 않을 네임스페이스 사용을 다신할 수도 있고 종종 3차원 좌표 같은 숫자들을 분리된 계층에 입력하도록 해 값이 많아지더라도 그나마 사람이 이해할 수 있는 상태를 유지할 수도 있습니다.
각 데이터를 구분하는 숫자는 숫자 자체가 의미를 가지지 않고 그냥 중복되지 않으면 됩니다. 종종 숫자의 각 자리에 의미를 부여해 긴 아이디를 만들지 않으면 불안해 하는 사람들이 있는데 이는 데이터에서 아이디가 필요한 이유와 일련번호를 부여하는 이유를 서로 혼동하기 때문에 일어나는 불안이라고 생각합니다. 아이디는 데이터 각각을 나머지와 구분하기 위한 고유한 숫자입니다. 아이디를 제외한 나머지 모든 값이 동일한 두 데이터가 있을 때 이들이 다름을 구분할 유일한 방법은 아이디입니다. 엑셀 환경에서는 아이디를 사람이 입력해야 할 때가 많은데 이 때 실수를 최소화 하고 이미 일어나는 실수를 쉽게 해결하기 위해서는 숫자가 의미를 가지지 않고 단지 다른 숫자와 겹치면 안 된다는 단순한 규칙만 있어야 합니다. 만약 아이디와 일련번호가 서로 같은 값을 사용한다면 여러 사람이 작업하는 환경에서 겹치는 숫자, 잘못 입력한 숫자를 만들기 쉽고 일련번호 규칙을 아는 사람만이 문제에 대응할 수 있습니다.
또한 일련번호를 설계하는 사람은 대체로 이런 체계를 설계하는데 전문성이 부족해 근시안적인 규칙을 고안하기 쉽습니다. 강화 재료 아이템은 최대 1000개까지 나타날 수 있는 번호 체계를 만들었지만 뒤에 가서 여러 무기가 나오며 무기 별로 서로 다른 강화석을 사용해야 하는 상황이 생기면 필요 이상으로 귀찮은 작업을 하게 됩니다. 또 이런 일련번호로부터 안정감을 느끼는 분들은 종종 제릿수 제한에 대한 지식이 없는 경우가 많은데 열 자리 숫자의 맨 앞자리를 4까지만 사용할 수 있음을 이해시키기는 쉽지 않습니다. 그러면서도 각 자리에 의미를 부여한 긴 숫자를 아이디로 사용하려고 하면 종종 난처합니다.
물론 데이터의 일부를 보고 데이터의 특징이나 종류, 형태를 짐작할 수 있으면 작업 속도가 빨라지는 장점이 있습니다. 그래서 아이디에 이 모든 의미부여를 하는 대신 작업 속도를 빠르게 만들 법 한 특징들을 별도로 분리된 값으로 만들어 놓습니다. 아이템의 장착 가능한 클래스 구분을 아이디에 클래스 코드 00
을 부여해 표현하는 대신 그냥 클래스 이름을 데이터에 포함하면 규칙을 모르는 사람이라도 데이터를 보고 이를 추측할 수 있습니다. 이런 취향에도 불구하고 데이터를 서로 구분하는 아이디에 의미가 있으면 좋을 때가 있는데 데이터 아이디가 파일시스템에 기록되어야 하는 상황입니다. 아트 에셋은 이런 상황에 자주 처하는데 이럴 때를 대비해 데이터의 특성을 한 열에 모아 파일시스템에 기록될 문자열을 별도로 분리된 값으로 만들어 놓곤 합니다.
다른 이야기가 길었는데 오늘은 이런 상황 속에서 일하다가 어느 프로젝트에서 모든 데이터를 통틀어 중복되지 않는 아이디 규칙을 정의하고 이를 엑셀 워크시트에 입력하며 사람이 관리해 달라는 요구를 받은 이야기를 해보겠습니다. 어느 프로젝트 초기에 엑셀 데이터 사용 파이프라인을 구축해야 했는데 흔한 첫 열을 아이디로 하고 나머지 열의 첫 행에는 값 이름을 쓰는 뻔한 방법을 사용할 거라고 예상했습니다. 이 예상이 크게 틀리지는 않았습니다. 개인적으로는 위에서 소개한 계층구조를 만들 수 있는 모양이기를 원했지만 비슷한 방법을 사용했던 프로젝트로부터 함께 온 몇몇 분들이 계층구조가 포함된 엑셀 워크시트를 불특정 다수의 기획자들에게 이해시키기 쉽지 않았다는 이유로 계층구조를 허용하지 않는 쪽으로 결정되고 있었습니다.
그런데 기술 책임자가 기존에 각 엑셀 파일마다 따로 사용하던 아이디를 처리하기 쉽지 않고 또 디버깅 상황에서 문제가 생긴 데이터를 찾기 쉽게 만들기 위해 모든 엑셀 파일이 공유하는 중복되지 않는 숫자를 엑셀 파일 첫 열에 넣고 관리해 달라는 요구사항을 말합니다. 혹시 여기까지 읽은 분들은 어렵지 않게 ‘UUID나 GUID 같은 걸 말하는 건가?’라고 생각할 수도 있었겠지만 게임 프로젝트의 기획팀 대부분은 이런 개념의 존재 자체를 모르는 경우가 많습니다. 그래서 이런 요구를 받으면 뭔가 어렵고 불편할 것 같으며 이전에 익숙하게 해 온 일련번호 부여 방법도 사용할 수 없을 것 같지만 프로그램에서 이렇게 요구하면 받아들일 수밖에 없습니다.
하지만 기계가 할 수 있을 것 같은 일을 사람이 하도록 하는 의사결정은 대부분 잘못됩니다. 이 경우 역시 마찬가지인데 모든 데이터에 걸쳐 구분할 수 있는 번호 체계가 있으면 좋겠다는데까지는 납득할 수 있지만 그걸 모든 엑셀 파일에 걸쳐 사람이 입력하고 관리했으면 좋겠다는 것은 납득하기 쉽지 않으며 잘못된 의사결정일 가능성이 높은 냄새를 풀풀 풍기고 있었습니다. 그렇다면 데이터를 읽을 때 기계가 겹치지 않는 번호를 생성해서 붙이면 되지 않느냐고 제안했고 이는 그럼 매번 번호가 바뀔 테니 디버그 정보를 익숙하게 다를 수 없기 때문에 안 된다는 답변을 들었습니다. 또 그렇다면 데이터를 읽을 때 기계가 데이터에 기반해 겹치지 않으며 매번 바뀌지 않는 번호를 만들면 되지 않느냐고 제안했지만 이번에는 혹시라도 겹치면 어떻게 할 거냐는 질문과 데이터가 바뀌면 번호가 바뀔 텐데 그럼 의미 없는 것 아니냐는 답변을 들었고요.
사실 슬슬 화를 내야 할까 고민했지만 아직 프로젝트 초반이었고 처음부터 나쁜 사람이 될 필요는 없을 것 같아 그러면 모든 데이터에 대해 겹치지 않는 숫자는 데이터를 읽을 때 기계가 부여하도록 하되 이 숫자를 만들어내는 규칙을 기획팀이 만들어 제안하기로 하며 회의를 마무리했습니다. 그래서 이 글을 쓰기 위해 이 사례를 기억해 내는 지금도 너무 웃긴 최대 42억, 열 자리까지 쓸 수 있는 이상한 숫자 규칙을 고안했습니다.
새로운 엑셀 워크시트가 생길 때마다 각 워크시트는 000
에서 999
까지 두 자리 숫자를 부여 받습니다. 실제로 엑셀 파일을 사용하는 여느 MMO 프로젝트는 쉽게 엑셀 파일 수가 100개를 넘어가기도 하고 또 일련번호 고갈이나 동시작업 시 파일 분할 등의 이유로 한 가지 데이터가 여러 파일을 사용하기도 하기 때문에 이를 고려한 결과입니다. 엑셀 워크시트 하나에서는 000001
부터 999999
까지 약 100만개의 데이터를 사용할 수 있습니다. 사실 각 워크시트마다 사용할 수 있는 데이터를 최대 10만개 까지로 해야 한다는 의견을 강하게 받았지만 그나마 숫자의 각 자리마다 의미를 부여해야 하는 요구사항을 아예 무시할 수는 없었기 때문에 그나마 한 자리를 더 사용하기로 했습니다.
그러면 마지막으로 한 자리가 남는데 이건 먼 미래에 국제화를 할 경우를 대비해 남겨 두기로 하고 개발에선 항상 1
을 사용하기로 했습니다. 하지만 이미 맨 앞자리에는 숫자를 4까지만 쓸 수 있었기 때문에 이 규칙을 고안할 시점에 이미 이 첫 자리를 국제화에 사용할 수 없을 거라고 생각하고 있었습니다. 하지만 더 이상 문제를 제기해 상황을 귀찮게 만들고 싶지 않았기 때문에 이 규칙을 고안하고 규칙을 또 다른 엑셀 워크시트로 만들어 관리하기로 하면서 상황을 마무리 지었습니다.
이 초반 결정은 이후 몇 년에 걸쳐 사용되었고 다행히 숫자 각 자리에 의미를 부여해 항상 큰 숫자를 아이디로 사용하기를 원하는 몇몇 사람들의 요구사항을 달성할 수는 없었지만 나머지 상황에는 그럭저럭 잘 동작했습니다. 엑셀 파일 수는 수백을 돌파했지만 여전히 자릿수에 여유가 있었습니다. 한편 첫 번째 자리를 국제화에 활용할 날은 결코 찾아오지 않았고요. 이 사례는 개인적인 측면에서는 나름 실패하지는 않았다고 생각하고 또 프로젝트 전체적인 측면에서는 완전 실패한 이상한 결정이었다고 생각합니다.
실패한 결정이라고 생각하는 이유부터 설명하면 먼저 엔지니어들이 그들 스스로 해결할 수 있는 문제를 쉽게 기술에 덜 능통한 다른 팀에 쉽게 밀어내는 상황을 처음부터 강력하게 통제하지 않았습니다. 이는 개발 기간 내내 비슷한 납득하기 어려운 상황을 자주 만들어냈으며 그나마 기획자들 중에서는 기술적인 이해가 아주 조금 더 있는 사람들이 번번히 이런 상황에 투입되어 당연한 결정을 내리는데 감정을 소모해야 했습니다. 또 실패하지는 않은 결정이라고 생각하는 이유를 설명하면 나름 초반부터 첨예한 상황을 겪으며 어처구니 없는 요구사항이라도 요구사항을 만족하는 방법을 제한시간 안에 고안해냈습니다. 또한 팀 빌딩 초반부터 나쁜 사람 혹은 함부로 대하면 안 되는 사람으로 인지되지 않고 적당히 대안을 제시해 이후 기획팀 중 엔지니어 조직에 협력적으로 행동하는 사람으로써 위치를 점했으며 이는 이후 아주 오랜 기간에 걸쳐 팀에서 개인적인 입지를 다지는데 도움을 주었습니다. 물론 그 댓가로 종종 감정을 소모해야 했고 때때로 양쪽 조직 모두의 불만을 받기도 했지만 전체적으로 보면 나쁘지만은 않았습니다.
결론. 이전에 참여했던 한 프로젝트 초반에 엔지니어 조직으로부터 모든 엑셀 워크시트에 걸쳐 중복되지 않는 숫자를 사람이 만들어 사람이 관리하라는 요구사항을 받았습니다. 도무지 납득할 수 없는 처사라고 생각했지만 팀 빌딩 초반부터 나쁜 사람이 되는 대신 적당히 요구사항을 만족하는 방법을 제안해 상황을 모면하고 그렇게 심하게 나쁘지는 않은 환경을 구축했습니다. 하지만 먼 미래의 내 관점에서 다시 생각해보면 도대체 왜 그런 요구를 받았어야 했는지 지금도 이해하기는 쉽지 않습니다.