NDC 2017 둘째 날, 아이펀팩토리 문대경 대표가 강단에 섰습니다. 현재 범용 게임 서버 엔진으로 시장에 출시된 '아이펀 엔진'의 포스트모템을 발표했는데요. 엔진을 개발 및 출시하고 난 뒤, 시장의 요구를 어떻게 받아들였는지, 그리고 추후 아이펀 엔진과 같은 외부 솔루션을 만들고자 하는 개발자들이 꼭 기억해야 할 사항들도 들어볼 수 있었습니다.




아이펀 엔진은 게임서버 프레임워크 개발 프로젝트로 시작했습니다. 네트워크 엔진이 아니라 서버 프레임워크 시스템이에요. 보다 손쉽게 게임을 개발하고 생산성을 높여서, 최종적으로 '게임을 좀 더 빨리 만들게 돕자'는 데 초점을 뒀죠. 처음에는 모바일 게임에서 쓰는 서버 엔진으로 시장에 나왔지만, 이후 콘솔도 지원하는 범용 엔진으로 업그레이드 되었습니다.



저희 아이펀 엔진 프로젝트가 처음 개발되고 난 후 어떻게 업그레이드 되었는지 체크해봤습니다. 오늘이 첫 삽을 뜬지 1,996일째입니다. 그동안 빌드 작업만 2,071번을 했고, 총 19명의 개발자가 이 프로젝트에 참여했습니다.



D+2 : 프로젝트 시작한지 2일째 되는 날, 우분투에 있는 데비안 패키징을 작성했습니다. 그 이유는 패키지 수준의 의존성을 갖게 되면, 엔진 개발자와 사용자 간 동일한 환경을 보장해줄 수 있어서입니다. 다운받아서 쓰는 사람이 '환경이 이상해서 안 된다' 이런 현상이 줄어든다고 보시면 됩니다.

D+4 : 4일째 되는 날엔, 'continuous integration'을 붙였습니다. 이렇게 함으로써 작업자 상관 없이 빌드 결과물의 객관성을 확보할 수 있었습니다.

D+8 : 이 때 DHT 기반의 P2P를 구현했습니다. 그런데 이건 807일 째 되는 날애 없앴어요. 서버쪽 P2P 기능으로 생각하고 들어갔는데, 이후 클라이언트 쪽에서도 활용 가능하도록 제거한 겁니다.

D+30 : 이벤트 기반 프로그래밍 형태로 변경했습니다. 개발자가 꼭 솔루션 전체를 이해하기보다는, 사용할 이벤트만 선별적으로 사용할 수 있게 함으로써 효율을 높였습니다.

D+41 : 문서화 작업을 시작했습니다. 사실 외부에 제공되는 솔루션의 경우, UI라고 할만한 게 없었습니다. 저는 솔루션에 있어 UI는 크게 두 가지라고 생각했습니다. 첫째가 인터페이스 함수, 그리고 두 번째가 문서화입니다. 이걸 적용한 거라고 보시면 됩니다.

D+45 : 분산 서버 구축을 위한 작업 결과물이 적용됐습니다. 서버의 확장성은 서버 설계 때부터 고려해야 하는데요. 이에 따라서 XMLRPC를 커스텀 RPC로 변경한겁니다. 저희 엔진만의 특성이 아니라, 외부에 나갈 솔루션이라면 이 부분을 꼭 생각하고 만들어야 합니다.

D+98 : 게임 서버 운영에 필요한 행동 로그 시스템을 구현했습니다. 프로그램 로그 외에 유저 행동 수집을 위한 로그를 구현했다고 봐도 될 것 같아요.

D+147 : 본격적인 TCP 네트워크 세션을 구현했습니다. IP가 변경되는 모바일 환경을 고려해서 TCP 위 세션 계층을 만든 거죠. 이후 세션 계층은 사용 편의성 때문에 두 번의 큰 변화를 겪게 됩니다.

D+228 : UDP 네트워크 세션을 적용했습니다. 세션 계층에 UDP와 웹소킷을 추가했죠. 이후 웹소킷은 사용 빈도가 적어서 삭제했습니다. 다만, 최근 시장 분위기가 다시 요구하는 상황이라 재적용을 고려 중입니다.

D+252 : ORM 초기 버전을 만들어 넣었습니다. DB와 관련해서 여러가지를 지원받을 수 있어 넣은 건데요. MongoDB를 백엔드로 해서 ORM을 구현했는데, 이후 MongoDB를 MySQL로 변경했습니다. MongoDB가 소개된지 오래되지 않아 국내에 MongoDB를 운영할 개발자가 많지 않았어요. 그게 솔루션을 도입하는 데 큰 걸림돌이 되어 결국 변경한겁니다.

