본문 바로가기

관심분야/게임

게임 컨텐츠 구현을 위한 V8 Javascript엔진..

저는 현재, 타이틀과 마찬가지로, Google의 V8 Javascript엔진을 게임개발에 사용하고 있습니다.


이러한 방식으로, 서비스를 만들고, 클라이언트와 통신을 합니다.


var wsaio = new WSAIO();

var l = wsaio.listen(8080, 10);


l.onreceive = function (fd, bson) {

    print("RECV: " + process.id + " " + fd);

};


l.onconnection = function (fd, addr) {

    print("CONNECTION: " + process.id + " " + JSON.stringify(addr));

    l.forEach(function (fd, o) {

        print("FOREACH: " + fd + " => " + JSON.stringify(o));

    });


    l.name = "New";

    process.nextTick(function () {

        wsaio.write(fd, {

            "name": "Hello"

        });

        wsaio.flush(fd);

        wsaio.forEach(fd, function (f, o) {

            print("FOREACH: " + f + " => " + JSON.stringify(o));

        });

    });

};


l.ondisconnection = function (fd) {

    print("DISCONNECTION: " + process.id + " " + fd);

};


이는 일반적으로 여러분이 생각하시는, 그 범위를 넘어서는 범위까지 입니다.


단순히, 비교하자면 NODE.JS와 비슷한 기능을 하는 프레임워크를 만들었다고 생각하시면 됩니다.


   잠깐, 겻다리로 말씀을 드리자면


   제가, V8 Javascript를 게임개발에 사용하고자 생각하고 시도를 했던건 벌써 3년전으로 거슬러 

   올라갑니다. 


   사용하고자 했던, 이유는 단순했습니다. 

   

       컨텐츠를 구현하는데 빠르게 개발하고 유지보수도 쉽게 하고 싶었기 때문입니다. 

       ' 서버 개발자를 구하기 어려운것도 한 몫했습니다.


   그런데, 접근이 쉽지가 않았습니다. 물론, 그 당시에도 NODE.JS가 존재 했습니다. 


   NODE.JS.


   그런데, 제가 원하는 구성을 하기에는 몇가지 문제가 있었습니다.


          1. 클라이언트/서버/데이터베이스의 자료형이 일관성 있게 사용하기를 원했습니다.

             예를 들어, 데이터베이스의 테이블에서 userid를 int로 사용했다면, 클라이언트까지 

             userid가 int로 전달되기를 원했습니다.


             Javascript는 배열(Array), 오브젝트(Object), 문자열(String), 숫자형(Double), 

            불리안(Boolean) 만을 지원합니다.

             그러나, 클라이언트와 데이터베이스는 수많은 자료형이 있습니다.


          2. 데이터베이스의 변경되는 내용에 대한 강력한 로깅기능이 필요했습니다.

             단순히, 개발을 하면서 아이템을 획득했다 라는 식의 로깅이 아니라, 플레이어는 아이템을

            획득하기 위해 어떠한 동작들이 이루어 졌고, 그 동작으로 인해 어떠한 테이블의 데이터들이

            변경되었는지에 대한 로깅을 원했습니다.

 

          3. 병렬처리가 가능한 프로세서 구성이 필요했습니다.


              게임을 만들다 보면, 하나의 프로세서가 모든 형태의 역활을 수행할수 없습니다. 

                  이러한 이유로, 컨텐츠 서버/PVP/채팅/로그인 등등의 역활을 하는 서버를 지정하게 

                  됩니다.

              이러한 역활의 구성을 쉽게 하기를 원했습니다.

          

          4. Fail-Over가 필요했습니다.

              완벽한 서버는 없습니다. 그렇기에, 서비스의 연속성을 가질 필요가 있습니다. 죽었다면, 

              다시 살아나야 했고..


          5. 무정지 업데이트가 필요했습니다.


     대부분의 기능을 NODE.JS의 PLUGIN으로 만들어 볼까 했는데.. PLUGIN으로 기능을 구현하는데는 한계가 있었습니다.


     처음 시도를 한 3년 전에는 V8 Javascript의 메모리 관리상의 이슈를 해결하지 못하여, Lua로 대체하여 사용하였으나,


     지금 하는 프로젝트에서는 V8 Javascript를 사용하고 있습니다.


지금 생각해보면, 이러한 방식의 개발은 많이 무모한 도전이었습니다. 배보다 배꼽이 더 큰 상황입니다. 


그런데도 이러한 방식으로 개발을 한 이유는, 퀄리티를 보장하기 위한 대안이 필요했기 때문입니다.


   기존의 개발 방법으로 개발을 하다 보니  런칭이 가까워 질수록 많아지는게 버그이며 모자라는게 

   시간이 되는 상황이 자주 발생되었습니다.


  이 상황을 자주 겪다보니 몇가지 요령이 생기기 시작하였습니다.


   - 자주 사용하는 기능을 묶어서 라이브러리화

   - 템플릿 형태로 소스의 개발을 패턴화


   처음에는 크리티컬한 이슈를 많이 줄이고 개발도 빠르게 진행이 되었으나, 이렇게 해도 

   문제가 해결되지 않습니다. 

   개발을 하는 개발자의 실력 차이는 어쩔수 없고, 오히려 버그는 더 찾기 어렵게 될 뿐이었습니다.


개발의 자유도를 유지하면서, 결과물에 대한 퀄리티를 보장하는 방법.


이러한 결과를 얻기위해서 만들어야 하는 프레임워크는 개발 난이도가 아주 높았고, 리스크도 크지만, 별다른 선택의 여지가 없다보니

단순하게 "그냥 만들자" 라고 시작을 했었습니다. 


그래서 첫 모델이 3년전에 나왔고, 지금 사용하는 모델은 최근이 완성이 되어서 개발에 사용하고 있습니다.


상용으로 판매되는 몇몇 서버엔진과는 틀린 접근 방식이지만,  접근성은 훨씬 쉽죠^^ 


지금은, 컨텐츠 개발을 위해 좀더 많은 시간을 투자할수 있다는 장점과, 개발자를 채용에 자유로워 지는 장점이 생겼습니다.



끝으로.. 이제 시간이 허락하는 대로, 개발하면서 정리한 TIP들을 올려볼까 합니다.