한 번에 언리얼 엔진 멀티 클라이언트 테스트 환경 구축하기

| 2022-06-21

언리얼 엔진에서 데디케이티드 서버 작업 중이리사면, 멀티 클라이언트로 테스트하는 팁을 꼭 얻어가세요!

안녕하세요, 넷마블 TPM실 기술분석팀 박정욱입니다.

여러 유저가 접속해서 플레이하는 온라인 게임은 1개 서버나 호스트에 여러 클라이언트가 붙어서 동작하는 구조를 기본으로 차용하고 있습니다. 리슨 서버, 서버-클라이언트, 데디케이티드 서버 등 종류도 많습니다. 오프라인으로만 플레이하는 패키지 게임이 아니라면, 완벽히 1대1 구조인 온라인 게임은 거의 찾아보기 힘들다고 해도 과언이 아닐 것입니다.

그래서 단일 클라이언트에서는 이슈가 발생하지 않더라도, 멀티 클라이언트 동작도 꼭 함께 확인해야 합니다. 단순히 이 이유가 아니더라도, 실제 개발 도중에 멀티 클라이언트 동작이 필요한 상황이 종종 생기기도 합니다. 단순히 2~3개보다 많이 구동해야 하는 상황을 마주하신 분도 계실 것 같습니다.

특히 언리얼 엔진에서 데디케이티드 서버로 개발 중이라면, 서버 측과 클라이언트 측을 동시에 보기 위해 다중 클라이언트 실행을 피하기는 매우 어렵습니다. 지금부터 언리얼 엔진으로 게임을 개발하는 중도에 이 상황을 만났을 때, 다중 클라이언트를 구동하는 팁을 소개합니다. 

  • 배치(Batch) 파일
    이번 글에서 활용할 예시는 배치 파일 형태 예시입니다. 배치 파일이 아니더라도, 각자 편한 방식으로 명령어 실행할 때 쓰는 옵션 등만 참고하시면 됩니다.

클라이언트를 바둑판식 배열로 배치

먼저 아래에 예시로 작성한 배치 파일을 살펴보겠습니다.

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

::set execute file location
SET exec_location=[클라이언트를 설치한 절대 경로.]
SET exec_name=[클라이언트 실행 파일. 예) test.exe]

::get client resolution
SET res_width=640
SET res_height=480

::get server ip / port
SET server_ip=[데디케이티트 서버 IP]
SET server_port=[데디케이티트 서버 port]

::get monitor width / height size
SET monitor_width=0
SET monitor_height=0

::get monitor resolution
FOR /F "tokens=*" %%g IN ('wmic path Win32_VideoController get CurrentHorizontalResolution ^| findstr /v /r /c:"^$" /c:"^\ *$" ^| findstr /v CurrentHorizontalResolution') do (SET monitor_width=%%g)
FOR /F "tokens=*" %%g IN ('wmic path Win32_VideoController get CurrentVerticalResolution ^| findstr /v /r /c:"^$" /c:"^\ *$" ^| findstr /v CurrentVerticalResolution') do (SET monitor_height=%%g)

echo %monitor_width% X %monitor_height%

set /a max_width_count=(%monitor_width%/%res_width%)-1
set /a max_height_count=(%monitor_height%/%res_height%)-1

::get client count
SET max_client_count=2
if not [%1] == [] set max_client_count=%1

set run_client_count=0
FOR /L %%i IN (0,1,%max_width_count%) do (
	FOR /L %%j IN (0,1,%max_height_count%) do (
		call :multiply %%i %%j
	)
)

goto :eof

:multiply
set /a real_pos_x=%1 * %res_width%
set /a real_pos_y=(%max_height_count% - %2) * %res_height%

echo "start %exec_location%\%exec_name% -game -ip=%server_ip% -port=%server_port% -windowed -winx=%real_pos_x% -winy=%real_pos_y% -resx=%res_width% -resy=%res_height% -automove"
start %exec_location%\%exec_name% -game -ip=%server_ip% -port=%server_port% -windowed -winx=%real_pos_x% -winy=%real_pos_y% -resx=%res_width% -resy=%res_height% -automove

set /a run_client_count=%run_client_count%+1
IF %run_client_count% == %max_client_count% exit 0
timeout 3 > NUL

ENDLOCAL

대략 배치 파일 구성을 살펴보면, 실행할 클라이언트 환경을 설정하고, 모니터 해상도를 인식합니다. 그 후, 클라이언트를 띄울 화면 위치를 잡고 바둑판식 배열 개수만큼 실행을 반복합니다.

주요 옵션

배치 파일에서 클라이언트를 실행할 때 바둑판식 배열을 위해 클라이언트의 크기나 위치를 설정하는 옵션을 사용합니다.

  • -resx / -resy: 클라이언트의 크기입니다. 고정 해상도로 개발 중이라면 적용 안 될 수도 있습니다.
  • -winx / -winy: 클라이언트가 시작할 좌상단 위치입니다. 배치 순서는 화면 좌측 하단부터 채우기 시작해서 우측 상단으로 채우는 N자 형태입니다.

