이 영상은 게임 클라이언트와 서버가 주고받는 패킷을 Protobuf(.proto) 한 파일로 정의하고, 같은 파일에서 생성한 코드로 봇 클라이언트까지 만드는 흐름을 보여 준다. 봇이 클라·서버와 같은 생성 코드를 쓰기 때문에 패킷 구조가 어긋나지 않고, 그 봇 하나를 서버 컨텐츠 검증과 퍼블리셔의 부하 테스트에 그대로 재사용할 수 있다.
왼쪽 에디터에 game_packet.proto 파일이 타이핑된다. syntax = "proto3";, package game; 아래에 LoginReq(account_id, token), EnterDungeonReq(dungeon_id, party_id), SkillUseReq(skill_id, target_id) 세 메시지가 선언된다. 각 필드에는 타입과 번호(= 1, = 2)가 붙는데, 이 번호가 직렬화된 바이트 안에서 필드를 구분하는 태그다.
오른쪽 카드 세 장이 이 파일의 성격을 정리한다.
- message = 패킷 하나: 필드 이름, 타입, 번호(tag)를 선언한다.
- 언어 중립 스키마: C#, C++, Go 등 원하는 언어로 코드를 생성할 수 있다.
- Single Source of Truth: 패킷의 원본은 이 파일 하나뿐이다.
인프라 쪽 감각으로 보면 API 스펙 파일 하나를 두고 모든 소비자가 그 스펙에서 코드를 뽑아 쓰는 구조와 같다.
.proto 카드에서 출발한 선이 가운데 protoc(codegen) 노드를 거쳐 오른쪽 세 카드로 갈라진다. Client(Unity · C#, GamePacket.cs), Server(C++, game_packet.pb.h), Bot Client(C# .NET, GamePacket.cs)다. 각 카드에는 EnterDungeonReq에 해당하는 생성 코드가 찍힌다. C# 쪽은 DungeonId, PartyId 속성, C++ 쪽은 dungeon_id(), party_id() 접근자다.
봇 카드에는 "클라와 같은 생성 코드를 그대로 사용"이라는 주석과 함께 new EnterDungeonReq { DungeonId = 101, PartyId = party.Id }로 패킷을 만드는 코드가 나온다. 봇도 손으로 바이트를 짜지 않고 클라와 같은 클래스를 쓴다는 뜻이다.
화면 문구는 "protoc 한 번 → 클라 · 서버 · 봇", "같은 .proto에서 생성 → 구조가 그대로 일치"다. 세 코드가 같은 스키마에서 나왔으니 필드 이름, 타입, 번호가 서로 다를 수 없다.
같은 화면에서 .proto의 EnterDungeonReq에 int32 difficulty = 3; 한 줄이 초록색으로 추가되고 버전 칩이 v1.3에서 v1.4로 바뀐다. 펄스가 protoc를 지나 세 카드에 동시에 도착하면 Client에는 Difficulty 속성, Server에는 difficulty() 접근자, 봇에는 같은 Difficulty 속성이 생긴다. 봇 카드의 Difficulty = 3, 줄에는 "시나리오에서 값 지정" 라벨이 붙는다. 재생성은 구조만 만들고, 값을 넣는 시나리오 코드는 사람이 쓰기 때문이다. 세 카드 모두 v1.4와 체크 배지를 단다.
왼쪽 아래에는 비교 대상으로 빨간 점선의 "손으로 짠 봇 패킷" 카드가 나온다. 버전은 v1.3에 머물러 있고 "번호 · 타입 수동 관리 → 어긋나면 서버가 잘못 파싱", "→ 테스트 결과를 믿을 수 없음"이라는 문구와 함께 X 표시가 붙는다.
문구는 "필드를 추가해도 재생성 · 재빌드 한 번이면 끝", "봇 패킷 구조가 클라 · 서버와 자동으로 같이 갱신"이다. 봇 · 클라 · 서버를 같은 .proto 리비전으로 다시 빌드해야 하므로 보통 CI에서 재생성을 강제한다. 봇을 별도로 손으로 유지하면 스키마가 바뀔 때마다 누군가 따라 고쳐야 하고, 그걸 놓치면 봇이 실제 클라와 다른 패킷을 보내게 된다.
앞부분은 주차별 간트 차트다. 서버팀의 "던전 컨텐츠 서버 로직"은 W3에 끝나고, 클라팀은 W7까지 "UI · 연출 · 리소스 작업 중…"이다. NOW 표시가 W3 끝에 오면 남는 빈 구간에 "클라 연동까지 대기…?"가 떴다가 "봇 클라이언트로 바로 컨텐츠 테스트" 막대로 바뀐다. 화면 문구는 "서버는 보통 클라보다 먼저 컨텐츠를 완성합니다.", "기다리지 말고, 봇이 클라 대신 패킷을 보내 검증합니다."다.
뒷부분은 Bot Client와 Game Server 사이의 시퀀스 다이어그램이다. 순서는 다음과 같다.
LoginReq → LoginAck
EnterWorldReq → EnterWorldAck
EnterDungeonReq → EnterDungeonAck
SkillUseReq × N을 연속으로 보내는 버스트
- 서버가 보내는
DungeonClearNoti
왼쪽의 Client 카드는 "개발 중…" 상태이고 "실제 클라가 보낼 패킷 순서 그대로 봇이 흉내"라고 적혀 있다. 오른쪽 "클라 없이 검증" 체크리스트에는 로그인 · 월드 입장, 던전 입장 시퀀스, 전투 패킷 반복, 클리어 · 보상 검증이 차례로 체크된다. 서버팀은 클라 완성을 기다리지 않고 실제 클라와 같은 순서의 패킷으로 컨텐츠 로직을 끝까지 돌려 볼 수 있다.
서버팀 카드에서 퍼블리셔(QA · 인프라팀) 카드로 "BotClient 패키지"가 넘어간다. 패키지에는 생성된 패킷 코드, 컨텐츠 시나리오, 부하 설정(동접 · RPS)이 들어 있고, 용도는 장비 스펙 산정과 라이브 인프라 테스트다.
이어지는 부하 대시보드에서 동시 접속 봇 수가 0에서 6,000까지 올라간다. 가운데에는 LB, Game Server, DB의 CPU 게이지가 있고, 오른쪽 "CPU 사용률 vs 동시 접속(Game Server · 1대)" 그래프에는 "임계 70%" 선이 그어져 있다. 곡선이 동접 5,000 지점에서 70%에 닿으면 "서버 1대 ≈ 동접 5,000" 마커가 뜬다. 아래 칩에는 RPS, p99 지연, DB QPS가 동접에 따라 함께 오른다.
결과 카드는 두 장이다.
- 장비 스펙 산정: 대당 동접 5,000(CPU 70% 기준), 목표 동접 50,000 → 게임 서버 10대 + 여유분. DB · LB 같은 공유 자원은 따로 측정한다.
- 라이브 인프라 테스트: 실서비스 환경에 같은 봇으로 부하를 넣어 LB · 네트워크 · DB 병목을 오픈 전에 확인한다.
화면 하단에 "수치는 설명을 위한 예시입니다"라고 표기되어 있다. 위 숫자는 모두 예시이며 실제 산정은 각 게임의 측정값으로 해야 한다.
용어 정리
- 패킷
- 클라이언트와 서버가 주고받는 메시지 한 단위다. 영상에서는
.proto의 message 하나가 패킷 하나에 해당한다.
- Protobuf (프로토콜 버퍼)
- Google이 만든 직렬화 형식이다. 스키마를
.proto 파일에 적고, 여기서 각 언어용 직렬화 코드를 생성해 쓴다.
.proto 파일- 메시지 이름, 필드 이름, 타입, 번호를 선언하는 스키마 파일이다. 영상에서는
game_packet.proto가 모든 패킷의 원본이다.
- 필드 번호(tag)
- 각 필드 뒤의
= 1, = 2 같은 숫자다. 직렬화된 바이트에서는 이름 대신 이 번호로 필드를 구분하므로 한 번 정하면 바꾸지 않는다.
protoc- Protobuf 컴파일러다.
.proto를 읽어 C#, C++ 등 지정한 언어의 클래스 코드를 만든다.
- 코드 생성(codegen)
- 스키마에서 소스 코드를 자동으로 만들어 내는 과정이다. 사람이 직접 짜지 않으니 클라, 서버, 봇의 패킷 구조가 같게 유지된다.
- Single Source of Truth
- 같은 정보의 원본을 한 곳에만 두는 원칙이다. 여기서는 패킷 정의가
.proto 한 파일에만 있다.
- 봇 클라이언트
- 사람 대신 프로그램이 실제 클라처럼 서버에 접속해 패킷을 보내는 테스트용 클라이언트다. 화면이나 리소스 없이 패킷 흐름만 재현한다.
- 패킷 플로우
- 로그인부터 던전 클리어까지 클라가 서버와 주고받는 패킷의 순서다. 봇은 이 순서를 그대로 따라 한다.
- 퍼블리셔
- 게임을 서비스하고 운영하는 회사 또는 조직이다. 영상에서는 QA와 인프라팀이 봇을 받아 부하 테스트를 한다.
- 동접 (CCU)
- 같은 시점에 접속해 있는 사용자 수다. 서버 대수를 정할 때 기준이 되는 값이다.
- 부하 테스트
- 많은 봇을 동시에 접속시켜 서버와 인프라가 어디까지 버티는지 재는 테스트다. 영상에서는 CPU 70%를 임계로 잡는다.
RPS / DB QPS- 초당 요청 수와 DB의 초당 쿼리 수다. 동접이 늘 때 서버와 DB가 받는 부하를 나타낸다.
p99 지연- 요청의 99%가 이 시간 안에 끝난다는 뜻의 응답 시간 지표다. 평균에 묻히는 느린 요청을 드러낸다.