top of page
검색

U.R.U.K


개요


  • 게임명 : U.R.U.K

  • 게임 장르 : 2D 탑다운 어드벤쳐 게임

  • 과목명 / 교수 : GAM150 / David Ly

  • 언어 / 프레임워크 / 개발도구 : C++ / doodle framework / Visual Studio 2019

  • 소스 컨트롤 솔루션 / 클라이언트 : Bitbucket / Sourcetree

  • 팀 규모 / 개발 기간 : 4인 / 14주

  • 사용 엔진 : U.R.U.K Engine (자체개발 엔진)


이번에 소개할 프로젝트는 제가 대학교에 다니면서 개발한 다섯번째 팀 게임 프로젝트입니다.


2학년 1학기부터 시작하는 이번 프로젝트를 위해서는 이전과 달리 한 학기라는 긴 시간이 주어졌고, 팀원들과 함께 기간 내로 어느 한 교수님이 개발하신 그래픽 프레임워크인 doodle framework, 그리고 C++ 프로그래밍 언어를 활용해 완성도 높은 2D 게임을 하나 개발하는 것이 이번 프로젝트의 주 목표였습니다. 방학 동안 동기 (포트폴리오 사이트 링크) 한 명이 주도적으로 개발한 게임 엔진, 그리고 제 기획안을 기반으로 학기의 시작과 함께 개발을 시작했습니다.


2주 동안 게임의 컨셉 기획서를 영문으로 작성하고, 4주간 게임의 프로토타입 버전을 개발한 후, 다음 4주간 알파 버전을 개발한 뒤, 2주 내로 베타 버전, 그리고 마지막 2주 내로 파이널 릴리스 버전을 개발하여 제출하는 과정을 총 네 명의 팀원이 역할을 분담하여 진행하게 되었습니다.


역할 분담



제 역할은 기획서의 작성, 기획 회의 주도, 그리고 게임플레이 코드의 전반적 구조를 결정하는 일이였고, 플레이어 및 AI의 메인 로직 담당, 엔진의 오디오 시스템 개발, 그리고 Flow-Field Pathfinding Solution (참고 영상 링크) 에 대한 연구 및 개발, 음악 작곡 및 SFX 제작, 컨셉 아트 제작, 포스터 제작, 그리고 스프라이트 에셋의 일부를 제공하는 일 또한 담당하였습니다.


또, 기획서뿐만 아니라 기술적 세부사항 문서의 Player Controls Behavior 파트, 그리고 Art Requirements Audio Requirements 파트를 작성하였고, 게임에 사용된 자체개발 엔진 레퍼런스 문서의 AudioBufferManagerAudioPlayerComponent 파트 또한 직접 작성하였습니다.


출시 계획 문서를 작성하기 위한 회의 또한 주도적으로 이끌었고, 기획서를 포함한 각종 문서에 들어간 대부분의 컨셉 아트들을 직접 그려넣으며 문서 전반에 쓰인 문법 및 영어 표현 / 어휘에 대한 검수를 계속하여 진행하였습니다.


협업 방식


코로나19가 발생하면서 게임 프로젝트 수업 또한 비대면으로 전환되었는데, 그럼에도 불구하고 팀 디스코드 서버를 통한 상시적인 소통, 잦은 회의와 개발상황 체크를 통한 적응형 스코핑, 그리고 소스 컨트롤 솔루션과 트렐로를 통한 지속적인 워크플로우 관리 덕분에 서로 만나지 않고도 계속하여 생산성을 높게 유지할 수 있었습니다.




임시 플로우 차트나 다이어그램 작성이 필요한 대화나 회의의 경우에는 마이크로소프트 화이트보드와 펜 타블렛을 활용하여 데이터의 시각화에 도움을 주었습니다.



또, 모든 아트 / 오디오 에셋들의 정보가 등록된 표를 만들어 개별 에셋의 현재 상태뿐만 아니라 작성자 정보, 그리고 라이선스 정보를 게임 완성 시까지 제대로 기록하여 관리하였고, 이는 개발 진척상황 파악에도 용이하였습니다.



하이 컨셉트 & 메인 게임 메카닉





"적들을 쓰러뜨리지 않고 게임을 진행하는 것이 강제되는 2D 던전 크롤러"




이 아이디어를 처음 내었을 때, 저는 언더테일과 같이 불살이라는 컨셉을 채용한 게임들을 플레이하고 큰 감동을 받고, 자신 또한 그러한 게임을 만들어보고 싶다는 의지에 불타고 있었습니다.