D+409 : 모바일 플랫폼 인증 기능을 구현했습니다. 가장 처음에 들어간 건 페이스북과 넥슨플레이였고요.

D+510 : 유니티 3D 대응을 시작했습니다. 클라이언트 플러그인 없이는 클라이언트 개발이 지나치게 어렵다는 걸 알기에, 이에 대응해야만 했습니다.

D+710 : 모바일 플랫폼 결제 검증 기능을 넣었어요. 구글플레이 스토어와 앱 스토어를 지원했습니다.

D+1099 : REST API EndPoint가 이 때부터 지원되었습니다.

D+1427 : 서버 엔진 프로파일러가 구현되었습니다. 블랙박스 인 게임엔진의 Visibility를 향상시킨 거죠.

D+1808 : C#을 지원하게 됐습니다. 처음에는 C++만 지원했는데, 사용 편의성을 확대하고자 넣게 되었습니다.

D+1827 : 언리얼의 데디케이티드 서버 관리 기능도 들어갔습니다. 비교적 최근에 들어간 기능입니다.

D+1861 : 모니터링 대시보드가 구현되었습니다. 이것도 블랙박스 인 서버 엔진의 Visibility를 향상시키는 데 목적이 있었습니다.


외부에 내놓는 솔루션은 개발 외적인 것들도 정말 중요합니다. 프로젝트를 만들게 된다면, 가장 먼저 이 솔루션 배포 방식부터 고민해보시는 걸 추천합니다. 일단 외부 제공 솔루션은 설치 과정이 단순해야합니다. 박스에서 꺼내자마자 바로 동작하는 걸 생각하시면 될 것 같습니다.

그 다음으로 중요한 것이 사후관리입니다. 배포 방식이 정해졌다고 해서 아무렇게나 만들면 안 됩니다. 문제하 한 번 생기면, 아무리 패치로 고친다고 해도 소용없습니다. 한 번 등을 돌린 소비자는 쉽게 돌아오지 않습니다.

이런 약점을 고치기 위해선 어떻게 해야 할까요. 저희는 내부적으로 Peer Code Review를 꾸준히 진행하고 있습니다. 버그를 작업자의 능력이 아닌, 시스템으로 풀 수 있도록 한 거죠.

비슷한 맥락으로, 버그를 줄이기 위한 또 다른 방법이 있는데요. 빌드를 자동화하는 겁니다. 빌드 자동화는 제품의 일관된 품질을 보장해줍니다. 작업자에 따라 결과물에 차이가 나는 상황을 미연에 방지할 수 있죠.

그리고 제가 거듭 강조하는 것이 '문서화'입니다. 구슬이 서말이라도 꿰어야 보배가 되는 거예요. 문서는 SW 솔루션에 있어 UI입니다. 내부 개발용 솔루션이라면 이걸 크게 신경쓰지 않는 것이 보통이지만, 외부에 제공하는 솔루션이라면 이 부분을 놓쳐서는 안 됩니다.

또, 블랙박스 사용자가 언제나 답답함을 느낄 수 있다는 걸 명심할 필요가 있습니다. 인터페이스는 최소화 하되, 동작은 직관적으로 만들어야 합니다.

마지막으로, 서비스를 운영하면서 모니터링을 소홀히 해서는 안 됩니다. 특히, 블랙박스를 진단할 수 있는 방식을 반드시 제공해야 합니다.

솔루션을 다루는 프로젝트는 개발자가 스스로를 과시하기 위한 것이 아닙니다. 읽기 쉬운 코드를 써야 하고, 상세한 commit log가 필요합니다. 또, 관리가 용이한 개발툴로 변경해야 하죠. 자신의 코드를 쓰면서 동료가 실수한다면, 그건 동료가 바보라서가 아닙니다. 자기만을 위한 코드를 짰다고 생각해야 하고, 동료들과 함께 작업할 수 있도록 코드를 수정해야 합니다.

그리고, 서버 엔진을 네트워크 엔진으로 착각하면 안 됩니다. 서버 엔진은 전반적인 생산성과 확장성에 대해 더 많이 생각해야만 합니다.



저도 이 프로젝트를 진행하면서 후회를 안 한 것은 아닙니다. 돌이켜보면, 사용자를 위한 편의성을 업그레이드하는 게 너무 늦었습니다. 인증/빌링 및 프로그래밍 언어에 대한 배려가 늦은 거죠. 아까 언급했던 C# 지원이 늦었던 것이 대표적입니다. 추후 저희와 비슷한 프로젝트를 진행하시는 분이 계시다면, 이 부분을 꼭 기억해 주셨으면 좋겠습니다.