버전 관리 시스템: 애셋 서버 vs Git

작년 초에 게임팀에 와서 가장 먼저 한 일은 당시 게임팀이 사용하고 있던 버전 관리 시스템을 Unity Asset Server에서 Git으로 바꾼 것입니다. Unity Asset Server의 Unity Editor에서 편리하게 사용할 수 있다는 장점이 있지만, Subversion, Git 등이 제공하는 브랜치(branch)를 따는 기능을 제공하지 않기 때문에 문제라고 생각하였습니다. 구체적으로 무엇이 문제일까요?

브랜치를 딸 수 없으면 모든 개발자가 항상 마스터(master)에 작업물을 반영해야 합니다. 예를 들어, 제품을 출시한 이후 개발자들이 다음 업데이트를 위한 작업물을 마스터에 반영하고 있다고 가정해 봅시다. 만약 출시한 릴리즈에 버그가 있어서 수정해야 하는 상황이면 어떻게 될까요?

출시 버전 기준으로 해당 버그만 고쳐서 다시 릴리즈를 해야 하는데, 이미 마스터에는 아직 작업 중인 다음 업데이트 내용이 반영되어 있게 됩니다. 새로운 기능이 보이지 않게 끄고, 안정성에 문제가 없는지 테스트하기 시작하면 더 이상 간단한 패치 수정이 아니라 사실상 새로운 릴리즈를 하는 상황이 됩니다. 출시 시점에 브랜치를 따두었다면, 마스터에 반영된 추가 작업과 별개로 출시 브랜치에 버그 수정만 반영하고 곧 바로 릴리즈를 할 수 있었을 겁니다.

릴리즈에 대한 버그 수정과 다음 릴리즈 작업을 동시에 준비하기 위해 브랜치를 만드는 방법은 이미 수많은 소프트웨어 개발에 사용되고 있는 일반적인 프로세스인데 Unity Asset Server가 이런 기본적인 버전 관리 기능을 제공하지 않는다는 사실이 이상하게 느껴졌던 부분입니다.

추천 개발 도서

제가 맡은 게임 개발팀은 모두 Unity3D 엔진을 이용해 iOS와 안드로이드를 위한 모바일 게임을 만들고 있습니다. 클라이언트 개발 언어는 C#을 사용하고 있습니다. 따라서 “코딩 스쿨”의 초점은 주로 객체지향 프로그래밍, 디자인 패턴, 리팩토링, 테스트, 소프트웨어 엔지니어링에 맞추었습니다. 개발팀에 필독서로 추천한 책은 다음과 같습니다.

[1] Design Patterns: Elements of Reusable Object-Oriented Software 

싱글톤, 팩토리, 템플릿 메소드 등 디자인 패턴을 정리한 고전 중에 고전입니다. 디자인 패턴이라는 말 자체를 모르는 개발자도 없지만, 모든 고전이 그렇듯 정작 이 책을 직접 읽은 개발자도 손에 꼽을 정도로 적습니다. 다른 디자인 패턴 책들은 전부 이 책을 풀어서 설명하는 수준이므로, 디자인 패턴을 제대로 공부하고 싶다면 반드시 원전을 읽어 보시라고 권합니다.

[2] Refactoring: Improving the Design of Existing Code

모바일 게임도 10 명 이상의 개발자가 1년 이상 기간 만드는 경우가 많아지면서 대충 돌아가는 코드가 아닌 지속적인 유지 보수가 필수가 되었습니다. 출시 이후에도 지속적인 업데이트를 통해 유저 이탈을 막아야 하는 만큼 유지보수가 하기 쉬운 코드를 만들기 위해 코드를 지속적으로 리팩토링할 필요가 있습니다.

이 책은 어떤 코드가 리팩토링이 필요한지 냄새(smell)를 맡는 방법을 알려줍니다. 문제 해결이란 문제 인식에서 출발하는 법이고, 어떤 코드가 나쁜 코드이고 개선이 필요한지 아는 것부터 리팩토링이 시작됩니다.

[3] Clean Code: A Handbook of Agile Software Craftsmanship

여러 명이 개발자가 같이 코드를 작성하고 유지 보수하기 위해서는 읽기 쉽고 이해하기 쉬운 코드를 작성하는 것이 필수입니다. 이 책은 C#이 아닌 Java를 예를 들고 있지만, 객체지향 프로그래밍 언어를 사용할 때 코드 가독성을 위해 어떤 부분을 고민해야 하는지 명쾌하게 설명하고 있습니다.

[4] Effective C# (Covers C# 4.0): 50 Specific Ways to Improve Your C# (2nd Edition)

생각보다 많은 개발자가 내가 사용하는 언어가 어떻게 동작하는지 정확한 의미(semantics)을 모르고 쓰고 있습니다. 또한 프로그래밍 언어는 단순히 문법(syntax)과 의미(semanitcs)만 알면 되는 게 아니라 해당 언어를 사용하는 사람들의 문화(idiom)을 배워야만 그 언어를 제대로 사용하는 것이라 할 수 있습니다. 이 책은 C# 사용 시 간과하기 쉬운 내용들을 잘 정리하여 설명하고 있습니다.

