ifunengine: 30분 만에 게임 서버 만들기
TRANSCRIPT
iFunEngine: 30분 만에 게임 서버 만들기김진욱 ([email protected])
https://ifunfactory.com/engine/
Who am I?
https://rein.kr/
2013. 5 ~: 아이펀팩토리
2012. 4 ~ 2013. 4: 넥슨 코리아
2007. 2 ~ 2012. 3: 엔씨소프트
C++ 기반 게임 서버 / Python 기반 백엔드 서비스 작성
얘기하려는 것
Unity3d 기반의 간단한 멀티플레이어 게임을 만들고,
이를 위한 서버를 작성하면서
필요한 기능 확인
간단한 구현 보여주기
코드: https://github.com/iFunFactory/demo-kgc-2015/
가상 키패드전후 입력으로 전진/후진 선택 좌우 입력으로 전진 방향 변경
기타조작얼굴 표정 변경 점프(달리는 중에만)
멀티 플레이어 처리이제 서버 코드를 추가해야합니다
ORM
Database
네트워크
게임로직
게임 서버가 하는 일?
클라이언트 메시지를 받아서 처리
기획된 게임 로직을 실행
저장할 데이터를 표현 (ORM)
데이터를 잃어버리지 않게 저장
네트워크 메시지 처리하기 (1)
서버와 클라이언트 사이에 미리 정한 메시지 형식으로 주고 받는다
여기서는 Google protobuf 를 쓴다
클라이언트→서버: 입력 전달 {이동, 방향전환, 점프, 표정}
서버→클라이언트: 각 클라이언트의 {위치/방향/점프/표정} 목록
(p_x, p_z)
a_v
Q (?, y, ?, w)= f(a_h)
네트워크 메시지 처리하기 (2)
unity-chan 프로젝트 변수 이용
클라이언트 상태
위치: (p_x, p_z)
방향: Q (사원수; y, w를 전송)
a_v: 방향으로 전진하는 속도
a_h: 방향 전환하는 속도
네트워크 메시지 추가하기(demo.)
Protobuf 메시지 정의하기
extend FunMessage { // 서버 -> 클라이언트 optional SpawnSelf sc_spawn_self = 16; // 연결된 직후에 받는 메시지 optional Spawn sc_spawn_other = 17; // 다른 유저가 연결되면 받는 메시지 optional UserUpdate sc_update = 18; // 모든 유저의 현재 상태 전달 optional Killed sc_killed = 19; // 유저 연결이 끊어지면 처리 optional FaceUpdate sc_face = 20; // 표정 업데이트
// 클라이언트 -> 서버 optional InputUpdate cs_input = 31; // 입력 변경 optional ChangeFace cs_face = 32; // 표정 변경 }
접속한 유저 처리(demo.)
접속한 유저 처리하기
새로 접속한 유저에게 적당한 위치를 정해준다 (x = -10 ~ 10; z = -10 ~ 10)
기존에 접속해 있던 유저들에게 새 유저 위치/방향 등을 알려준다
새로 접속한 유저에게 기존에 접속해 있던 유저 정보를 알려준다
이동하는 유저 처리(demo.)
이동하는 유저 처리 (1)
다음 정보를 모든 유저에게 알린다:
현재 위치
변경된 이동 방향
변경된 회전 방향
점프 상태
이동하는 유저 처리 (2)
모든 유저는 똑같은 방식으로 처리한다:
이동한 유저: 위치 이동 메시지가 오면 그 때 자신의 정보를 업데이트한다
다른 유저: 위치 이동 메시지가 오면 이동한 유저의 정보 업데이트
문제점: 반응 속도가 느리다
해결책: 바로 자기 화면을 업데이트하고 / 나중에 메시지가 오면 보간
오늘 발표에선 다루지 않습니다
점프? 표정 처리?(demo.)
점프 / 표정처리
유저 입력 메시지에 점프/표정 부분을 추가
해당 부분을 서버에서 감지하고 다른 클라이언트에 전달
전달 받은 클라이언트는 Unity-chan! 인스턴스에 반영
실제 서비스까지 가려면?
게임서버 게임서버 …
Game Servers
세션 저장소 데이터 캐시 랭킹 캐시
Redis 서버군
유저 데이터 랭킹 데이터 …
MySQL 서버군
Haproxy …
로드밸런서
샤딩 프록시 샤딩 프록시
빌링 서버
…
외부 결제 관련
랭킹 서버
랭킹 서버
랭킹 서비스
클라이언트
여기서 다루지 않은 것
게임서버와 데이터 베이스 사이에 오가는 데이터를 어떻게 표현하는가?
데이터 베이스에는 어떤 방식으로 읽고 쓰는가?
랭킹, 결제, 인증, … 의 외부 서비스는 어떻게 처리할까?
게임 서버가 여러 대가 되면 각 서버끼리 데이터는 어떻게 공유할까?
자주 접근하는 데이터는 어떻게 공유하는가?
여러 서버 중 한 대가 크래시하면?
Q&A