TIL#71-멀티플레이 서버 구조와 Dedicated Server

ㅎ12·1일 전
post-thumbnail

📚 금일 학습 내용

: 멀티플레이 게임에서는 여러 플레이어가 같은 게임 상태를 공유해야 한다.
이를 위해 플레이어 간의 데이터를 주고받는 서버 구조가 필요하며, 대표적으로 P2P Server, Listen Server, Dedicated Server 방식이 있다.

이번에는 각 서버의 기본적인 차이와 Unreal Engine에서 Dedicated Server가 실행되고 클라이언트가 접속하는 흐름을 정리해 보았다.


1. 서버의 종류

P2P Server (Peer to Peer)

P2P는 Peer와 Peer가 직접 연결되어 통신하는 방식이다.

별도의 중앙 서버를 중심으로 모든 데이터를 처리하는 것이 아니라 각 사용자가 서로 데이터를 주고받는다.

구조가 비교적 단순할 수 있지만 클라이언트 간 직접 연결이 필요하기 때문에 네트워크 환경의 영향을 받을 수 있고, 게임 상태에 대한 권한 관리나 보안 측면에서도 고려해야 할 부분이 많다.


Listen Server

Listen Server는 한 플레이어의 게임이 서버 역할과 클라이언트 역할을 동시에 수행하는 방식이다.

즉, 방을 만든 Host가 서버 역할을 하면서 동시에 직접 게임에도 참여한다.

Host PC에서 게임 로직과 서버 처리가 함께 이루어지기 때문에 별도의 Dedicated Server를 운영하지 않아도 된다는 장점이 있다.

하지만 Host의 네트워크나 PC 상태가 다른 플레이어에게 영향을 줄 수 있고, Host가 게임에서 나가면 별도의 Host Migration 기능이 없는 경우 세션을 유지하기 어려울 수 있다.


Dedicated Server

Dedicated Server는 게임에 직접 참여하는 플레이어 없이 서버 역할만 담당하는 독립적인 프로세스이다.

Listen Server와 달리 서버를 실행하는 컴퓨터에서 플레이어가 직접 게임을 플레이하지 않는다.

게임의 중요한 상태와 로직을 서버가 관리하고, 각 Client는 서버와 통신하면서 필요한 정보를 전달받는다.

구조를 단순화하면 다음과 같다.

Server ↔ Client 1
Server ↔ Client 2
Server ↔ Client 3

Client끼리 직접 게임 데이터를 주고받는 것이 아니라 Server를 중심으로 통신하는 구조이다.


2. Dedicated Server의 실행 흐름

1) Server 실행

먼저 Dedicated Server 프로세스를 실행한다.

PIE 환경에서 서버를 실행하거나 별도의 Server 실행 파일을 이용하여 서버 프로세스를 실행할 수 있다.

서버가 특정 Level을 열고 네트워크 연결을 받을 수 있는 상태가 되면 Client가 해당 서버의 IP 주소와 Port 번호를 이용하여 접속할 수 있다.

Listen 상태로 실행된 World는 네트워크 연결을 받을 수 있도록 준비된다.

반대로 일반적인 싱글플레이 실행에서는 외부 Client의 접속을 받는 서버로 동작하지 않는다.


2) Server에서 Level을 연다

Server가 실행되면 게임에 사용할 Level(World)을 로드한다.

Level에는 World Settings가 존재하며, 여기에는 해당 Level에서 사용할 GameMode 등의 설정이 들어갈 수 있다.

이를 바탕으로 서버에서 게임 진행에 필요한 Actor들이 생성된다.

대표적으로 다음과 같은 것들이 있다.

  • GameMode
  • GameState

여기서 중요한 차이가 있다.

GameMode는 Server에만 존재한다.

GameMode는 게임의 규칙이나 플레이어 접속 처리 등 서버 권한이 필요한 로직을 담당하기 때문에 Client에는 복제되지 않는다.

반면 GameState는 Server에서 생성되고 Client들에게 Replication되어 전체 게임 상태를 공유하는 데 사용된다.

따라서 정확하게는 GameMode 자체가 Server라는 뜻은 아니지만, GameMode는 서버 권한을 가진 환경에서만 존재하는 Actor라고 이해할 수 있다.


3. Client가 Server에 접속하는 과정

1) Client가 접속을 요청한다

Client는 Server의 IP 주소와 Port 번호를 이용하여 접속을 시도한다.

Server는 Client의 접속을 처리하고 Client가 서버와 동일한 게임 World에서 플레이할 수 있도록 필요한 접속 및 Level 전환 과정을 진행한다.

Client는 서버가 사용하고 있는 Level을 로드하고 게임에 참여할 준비를 한다.


2) Player 관련 Actor가 생성된다

Client가 정상적으로 게임에 참여하면 서버는 해당 플레이어를 위한 객체들을 생성하고 관리한다.

대표적으로 다음과 같은 Actor가 있다.

  • PlayerController
  • PlayerState
  • PlayerCharacter 또는 Pawn

여기서 각각의 역할이 조금씩 다르다.

PlayerController

플레이어의 입력과 Pawn 제어 등을 담당한다.