하지만 1학기라는 개발기간 내로 언더테일 정도의 스토리텔링이나 장황한 맵과 화려한 아트 에셋들을 준비하는 것은 당연히도 무리라고 판단했고, 다른 방식으로 불살이라는 컨셉을 실현할 방법을 찾고 있었습니다.


그러던 중, 비록 완전한 불살은 아니였지만, 현재 게임 내에 살아있는 캐릭터 (플레이어 포함) 들의 수를 세서 그걸로 무언가가 돌아가게 하면 되는거 아닌가? 라는 생각이 문득 들어 아이디어를 정리해보게 되었고, 이를 정리하여 같은 방 내에 정해진 수의 생명체가 살아있을 때에만 열리는 문이라는 아이디어가 나오게 되었습니다.


이렇게 하면 적을 유인해서 방으로 끌고 들어오는 추격 컨텐츠, 그리고 불필요한 적을 쓰러뜨리는 전투 컨텐츠 모두가 충족될 것이라고 생각했지만, 떠오르는 문제가 몇가지 있었습니다.




1. 만약 모든 적들을 잡을 수 있게 된다면, 단순히 모두 한군데에 모은 다음에 숫자가 맞을 때까지 한 마리씩만 잡으면 되는 것이 아닌가?


2. 몬스터들을 너무 많이 잡아서 클리어 자체가 불가능해지면 어떻게 되는 거지?


3. 어디에 어느 몬스터가 있는지 어떻게 알고 게임을 진행하는거지? 추격전을 펼치게 되면 필연적으로 아직 들어가보지 않은 방에도 들어갈 수 있을텐데, 이러면 문제가 생기는게 아닐까?




여기서 두번째 문제를 해결하는 데에는 여러 방법이 있었는데, 처음에는 스포너 개념을 도입하여 몬스터가 쓰러지게 되면 계속 생성되게 할까도 생각해보았지만, 이를 구현하고 테스팅할 시간이 부족하다고 판단, 몬스터 스포너 대신 레벨 재시작 버튼을 넣는 것으로 해결하였습니다.


세번째 문제는 화면 하단에 미니맵을 만들어 맵의 구조와 몬스터의 종류를 알 수 있도록 하여, 플레이어가 몬스터를 끌고 다니기 전에 미리 전략을 짤 수 있도록 하였습니다.


그리고 가장 중요한 첫번째 문제를 해결하기 위해, 저는 플레이어가 잡을 수 있는 적, 잡지는 못하지만 스턴 상태로 만들 수 있는 적, 그리고 플레이어의 공격을 완전히 무시하는 적이라는 세 종류의 적을 만들었습니다. 그리고 가위바위보와 같은 먹이사슬 관계를 도입하여, 필연적으로 몬스터들을 유인해서 몬스터 사이의 관계를 잘 이용해야만 문을 여는 것이 가능하도록 게임의 구조를 설계하였습니다.


