개발 공부/기타

[Palworld] Palworld 서버 최적화하기(서버 내부에서)

susong 2024. 2. 4. 17:19
728x90

Palworld(이하 팔월드) Dedeicated 서버를 운영하고 있다면, 가장 신경 쓰이는 부분은 게임 서버의 퀄리티일 것이다. 특히, 현재 팔월드 게임은 콘텐츠는 알차나 게임의 기술적인 완성도를 보면 만들어졌다고 보기 어렵기 때문에 더더욱 그렇다. 메모리 누수는 기본에, 멀티쓰레딩도 제대로 처리되고 있는지 확신이 들지 않을 정도이다.

 

이런 상황이지만, 게임을 잘 만들어서 즐기고 싶으니, 그리고 또 내 서버에 온 플레이어들이 재미있게 즐길 수 있게 하기 위해서 여러가지 최적화 방법을 고민해 봤고, 그 과정을 공유해보고자 한다. 아래 내용은 모두 리눅스(정확히는 우분투)를 기준으로 구성되어 있다. 윈도우도 파일 위치나 큰 내용적인 부분에서 차이가 없기 때문에 OS 간 차이를 이해하고 있다면 쉽게 따라 할 수 있을 것이라고 본다.

주말에 잠깐 사람 없을 때 한 컷 평균적으로 저정도 나온다(서울 내 접속시)

Engine.ini 설정 변경을 통한 네트워크 최적화

Linux에 팔월드를 설치했다면, 팔월드가 설치된 위치가 있을 것이다. $(팔월드 서버 위치)/Saved/Config/LinuxServer로 들어가면, 현재 운영하고 있는 서버의 Config값들을 볼 수 있는데, 이 방법은 Config 중 Engine.ini의 값을 바꾸는 테크닉이다. Config중 Engine.ini에 들어가면 여러 경로들이 보이는데 대충 아래와 같은 내용들을 확인할 수 있을 것이다.

// 위에 추가적인 내용들 있음
Paths=../../../Engine/Plugins/VirtualProduction/LiveLinkCamera/Content
Paths=../../../Engine/Plugins/VirtualProduction/Takes/Content
Paths=../../../Engine/Plugins/Web/HttpBlueprint/Content
Paths=../../../Pal/Plugins/DLSS/Content
Paths=../../../Pal/Plugins/EffectsChecker/Content
Paths=../../../Pal/Plugins/HoudiniEngine/Content
Paths=../../../Pal/Plugins/PPSkyCreatorPlugin/Content
Paths=../../../Pal/Plugins/PocketpairUser/Content
Paths=../../../Pal/Plugins/SpreadSheetToCsv/Content
Paths=../../../Pal/Plugins/Wwise/Content
// 마지막 줄(이 위치에 아래 내용 복붙하면 된다)

우리가 해야되는 일은 마지막 줄인

Paths=../../../Pal/Plugins/Wwise/Content에 이어서 아래 값들을 넣어주는 것이다.

; Online Subsystem Utils Configuration
; Adjusting tick rates for LAN and Internet servers to enhance the frequency of game state updates, 
; leading to smoother gameplay and less desynchronization between server and clients.
[/script/onlinesubsystemutils.ipnetdriver]
LanServerMaxTickRate=120  ; Sets maximum ticks per second for LAN servers, higher rates result in smoother gameplay.
NetServerMaxTickRate=120  ; Sets maximum ticks per second for Internet servers, similarly ensuring smoother online gameplay.

; Player Configuration
; These settings are crucial for optimizing the network bandwidth allocation per player, 
; allowing for more data to be sent and received without bottlenecking.
[/script/engine.player]
ConfiguredInternetSpeed=104857600  ; Sets the assumed player internet speed in bytes per second. High value reduces chances of bandwidth throttling.
ConfiguredLanSpeed=104857600       ; Sets the LAN speed, ensuring LAN players can utilize maximum network capacity.

