6.0 KiB
마지막수정일
| 마지막수정일 |
|---|
| 2024-03-01 |
Component 구성
컴포넌트 구성과 역할을 설명합니다.
객체
서버 내에 객체는 다음 그림과 같습니다.
MongoDB
메인 DB는 MongoDB입니다.
Collection은 다양하나, 게임 엔진에 필요한 값과 게임 엔진에 필요하지 않은 값이 분리됩니다.
분리되는 예시는 다음과 같습니다.
-
게임 내부 Collection
- 장수의 능력치
- 장수의 금/쌀
- 장수의 수비 켬/끔 여부
- 도시의 현재 스탯
- 국가의 금/쌀, 전략 수치
- 국가의 게임 내 정책(세율, 지급률)
-
게임 외부 Collection
- 장수의 메시지함
- 국가의 방침 게시물
- 국가의 회의록
- 국가간 외교 메시지
- 로그인 정보, 벌점
- 유니크 경매장 진행상태
게임 엔진
턴 실행과 관련된 게임 핵심 로직을 처리하는 엔진 컴포넌트이며, 게임 내부 Collection에 대한 쓰기 명령은 게임 엔진에서만 가능합니다.
게임 엔진은 예외적인 경우에 게임 외부 Collection의 쓰기 명령을 할 수 있지만, 게임 내부에 영향을 주지 않는 경우여야만 합니다. 만약 예전에는 게임 외부 Collection에 기록되는 데이터였다 할지라도, 게임 엔진에서 다루기 시작한다면 게임 내부 Collection으로 이관됩니다.
명령 처리 순서
게임 엔진은 내부적으로 세개의 처리 큐를 가집니다.
- 장수 처리 Queue: 턴마다 처리되는 장수 명령 처리 Queue입니다.
- NPC Action Queue: NPC의 명령을 처리하는 Queue입니다.
- NPC 명령 선택기의 입력 요청이 이곳에 쌓입니다.
- 유저 Action Queue: 유저의 명령을 처리합니다.
- API 처리기를 통해 전달됩니다.
세개의 처리 큐는 장수 처리 Queue > NPC Action Queue > 유저 Action Queue 순의 우선순위를 가집니다.
DB 반영 시점
MongoDB에 데이터가 기록되는 시점은 Queue의 아이템 하나를 해소했을 때 이루어집니다. 즉, 장수의 턴 하나가 완전히 실행되었을 때에만 DB에 반영된다고 할 수 있습니다.
게임 엔진 내에서 변경되는 내용은 메모리 내의 저장소에만 담아두고, 처리를 마치는 시점에 변경된 내용을 정리하여 한번에 쓰기 작업을 수행하여 Transaction을 모사합니다.
NPC 명령 선택기
NPC 명령 선택기는 NPC가 어떤 턴을 실행해야할지만을 연산하는 컴포넌트입니다.
NPC의 실행턴보다 일정 시간 이전에 적절한 턴이 무엇인지 계산하고, 게임 엔진으로 결과값을 전송합니다.
이때 명령의 규격은 일반 유저가 내리는 명령 규격과 유사한 형태를 갖습니다.
Note
기존 삼모전 PHP에서는 명령 선택기가 게임 엔진과 동기적으로 구성되어있었습니다.
API 처리기
API 처리기는 유저의 명령을 받아 1차적으로 처리합니다.
게임 외부 데이터에 대한 처리라면 읽기/쓰기를 모두 수행하며, 게임 내부 데이터이면 읽기 작업은 직접할 수 있습니다.
턴 입력 등 쓰기 작업이 요구되는 경우라면 게임 엔진에 해당 작업을 요청하고, 작업이 끝날때까지 기다린 다음, 엔진으로부터 결과값을 받아 반환합니다.
Warning
어떠한 경우에도 게임 내부 DB에 직접 쓰기를 해서는 안됩니다.
게임 엔진은 메모리 cache에 강력히 의존하므로, 내부 DB에 직접 쓰는 작업은 게임 엔진의 처리 결과를 훼손할 것입니다.
기존 삼국지 모의전투 PHP와 비교하여 달라진 부분
게임 엔진
PHP 버전에서 장수 처리 Queue는 sammo::TurnExecutionHelper에 해당합니다.
턴 실행 도중에 장수의 행동 또는 국가 정보가 바뀔 수 있으므로, 처리 시점에 DBMS로부터 최신 정보를 가져와 처리하고, 장수 한명의 실행이 마무리되면 모든 cache를 invalidate합니다.
이러한 처리 방법은 장수 처리 Queue 하나만으로 운영되는 형태로 생각할 수 있습니다.
NPC 명령 선택기
NPC의 실행 턴이 무엇이 될지는 엔진내에 NPC 턴 실행 직전에 결정되므로, 게임 엔진 에서 처리되어있다고 볼 수 있습니다.
sammo::GeneralAI가 처리를 전담하고 있으며, sammo::TurnExecutionHelper가 sammo::GeneralAI::chooseNationTurn(), sammo::GeneralAI::chooseGeneralTurn()를 호출하는 방식입니다.
게임 엔진과 분리되어 있지 않으므로, 턴 입력, 세율 조정 등의 작업이 직접 이루어졌습니다.
API 처리기
유기체 서버 시절에서는 c_*.php 계열 함수들이 API를 처리하는 형태였고, 이후 HiDCHe 에서 json web api 처리를 위해 j_*.php 계열 함수들이 추가되었습니다.
0.23 버전부터는 api.php를 통해 처리하는 (제대로 된)API 처리기가 도입되었습니다.
api.php?path=**/*의 경로는 sammo::API::**::*.php 이하의 클래스를 생성하고 호출합니다.
이때의 API 처리기는 게임 엔진에서 다루어야 할 데이터 변경도 같이 하고 있어 게임 엔진 측에서 조심해서 DB를 조회하도록 하여야 했습니다.
DBMS
PHP 버전에서는 MariaDB를 사용하였습니다.
다만, 게임 내의 모든 데이터를 column으로 처리하는 데에는 무리가 있어 크게 두가지 방식으로 나누어 확장 데이터를 처리하였습니다.
general,city,nation테이블에aux필드를 만들어 json으로 처리storage,nation_env와 같은 Key/Value(json) 테이블을 만들어 처리
게임 엔진의 턴 실행과 연계된 부분인가, 유저 API에 연계된 부분인가에 따라서 다르게 저장되고 있어 일관성이 떨어지는 문제가 있었습니다.
"어차피 많은 데이터가 json으로 따로 관리되니, 굳이 RDBMS일 이유가 있는가?"가 DBMS 전환의 가장 큰 이유입니다.