포식이 (Poh'Shigi)


다른 몬스터와 단둘이 남겨지면 해당 몬스터를 포식하고 크기를 키웁니다.

같은 포식이끼리도 서로 크기가 다르다면 더 큰 쪽이 더 작은 쪽을 포식합니다.

플레이어의 공격으로 포식이를 쓰러뜨릴 수는 없지만, 잠시 기절시킬 수는 있습니다.

낮은 이동속도를 가지고 있기 때문에 유인하고 따돌리기가 용이합니다.


콩돌이 (Kon'Dhory)


가장 약한 몬스터로, 유일하게 플레이어의 공격에 쓰러지는 몬스터입니다.

약하지만, 가장 빠르기 때문에 따돌리기 어렵습니다.


송사리 (Son'Xhary)


플레이어의 공격에 완전히 면역인 유일한 몬스터입니다.

하지만 송사리도 포식이 앞에서는 그저 좋은 단백질 공급원일 뿐입니다.

플레이어는 송사리를 쓰러뜨릴 수는 없지만, 랜턴을 통해 쫓아낼 수 있습니다.

랜턴을 들면 검을 장비하지 못하므로, 콩돌이와 포식이로부터의 공격에 무방비해집니다.

포식이보단 빠르지만, 콩돌이보다는 느리기에 어렵지 않게 따돌릴 수 있습니다.


물고기 문양의 문 (The Fish Gate)


이 종류의 모든 문들은 정해진 숫자만큼 몬스터를 끌어와야만 문이 열리게 되어있습니다.

검은색, 파란색, 그리고 빨간색의 인디케이터를 통해 부족하거나 넘치는 숫자를 알 수 있습니다.

매 층마다 하나씩의 물고기 문양의 문이 있고, 이 문을 넘어서면 더 깊숙이 내려갈 수 있습니다.



몬스터의 종류가 너무 많으면 플레이어가 기억하기 힘들 것이라 생각하여 몬스터의 종류를 종류로 제한하였고, 플레이어의 공격에 대한 반응의 차이, 그리고 여기에 더해진 서로 먹고 먹히는 생태계적 특성 또한 제대로 활용함으로써 다양하고 재미있는 퍼즐을 만들 수 있었습니다.


게임 목표 & 보상


던전 안에 들어온 플레이어의 손에는 검과 랜턴, 그리고 첫번째 층의 지도가 쥐어져 있었습니다.


먼저 지도를 보며 계획을 세운 뒤, 검과 랜턴을 활용하여 적을 쓰러뜨리고, 유인하고, 서로 포식하게 둠으로써 매 층마다 있는 물고기 문양의 문을 열어가며 던전 코어를 향해 다가갑니다.


네개의 퍼즐 레벨을 클리어한 뒤, 마지막 다섯번째 레벨에 있는 던전 코어를 부수고 나면 엔딩 일러스트와 함께 크레딧이 나오게 됩니다.



게임의 난이도가 상당히 높고, 또 플레이타임이 비교적 길었던 만큼 멋진 엔딩 일러스트로써 플레이어에게 보상을 주기를 원했습니다. 때문에 엔딩 일러스트만큼은 심혈을 기울여 높은 퀄리티로 제작하도록 하였습니다.


게임 플로우



학기 초에 작성했던 기획서에는 던전과 마을을 들락날락할 수 있고, 또 인벤토리와 아이템 상점 등이 있는 Provision 시스템이 있었지만, 개발 일정상 메인 메카닉과 직접적으로 연관되지 않은 대부분의 요소들을 제외하기로 하였기에 최종본의 게임 플로우에서는 빠지게 되었습니다.


레벨 디자인



첫 번째 레벨입니다. 문을 여는 데에 플레이어를 포함하여 여섯 생명체가 필요하므로, 아무도 쓰러뜨리지 않고 문에 다가가야만 문을 열 수 있습니다.


플레이어가 아무도 쓰러뜨리지 않더라도 포식이와 다른 몬스터를 단둘이 남겨두면 포식이가 다른 몬스터를 쓰러뜨릴 수 있기에, 방심하고 있다가 뒤통수를 맞기 쉬운 레벨입니다.


첫 레벨인 만큼 몬스터들을 각각 파악하기 용이하도록 최대한 몬스터들을 서로 따로 두어 배치하였고, 통로에 장애물이 없는 일자 구간을 많이 만들어 단순히 뛰어서도 몬스터들을 따돌릴 수 있도록 설계하였습니다.



두 번째 레벨입니다. 마찬가지로 문을 열기 위해서는 여섯 생명체가 필요한데, 무조건 지나야만 하는 중앙 방에는 따돌리기 어려운 콩돌이가, 그리고 바로 옆에 방에는 포식이 두 마리와 같이 있는 콩돌이가 있는데, 해당 방에는 이미 처음부터 포식이 여러마리가 위치하고 있기 때문에 포식이를 한 마리만 달고 방을 나오게 되면 남은 포식이가 콩돌이를 먹어치우게 됩니다.


하지만 그만큼 몬스터들을 따돌리기 쉽도록 맵에 블록을 많이 배치하였으므로, 여러 마리를 동시에 끌고 다니면서 칼과 랜턴을 잘 활용하는 것이 강제되는 레벨이라고 볼 수 있습니다.



세 번째 레벨입니다. 문을 열기 위해 필요한 생명체의 수는 단 셋이지만, 문제는 문까지 가는 길에 많은 수의 포식이들이 위치하여 있고, 문이 위치한 바로 앞에 있는 방에는 게임에서 가장 따돌리기 어려운 콩돌이들이 두 마리씩이나 위치하여 있는 만큼, 숫자가 부족한 대신 숫자를 초과하여 문이 닫힐 리스크가 있는 레벨입니다.


또, 송사리와 포식이들의 위치가 무시하기 굉장히 까다로운 곳들에 위치해 있어 강행돌파를 어설프게 시도하다간 그대로 비명횡사할 수 있습니다.


클리어하는 방법으로는 포식이를 활용하여 몬스터들을 하나하나 처치하면서 안전하게 진행하는 방식, 그리고 다른 몬스터들을 끌고 들어갈 것을 감안하여 돌진한 다음에 콩돌이들을 처치하여 숫자를 맞추는 방식 등이 있습니다.



마지막 레벨입니다. 인게임 미니맵에서는 방과 통로들이 모두 모여 물고기 모양이 되도록 미니맵을 그렸고, 마지막 레벨인 만큼 난이도를 높게 조정하였습니다.


여러 갈래로 길을 뚫어놓았기에 가능한 경우의 수가 상당히 많고, 특이한 지형지물이 많은 레벨이므로 도주 시의 지형지물의 활용이 추천되는 레벨입니다.


적 AI



적 스테이트 머신 (알파 버전)

모든 몬스터들은 기본적으로 위와 같이 발견, 추적, 공격이라는 각 스테이트 사이를 조건에 따라 바꿔가며 행동하게 됩니다. 처음 플레이어를 발견하면 울음소리와 함께 발견 애니메이션을 재생하고, 그 뒤에는 움직이는 애니메이션과 함께 플레이어를 쫓아옵니다.



하지만 송사리나 포식이와 같이 특수한 조건에 따른 행동이 지정되어있는 몬스터들은 조건이 발동되면 하던 일을 중지하고 미리 지정된 행동을 행합니다.



위의 그림과 같이 발견 사거리와 추적 사거리에 차이가 있기 때문에, 이동 속도가 느린 포식이와 같은 몬스터들은 비교적 따돌리기가 쉽지만, 이동 속도가 빠른 콩돌이와 같은 몬스터들은 따돌리기가 매우 까다롭습니다.


이를 해결하기 위해 새로운 방에 들어갔을 때 출입문이 곧바로 닫히도록, 그리고 그로부터 다시 출입문이 열리기까지의 시간에 딜레이를 두었고, 이 딜레이를 잘만 활용하면 여러 방을 넘나들며 속도가 빠른 몬스터들도 얼마든지 따돌릴 수 있습니다.



또, 포식이의 경우에는 다른 몬스터를 포식할 시에 포식당하는 몬스터의 울음소리가 방 밖까지 울려 퍼지도록 하여, 플레이어가 포식이의 행동과 시점을 알 수 있도록 하였습니다.


아트 디자인



풀타임 아티스트 없이 모두가 열심히 코드를 짜야만 개발일정을 맞출 수 있는 환경이였기에 최대한 단순하면서도 명료한 아트스타일을 선택했습니다. 참고가 된 게임들로는 Don't Starve, 그리고 팔라독 등이 있습니다.



또, 2D Rigged Animation 제작 툴을 개발해준 동기 덕에 스프라이트 에셋만 가지고도 캐릭터들을 부드럽게 애니메이팅 할 수 있었고, 이 툴과 함께 State Machine Factory 을 연동시켜 (애니메이터 함수들에 대한 콜을 스테이트 전환 시에 실행되는 람다 함수에 집어넣어) 플레이어의 상태에 따른 애니메이션 전환을 구현할 수 있었습니다.



플레이어 스테이트 머신

오디오 디자인


모든 음악 클립들을 직접 작곡하여 게임에 적용시켰고, 그 외의 SFX들은 직접 만들거나 게임의 환경에 맞도록 이펙트를 넣어 변조하여 사용했습니다. 게임의 어두운 분위기에 맞도록 던전 크롤러 게임들을 참고하여 무겁고 어두운 느낌의 앰비언트 FX를 자주 활용하였고, 몬스터의 울음소리는 제가 직접 녹음한 목소리를 자르고 변형시켜 활용하였습니다.


또, 게임 디자인의 특성상 다른 방에서 일어나는 일 (포식이의 포식) 에 대한 피드백이 제대로 주어져야 플레이어가 상황을 파악하고 그에 따라 행동할 수 있는데, 저는 이를 개별 몬스터의 울음소리로써 전달하기로 결정했습니다. 허나 다른 방에서 내는 울음소리와 같은 방에서 나는 울음소리가 같다는 것은 있을 수 없었기에 평범한 울음소리 클립과 필터가 걸린 울음소리 클립을 개별로 만들어 게임에 적용시켰습니다.



컨셉 기획서




기술적 세부사항 문서



출시 계획 문서



U.R.U.K 엔진 레퍼런스



프레젠테이션 자료




각각 게임 아이디어 소개, 베타 버전, 그리고 파이널 버전 프레젠테이션 때의 슬라이드들입니다.


이번 프로젝트를 하면서는 PPT 제작뿐만 아니라 게임의 기획 의도 설명, 그리고 게임의 데모를 직접 시연하면서 설명을 덧붙이는 등의 역할을 맡았고, 모두 대본 없이 영어로 진행하였습니다.


영어로 문서화한 디자인 요소들을 데모 시연과 함께 즉석에서 말로 바꾸어 설명함으로써, 게임의 기획 내용을 영어로 전달하는 데에 있어서의 능력을 훈련할 수 있었습니다.


동기들과 선후배분들이 참여한 상태로 발표를 진행한 후, 게임에 대한 짧은 Q&A 세션을 가진 뒤에 교수님들로부터 여러 피드백을 받고 프레젠테이션을 끝냈습니다.


개발 환경



ECS 디자인 패턴을 채용한 자체개발 엔진과 엔진 레퍼런스, 그리고 C++ 언어를 활용하여 씬 속의 여러 오브젝트들에 개별 컴포넌트들을 붙여 기능을 구현하는 식으로 개발을 진행하였고, 게임플레이 로직 파트 이외의 팀원들이 함께 개발한 State Machine Factory 툴, 2D Rigged Animation 제작 툴, 맵 에디터, 미니맵 에디터 등의 여러 자체개발 툴들을 활용하여 게임 내에 다양한 컨텐츠를 채워넣었습니다.



에디터로는 Visual Studio 2019를 활용하였으며, 하나의 큰 비주얼 스튜디오 솔루션 안에서 툴이나 게임플레이 파트별로 프로젝트를 나누는 식으로 세팅을 한 다음, 개별 브랜치에서 각자의 맡은 파트를 개발하여 추후에 모듈을 합치는 식으로 개발을 진행하였기에, 브랜치 병합 외의 이유로 인한 불필요한 충돌을 방지할 수 있었습니다.



또, 디버그와 릴리스에 시각적 디버깅용 빌드 구성을 추가하여, 빌드 구성만의 변경만으로도 시각적 디버깅을 할 수 있도록 하였습니다.


개발과정 내내 Bitbucket과 Sourcetree를 활용하여 소스 파일들을 관리하였고, Inno Setup (소개 페이지 링크) 을 활용한 윈도우용 게임 인스톨러를 만들어 배포하였습니다.


포스트모템




개발 후기



살면서 처음 써보는 장기간 프로젝트를 위한 게임 컨셉 기획서였기에 작성하는 내내 개별 기능들의 스케일을 크게 잡았는데, 아직 경험이 부족했던 만큼 디테일에 부족했던 점들이 많아 개발과정 내내 즉석에서 회의를 통해 디테일을 결정하는 일도 많았고, 개발 속도가 출시 계획을 따라가지 못해 계획되었던 기능들을 갈아엎거나 쳐내는 일이 비일비재했습니다.


기획 회의에서의 잠깐의 판단 미스가 나중에 정말로 큰 코드 구조상의 문제점으로 다가온 일도 있었고, 제 기획자로써의 실수 때문에 팀 전체가 개발 일정에 큰 손해를 보게 되었습니다. 이 경험 덕분에 기획자와 프로그래머가 개별 게임 기능들의 구현 방식의 원리, 구체적으로는 기능들 사이의 기술적인 충돌 가능성에 대해 제대로 짚고 넘어가지 않았을 경우에 생길 수 있는 문제들을 직접 경험할 수 있었고, 게임 프로그래밍에 쓰이는 각종 디자인 패턴들에 대한 이해도가 더 높았더라면 회의 시에 프로그래머와 더 자세히 얘기하여 미리 문제를 방지할 수 있지 않았을까라는 생각이 들었습니다.


프레젠테이션을 통해 교수님과 학생들 앞에서 게임의 현재 진행상황을 검증해야 하는 마일스톤 프레젠테이션이 있을 때마다 밤을 새며 작업했고, 인스톨러 제작 직전에 치명적인 버그가 여럿 터지는 바람에 마지막 주에는 아예 잠을 제대로 자지 못했는데 (결국 제출 시까지 플레이어 애니메이션 버그는 고치지 못했습니다), 이러한 힘들었던 경험 덕에 제대로 된 스코핑과 계획이 얼마나 중요한지, 기획자에게는 얼마나 다양한 능력이 요구되는지, 또, 이러한 실수들을 줄여나가기 위하여 어떤 식으로 노력해야 할지에 대해 정말로 많은 것을 깨달을 수 있었던, 힘들었지만 귀중한 경험이였습니다.

ความคิดเห็น


bottom of page