> For the complete documentation index, see [llms.txt](https://docs.edgegap.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.edgegap.com/docs.edgegap.com-ko/unreal-engine.md).

# Unreal Engine - 시작하기

직접 해보며 Edgegap에서 첫 전용 서버를 배포하세요. 이 가이드가 끝나면 비용 없이 Edgegap으로 전용 서버를 배포하게 됩니다.

Docker Desktop으로 빌드하는 것이 시작하기에 가장 빠르고, 쉽고, 가장 신뢰할 수 있는 방법입니다.

{% embed url="<https://youtu.be/q7ljcr9rAWE>" %}

## ✔️ 준비

시작하기 전에 반드시 [Edgegap에 무료 계정을 생성하세요](https://app.edgegap.com/auth/register) (신용카드 불필요).

**개발 머신에서 몇 가지 필수 항목을 구성하세요:**

<details>

<summary><a href="https://www.docker.com/products/docker-desktop/">Docker Desktop 및 Docker Edgegap 확장 프로그램 설치</a></summary>

* [공식 소스에서 Docker Desktop 설치](https://www.docker.com/products/docker-desktop/) (계정이 필요하지 않습니다).
* 설치가 완료되면 컴퓨터를 다시 시작하세요.
* 설정 ⚙️ > 확장 프로그램 > Docker 확장 프로그램 활성화로 이동하세요.
* [공식 Docker 마켓플레이스에서 확장 프로그램을 설치하세요(이 링크를 클릭하세요).](https://www.docker.com/products/docker-desktop/)

</details>

<details>

<summary><a href="https://open.docker.com/extensions/marketplace?extensionId=edgegap/docker-extension">Edgegap Quickstart Docker 확장 프로그램 설치</a></summary>

* Docker Desktop / 확장 프로그램 / 둘러보기에서 설치하거나 [링크를 사용하세요](https://open.docker.com/extensions/marketplace?extensionId=edgegap/docker-extension).

<figure><img src="/files/17d13f47476dc4dcaf81956beb14da18abe1adc0" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary><a href="https://www.unrealengine.com/en-US/ue-on-github">GitHub에서 언리얼 엔진 리소스에 접근하기</a></summary>

* [GitHub 계정에 가입하세요.](https://github.com/)
* 다음 위치로 이동하세요 [언리얼 엔진 연결된 계정 대시보드 페이지](https://www.epicgames.com/account/connections).
* GitHub 계정을 에픽 계정에 연결하세요.
  * 에픽 게임즈가 귀하의 GitHub 계정에 접근하도록 허용하세요.
  * GitHub에서 에픽 게임즈 조직에 가입하라는 이메일 초대를 수락하세요.

</details>

<details>

<summary><a href="https://github.com/settings/tokens/new">GitHub 개인 액세스 토큰(클래식) 생성</a></summary>

* 권한만 활성화 `[read:packages]` ,
* 토큰 생성 - **이 값을 안전하게 보관하세요. 다시는 볼 수 없습니다**.

</details>

{% hint style="info" %}
**서버 빌드에 자신이 있나요?** 건너뛰기 [#customize-server-image](#customize-server-image "mention") 및 [고급 기능](/docs.edgegap.com-ko/learn/advanced-features.md).
{% endhint %}

## ⚙️ 1. 프로젝트 구성 <a href="#id-1-configure-project" id="id-1-configure-project"></a>

Windows, Mac 또는 Linux 기기를 사용하든 상관없이, 당신은 **서버를 Linux 런타임용으로 빌드해야 합니다**., 대부분의 클라우드 제공업체(Edgegap 포함)가 현재 Linux에서 실행되기 때문입니다. 걱정하지 마세요, Linux 지식은 필요하지 않습니다.

{% hint style="info" %}
이 방법은 Unreal Engine 소스 코드를 다운로드하거나 소스에서 빌드할 필요가 없습니다!
{% endhint %}

☑️ 먼저 **Unreal Engine 버전을 확인하세요** - 프로젝트 파일의 값으로 미리 채워져 있습니다.

☑️ **GitHub 사용자 이름과** [**PAT**](#user-content-fn-1)[^1] 에서 [#preparation](#preparation "mention"), GitHub에서 종속 항목을 다운로드하기 위해.

<details>

<summary><a href="https://github.com/settings/tokens/new">GitHub 개인 액세스 토큰(클래식) 생성</a></summary>

* 권한만 활성화 `[read:packages]` ,
* 토큰 생성 - **이 값을 안전하게 보관하세요. 다시는 볼 수 없습니다**.

</details>

☑️ **Unreal Engine 버전 호환성 검사 비활성화** 전용 서버용 및 **설정 `IpNetDriver` 기본 드라이버 또는 대체 드라이버로** 복제 네트워킹용:

{% hint style="warning" %}
확인하세요 **입력하십시오 `DefaultServerTarget`  이 스니펫 끝에**!
{% endhint %}

<pre data-title="Config/DefaultEngine.ini"><code><a data-footnote-ref href="#user-content-fn-2">[ConsoleVariables]</a>
net.IgnoreNetworkChecksumMismatch=1
net.CurrentHandshakeVersion=2
net.MinHandshakeVersion=2
net.VerifyNetSessionID=0
net.VerifyNetClientID=0

<a data-footnote-ref href="#user-content-fn-3">[/Script/Engine.GameEngine]</a>
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="OnlineSubsystemUtils.IpNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")

<a data-footnote-ref href="#user-content-fn-4">[/Script/OnlineSubsystemUtils.IpNetDriver]</a>
MaxClientRate=1000000000
MaxInternetClientRate=1000000000
InitialConnectTimeout=120.0
MaxNetTickRate=60
NetServerMaxTickRate=60

<a data-footnote-ref href="#user-content-fn-5">[/Script/BuildSettings.BuildSettings]</a>
DefaultServerTarget=LyraServer
</code></pre>

☑️ **Unreal Engine 재시작** 최신 변경 사항을 다시 불러오려면.

☑️ **전용 서버 타겟 스크립트 생성** 다음을 복사하여 `<PROJECT>Editor.Target.cs` 프로젝트 루트 폴더의 파일을 복사하고 복사본의 이름을 `<PROJECT>Server.Target.cs`.

☑️ **다음에 대한 참조를 바꾸세요** 단어 **`Editor`** **로** **`Server`** 서버 타겟 스크립트에서.

☑️ **서버 빌드 기본값 수정** 서버 타겟 스크립트를 편집하여:

<pre data-title="Source/<PROJECT>Server.Target.cs"><code>bOverrideBuildEnvironment = true;
<a data-footnote-ref href="#user-content-fn-6">bUseLoggingInShipping = true;</a>
<a data-footnote-ref href="#user-content-fn-7">bUseChecksInShipping = false;</a>
<a data-footnote-ref href="#user-content-fn-8">bBuildWithEditorOnlyData = false;</a>
<a data-footnote-ref href="#user-content-fn-9">bUsesSlate = false;</a>
<a data-footnote-ref href="#user-content-fn-10">bCompileCEF3 = false;</a>
</code></pre>

✅ 이제 다음 단계로 진행할 수 있습니다.

<details>

<summary>선택 사항: 스팀 통합</summary>

다음으로 **스팀 통합**사용하려면 `IpNetDriver` 를 기본 네트 드라이버로 설정하고 다음을 확인하세요 [리눅스용 64비트 steamclient.so](https://developer.valvesoftware.com/wiki/SteamCMD#Ubuntu) 파일이 이미지의 경로에 복사되어 있는지 `/home/ubuntu/.steam/sdk64/` .

{% hint style="success" %}
추가 `steamclient.so`  리눅스 라이브러리를 우리의 단일 클릭으로 [도커 확장 기능을 사용해](/docs.edgegap.com-ko/unreal-engine.md).
{% endhint %}

<a href="https://github.com/edgegap/edgegap-unreal-buildutils/raw/refs/heads/main/steamclient.so" class="button secondary" data-icon="square-down">steamclient.so 다운로드</a>

<pre class="language-docker" data-title="Dockerfile"><code class="lang-docker">...
<a data-footnote-ref href="#user-content-fn-11">RUN mkdir -p /home/ubuntu/.steam/sdk64</a>
<a data-footnote-ref href="#user-content-fn-12">COPY ./steamclient.so /home/ubuntu/.steam/sdk64/steamclient.so</a>
<a data-footnote-ref href="#user-content-fn-13">RUN chmod 755 /home/ubuntu/.steam/sdk64/steamclient.so</a>
...
</code></pre>

{% hint style="warning" %}
**스팀 릴레이를 통해 패킷을 전송하여 연결 문제나 지연 급증을 일으킬 수 있으므로 스팀 네트워킹을 비활성화했는지 확인하세요.** 이는 리더보드, 업적, 음성 기능 또는 스팀 스토어에 게임을 게시하는 등 다른 Steamworks 기능 사용을 막지 않습니다.
{% endhint %}

<pre data-title="Config/DefaultEngine.ini"><code>[OnlineSubsystemSteam]
bUseSteamNetworking=false
bAllowP2PPacketRelay=false
<a data-footnote-ref href="#user-content-fn-14">SteamDevAppId=480</a>
<a data-footnote-ref href="#user-content-fn-14">SteamAppId=480</a>
</code></pre>

</details>

## 🔧 2. 게임 서버 빌드 <a href="#id-2-build-game-server" id="id-2-build-game-server"></a>

이제 프로젝트를 빌드하고 쿠킹한 다음, 쉽게 재사용할 수 있는 Docker 이미지로 패키징합니다.

개발자 팀과 함께 작업하면 코드를 공유해야 합니다. 문제가 발생했을 때 듣고 싶은 마지막 말은 “내 환경에서는 잘 돼”일 것입니다. 게임 서버는 전 세계 수천 대의 서버 머신에서 안정적으로 실행되어야 합니다.

서버를 안정적으로 만들기 위해 Docker를 사용합니다 - 운영 체제 수준까지 서버 코드의 모든 종속성이 어디서 어떻게 서버가 시작되든 항상 정확히 동일하도록 보장하는 가상화 소프트웨어입니다.

{% hint style="info" %}
시청을 권장합니다 ["로컬에 설치하지 마세요" (비디오)](https://www.youtube.com/watch?v=J0NuOlA2xDc\&ab_channel=Coderized). **Docker를 사용할 때 Dockerhub를 사용할 필요는 없습니다**Docker ≠ Dockerhub. Docker를 프로그래밍 엔진으로 보고 Dockerhub를 앱 스토어로 생각하세요.
{% endhint %}

☑️ 다음 옵션을 구성할 수 있습니다(또는 기본값을 유지하세요):

* **이미지 이름** 은(는) 배포 전에 서버 빌드를 표시하는, 선택한 고유 식별자입니다.
  * 보통 게임 이름이 포함됩니다. 예: “my-game-server”.
* **이미지 태그** 은(는) 이미지의 특정 버전을 가리키는 식별자입니다.
  * “빌드 아티팩트”라는 용어가 이미지의 특정 버전을 가리키는 데 사용되기도 합니다.
  * 타임스탬프는 태그에 좋은 옵션입니다. 예: `2024.01.30-16.23.00-UTC`  (기본값).

☑️ **프로젝트 빌드** 구성이 만족스러우면 실행하세요. 이 단계를 완료하면 Linux 게임 서버 실행 파일이 포함된 새 이미지가 로컬 Docker 클라이언트에 추가됩니다.

✅ 이제 다음 단계로 진행할 수 있습니다.

## 🧪 3. 서버를 로컬에서 테스트 <a href="#id-3-test-server-locally" id="id-3-test-server-locally"></a>

업로드하고 배포하기 전에(약간의 시간이 걸릴 수 있음) 서버 이미지가 제대로 작동하는지 확인하기 위해 로컬(사용자 기기)에서 배포하고 게임 클라이언트를 연결해 보겠습니다.

☑️ **로컬에서 실행할 이미지 태그를 선택하세요** (원격 이미지는 다운로드됩니다). 선택적으로 추가 [docker run 인수](https://docs.docker.com/reference/cli/docker/image/build/#options) 를 제공하여 로컬 테스트를 맞춤 설정할 수 있습니다:

* `-p 7777:7777/udp` - 이는 로컬 컨테이너의 [포트 매핑입니다](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md#port-mapping),
* `-e ARBITRIUM_PORT_GAMEPORT_INTERNAL=7777`  은(는) [환경 변수](#environment-variables) 실제 Edgegap 배포를 모의하며, 게임 서버에 플레이어 연결을 수신할 내부 포트를 알려줍니다.

☑️ 구성이 마음에 들면 **로컬 서버 시작**. 이 단계를 완료하면 **새 컨테이너가 시작됩니다** 개발 머신에서.

☑️ 이제 Unreal Engine Editor(PIE) 게임 클라이언트를 로컬 서버 컨테이너에 연결할 시간입니다. Unreal PIE 콘솔을 여는 단축키는 `~`  (틸드)이며, 다음으로 연결하세요 `open <ip>:<port>`:

* `ip`  = `localhost`  또는 `127.0.0.1`  (대부분의 경우 동일),
* `포트`  = Docker GUI에서 컨테이너의 무작위 외부 포트 값입니다.

<figure><img src="/files/cdf68395952a0fe6511b1cf80a1055d1aeb83fb0" alt=""><figcaption></figcaption></figure>

☑️ 로컬 서버 컨테이너에 연결하여 문제없이 플레이할 수 있는지 확인한 후에는 기기의 리소스를 다른 프로그램용으로 확보하기 위해 컨테이너를 삭제할 수 있습니다 🗑️

✅ 이제 다음 단계로 진행할 수 있습니다.

<details>

<summary>문제 해결 및 FAQ</summary>

클라이언트를 서버에 연결할 수 없습니다 - `요청 시간이 초과되었습니다.` , `요청 시간이 초과되었습니다` , `ConnectionFailed` , 또는 `포트 확인 실패`

* 먼저 컨테이너가 실행 중이며 로그에 런타임 오류가 없는지 확인하세요.
* 에서 포트 값이 `docker run` 명령과 일치하는지 확인하세요.
* 게임 클라이언트가 다음에 연결하고 있는지 확인하세요 **외부 포트** 컨테이너 세부 정보 페이지에 표시된 값은 보안상의 이유로 항상 무작위로 지정됩니다.
* 대상 파일의 이름을 변경하고, 단계에서 설명한 대로 게임 빌드를 구성했는지 확인하세요 [#id-1-configure-project](#id-1-configure-project "mention").

***

컨테이너는 실행 중이지만 이후 몇 분 동안 연결할 수 없습니다.

* 컨테이너가 올라오면 게임 엔진 초기화가 시작됩니다. 이 과정은 몇 초에서 몇 분까지 걸릴 수 있으며, 이 기간 동안 서버는 플레이어 연결을 수락하지 않습니다.
* 이 시간을 줄이기 위해 서버 초기화를 최적화하는 것을 고려하세요.
* 게임 클라이언트는 제한된 시간 동안(초기화 시간에 따라) 1초 간격으로 재연결을 시도한 뒤, 매치메이킹으로 돌아가야 합니다.
* 로딩 씬을 추가하여 서버가 클라이언트와 동시에 초기화(그리고 Unreal Engine의 경우 이동)를 수행하면서 양쪽 상태를 동기화할 수 있도록 고려하세요.

***

`경고: 바인드 주소에 대한 소켓을 생성할 수 없습니다`

* Fab 에셋 스토어를 통해 Epic의 Steam Subsystem 플러그인을 설치하세요.
* github에서 다운로드한 SteamCore 소스 버전을 Edgegap Integration Kit(EGIK)과 함께 사용할 경우, Epic Games의 플러그인 배포 정책 때문에 Epic의 Steam Subsystem 플러그인은 포함되지 않습니다.

***

연결은 되었지만 화면이 완전히 검은색입니다.

* 올바른 **게임 기본 맵** 가 **편집 / 프로젝트 설정 / 맵 및 모드**.

</details>

## ☁️ 4. Edgegap에 게시 <a href="#id-4-publish-to-edgegap" id="id-4-publish-to-edgegap"></a>

서버를 온라인으로 배포할 시간입니다! 이제 이미지가 플레이어를 성공적으로 호스팅할 수 있으므로 이를 Edgegap에 업로드하여 전 세계 어디에서나 실행할 수 있습니다. 이 가이드에서는 [**Edgegap의 컨테이너 레지스트리**](/docs.edgegap.com-ko/learn/advanced-features/edgegap-container-registry.md) (이미지 저장소).

☑️ **애플리케이션 이름을 선택하세요** Edgegap에서 유사한 이미지를 표시하고 그룹화하기 위해 사용합니다.

☑️ **게시할 이미지 태그를 선택하세요** 및 **이미지 업로드**. 이 단계를 완료하면 서버 이미지가 Edgeap Registry에 업로드되고 새로운 [애플리케이션 버전이 생성됩니다](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md) 웹 브라우저에서. **다음을 생성했는지 확인하세요** [**포트 매핑입니다**](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md#port-mapping) **프롬프트가 표시되면,** 기본값으&#xB85C;**.**

{% hint style="success" %}
버그를 발견하여 다시 빌드/게시해야 하나요? 다음을 사용하세요 **소스에서 다시 빌드** 하여 [#id-2.-build-game-server](#id-2.-build-game-server "mention") 및 [#id-4.-publish-to-edgegap](#id-4.-publish-to-edgegap "mention") **현재 확장 프로그램 입력 값으로 빠르게**
{% endhint %}

✅ 이제 다음 단계로 진행할 수 있습니다.

<details>

<summary>문제 해결 및 FAQ</summary>

`거부됨: 저장소 리소스 756.6 MiB를 추가하면 현재 사용량 4.3 GiB에서 업데이트될 때 구성된 상한 4.7 GiB를 초과합니다` , `참조 "layer-sha256:--------"에 대한 커밋에 실패했습니다: https://registry.edgegap.com/로의 PUT 요청에서 예기치 않은 상태가 반환되었습니다`

* 다음에서 이미지 저장 공간이 부족한 것 같습니다 [컨테이너 레지스트리](https://app.edgegap.com/registry-management/repositories/list). 사용하지 않는 빌드 아티팩트(있는 경우)를 제거하거나 서버 빌드 크기를 최적화하는 것을 고려하세요. 사용자 지정 Dockerfile이나 .dockerignore를 사용하는 경우 이미지에 불필요한 파일을 복사하고 있을 수 있습니다.

***

`애플리케이션 한도 2에 도달했습니다` , `도커 태그/버전 업데이트 불가: 애플리케이션 버전 한도 2에 도달했습니다`

* 무료 요금제 한도에 도달했습니다. 계정 업그레이드를 고려하세요. 또는 당사의 /을 통해 기존 리소스를 제거할 수 있습니다 [대시보드](https://app.edgegap.com/).

***

새 애플리케이션 버전이 플러그인/확장에 나열되지 않습니다.

* 마지막 단계에서 앱 버전 생성 양식을 완료했는지 확인하세요.

</details>

## 🚀 5. 클라우드에 배포 <a href="#id-5-deploy-to-cloud" id="id-5-deploy-to-cloud"></a>

이 가이드의 마지막 단계로, 이 단계를 완료하면 전 세계 어디에서든 플레이어가 접속할 수 있는 Edgegap 클라우드에 서버가 배포됩니다.

☑️ **애플리케이션과 버전을 선택하세요** 배포를 위해 이전 단계에서.

☑️ 준비가 되면, 누르세요 **클라우드에 배포**, 도달할 때까지 기다리세요 [/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-3.-deployment-ready](https://docs.edgegap.com/docs.edgegap.com-ko/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-3.-deployment-ready "mention"). 이 단계를 완료하면 결과적으로 [새 배포가 시작됩니다](https://app.edgegap.com/deployment-management/deployments/list) 귀하의 Edgegap 계정에서.

☑️ 콘솔 출력에 새로운 오류가 없는지 확인하세요. 또한 다음이 [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#container-logs) 오류를 표시하지 않는지 및 귀하의 [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#container-metrics) 가(이) vCPU 또는 메모리의 100% 자원 사용을 나타내지 않는지 확인하세요. 그렇지 않으면 새 플레이어 연결이 거부되거나 서버가 재시작 루프에 갇힐 수 있습니다. 문제 해결 단계는 아래를 참고하세요.

☑️ 이제 마지막 테스트를 수행하고 **Unreal Engine Editor를 클라우드 배포에 연결합니다**. 다음을 확인하세요 **배포의 호스트** 를 서버 IP 대신 사용하고, 배포의 **외부 포트**, 게임 클라이언트에서 Unreal 콘솔을 여세요(틸드 `~`)를 누른 다음 입력하세요 `open {host}:{port}` .

<figure><img src="/files/fd9d47f05b1771f5461b8d2aaaecea2deb3e30d2" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Edgegap 클라우드에서 배포의 외부 포트는 임의로 선택되어 잠재적 공격자(해커)가 피해를 일으키기 전에 속도가 느려지고 탐지되도록 합니다.
{% endhint %}

{% hint style="warning" %}
**테스트 시 VPN 비활성화** 보다 현실적인 조건을 위해 그리고 [저지연 배포를 받으려면](/docs.edgegap.com-ko/learn/orchestration/deployments.md#server-placement).
{% endhint %}

☑️ 배포에 문제없이 연결할 수 있음을 확인하고 테스트를 마쳤다면, **배포 중지** 다음 빌드를 위해 계정의 용량을 확보하려면.

* 문제가 발생한 경우, [배포의 대시보드 로그를 검사하세요](https://app.edgegap.com/deployment-management/deployments/list).
* 문제를 해결할 수 없다면, 저희는 [커뮤니티 디스코드](https://discord.gg/NgCnkHbsGp) 에서 도와드릴 수 있으며 기꺼이 지원하겠습니다.

🙌 Edgegap에서의 첫 배포를 축하합니다! 더 알아보고 싶다면 계속 읽어보세요.

<details>

<summary>문제 해결 및 FAQ</summary>

클라이언트를 서버에 연결할 수 없습니다 - `요청 시간이 초과되었습니다.` , `요청 시간이 초과되었습니다` , `ConnectionFailed` , 또는 `포트 확인 실패`

* 먼저 배포가 Ready 상태인지, 그리고 배포 로그에 런타임 예외나 오류가 없는지 확인하세요. 배포가 중지되었다면 다음에서 로그를 확인하세요 [대시보드](https://app.edgegap.com/deployment-management/deployments/list).
* 서버 빌드의 넷코드 설정에서 포트 설정이 다음의 내부 포트와 일치하는지 확인하세요 [앱 버전](https://app.edgegap.com/application-management/applications/list). 플러그인 빌드의 경우 포트는 자동으로 설정됩니다. 다음을 편집하여 포트 매핑을 변경할 수 있습니다 [앱 버전](https://app.edgegap.com/application-management/applications/list) 재빌드 없이. 넷코드 통합에서 프로토콜을 찾으세요.
* 게임 클라이언트가 다음에 연결하고 있는지 확인하세요 **외부 포트** 배포 세부 정보 페이지에 표시된 값은 보안상의 이유로 항상 무작위로 지정됩니다.
* 대상 파일의 이름을 변경하고, 단계에서 설명한 대로 게임 빌드를 구성했는지 확인하세요 [#id-1.-configure-project](#id-1.-configure-project "mention").
* 중국에 위치해 있고 다음을 사용하고 있나요 [Smart Fleets](https://docs.edgegap.com/docs/deployment/session/fleet-manager/fleet)? 연결이 중국의 만리방화벽에 의해 차단될 수 있습니다. 플릿에 중국에 위치한 서버를 추가하거나 VPN을 사용하여 연결하는 것을 고려하세요.

***

배포는 준비되었지만 이후 몇 분 동안 연결할 수 없습니다.

* 배포가 Ready 상태가 되면 게임 엔진 초기화가 시작됩니다. 이 과정은 몇 초에서 몇 분까지 걸릴 수 있으며, 이 기간 동안 서버는 플레이어 연결을 수락하지 않습니다.
* 이 시간을 줄이기 위해 서버 초기화를 최적화하는 것을 고려하세요.
* 게임 클라이언트는 제한된 시간 동안(초기화 시간에 따라) 1초 간격으로 재연결을 시도한 뒤, 매치메이킹으로 돌아가야 합니다.
* 로딩 씬을 추가하여 서버가 클라이언트와 동시에 초기화(그리고 Unreal Engine의 경우 이동)를 수행하면서 양쪽 상태를 동기화할 수 있도록 고려하세요.

***

`경고: 바인드 주소에 대한 소켓을 생성할 수 없습니다`

* Fab 에셋 스토어를 통해 Epic의 Steam Subsystem 플러그인을 설치하세요.
* github에서 다운로드한 SteamCore Integration Kit(SIK) 소스 버전을 Edgegap Integration Kit(EGIK)과 함께 사용할 경우, Epic Games의 플러그인 배포 정책 때문에 Epic의 Steam Subsystem 플러그인은 포함되지 않습니다.

***

연결은 되었지만 화면이 완전히 검은색입니다.

* 올바른 **게임 기본 맵** 가 **편집 / 프로젝트 설정 / 맵 및 모드**.
* 다음을 확인하세요 [Unreal Engine 버전 호환성 검사가 비활성화되어 있습니다](#id-2.-configure-game-server-builds) 에서 `DefaultEngine.ini`.

***

배포가 중지/재시작되어 더 이상 로그에 접근할 수 없습니다.

* 예외로 인해 서버 프로세스가 충돌하면, 시스템이 서버를 자동으로 재시작하려고 시도합니다. 근본 원인을 찾기 위해 서버를 로컬에서 테스트해 보세요.
* 로그는 배포가 지속되는 동안에만 보관됩니다. 배포가 중지된 후 로그를 확인하려면 [타사 로그 저장소를 통합하세요](https://docs.edgegap.com/docs/deployment/endpoint-storage).
* 다음을 참조하세요 [/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped](https://docs.edgegap.com/docs.edgegap.com-ko/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped "mention") 배포가 중지되는 모든 원인을 알아보세요.

***

내 배포가 X분 후 자동으로 중지되었습니다.

* 무료 티어 배포는 60분 제한이 있습니다. 계정 업그레이드를 고려하세요.
* 모든 배포는 서버 정리 정책에 따라, 인프라 유지 관리를 위해, 그리고 배포가 제대로 종료되지 않아 예상치 못한 비용이 누적되는 것을 방지하기 위해 실행 24시간 후 종료됩니다. 장시간 실행되는 서버의 경우 다음 사용을 고려하세요 [전용 플릿](/docs.edgegap.com-ko/learn/orchestration/private-fleets.md) 와 함께 [영속성](/docs.edgegap.com-ko/learn/orchestration/persistence.md).
* 다음을 참조하세요 [/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped](https://docs.edgegap.com/docs.edgegap.com-ko/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped "mention") 배포가 중지되는 모든 원인을 알아보세요.

***

플레이어가 내 배포를 떠나면 어떻게 되나요?

* 기본적으로 서버는 플레이어 연결을 거부하지 않습니다. 다양한 방법과 플레이어 인증 제공자를 사용할 수 있으므로 플레이어 인증은 개발자의 몫입니다.
* 게임 클라이언트는 예기치 않은 클라이언트 충돌 시 재연결을 시도하기 위해 연결 정보를 로컬에 저장할 수 있습니다.
* 플레이어가 진행 중인 게임에 참여할 수 있도록 하려면 다음 사용을 고려하세요 [심층 살펴보기](/docs.edgegap.com-ko/learn/matchmaking/matchmaker-in-depth.md#backfill) 또는 [세션](https://docs.edgegap.com/docs/deployment/session).

***

서버가 준비된 후 CPU 사용률이 100%로 표시됩니다.

* 게임 엔진은 서버 초기화 중 CPU 집약적인 작업을 수행하는 경향이 있으므로 문제가 아닐 수도 있습니다. 배포 시작 후 2\~3분이 지나도 CPU 사용량이 줄지 않으면 서버를 최적화하거나 앱 버전 리소스를 늘려야 할 수 있습니다.
* 처리하는 메시지 수를 줄이므로 틱 속도를 낮추면 CPU 사용량을 줄이는 데 도움이 됩니다.
* 무료 티어에서는 1.5 vCPU와 3GB 메모리(RAM)로 제한됩니다.
* 새 앱 버전을 만들 때 할당된 리소스를 늘릴 수 있습니다. 대시보드에서 앱 버전을 복제하고 서버나 이미지를 다시 빌드하지 않고 필요에 따라 이 값을 조정할 수 있습니다.

***

내 배포가 반복적으로 재시작되며 오류를 표시합니다 `OOM kill`

* 이는 할당된 메모리 양을 초과해서 발생합니다. 객체 풀링, 압축 또는 씬에서 불필요한 객체 제거로 메모리 사용을 최적화하는 것을 고려하세요.
* 무료 티어에서는 1.5 vCPU와 3GB 메모리(RAM)로 제한됩니다.
* 새 앱 버전을 만들 때 할당된 리소스를 늘릴 수 있습니다. 대시보드에서 앱 버전을 복제하고 서버나 이미지를 다시 빌드하지 않고 필요에 따라 이 값을 조정할 수 있습니다.

***

때때로 서버의 메모리(RAM) 사용량이 높은 값으로 급증하는데, 문제인가요?

* 할당된 앱 버전 메모리 양을 초과하지 않는 한 문제되지 않습니다.
* 할당된 앱 버전 메모리 양을 초과하면 `OOM kill` (위 참조).

***

같은 머신에서 실행 중인 다른 서버가 내 서버 성능에 영향을 주나요?

* 아니요, 우리 플랫폼은 할당된 리소스가 다른 스튜디오나 공유 인프라의 다른 서버에 의해 사용되지 않도록 보장합니다. Edgegap에는 시끄러운 이웃이 없습니다.

</details>

## 👉 다음 단계

클라이언트/서버 구성이 작동하면, 반드시 **프로젝트 복사본을 저장하세요** (git과 같은 버전 관리 소프트웨어를 사용하여) 문제가 발생했을 때 항상 작업 내역을 추적할 수 있도록.

서버 수명주기 및 검색 가능성과 관련된 주제를 더 알아보려면 계속 읽으세요.

### 배포 중지

매치가 끝나면(또는 플레이어가 떠나면) 비용 절감을 위해 배포를 중지할 수 있습니다. [비어 있거나 부분적으로만 채워진 상태로 실행하면 비용이 불필요하게 증가할 수 있습니다!](https://edgegap.com/blog/how-session-fill-rate-affects-your-multiplayer-hosting-costs)

이 가이드를 따르고 Docker 확장 프로그램으로 빌드했다면, 다음 메서드를 간단히 호출할 수 있습니다 `FGenericPlatformMisc::RequestExit` . 패키지된 이미지에 서버 프로세스를 관리하는 스크립트를 추가했으며, 이 스크립트가 자동으로 우아한 배포 종료를 수행합니다.

서버 수명 주기 관리를 사용자 지정하려면 다음을 수정하세요 [예시 `StartServer.sh`](https://github.com/edgegap/edgegap-unreal-buildutils/blob/main/StartServer.sh)  스크립트.

{% hint style="info" %}
Unreal에서 수명 주기를 관리하는 것을 선호하나요? 다음을 참조하세요 [개발자 도구](/docs.edgegap.com-ko/unreal-engine/developer-tools.md#integration-kit) 자체 중지 API 블루프린트
{% endhint %}

{% hint style="warning" %}
귀하의 것을 연결하세요 [엔드포인트 저장소](/docs.edgegap.com-ko/docs/endpoint-storage.md) 배포 로그를 받으려면 연결하세요. 그렇지 않으면 삭제됩니다!
{% endhint %}

### 주입된 변수

주입된 환경 변수를 통해 배포 ID, 서버 IP 주소, 서버 위치 등 유용한 정보를 읽을 수 있습니다. 각 배포에는 자동으로 다음이 포함됩니다:

* [배포 변수](/docs.edgegap.com-ko/learn/orchestration/deployments.md#injected-environment-variables) - Edgegap이 자동으로 제공합니다,
* [매치메이킹 변수](/docs.edgegap.com-ko/learn/matchmaking/matchmaker-in-depth.md#injected-environment-variables) - 사용 시 Edgegap이 자동으로 제공합니다 [매치메이킹](/docs.edgegap.com-ko/learn/matchmaking.md),
* [앱 버전 변수](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md#injected-variables) - 사용자가 구성할 수 있는 사용자 지정 키-값 쌍입니다.

{% hint style="success" %}
다음을 가져오세요 [개발자 도구](/docs.edgegap.com-ko/unreal-engine/developer-tools.md#integration-kit) 하여 **Blueprints를 사용해 타입이 지정된 변수를 쉽게 읽을 수 있습니다**.
{% endhint %}

### 서버 프로파일링

Edgegap에서 서버 성능 문제를 이해하고 최적화하려면 다음을 살펴보세요 [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#container-logs), [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#container-metrics), 그리고 그 외 [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#dashboard-monitoring) 사용 가능한 도구가 있습니다.

Edgegap에서는 기존 Unreal Engine 프로파일링 도구도 사용할 수 있습니다:

* [Unreal Engine 서버에서 트레이싱을 구성하세요](https://dev.epicgames.com/documentation/en-us/unreal-engine/developer-guide-to-tracing-in-unreal-engine) (내장 및 사용자 지정 이벤트):
  * 다음을 사용하여 서버 디스크에 트레이스를 저장: `-tracefile`, 타사 저장소에 업로드하여 오프라인으로 분석하거나,
  * 또는 다음을 사용해 트레이스 데이터를 스트리밍하세요 [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#port-mapping) 내부 포트용 `1981` UDP 프로토콜로.
* 분석 [Memory Insights](https://dev.epicgames.com/documentation/en-us/unreal-engine/memory-insights-in-unreal-engine) 및 [Networking Insights](https://dev.epicgames.com/documentation/en-us/unreal-engine/networking-insights-in-unreal-engine) 및 [#optimize-server-builds](#optimize-server-builds "mention").

### 세션 자동화

{% hint style="warning" %}
**배포를 수동으로 시작하고 URL과 포트를 붙여넣는 것만으로는 라이브 게임에 충분하지 않습니다.**
{% endhint %}

다음 중 하나를 사용해 세션 관리 및 필요에 따른 확장을 위한 인기 게임 흐름을 자동화하세요:

{% columns %}
{% column width="33.33333333333333%" %}
[매치메이킹](/docs.edgegap.com-ko/learn/matchmaking.md):

* 짧은 라운드
* 온디맨드 매치
* 실력 등급 및/또는\
  사용자 지정 규칙
  {% endcolumn %}

{% column width="33.33333333333333%" %}
[서버 브라우저](/docs.edgegap.com-ko/learn/server-browser.md):

* 지속형 또는 라운드
* 소셜 지역 허브
* 자동 할당 및/또는\
  사용자 지정 검색
  {% endcolumn %}

{% column width="33.33333333333333%" %}
사용자 지정 백엔드:

* 라이브 게임 마이그레이션
* [v2 API로 배포](/docs.edgegap.com-ko/docs/api/dedicated-servers.md)
* [웹훅 관찰](/docs.edgegap.com-ko/learn/orchestration/deployments.md#webhooks)
  {% endcolumn %}
  {% endcolumns %}

### 빌드 최적화

**클라이언트 전용 에셋을 서버 에셋과 분리하도록 에셋 청크 구성을 설정하세요.**

* 다음을 살펴보세요 [Asset Chunking 기법과 권장 사항](https://dev.epicgames.com/documentation/en-us/unreal-engine/preparing-assets-for-chunking-in-unreal-engine) Epic 제공.

**클라이언트 전용이고 서버 실행에 필요하지 않은 에셋과 플러그인을 제외하세요.**

* 다음에 대해 알아보세요 [빌드 시 에셋 및 플러그인 제외](https://dev.epicgames.com/community/learning/tutorials/Kp1k/unreal-engine-build-time-asset-and-plugin-exclusion).

**콘텐츠 쿠킹 전략을 검토하세요.**

* 다음을 고려하세요 [Cooking on the Fly(COTF)](https://dev.epicgames.com/documentation/en-us/unreal-engine/build-operations-cooking-packaging-deploying-and-running-projects-in-unreal-engine#cookonthefly) 를 사용하여 클라이언트 에셋 쿠킹을 지연시키고 서버 빌드를 더 빠르게 하세요.

**런타임 메모리 부담을 줄이기 위해 레벨 스트리밍을 구현하세요.**

* 디자인상 플레이어들이 대부분 같은 맵 영역에 함께 머문다면, [레벨 스트리밍이 서버의 메모리 사용량을 줄여줄 수 있습니다](https://dev.epicgames.com/documentation/en-us/unreal-engine/level-streaming-in-unreal-engine) 60% 이상 줄이고 클라이언트 성능을 향상시킬 수 있습니다!

**서버 실행에 꼭 필요한 것만 포함하세요.**

* 이미지에 사용하지 않는 파일을 복사하면 이미지가 불필요하게 커지고, 업로드가 길어지며, 캐싱 속도가 느려지고, 전반적인 서버 시작도 느려집니다. [Docker 이미지 최적화 제안을 검토하세요](https://docs.docker.com/build-cloud/optimization/#dockerignore-files).

<details>

<summary>예시 <code>.dockerignore</code> 파일로 추가 파일을 제거하세요.</summary>

```docker
# 컴파일된 객체 파일
*.slo
*.lo
*.o
*.obj

# 사전 컴파일된 헤더
*.gch
*.pch

# 컴파일된 동적 라이브러리
*.so
*.dylib
*.dll

# Fortran 모듈 파일
*.mod

# 컴파일된 정적 라이브러리
*.lai
*.la
*.a
*.lib

# 실행 파일
*.exe
*.out
*.app
*.ipa

# 이러한 프로젝트 파일은 엔진에 의해 생성될 수 있습니다
*.xcodeproj
*.xcworkspace
*.sln
*.suo
*.opensdf
*.sdf
*.VC.db
*.VC.opendb

# 사전 컴파일된 에셋
**/SourceArt/**/*.png
**/SourceArt/**/*.tga

# 빌드
**/Build/*

# PakBlacklist-<BuildConfiguration>.txt 파일 허용 목록
!**/Build/*/
**/Build/*/**
!**/Build/*/PakBlacklist*.txt

# Build의 아이콘 파일은 무시하지 마세요
!**/Build/**/*.ico

# 에디터가 생성한 구성 파일
**/Saved/*
**/Intermediate/*
**/DerivedDataCache/*
**/Binaries/*
**/Build/*
**/Releases/*
**/Packaged/*
```

</details>

**다음을 사용하는 것을 고려하세요** [**다단계 Docker 빌드(링크)**](https://docs.docker.com/build/building/multi-stage/)**.**

* 대규모 서버 종속 항목을 별도의 이미지로 분리하여 다단계 빌드에서 재사용하세요. Docker는 각 레이어를 캐시하고 이전 버전을 단순히 재사용하며, 명시적으로 지시하지 않는 한 이 부분의 업로드를 건너뛰므로 대역폭과 업로드 완료를 기다리는 시간을 절약할 수 있습니다.
* Dockerfile 명령 중 하나가 왜 오류를 내는지 확실하지 않다면 로컬에서 디버깅해 보세요. 문제가 발생하기 직전에 새 스테이지를 만드세요(두 번째 `FROM` 명령을 추가하고, `--target` 를 사용해 빌드 프로세스가 문제의 단계에서 멈추도록 지시한 다음, `docker exec -it {container} /bin/bash` 를 사용해 컨테이너 내부의 대화형 터미널에 들어가세요. 그런 다음 기본 이미지의 셸 명령으로 더 조사할 수 있습니다(예: `top` Ubuntu에서).

### 이미지 사용자 지정

빌드 크기 최적화, 불필요한 종속 항목, 더 복잡한 시작 프로세스 때문에 이미지에 대한 더 많은 제어가 필요한 사용자를 위해 자체 Dockerfile 추가도 지원합니다. 이제 몇 가지 “직접 해보는” 팁과 모범 사례를 공유하겠습니다.

**항상 작동하는 서버 빌드로 작업하고 있는지 확인하세요.**

* 문제가 커스텀 Dockerfile과 관련되었다고 가정하기 전에, Unity 서버 빌드를 시작할 수 있는지와 Unity의 빌드 과정에서 예외나 오류가 발생하지 않았는지 확인하세요.

**업로드하기 전에 항상 로컬에서 테스트하세요.**

* 이미지를 로컬에서 테스트하면 업로드가 끝날 때까지 기다리는 시간을 크게 절약할 수 있습니다. 또한 Edgegap 리소스를 필요로 하지 않기 때문에 완전히 무료입니다 ✨.
* 로컬에서 테스트할 때 내부 포트를 올바르게 설정했는지 확인하세요:

  ```bash
  docker run \
    -p 7777/udp \
    -e ARBITRIUM_PORTS_MAPPING='{"ports":{"gameport":{"internal":7777}}}' \
    'registry.edgegap.com/<repository>:<tag>'
  ```

**기본 사항을 숙지했는지 확인하세요. 모든 Dockerfile에는 몇 가지 필수 명령이 필요합니다:**

* `FROM {image}` 는 베이스 이미지입니다. Unity 프로젝트의 경우 보통 장기 지원되는 Linux를 사용하지만, 어떤 Linux 기반 베이스 이미지라도 괜찮습니다. 이러한 이미지는 보통 dockerhub에 저장된 공개 이미지입니다. Dockerfile 참조는 여기. [Dockerfile 참조는 여기](https://docs.docker.com/reference/dockerfile/#from).
* `COPY {source} {destination}` 호스트 머신의 리눅스 서버 빌드를 이미지 내부로 복사하여 나중에 시작할 수 있게 합니다. [Dockerfile 참조는 여기](https://docs.docker.com/reference/dockerfile/#copy).
* `USER {user}` 는 다음에 와야 합니다 [useradd (ubuntu) 명령](https://manpages.ubuntu.com/manpages/bionic/man8/useradd.8.html) 또는 이에 상응하는 것으로, 모든 것을 `root` 로 실행하지 않는 것이 더 안전합니다. [Dockerfile 참조는 여기](https://docs.docker.com/reference/dockerfile/#user).
* `CMD {command}` 는 마지막 줄이 될 것이며, 대부분 `StartServer.sh` 또는 일종의 시작 스크립트를 호출하여 모든 설정이 완료된 후 서버가 올바르게 초기화되도록 합니다. [Dockerfile 참조는 여기](https://docs.docker.com/reference/dockerfile/#cmd).
* 다음을 사용하지 마세요 `VOLUME` - 이렇게 하면 Edgegap에서 로컬 스토리지를 마운트할 수 없습니다. 대신 우리의 Endpoint Storage 기능을 고려하고 S3 버킷을 사용하세요. 자세한 내용은 [Endpoint Storage](https://docs.edgegap.com/docs/deployment/endpoint-storage),
* `EXPOSE 7777/UDP`  는 필요하지 않습니다! 이것은 실제로 컨테이너 외부에서 내부 서버 포트를 사용 가능하게 하지 않으며, 개발자에게 주는 힌트일 뿐이고 포트는
  * 로컬에서 테스트할 때 `docker run <image> -p 7777/udp` ,
  * 로 게시되어야 하거나 [Edgegap Port Mapping](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md#other-parameters-optional).

**매개변수 선언은 가능한 늦은 시점까지 지연하세요. 서버 빌드 시간이 길기 때문에 구성 가능성(Configurability)이 조합 가능성(composability)보다 우선입니다.** [**이 접근 방식을 Dockerfile 명령에 적용하여 더 빠르게 빌드하고 업로드하세요.**](https://medium.com/@esotericmeans/optimizing-your-dockerfile-dc4b7b527756)

* 시나리오: 배포 단계, 버전, 게임 모드, 맵, 서버당 플레이어 수, 백업 빈도 등과 같은 매개변수를 정의해야 할 때.
* 나쁜 해결책: 매개변수 조합마다 별도의 이미지를 만드는 것. 이 방법은 이미지를 재빌드하는 데 모든 시간을 소비하게 하며 이로 인한 이점은 거의 없습니다.
* 더 나은 해결책 - 구성 매개변수를 적시에 대체하세요:
  1. 배포 매개변수 - 배포 직전에 제공되는 것 - 매치메이킹 선택자는 환경 변수로 전달되거나, 배포 시점에 환경 변수를 전달하는 커스텀 세션 관리 시스템 등,
  2. 버전 매개변수 - 앱 버전의 모든 배포에 공유되는 것 - 배포 단계, 아티팩트 태그, 서드파티 비밀 및 엔드포인트 등; 그리고
  3. 하나의 단일 이미지 - 시작 시 모든 구성 옵션을 포함하고 로드합니다.

**Edgegap 배포에서 데이터베이스를 실행하지 마세요.**

* Edgegap 배포는 장기 실행 프로세스를 위한 것이 아니며, 장기간 실행 후 별도의 통지 없이 종료될 수 있습니다. 이러한 방식으로 실행되는 데이터베이스(분산형일지라도)는 종료되어 되돌릴 수 없는 데이터 손실을 초래할 수 있습니다. 데이터베이스가 필요하다면 서드파티 DBaaS를 고려하세요.
* 다음 사용을 고려하세요 [관리형 클러스터(Managed Clusters)](https://app.edgegap.com/cluster-management/clusters/list) 데이터베이스 및 장기 실행 서비스 호스팅을 위해.

[^1]: 개인 액세스 토큰

[^2]: 호환성 검사 비활성화

[^3]: IpNetDriver 사용

[^4]: 클라이언트/서버 틱 속도 및 타임아웃 설정

[^5]: 서버 빌드를 기본 대상(target)으로 설정

[^6]: 로그 활성화

[^7]: 검사 사용 안 함

[^8]: 에디터 콘텐츠 패키징하지 않음

[^9]: Slate UI(에디터) 패키징하지 않음

[^10]: CEF3(에디터) 컴파일하지 않음

[^11]: 상위 디렉터리 생성

[^12]: steamclient.so 파일 복사

[^13]: steam 클라이언트 실행 허용

[^14]: 스팀 퍼블리셔 포털에서 찾기