소프트웨어 복잡성

소프트웨어 공학의 고전인 The Mythical Man-Month를 보면 소프트웨어 복잡성을 크게 2가지로 구분하고 있습니다. 요구사항 자체가 복잡하기 때문에 소프트웨어가 복잡해지는 본질적 복잡성(essential complexity)과 여러 이유로 우리 스스로가 초래한 돌발적 복잡성(accidental complexity)가 있습니다.

일례로, 미션, 아레나, 레이드 등 여러 게임 모드와 캐릭터 수집, 진화, 아이템 수집, 제작 등 포함된 RPG 게임은 간단한 퍼즐 게임보다 요구사항 자체가 절대적으로 많기 때문에 본질적으로 더 복잡하다고 표현합니다. 이러한 본질적 복잡성은 그 자체로 줄일 수가 없는 것이 특징이기도 하죠.

반대로 돌발적 복잡성은 레거시 코드, 플랫폼 버그, 툴의 사용성 등 다양한 원인으로 발생합니다. 예를 들어, 과거 피처폰으로 게임은 지금보다 요구사항 자체가 훨씬 간단한 게임이었지만 피처폰의 개발 환경 자체가 지금의 스마트폰과 비교할 수 없는 수준으로 불편했기 때문에 돌발적 복잡성이 높았습니다.

현재 많은 게임 개발사가 사용하고 있는 Unity3D는 이런 돌발적 복잡성을 상당히 줄여주는 툴입니다. C#이라는 언어도 C/C++과 비교해서 추상화 수준이 높고, 메모리 관리 등 저수준 최적화 작업에 신경을 쓸 필요가 없게 만들어 주기 때문에 돌발적 복잡성을 줄여준다고 볼 수 있습니다.

하지만 이러한 기대가 처참하게 깨지는 경우도 여전히 존재합니다. 일례로, Unity 엔진은 지금 기준으로 보면 상당히 구버전 Mono 엔진을 사용하고 있고 iOS AOT 컴파일러에 버그가 있어서 Linq 쿼리 중 일부가 iOS에서만 크래시나는 문제가 있습니다.

Unity의 iOS 빌드 이슈를 이해하고 이에 맞춰 문제가 되는 코드의 사용을 피하는 것이 팁인데, 이런 지식 자체는 만들고자 하는 게임의 본질적인 복잡성과는 아무런 관련이 없는 돌발적 복잡성의 대표적인 예라고 할 수 있습니다.

임베디드 시스템이 데스크톱 환경에 비해 불우한 개발 환경인 이유는 각종 디바이스 버그로  발생하는 이슈들에 대응해야 하기 때문입니다. 스마트폰 시대의 모바일 게임 개발은 과거와 비교할 수 없는 수준으로 발전했지만, 여전히 은총알은 요원해 보입니다.

게임 코딩 스쿨 블로그를 시작하며

10년 가까이 셋탑박스, 핸드폰, 디지털TV를 포함한 임베디드 시스템 분야에서만 일하다가 운명의 장난처럼 게임 개발팀을 맡아서 일한 지 벌써 1년 2개월이 흘렀습니다.

축구 선수가 야구팀 코치나 감독을 맡은 것처럼 생뚱 맞은 조합이긴 하지만 어떤 운동이든 기초 체력이 중요한 것처럼 임베디드 시스템이나 게임이나 프로그래밍 기초, 방법론에는 큰 차이가 없다는 생각에 사내에서 게임 개발자를 위한 “코딩 스쿨”을 시작하게 되었습니다.

이 블로그를 통해 그간 “코딩 스쿨”, “코드 개선 회의”, “리팩토링 회의” 등 다양한 이름으로 진행한 세미나 내용을 정리하고 나름의 노하우와 시행 착오 경험을 여러 게임 개발자 분들과 공유하고자 합니다.

그럼 시작하겠습니다.

Building Mono project on the Travis CI OS X Build Environment

Today I changed the Travis CI config file of EncryptedType project to build on Mac OS X.

Here is EncryptedType’s .travis.yml file.

language: objective-c

env:
  global:
    - MONO_VERSION=3.10.0

install:
  - wget "http://download.mono-project.com/archive/${MONO_VERSION}/macos-10-x86/MonoFramework-MDK-${MONO_VERSION}.macos10.xamarin.x86.pkg"
  - sudo installer -pkg "MonoFramework-MDK-${MONO_VERSION}.macos10.xamarin.x86.pkg" -target /

script:
  - ./build.sh Build

EncryptedType is a .NET project written in C#, but the language given here is objective-c. This is THE TRICK! Travis CI automatically uses the OS X build environment when the specified language is objective-c.