; Socket Subsystem Epic Configuration
; Tailoring the max client rate for both local and internet clients, this optimizes data transfer rates, 
; ensuring that the server can handle high volumes of data without causing lag.
[/script/socketsubsystemepic.epicnetdriver]
MaxClientRate=104857600          ; Maximum data transfer rate per client for all connections, set to a high value to prevent data capping.
MaxInternetClientRate=104857600  ; Specifically targets internet clients, allowing for high-volume data transfer without restrictions.

; Engine Configuration
; These settings manage how the game's frame rate is handled, which can impact how smoothly the game runs.
; Smoother frame rates can lead to a better synchronization between client and server.
[/script/engine.engine]
bSmoothFrameRate=true    ; Enables the game engine to smooth out frame rate fluctuations for a more consistent visual experience.
bUseFixedFrameRate=false ; Disables the use of a fixed frame rate, allowing the game to dynamically adjust frame rate for optimal performance.
SmoothedFrameRateRange=(LowerBound=(Type=Inclusive,Value=30.000000),UpperBound=(Type=Exclusive,Value=120.000000)) ; Sets a target frame rate range for smoothing.
MinDesiredFrameRate=60.000000 ; Specifies a minimum acceptable frame rate, ensuring the game runs smoothly at least at this frame rate.
FixedFrameRate=120.000000     ; (Not active due to bUseFixedFrameRate set to false) Placeholder for a fixed frame rate if needed.
NetClientTicksPerSecond=120   ; Increases the update frequency for clients, enhancing responsiveness and reducing lag.

 

이 내용을 설명하면, 아래와 같다.

 

LanServerMaxTickRate: 이 설정은 로컬 영역 네트워크(LAN) 서버를 위한 것입니다. 서버가 초당 처리하는 업데이트 또는 "틱"의 최대 수를 지정합니다. 높은 틱률(여기서는 120으로 설정)은 서버가 더 자주 업데이트되어 LAN 설정에서 게임플레이가 더 부드럽고 플레이어의 동작에 대한 응답이 더 즉각적이 될 수 있음을 의미합니다.

 

NetServerMaxTickRate: LAN 설정과 유사하지만 인터넷 기반 서버를 위한 것입니다. 이것도 서버의 최대 틱률을 120로 설정합니다. 이 높은 틱률은 지연을 줄이고 인터넷을 통해 연결하는 플레이어들에게 게임의 전반적인 반응성을 향상시키는 데 유리합니다.

 

ConfiguredInternetSpeed: 이 설정은 각 플레이어의 네트워크 대역폭 할당을 최적화하는 데 중요합니다. 플레이어들에게 높은 가정 인터넷 속도(100 Mbps)를 설정하여 네트워크 대역폭 제한의 가능성을 줄입니다. 이는 서버가 각 플레이어가 고속 인터넷 연결을 가지고 있다고 가정하고 그에 따라 데이터를 송수신하며, 지연을 줄이는 데 도움이 될 수 있습니다.

 

ConfiguredLanSpeed: 인터넷 속도 설정과 유사하지만 LAN에 있는 플레이어들을 위한 것입니다. 이는 LAN에 있는 플레이어들이 게임 서버에 의해 부과된 인위적인 제한 없이 네트워크의 최대 용량을 활용할 수 있도록 보장합니다.

 

MaxClientRateMaxInternetClientRate: 이 설정들은 클라이언트(플레이어)의 데이터 전송 속도를 최적화하기 위한 것입니다. 둘 다 같은 높은 값(100 Mbps)으로 설정되어 서버가 높은 데이터량을 처리할 수 있도록 하여 지연을 방지합니다. 이는 플레이어 활동이 많거나 게임이 대량의 데이터를 전송하는 상황에서 특히 중요합니다.

 

bSmoothFrameRate: 이 설정은 게임 엔진이 프레임률의 변동을 부드럽게 하도록 합니다. 이를 통해 더 일관되고 시각적으로 안정된 게임 경험을 제공하려고 합니다. 프레임률 스무딩은 게임 성능과 시각적 품질 사이의 균형을 유지하는 데 특히 유리합니다.

 

