Skip to content

Commit a8b5694

Browse files
committed
docs: 프로젝트 설명(README) 최신화
1 parent ec36583 commit a8b5694

11 files changed

Lines changed: 252 additions & 94 deletions

File tree

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ packages/
1414
db.config
1515

1616
## [ 로그 ]
17-
*.log
17+
*.log
18+
/Manager/QuestManager.cs
19+
/C#_GameServer.csproj
20+
/GameObject/Quest.cs

C#_GameServer.csproj

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
</PropertyGroup>
3737
<ItemGroup>
3838
<Compile Include="Common\Packet.cs" />
39+
<None Include="CsharpGameServer-Doc\doc\networking.md" />
3940
<Compile Include="DataManage\ItemData.cs" />
4041
<Compile Include="DataManage\MapData.cs" />
4142
<Compile Include="DataManage\NpcData.cs" />
@@ -54,7 +55,6 @@
5455
<Compile Include="GameObject\Map.cs" />
5556
<Compile Include="GameObject\Monster.cs" />
5657
<Compile Include="GameObject\Player.cs" />
57-
<Compile Include="GameObject\Quest.cs" />
5858
<Compile Include="DataManage\DataManager.cs" />
5959
<Compile Include="Game\Dialogue\DialogueAcceptDecline.cs" />
6060
<Compile Include="Game\Dialogue\DialogueBase.cs" />
@@ -69,7 +69,6 @@
6969
<Compile Include="Manager\LoginManager.cs" />
7070
<Compile Include="DataManage\MonsterData.cs" />
7171
<Compile Include="Manager\NpcManager.cs" />
72-
<Compile Include="Manager\QuestManager.cs" />
7372
<Compile Include="Manager\MapManager.cs" />
7473
<Compile Include="Network\PacketHandler.cs" />
7574
<Compile Include="Network\PacketMaker.cs" />
@@ -197,8 +196,16 @@
197196
</ItemGroup>
198197
<ItemGroup>
199198
<None Include="App.config" />
199+
<None Include="CsharpGameServer-Doc\doc\architecture.md" />
200+
<None Include="CsharpGameServer-Doc\README.md" />
200201
<None Include="packages.config" />
201202
<None Include="protocol.proto" />
203+
<None Include="README.md" />
204+
</ItemGroup>
205+
<ItemGroup>
206+
<Content Include="classDiagram.png" />
207+
<Content Include="image01.PNG" />
208+
<Content Include="sequenceDiagram.png" />
202209
</ItemGroup>
203210
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
204211
<Import Project="packages\System.ValueTuple.4.6.1\build\net471\System.ValueTuple.targets" Condition="Exists('packages\System.ValueTuple.4.6.1\build\net471\System.ValueTuple.targets')" />

