lee-seungjae.github.io

모 MMORPG에서 쓴 언어들

2010-08-12

C++

클라이언트와 서버, 그리고 일부 툴. 달리 설명이 필요한가?

C#

퀘스트 툴처럼 복잡한 UI가 필요하거나, 엑셀 파일을 익스포트 없이 직접 읽고 싶은 경우 닷넷프레임워크 환경에서 작업하면 작업 속도가 매우 빠르다. 게다가 자바를 써 본 프로그래머라면 금방 적응할 수 있다.

다만 대부분의 툴은 어쨌거나 게임 로직을 많든 적든 알고 있어야 하는데, 툴을 게임 코드와 다른 언어로 작성할 경우 같은 내용의 코드를 중복해서 만들게 된다. 이 비용이 만만치 않을 수 있으니 잘 생각해야 한다. XML스러운, 양쪽 언어에서 편하게 읽고 쓸 수 있는 표현법을 확보해 두는 건 필수다. 아니면 편집 관련된 핵심 코드도 C++로 짜서 툴에 링크하고 툴 코드는 GUI 역할만 할 수도 있는데.. 방법에 따라 정도의 차이는 있겠지만 어쨌거나 언어 사이를 넘어다니는 일은 몹시 피곤하다(아예 CLR이나 JVM 위에서 다 짤 거면 논외-_-).

C++/CLI

이펙트 툴, GUI 툴에 들어갔다. 네이티브 C++로 만든 엔진을 닷넷프레임워크 코드와 붙이려면 이걸 통해야 한다.

추가된 문법이 좀 있는데 모양만 봐서는 알 수 없으니 공부를 해야 한다.

내가 직접 만진 적은 거의 없지만 뭔가 알고싶지 않은 미묘한 문제에 고생했던 기억이 몇 번 있다. 단지 익숙한 도구가 아니기 때문일 수도 있으나… 어쨌든 인상이 별로 좋지 않다.

FSM

유한상태기계를 표현하기 위한 언어. 플레이어 캐릭터의 조작법을 서술하기 위해 새로 만들었다. 일반적인 프로그래밍 언어로서의 표현력은 떨어지지만, 스크립트 언어 치고 오버헤드가 작고, 표현에 군더더기가 없어서 복잡한 로직도 쉽게 읽고 쓸 수 있다.

FSM에서 트랜지션이 발생할 때 해당 트랜지션을 나타내는 고유번호만 다른 클라이언트에 보내면, 받은 곳에서는 그 고유번호에 해당하는 액션들을 재생해 주면 거의 코딩 오버헤드 없이 플레이어 캐릭터의 행동을 다른 클라이언트에서 재생할 수 있었다.

오픈베타를 시작하고 나서 FSM과 관련된 버그들이 자꾸 튀어나왔다. 대시하다가 배경 오브젝트를 조사하면 움직이지 못하게 된다든지, 탱이를 든 채로 공중에서 NPC에게 말을 걸면 얼어버린다던지 하는 버그인데, 대체로 C++단에서 가지고 있는 '상태' 와 FSM의 상태가 서로 모순되는 경우였다. 매번 문제를 해결하고 다른 문제가 없다는 것을 증명하기가 몹시 까다로웠다. 케이스 바이 케이스로 해결하기보다 설계상의 문제점을 해결하는 것이 바람직하지만, 프로젝트 종료 시점까지 그럴 기회는 생기지 않았다.

FSM은 몬스터 인공지능에도 도입했다. 가장 추상적인 차원에서 몬스터의 상태와 행동을 기술하는 데 썼다. 문법이 간단하기 때문에 .fsm 파일을 몬스터 종류별로 추가하기를 의도했으나, 몬스터의 변종이 굉장히 많아지면서 담당자가 GG를 쳐버렸다. 결국 대부분의 몹 인공지능을 커버할 수 있는 수퍼 AI파일을 만들고, 실제로 몹별로 필요한 AI는 서버가 뜨는 시점에 텍스트 전처리를 통해 생성했다.

루아

서버의 맵별 스크립트에 썼다. 인던에서 어떤 몹이 어느 위치에 언제 젠될지 같은 걸 서술했다. 프로그래머가 C++로 기능을 만들고 루아 코드도 좀 섞어서 스크립트 담당자가 쓰기 좋은 환경을 만들었다(코루틴과 타이머를 래핑해서 Sleep 같은걸 만든다든지).

PvP맵도 플레이어끼리 공격가능여부 등의 설정과 누가 누굴 쓰러뜨렸다는 콜백 정도만 C++로 빼고 대부분의 로직을 맵 스크립트로 만들었다.

나중에는 몬스터 AI(.fsm)와 맵별 스크립트가 통신할 방법이 없어서 구현하지 못한 기획도 있었다. 좀 더 오래 서비스했다면 아마 서로 통신할 수 있는 채널을 만들었을 것이다. 처음부터 몬스터 AI도 루아로 짰으면 개발이 편했을 것 같은데, CPU를 얼마나 더 잡아먹게 될지가 궁금하다.

막판엔 클라이언트에도 넣었다. PVP 맵에서만 나오는 UI에 적용했는데, 서버 스크립트에 의해 온전히 제어되는 형태였다. 좀더 일찍 넣지 않은 것을 후회했다. 초반에 작업한 거대 보스에도 스크립트를 적용했으면 거대 보스를 더 쉽게 많이 만들 수 있었을 것이고, UI 라이브러리와 툴에 통합했으면 복잡한 UI의 동작을 서술하고 테스트하기 편했을 것이다.

이벤트(언제부터 언제까지 경험치 두 배! 따위)를 기술하는 데도 루아를 썼다. 물론 맵 스크립트와 별도 VM에서 돌았다. 이것도 reload 가능하게 만들었고, 운영툴에서 reload 명령을 내릴 수 있도록 했다. 직접 관련없는 얘기긴 하지만 날짜/시간 관련된 로직(기간제한템, 하루에 한번씩 지급하는 물건 등)은 테스트하기 정말 지저분하고 실수가 눈에 잘 띄지 않으니, 현재 날짜/시간을 얻는 부분을 간접계층으로 빼내고 TDD하도록 하자.

PHP

운영툴.

배치파일

빌드, 패키징, 팀내 배포 스크립트.

목록으로
@0xcafea1fa RSS