bUseFixedFrameRate: 설정에서 'false'로 설정된 이 옵션은 게임이 고정값에 프레임률을 잠그는 대신 동적으로 프레임률을 조정할 수 있게 합니다. 이 동적 조정은 게임이 다양한 처리 요구에 적응할 수 있게 하여 전반적인 성능을 향상시킬 수 있습니다.

 

SmoothedFrameRateRange: 이는 부드러운 프레임률의 목표 범위를 설정하며, 하한은 30 FPS이고 상한은 120 FPS입니다. 게임은 이 범위 내에서 프레임률을 유지하려고 시도하며, 프레임률의 급격한 상승이나 하락을 부드럽게 하여 일관된 게임플레이를 유지합니다.

 

MinDesiredFrameRate: 이는 프레임률의 최소 임계값으로, 60 FPS에서 설정됩니다. 이는 게임이 최소한 이 프레임률에서 부드럽게 실행되도록 보장하는 기준선입니다.

 

NetClientTicksPerSecond: 초당 클라이언트 업데이트의 빈도를 120으로 증가시킨 설정은 게임 상태가 자주 새로고침되게 합니다. 자주 업데이트되는 것은 게임플레이의 반응성을 향상시키고 특히 빠른 진행 상황에서 지연을 줄일 있습니다.

 

일단 위와 같은 방식을 적용하기 전/후로 평균적으로 10 프레임 정도의 성능 향상을 확인했으나, 이게 꼭 저것 때문인지 다른 이유인지는 확인되지는 않다. 하지만, 다수의 해외 커뮤니티 의견을 토대로 보면 효과기 있는 것으로 보인다.

* 당연히 서버는 끈 상태에서 변경해 줘야 된다! 또, 설정을 바꾸기 전에 백업은 필수!

원글 링크

 

서버 자동으로 끄고 키기

(놀랍게도..) 제작사에서도 권하고 있는 방법으로, 현재는 서버를 운영할 때 필수적으로 하는 설정이다. 나 같은 경우에는 매 6시간마다 Restart를 해주고 있으며, 리스타트를 할 때 동시에 서버 업데이트를 확인 + 설치하는 것까지 병행하고 있다.

 

서버를 운영하는 방법으로는 여러 가지 방법이 있겠지만, 나는 개인적으로 선호하는 Systemd를 이용해서 운영하고 있다. 해당 방법을 이용하면, 서버가 켜졌을 때 지속적으로 해당 프로세스가 띄워져 있는 것을 보장할 수 있다. 간단하게 하는 방법을 설명하면 아래와 같다. 우분투에서 시스템 데몬 파일들은 정해진 스크립트들을 따라서 백그라운드에서 실행되는데, 그 위치는 /etc/systemd/system/이다.

 

(Name)@(ServerName):/etc/systemd/system$ cat palserver.service 
[Unit]
Description=Pal Server

[Service]
User=$(USER)
WorkingDirectory=/home/$(USER)/Steam/steamapps/common/PalServer
ExecStart=/home/$(USER)/Steam/steamapps/common/PalServer/PalServer.sh -useperfthreads -NoAsyncLoadingThread -UseMultithreadForDS
Restart=always
RestartSec=180
ExecStopPost=/bin/bash -c '/home/$(USER)/update_palserver.sh'

[Install]
WantedBy=multi-user.target

$(USER)은 자신의 상황에 맞게 작성해면된다. 일반적으로, 위에 (Name)이라고 있는 내용으로 대체하면 된다. 간단하게 스크립트를 설명하면, PalServer가 설치된 곳에 들어가서 팔 서버를 실행시키라는 의미다. 그리고 개발사에서 하라고 하는 여러 옵션들(스레드 쓰기 등등)도 포함되어 있다.

 

나 같은 경우에 껐다 킬 때마다 Update 쉘을 돌리고 싶어서 해당 내용도 포함해 두었다. 서버가 갑작스럽게 종료되면 업데이트를 자동적으로 진행한다. 그리고 업데이트는 평균 90초 정도 걸려서, 업데이트 시간의 2배의 시간을 줌으로써 안전하게 업데이트하도록 설정해 두었다.

 

