Game Dev – Voxel Horizon 게임서버에 NPC를 넣었다.

NPC를 넣었다.
Voxel Horizon에서는 기본적인 충돌처리를 ‘타원체 vs 삼각형’ , ‘타원체 vs 타원체’로 충돌처리를 해서 미끄러짐 벡터를 구하는 방식으로 처리하고 있다.
이런 방식에선 NPC가 복셀 사이에 걸려서 제대로 움직이지 못할 가능성이 높다. 그래서 처음부터 NPC는 넣지 않을 생각이었다.
그러나 나 혼자 이 게임을 서비스한다면 분명 서버에 동시접속자 수가 10명도 안될것이다. 혹은 로컬서버로 플레이하고 있다면 틀림 없이 플레이어 혼자일것이다.
역시 심심하지 않으려면 놀아줄 NPC가 필요하다.
그래서 복셀 지형에 대한 좀더 똑똑한 이동처리는 나중에 생각하기로 하고 NPC를 넣기로 했다.

예전에 내가 만든 게임은 NPC서버와 Game서버를 분리했었다. 그 시절엔 최대의 확장성을 고려해서 그렇게 만들었지만 경험이 쌓이니 그렇게 할 이유가 없다는 결론을 얻었다. 서버 구조만 복잡해진다. 서버간 동기화하기 힘들다. 코드 작성과 디버깅 모두 더 많은 노력이 들어가지만 막상 서버를 확장할 일은 안생긴다. 사실 내 게임과 같이 서버에서 충돌처리를 하는 방식으론 NPC서버와 게임서버가 분리될 경우 위치를 동기화시키는것도 큰 일이다. 이 때문에 먼저 프로젝트에서 게임서버와 NPC서버의 프로세스를 분리했음에도 불구하고 shared memory로 이동처리 데이터를 공유해야했다. 분산서버의 장점이 70%는 날아간것이다.
그래서 이번엔 Game서버에 바로 NPC 매니저를 구현했다.

캐릭터를 관리하고 충돌처리, 전투판정하는 코드는 NPC라고 다르지 않다. 플레이어를 처리하는 코드와 NPC를 처리하는 코드는 똑같다. 따라서 NPC의 행동을 결정하는 코드와 가상의 패킷을 처리하는 코드만 구현하면 된다.
가상의 패킷 처리라는 것은
서버가 플레이어에게 패킷을 보낼때, NPC와 플레이어의 구분 없이 SendToActor()로 패킷을 보내면 플레이어에게는 네트워크로 패킷을 보내고, NPC에게는 NPC의 Virtual Client 인스턴스로 메시지를 전달하거나 콜백을 호출하게 하는걸 말한다.
이렇게 하면 서버에서 각종 이벤트 핸들러를 작성할때 NPC와 플레이어를 구분해서 코드를 두벌씩 짤 필요가 없다.

NPC를 배치할 수 있는 툴을 만들고 NPC의 설정 데이터를 DB에 저장해야한다. 현재는 서버의 콘솔에서 NPC를 수동으로 넣을 수 있도록 했다.

이제 NPC와 전투가 가능하다.
전투중에 지형지물이 뽀개지니 새로운 느낌이다.
이 프로젝트 처음 시작할때 MSX의 Warroid라는 게임을 3D로 구현할 생각이었다. Warroid는 이 영상처럼 엄폐물을 파괴해가며 1:1 전투를 하는 게임이다.
지금은 구조물을 만들어가는 쪽으로 방향을 선회했다. 단 인스턴스 PvP던전에서의 전투는 Warroid와 같은 같은 방식으로 플레이하게 할 생각이다.


4 thoughts on “Game Dev – Voxel Horizon 게임서버에 NPC를 넣었다.

  1. 우와 진짜 재밌어 보입니다. 마인크래프트 처럼 지형이 상호 작용해서 변형이 가능하네요. 땅을 부숴서 전략을 구사할 수 있을것 같습니다.
    두번째 클라이언트 띄워서 두번째 캐릭으로 절벽위에 서있는 처번째 캐릭을 바라보는 장면에서 두근 거렸습니다. 출시되면 꼭 해보고 싶어요.

    좋아요

  2. npc 버추얼 클라이언트를 만들어서 서버쪽 모듈은 유저나 npc랑 구분없이 하나로 가고, 버추얼 클라이언트에 ai 코드 넣어서 처리하는 거 너무 기발합니다, 버추얼 클라이언트니까 자동 테스터로 사용자 가상화 해서 서버 부화 테스트 리팩토링 이후 일체점검 같은거에도 활용가능할것 같습니다. 제가 응용프로그램 개발자라 감히 댓글달기 뭐해 넘어 가려다.. 버추얼 클라이언트 좋은 영감을 받아 갑니다.

    좋아요

    1. 버추얼 클라이언트 코드를 서버 바깥으로 빼서 네트워크로 연결하면 스트레스 테스트용 더미 클라이언트가 됩니다. 실제로 그렇게 스트레스 테스트용 클라이언트를 만들어서 테스트를 합니다.

      좋아요

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중