CsharpGameServer-Doc/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# C# GameServer
2+
3+
## 아키텍처
4+
- [클래스 구성](./doc/architecture.md)
5+
6+
## 네트워킹
7+
- 네트워킹 개요
8+
- [메모리 단편화](./doc/networking.md)
9+
- 세션 파이버
10+
- 로그인 과정
11+
- 메시지 송수신
12+
- 메시지 핸들링
13+
14+
## 3. 주요 기능 구현 목록
15+
* IOCP
16+
* 싱글 스레드 게임 로직 처리
17+
* 로그인
18+
* 세션 관리
19+
* 플레이어 상태 관리
20+
* 몬스터 AI
21+
*
22+
* 인벤토리
23+
* 퀘스트 시스템
24+
* JSON 기반 리소스 로드 시스템
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# 시스템 아키텍처 및 클래스 구성
2+
- 프로그램 메인
3+
- Program.cs: 서버 초기화 및 실행 진입점
4+
5+
- 게임 로직 스레드
6+
- GameLogicThread.cs: 게임 로직 처리 및 일정한 틱 레이트 유지
7+
8+
- 게임 데이터 관리
9+
- DataManager.cs: 게임 데이터 관리 [싱글톤]
10+
- MonsterData.cs: 몬스터 데이터 로드 및 관리
11+
- MonsterTemplate.cs: 몬스터 템플릿 정의
12+
- ItemData.cs: 아이템 데이터 로드 및 관리
13+
- ItemTemplate.cs: 아이템 템플릿 정의
14+
- MapData.cs: 맵 데이터 로드 및 관리
15+
- MapTemplate.cs: 맵 템플릿 정의
16+
- QuestData.cs: 퀘스트 데이터 로드 및 관리
17+
- QuestTemplate.cs: 퀘스트 템플릿 정의
18+
19+
- 패킷 처리
20+
- Packet.cs: 패킷 정의 및 직렬화/역직렬화 구현
21+
- PacketHandler.cs: 패킷 처리 로직 구현
22+
- PacketMaker.cs: 패킷 생성
23+
- PacketSerializer.cs: 패킷 직렬화
24+
- RecvBuffer.cs: 수신 버퍼 관리
25+
- ~~PacketParser.cs: 패킷 역직렬화~~ (미리 역직렬화하여 게임로직스레드의 부하를 줄이려고 테스트 해봤으나 효과가 크지 않았음)
26+
- ~~Protocol.cs: 패킷 정의~~ Google Protocol Buffers를 활용하여 JSON Serializition 비용을 줄이려고 테스트 해봤으나 효과가 크지 않았음)
27+
28+
- 네트워크 및 세션
29+
- SessionManager.cs: 세션 관리 및 연결/해제 처리
30+
- UserSession.cs: 네트워크 처리(IOCP)를 담당하는 세션 객체
31+
32+
- 로그인
33+
- LoginManager.cs: 로그인 처리 및 세션 관리
34+
35+
- DB 제어
36+
- DbTransactionWorker.cs: 큐에 들어오는 DB 작업을 처리하는 워커 스레드 생성 및 처리 [싱글톤]
37+
- DbManager.cs: CRUD 함수가 구현된 곳
38+
- DbJob.cs: DB 작업 정보를 담는 클래스 (나중에 추가확장 가능. 예: 작업 우선순위, 재시도 횟수 등)
39+
- RequestDto.cs: DTO 정의 클래스
40+
41+
- 게임 시스템
42+
- 플레이어
43+
- PlayerManager.cs: 플레이어 관리 [싱글톤]
44+
- Player.cs: 플레이어 정보 및 상태 관리
45+
- 인벤토리
46+
- Inventory.cs: 인벤토리 관리 (플레이어에 붙는 컴포넌트)
47+
- 퀘스트
48+
- QuestComponent.cs: 퀘스트 진행 상태 관리 (플레이어에 붙는 컴포넌트)
49+
- QuestProgress.cs: 퀘스트 진행 상태 정보
50+
- QuestCondition.cs: 퀘스트 조건 정보
51+
- 맵
52+
- MapManager.cs: 맵 관리 [싱글톤]
53+
- Map.cs: 맵 정보 및 해당 맵에서 발생하는 모든 이벤트 처리
54+
55+
- 몬스터
56+
- Monster.cs: 몬스터 정보 및 상태 관리
57+
- NPC
58+
- NpcManager.cs: NPC 대화 처리 및 퀘스트 수락/진행/완료 처리 [싱글톤]
59+
- 아이템
60+
- ItemManager.cs: 퀘스트 컴포넌트에서 보상지급 시 사용되는 아이템 생성 DB 요청 로직을 따로 분리함
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# 네트워킹
2+
- IO 스레드 개수 8개로 설정
3+
- IO스레드는 CLR의 스레드풀을 활용
4+
- 물리가 아닌 논리프로세스 개수 만큼 설정하는 이유는 레지스터가 논리프로세스 수 만큼 있기 때문에 컨텍스트 스위칭이 발생하지 않기 때문
5+
- 캐시는 물리 개수 만큼 있지만 두 스레드가 같은 데이터를 읽고 있다면 성능상 이점이 생긴다(캐시히트라고 함. 반대의 경우는 캐시오염)
6+
- 특정 논리 프로세서에 붙이는 방법은 ProcessThread.ProcessorAffinity 설정
7+
- IOCP는 자체적으로 캐시히트율을 높이기 위해 가장 최근에 일을 마친 스레드를 먼저 깨우고 있음
8+
9+
## 메모리 단편화
10+
- 85KB 이하는 SOH(Small Object Heap)에 할당됨
11+
- GC가 압축을 할 때 Pinning(고정)된 객체 때문에 단편화가 발생
12+
- Pinning은 IO작업 중일 때 발생
13+
- 그래서 버퍼를 85KB 이상으로 할당하여 LOH(Large Object Heap)에 할당되도록 함
14+
- LOH는 GC가 압축을 기본적으로 하지 않음 (2세대 GC에서는 압축)
15+
- LOH의 단편화도 문제가 되지만 ArrayPool을 사용하여 단편화 문제를 완화했음
16+
17+
## SocketAsyncEventArgs
18+
- 기존방식: BeginReceive를 호출할 때마다 내부적으로 IAsyncResult 객체가 생성되고 소멸됨. 매우 비효율적
19+
- SocketAsyncEventArgs는 미리 만들어두고 재사용이 가능함. 현재 풀링방식으로 구현해놓지 않았음. 세션 내에서만 재사용 중