그리고 자동적으로 꺼지게 하고 싶다면 아래 스크립트를 만들고 CRON에 등록하면 된다.(해당 스크립트는 RCON이 설치되어 있어야 하며, 스크립트와 RCON 클라이언트가 같은 위치에 있어야 한다)

#!/bin/sh

RCON_PORT=(본인이 설정한 포트)
ADMIN_PASSWORD=(비밀번호)

echo 'broadcast Auto_Reboot_Initialized_Time_to_take_Rest' | ./RCON -P $RCON_PORT -p $ADMIN_PASSWORD
echo 'save' | ./RCON -P $RCON_PORT -p $ADMIN_PASSWORD
echo "shutdown 300 Server_is_going_to_reboot_in_5_minutes" | ./RCON -P $RCON_PORT -p $ADMIN_PASSWORD

해당 내용은 broadcast로 서버 인원들에게 곧 종료된다고 알린 후 -> 저장 -> 그리고 5분 후에 종료하는 스크립트이다.

 

해당 내용을 crontab -e를 입력해서 6시간마다 돌리도록 만들면 된다. 대강 모습은 아래와 같을 것이다.

# Cron 기본적은 설명들~~

0 */6 * * * $(해당 스크립트 위치)

위 명령은 모든 날, 요일, 매 6시간마다 0분일 때(정각일 때) 해당 스크립트를 실행시키라는 뜻이다. 우리는 위에 종료를 지시하는 스크립트를 실행시켰기 때문에, 서버는 6시간마다 5분 후 종료될 것이다. 하지만, 걱정 마시라 종료되고 3분 후에 우리는 데몬에 의해서 알아서 다시 서버가 구성될 것이니까.

 

메모리 누수를 만드는 게임 특성 제거하기

위의 Engine.ini 파일의 위치에 들어가면, PalWorldSettings.ini설정 또한 있다. 해당 파일에서는 서버 내 게임 특성을 변경/제거할 수 있는데 그 내용은 오른쪽 팔월드 공식 사이트에 들어가면 확인할 수 있다. 팔월드 설정파일(Official)

 

이 중에서 현재 메모리 누수로 가장 주목받는 부분은 기지 습격인데, 해당 부분을 False로 바꿔준다. 즉, bEnableInvaderEnemy=False로 설정을 바꿔준다. (놀랍게도 해당 Config 설정들이 공식 사이트에 설명되어 있지 않다..)

 

또, bIsMultiplay을 True로 변경해 준다. (bIsMultiplay=True, 기본은 False임) 그리고 그 외에, 서버 메모리를 많이 잡아먹는 주범인 아이템 숫자를 제한해 준다. DropItemMaxNum=1500 서버 바닥에 떨어져 있는 아이템 수를 제한하는 것이라 플레이어 입장에서 불편함을 느끼지 않을 것이다. 또, ServerPlayerMaxNum도 자신의 서버가 감당할 수 있을 정도로 제한하자.

 

커뮤니티나, 서버 운영자들 사이에서 일반적으로 받아들여지는 RAM당 인원은 기본 8G + (인당 2G)이다. 본인의 서버가 12명 정도 상시 들어온다고 하면, 32기가 정도의 렘을 쓰자 그러면 쾌적하게 운영할 수 있을 것이다.

맺으며

이렇게 까지 해도 서버가 최적화가 안된다면.. 어쩔 수 없다. 업데이트를 기다리자.. 현재 서버 프로그램을 살펴보면 Core도 다 사용하지 않고, 멀티코어 지원도 잘 안되며, 절대 나면 안 되는 메모리 누수는 기본은 덤이고 등등 등등 정말 문제가 많다. 하지만, 이번에 돈을 왕창 벌었으니까 앞으로는 어느 정도 해결될 것이라고 본다.

 

나는 현재 GCP에서 서버를 구성하고 있으며, N2D(4 Core, 24GB) 기준 위와 같은 최적화 및 기타 인프라 설정을 통해 RTT 40, Jitter 4, Packet Loss 0을 평균을 기록하고 있다. 열심히 서버 구성하는 모든 분들에게 도움이 되었기를! 

728x90