-
스파르타) The Last Rollback (D-19, Node.js 게임 서버 최종 프로젝트)TIL-sparta 2024. 8. 9. 22:41
학습 키워드: Node.js, Bull queue
트러블 슈팅
1) 몬스터 동시 처치 원자성 문제 해결:
(상세 변경 사항은 위 commit 참고)
현재 개발중인 게임은 구조상 몬스터 웨이브를 막다보면 킬 경쟁이 일어날 수 밖에 없다. 그런데 여러명의 유저가 동시에 하나의 몬스터를 잡기 위해 공격하다보면 마지막 일격을 여러명이 가하는 상황이 생긴다. 문제는 몬스터에게 피해를 입히는 패킷을 전송했을 때 서버에서 마지막 일격을 가한 유저에게 보상을 주면서 동시에 웨이브의 kill count를 올려주고 있는데, 이 작업이 원자적으로 이루어지지 않아서 값이 두 번 올라가면서 웨이브 몬스터가 모두 처치되지 않은 상황에서 갑자기 라운드가 종료되어 버리는 현상이 생겼다. 마지막 남은 몬스터가 보스 몬스터인 경우가 많기 때문에 보스를 잡다가 도중에 몬스터가 증발해버려서 쉽게 눈치챌 수 있었다.
문제도 인지하고 있었고 해결 방안 또한 알고 있었으나 빠른 기능 개발에만 몰두하다 보니 서버 코드가 난잡하게 작성되어 있어 Bull queue 도입을 미루고 있었다. 결국 시연을 하기 위해서는 이 문제의 해결을 더 이상 미룰 수 없다고 판단해서 코드를 수정하게 되었다.
현재 몬스터를 공격하기 위한 통신 구조는 플레이어가 몬스터를 공격할 때 우선적으로 공격 자체가 유효한지를 판단하기 위해 C_PlayerAttack이라는 패킷을 서버에 전송한 뒤, 검증이 완료되면 공격을 허가하는 S_PlayerAttack 패킷을 보내게되고, 해당 플레이어의 공격이 발생하면서 몬스터가 피격 당하는 순간 C_MonsterAttacked 패킷이 발생한다. 이 패킷을 서버의 attackedMonsterHandler에서 처리해주고 있었는데, Bull 큐로 데미지 판정을 구현하려면 해당 위치와 dungeon.class.js에 구현된 코드 모두를 수정해줄 필요가 있었다.
이전에 match_queue를 구현했던 방식과 비슷하게 consumer, producer, processor 함수 들을 정의하고, attackedMonsterHandler가 받은 내용을 큐에 넣어서 체력 감소 및 사망 판정을 순차적으로 진행하도록 변경했다. 몬스터 피격 프로세스 전체의 코드 자체가 상당히 길어서 이를 모두 동기적으로 처리하면 몬스터 체력 감소가 늦어져 유저 경험이 나빠질 수 있다. 그러므로 dungeon.class.js의 updatePlayerAttackMonster 메서드에서 체력 감소와 사망 상태 검증 부분까지만 동기적으로 진행하고 나머지 부분을 비동기 처리하여 processor 함수가 다음 작업을 빠르게 진행할 수 있게 조정했다.
--
REFERENCES:> 프로젝트 repo
728x90'TIL-sparta' 카테고리의 다른 글
[Docker] Docker Desktop 사용해보기 (0) 2024.08.11 스파르타) The Last Rollback (D-18, Node.js 게임 서버 최종 프로젝트) (0) 2024.08.09 스파르타) The Last Rollback (D-20, Node.js 게임 서버 최종 프로젝트) (0) 2024.08.07 스파르타) The Last Rollback (D-21, Node.js 게임 서버 최종 프로젝트) - latency, timer (0) 2024.08.07 스파르타) The Last Rollback (D-22, Node.js 게임 서버 최종 프로젝트) - buffer, bull queue, JSON circular structure (0) 2024.08.06