GameObject/Quest.cs

Lines changed: 0 additions & 69 deletions
This file was deleted.

Manager/QuestManager.cs

Lines changed: 0 additions & 20 deletions
This file was deleted.

README.md

Lines changed: 136 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,136 @@
1-
# C-_GameServer
2-
마비노기 모바일 실버바인 서버엔진2 따라 구현하기
1+
# 🚀 C# Game Server
2+
> **NDC2018 [실버바인 서버 엔진 2] 설계 리뷰를 바탕으로 재구성한 C# IOCP & Stackless Fiber 서버**
3+
4+
---
5+
6+
## 1. 프로젝트 소개
7+
- 프로젝트 명: C# GameServer (Silvervine Engine 2 Reference)
8+
- 설명: 마비노기 모바일에서 사용된 실버바인 서버 엔진의 구조를 학습하고 IOCP 기반의 비동기 소켓 통신과 싱글 스레드 게임 로직 처리를 C#으로 구현한 프로젝트
9+
10+
## 2. 핵심 기술 스택
11+
- 언어: C#
12+
- 네트워크: IOCP
13+
- 데이터 형식: JSON[리소스 로드, 패킷 직렬화(일부는 ProtoBuf 테스트 사용)]
14+
- 데이터베이스: MySQL, Dapper(ORM)
15+
- 로깅: Serilog(Seq 연동)
16+
17+
## 3. 아키텍처
18+
19+
### 🏗️데이터 흐름도
20+
> 클라이언트의 요청이 IOCP를 통해 수신되어 싱글 스레드 게임 로직에서 처리되고, 비동기 DB 작업으로 이어지는 전체 파이프라인
21+
22+
![sequenceDiagram](./sequenceDiagram.png)
23+
24+
### 🧱서버 컴포넌트 구조
25+
> 서버의 주요 도메인 간의 관계와 구조
26+
27+
![classDiagram](./classDiagram.png)
28+
29+
### ⚡실버바인 서버엔진2 아키텍처 따라하기
30+
- **Stackless Fiber 기반 로직 처리**
31+
- 실버바인의 Stackful Fiber 구조를 분석하여 C#의 `async/await`와 Task를 활용하여 `Stackless` 방식으로 구현
32+
- 비동기 IO 대기 구간이 포함된 로직을 동기식 순차 코드처럼 작성할 수 있게 하여 생산성을 높이는 구조로 설계
33+
- **Single-Thread Game Loop**
34+
- 모든 게임 로직을 `싱글 스레드` 루프에서 순차적으로 처리하여 `데이터 일관성`을 보장
35+
- 멀티스레드 환경의 `경쟁상태`와 `데드락` 문제를 근본적으로 제거하여 로직 설계 난이도를 낮춤
36+
- **Job Queue 시스템**
37+
- `네트워크 IO` 와 `DB` 작업을 `게임 로직 스레드`와 분리하여 병목 현상 없는 구조로 설계
38+
39+
### 📈 성능 지표
40+
- **처리량:** 동시 접속자 500명, 초당 10만 패킷(이동 패킷 200/s) 무난하게 처리 가능
41+
- **안정성:** 대규모 브로드캐스팅 상황에서도 **평균 루프 타임 8ms** 미만 유지(루프는 몬스터, 플레이어 브로드 캐스트 로직도 처리 중인 상태)
42+
43+
### 🌐 네트워크
44+
- **IOCP 기반 비동기 네트워크**
45+
- 적은 수의 스레드로 여러 접속자를 효율적으로 처리
46+
- 세션마다 버퍼풀과 SocketAsyncEventArgs를 활용하여 GC 부담을 최소화
47+
- ArraySegment를 활용하는 RecvBuffer 클래스를 통해 메모리 절약
48+
49+
### 💾 데이터베이스
50+
- **비동기 DB 워커**
51+
- 별도의 DB 전용 스레드로 분리하여 게임 로직의 중단(Blocking) 없이 안전하게 데이터를 저장하고 불러올 수 있도록 설계
52+
53+
### 🎮 MMORPG 게임 콘텐츠 시스템 구성
54+
| 시스템 명칭 | 주요 역할 및 상세 기능 |
55+
| :--- | :--- |
56+
| **인증 시스템** | 클라이언트 접속 제어, DB 연동을 통한 사용자 인증 및 캐릭터 정보 로딩 |
57+
| **엔티티 관리** | **플레이어****몬스터** 객체의 생명주기 및 상태 관리 |
58+
| **월드 시스템** | 게임 내 **** 데이터 관리 및 구역별 엔티티 동기화 |
59+
| **상호작용 시스템** | **NPC** 대화, **퀘스트** 수락/완료 로직 및 보상 처리 |
60+
| **아이템 시스템** | **인벤토리** 관리, 아이템 획득 및 사용 로직 처리 |
61+
| **리소스 로드 시스템** | **JSON 기반 리소스 관리 클래스**를 통해 코드 수정없이 콘텐츠 확장 가능 |
62+
63+
### 📂 프로젝트 구조
64+
```text
65+
Root/
66+
├── GameLogicThread.cs
67+
├── Program.cs
68+
├── Protocol.cs
69+
├── protocol.proto
70+
├── Common/
71+
│ └── Packet.cs
72+
├── DataManage/
73+
│ ├── DataManager.cs
74+
│ ├── ItemData.cs
75+
│ ├── MapData.cs
76+
│ ├── MonsterData.cs
77+
│ ├── NpcData.cs
78+
│ ├── QuestData.cs
79+
│ └── DataManage/Template/
80+
│ ├── ItemTemplate.cs
81+
│ ├── MapTemplate.cs
82+
│ ├── MonsterTemplate.cs
83+
│ ├── NpcTemplate.cs
84+
│ └── QuestTemplate.cs
85+
├── DB/
86+
│ ├── DbManager.cs
87+
│ ├── DbJob.cs
88+
│ ├── DbTransactionWorker.cs
89+
│ └── Dto/
90+
│ └── RequestDto.cs
91+
├── Game/
92+
│ ├── Game/Dialogue/
93+
│ │ ├── DialogueBase.cs
94+
│ │ ├── DialogueSimple.cs
95+
│ │ ├── DialogueOk.cs
96+
│ │ ├── DialogueNext.cs
97+
│ │ ├── DialogueAcceptDecline.cs
98+
│ │ └── DialogueSelection.cs
99+
│ └── Game/Quest/
100+
│ ├── QuestComponent.cs
101+
│ ├── QuestCondition.cs
102+
│ └── QuestProgress.cs
103+
├── GameData/
104+
│ ├── Item/ (Item01.json ~ Item04.json)
105+
│ ├── Map/ (Map01.json)
106+
│ └── Monster/ (monster01.json ~ monster03.json)
107+
├── GameObject/
108+
│ ├── Player.cs
109+
│ ├── Monster.cs
110+
│ ├── Map.cs
111+
│ └── Inventory.cs
112+
├── Manager/
113+
│ ├── PlayerManager.cs
114+
│ ├── MapManager.cs
115+
│ ├── SessionManager.cs
116+
│ ├── LoginManager.cs
117+
│ ├── NpcManager.cs
118+
│ └── ItemManager.cs
119+
└── Network/
120+
├── UserSession.cs
121+
├── PacketHandler.cs
122+
├── PacketMaker.cs
123+
├── PacketSerializer.cs
124+
├── RecvBuffer.cs
125+
└── PacketParser.cs
126+
```
127+
128+
## 4. 설계 상세 및 문서
129+
- **[C# GameServer 문서](./CsharpGameServer-Doc/README.md)**
130+
131+
## 5. 구동 이미지
132+
![ServerScreen](./image01.PNG)
133+
134+
## 🔗 관련 링크
135+
- [실버바인 서버 엔진 2 설계 리뷰 (NDC2018)](http://ndcreplay.nexon.com/NDC2018/sessions/NDC2018_0075.html)
136+
- [C# GameServer 클라이언트](https://github.com/devhwan0421/MiniRPG)

classDiagram.png

48.5 KB
Loading

image01.PNG

34.2 KB
Loading

0 commit comments

Comments
 (0)