만든 배치 파일을 실행할 때는 배치 파일에 실행할 클라이언트 개수를 같이 입력합니다.

// [파일이름].bat [실행할 클라이언트 개수]
$ multirun.bat 6

화면 해상도에 맞춰 최대 실행 개수에 제약이 걸려 있으니 클라이언트 해상도를 적절히 조절해서 사용하셔야 합니다. (예시 배치 파일에서 ‘res_width’와 ‘res_height’ 부분입니다.) 또한, CPU와 GPU 리소스가 소화할 수 있는 범위 내에서 작업하시는 것이 정신 건강에 좋습니다.

클라이언트 6개 실행 결과

아래 화면은 클라이언트 6개를 바둑판식으로 배열한 결과입니다.

클라이언트 6개를 구동한 화면

실행 후 동작 상황을 살펴보면, 당연히도 CPU 사용률이 매우 높습니다. 프레임을 제한한 백그라운드 실행임에도 사용률이 높기 때문에, 평소 로컬에서 실행하실 때에는 소량(10개 미만)만 실행하는 것이 좋아 보입니다.

헤드리스 클라이언트

UI가 없는 클라이언트를 헤드리스 클라이언트(Headless Client)라고 합니다. 만약 테스트 클라이언트 안에 자동으로 플레이하는 AI나 봇을 제작해둔다면, 클라이언트 실행에 필요한 리소스 소모량을 줄일 수 있습니다.

아래는 헤드리스 클라이언트를 실행하는 배치 파일 예시입니다.

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

::set execute file location
SET exec_location=[클라이언트를 설치한 절대 경로.]
SET exec_name=[클라이언트 실행 파일. 예) test.exe]

::get server ip / port
SET server_ip=[데디케이티트 서버 IP]
SET server_port=[데디케이티트 서버 port]

::get client count
SET max_client_count=2
if not [%1] == [] set max_client_count=%1

set run_client_count=0
FOR /L %%i IN (0,1,%max_client_count%) do (
	call :multiply
)
goto :eof

:multiply
echo "start %exec_location%\%exec_name% -game -ip=%server_ip% -port=%server_port% -windowed -automove -nullrhi"
start %exec_location%\%exec_name% -game -ip=%server_ip% -port=%server_port% -windowed -automove -nullrhi
timeout 3 > NUL

ENDLOCAL

UI가 없기 때문에 모니터 해상도를 인식하거나 클라이언트 크기를 설정하는 등의 작업이 필요 없어졌습니다. 상대적으로 배치 파일 길이 자체가 위 바둑판식 배열 때보다 많이 짧아졌습니다.

주요 옵션

헤드리스 모드를 실행하는 방법은 간단합니다. 클라이언트나 서버(데디케이티드 서버 포함)를 실행할 때 아래 옵션만 추가하면 됩니다.

$ test.exe -nullrhi

UI 없이 클라이언트가 구동되므로, 실제 실행 여부는 프로파일링 파일 생성 여부나 작업 관리자에서 실행 중인 프로세스 리스트로 확인하시면 됩니다.

  • 넷마블 마젤란실 밸런싱AI팀 이승철님 피드백
    옵션에 ‘-nosound’를 추가하면, 클라이언트에서 나오는 사운드도 끌 수 있습니다. 멀티 클라이언트를 실행하므로, 서로 싱크가 맞지 않는 소리가 겹쳐 들려 받게되는 고통에서도 해방될 수 있습니다.

클라이언트 백그라운드 실행

아래 화면은 실제 동작 확인용 클라이언트 1개와 헤드리스 클라이언트 6개를 실행한 결과입니다.

확인용 클라이언트 1개와 헤드리스 클라이언트 6개 실행

단순히 실행한 클라이언트 개수로만으로 비교하자면 바둑판식 배열 때보다 실행한 클라이언트가 1개만큼 늘었지만, 실제 리소스 사용량은 매우 적습니다. 로컬에서 테스트할 때 클라이언트를 더 많이 실행할 수 있어 보입니다.

단, 헤드리스 클라이언트를 실행했을 때는 번거롭지만 작업 관리자에서 직접 프로세스를 찾아서 종료해야 합니다. 혹은 필요한 조건에 맞춰서 자동으로 클라이언트가 종료되도록 게임 내에 설정을 추가해두시면 됩니다.

멀티 클라이언트를 실행하면서 프로파일링을 위해 필요한 옵션은 이전 글들을 참고해주세요.

멀티 클라이언트

개발 방향과 앱 공존성 이슈로 인해, 멀티 클라이언트 실행을 금지하거나 보안 툴에서 차단하고 있는 경우도 있으리라 생각합니다. 관리자 또는 관계자와 함께 논의하셔서, 멀티 클라이언트 실행으로 얻을 수 있는 이점을 꼭 챙기시기를 바랍니다.