PlayerController는 서버에 존재하며, 해당 PlayerController를 소유한 Client에도 존재한다.

다만 다른 플레이어의 PlayerController가 모든 Client에게 그대로 복제되는 구조는 아니다.

PlayerState

플레이어 이름, 점수, 팀 정보처럼 다른 플레이어에게도 공유될 필요가 있는 정보를 관리한다.

PlayerState는 Server에서 관리되며 다른 Client들에게도 Replication될 수 있다.

PlayerCharacter / Pawn

실제 게임 World에서 움직이고 행동하는 플레이어 캐릭터이다.

Server가 권한을 가지고 관리하며, 위치나 상태 등의 필요한 정보가 다른 Client들에게 Replication된다.


4. 두 번째 Client가 접속한다면?

Client 2가 Server에 접속하는 경우에도 기본적으로 같은 과정이 반복된다.

  1. Client 2가 Server의 IP와 Port를 통해 접속을 요청한다.
  2. Server가 Client 2의 접속을 처리한다.
  3. Client 2가 Server의 게임 World에 참여한다.
  4. Server에서 Client 2를 위한 PlayerController, PlayerState, PlayerCharacter 등이 생성된다.
  5. 필요한 Actor와 상태가 각 Client에게 Replication된다.

이제 Server에는 Client 1과 Client 2에 해당하는 플레이어 정보가 모두 존재하게 된다.

각 Client에는 다른 플레이어의 PlayerState와 Character 등 공유가 필요한 정보가 Replication된다.

따라서 Client 1의 화면에서는 Client 2의 Character를 확인할 수 있고, Client 2의 화면에서도 Client 1의 Character를 확인할 수 있다.

즉,

Client 1 → Server → Client 2

Client 2 → Server → Client 1

과 같은 흐름으로 서로의 게임 상태를 공유하게 된다.


5. 서버-클라이언트 구조의 핵심

Dedicated Server 기반의 서버-클라이언트 구조에서 중요한 점은 게임 상태에 대한 권한을 Server가 가지고 있다는 것이다.

Client가 어떤 행동을 했다고 해서 Client가 다른 Client의 게임 상태를 직접 변경하는 것이 아니다.

예를 들어 Client 1이 공격했다고 가정하면 개념적인 흐름은 다음과 같다.

Client 1
↓
Server에 행동 전달
↓
Server에서 행동 및 게임 상태 처리
↓
필요한 결과를 Replication
↓
Client 1 / Client 2에서 결과 확인

즉, Client 1과 Client 2가 직접 서로에게 게임 상태를 전달하는 것이 아니라 Server가 중간에서 게임 상태를 관리하고 필요한 정보를 각 Client에게 전달한다.

이러한 구조는 이후 배우게 될 RPC와 Property Replication을 이해하는 데 중요한 기반이 된다.


RPC와 Replication

멀티플레이 환경에서는 Server와 Client가 서로 다른 프로세스에서 실행되기 때문에 한쪽에서 발생한 함수 호출이나 변수 변경이 자동으로 다른 컴퓨터에 그대로 적용되는 것은 아니다.

따라서 네트워크를 통해 필요한 동작이나 데이터를 전달해야 한다.

대표적인 방법이 다음 두 가지이다.

RPC (Remote Procedure Call)

네트워크를 통해 다른 실행 환경에서 함수를 호출하기 위한 방식이다.

예를 들어 Client가 자신의 행동을 Server에 전달하거나, Server가 특정 Client 또는 여러 Client에게 특정 동작을 실행하도록 전달하는 데 사용할 수 있다.

Property Replication

Server에서 관리하는 Actor의 특정 Property 값을 Client에게 동기화하는 방식이다.

예를 들어 플레이어의 체력이나 상태처럼 여러 Client가 알아야 하는 값은 Server에서 변경된 후 Replication을 통해 Client에 전달할 수 있다.

따라서 앞으로 RPC와 Replication을 공부할 때는 먼저 다음 구조를 기억하는 것이 중요하다.

Server가 게임 상태에 대한 권한을 가지고 있으며, Client들은 Server와 통신한다.


Remind Point

  • P2P는 Peer끼리 직접 통신하는 구조이다.
  • Listen Server는 한 플레이어가 Server와 Client 역할을 동시에 수행한다.
  • Dedicated Server는 플레이어 없이 Server 역할만 수행하는 독립적인 프로세스이다.
  • Dedicated Server 구조에서는 Server가 게임 상태에 대한 권한을 가진다.
  • GameMode는 Server에만 존재한다.
  • GameMode는 게임 규칙과 플레이어 접속 처리 등 서버 측 로직을 담당한다.
  • GameState는 Server에서 생성되고 Client들에게 Replication된다.
  • PlayerController는 Server와 해당 Controller를 소유한 Client에 존재한다.
  • PlayerState는 다른 Client에게도 공유될 수 있도록 Replication된다.
  • PlayerCharacter/Pawn 역시 필요한 상태가 다른 Client들에게 Replication된다.
  • Client끼리 게임 상태를 직접 주고받기보다는 Server를 중심으로 통신한다.
  • 이 Server-Client 구조를 이해하는 것이 이후 배우는 RPC와 Property Replication의 기본이 된다.

0개의 댓글