# Unreal Engine

Learn by doing and deploy your first Dedicated Server on Edgegap. By the end of this guide, you will have deployed a dedicated server with Edgegap at no cost.

Building with Docker Desktop is the fastest, easiest, and most reliable method to get started.

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

## ✔️ Preparation

Before you get started, make sure to [create a free account with Edgegap](https://app.edgegap.com/auth/register) (no credit card required).

**Configure a few essentials on your development machine:**

<details>

<summary><a href="https://www.docker.com/products/docker-desktop/">Install Docker Desktop (or Docker CLI)</a></summary>

* [Install Docker Desktop from the official source](https://www.docker.com/products/docker-desktop/) (no account required),
* make sure to restart your computer after completing the installation.

</details>

<details>

<summary><a href="https://open.docker.com/extensions/marketplace?extensionId=edgegap/docker-extension">Install Edgegap Quickstart Docker Extension</a></summary>

* Install from Docker Desktop / Extensions / Browse or [using the link](https://open.docker.com/extensions/marketplace?extensionId=edgegap/docker-extension).

<figure><img src="https://3027732442-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2FraFWUCJWPZYvBMLieBUZ%2Fimage.png?alt=media&#x26;token=186886ac-accb-421d-b560-3ccefa7f29cb" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary><a href="https://www.unrealengine.com/en-US/ue-on-github">Gain Access to Unreal Engine resources on GitHub</a></summary>

* [Sign up for a GitHub account.](https://github.com/)
* Navigate to your [Unreal Engine linked accounts dashboard page](https://www.epicgames.com/account/connections).
* Link GitHub account with your Epic account.
  * Authorize Epic Games to access your GitHub account.
  * Accept email invitation to join Epic Games organization on GitHub.

</details>

<details>

<summary><a href="https://github.com/settings/tokens/new">Generate GitHub Personal Access Token (classic)</a></summary>

* enable only permission `[read:packages]` ,
* generate token - **store this value safely, you won't see it again**.

</details>

{% hint style="info" %}
**Confident in your server builds?** Skip to [#customize-server-image](#customize-server-image "mention") and [advanced-features](https://docs.edgegap.com/learn/advanced-features "mention").
{% endhint %}

## ⚙️ 1. Configure Project <a href="#id-1-configure-project" id="id-1-configure-project"></a>

Whether you’re using a Windows, Mac, or a Linux machine, you will **need to build your server for Linux runtime**, as most cloud providers nowadays (including Edgegap) run on Linux. Don’t worry, no Linux knowledge is required.

{% hint style="info" %}
This method doesn't require downloading Unreal Engine source code, or building it from source!
{% endhint %}

☑️ Start by **verifying your Unreal Engine version** - pre-filled with value from your project files.

☑️ **Input GitHub username and** [**PAT**](#user-content-fn-1)[^1] from [#preparation](#preparation "mention"), to download dependencies from GitHub.

<details>

<summary><a href="https://github.com/settings/tokens/new">Generate GitHub Personal Access Token (classic)</a></summary>

* enable only permission `[read:packages]` ,
* generate token - **store this value safely, you won't see it again**.

</details>

☑️ **Disable Unreal Engine version compatibility check** for dedicated servers and **set `IpNetDriver` as the default driver or the fallback driver** for replication networking:

{% hint style="warning" %}
Make sure to **input your `DefaultServerTarget`  at the end of this snippet**!
{% 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>

☑️ **Restart Unreal Engine** to reload latest changes.

☑️ **Create a dedicated server target script** by copying your `<PROJECT>Editor.Target.cs` file in project root folder and renaming the copy to `<PROJECT>Server.Target.cs`.

☑️ **Replace any references to** word **`Editor`** **with** **`Server`** in your server target script.

☑️ **Modify server build defaults** by editing your server target script:

<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>

✅ You may now proceed to the next step.

<details>

<summary>Optional: Steam Integration</summary>

To **integrate Steam**, use `IpNetDriver` as your default Net Driver and verify that the [64 bit steamclient.so for Linux](https://developer.valvesoftware.com/wiki/SteamCMD#Ubuntu) is copied to image on path `/home/ubuntu/.steam/sdk64/` .

{% hint style="success" %}
Add `steamclient.so`  linux library with a single click using our [docker extension](https://docs.edgegap.com/unreal-engine).
{% endhint %}

<a href="https://github.com/edgegap/edgegap-unreal-buildutils/raw/refs/heads/main/steamclient.so" class="button secondary" data-icon="square-down">Download 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" %}
**Make sure to disable steam networking, which sends packets through Steam Relay and may cause connection issues or lag spikes.** This doesn't prevent you from using other Steamworks features like Leaderboards, Achievements, Voice, or publishing your game on Steam Store.
{% 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. Build Game Server <a href="#id-2-build-game-server" id="id-2-build-game-server"></a>

Now we'll build and cook your project, and package it in an easily reusable docker image.

Working in a team of developers means sharing your code. When things go wrong, the last thing you want to hear is “it works on my machine”. Game servers have to run reliably on any machine, since a successful games’ servers will run on thousands of server machines across the world.

To help make your server reliable, we use Docker - virtualization software to ensuring that all of your server code dependencies down to the operating system level are going to be always exactly the same, no matter how or where the server is launched.

{% hint style="info" %}
We recommend watching ["Never install locally" (video)](https://www.youtube.com/watch?v=J0NuOlA2xDc\&ab_channel=Coderized). **You DON'T need to use Dockerhub with Docker**.  Docker ≠ Dockerhub. Think of Docker as a programming engine and Dockerhub as it’s App Store.
{% endhint %}

☑️ You may configure the following options (or keep defaults):

* **Image name** is a unique identifier of your choice, labeling your server build before shipping.
  * Usually, this will include the name of your game - for example “my-game-server”.
* **Image tag** is an identifier pointing to a specific version of your image.
  * The term “build artifact” is sometimes used to refer to a specific version of your image.
  * Timestamps are a great option for tagging, e.g. `2024.01.30-16.23.00-UTC`  (default).

☑️ **Build Project** once you're satisfied with your configuration. Completing this step will add a new image with your linux game server executable in your local Docker client.

✅ You may now proceed to the next step.

## 🧪 3. Test Server Locally <a href="#id-3-test-server-locally" id="id-3-test-server-locally"></a>

Let’s try deploying locally (on your machine) and connecting a game client, to make sure the server image is functioning properly before we upload and deploy (which may take a bit of time).

☑️ **Select the image tag you wish to run locally** (remote images will be downloaded). Optionally, more [docker run arguments](https://docs.docker.com/reference/cli/docker/image/build/#options) can be supplied to customize your local test:

* `-p 7777:7777/udp` - this is your local container [port mapping](https://docs.edgegap.com/learn/orchestration/application-and-versions#port-mapping),
* `-e ARBITRIUM_PORT_GAMEPORT_INTERNAL=7777`  is an [environment variable](#environment-variables) mocking a real Edgegap deployment, telling your game server the internal port to listen on for player connections.

☑️ Once you’re happy with your configuration hit **Start Local Server**. Completing this step will result in a **new container being started** on your development machine.

☑️ Now it's time to connect your Unreal Engine Editor (PIE) game client to your local server container. Open Unreal PIE console with `~`  (tilde) and connect with `open <ip>:<port>`:

* `ip`  = `localhost`  or `127.0.0.1`  (equivalent in most cases),
* `port`  = randomized external port value of the container in Docker GUI.

<figure><img src="https://3027732442-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2FCDGTUe5ests3DI3u9rTV%2Fimage.png?alt=media&#x26;token=8c4799d8-0622-4142-91a5-93fd1816149c" alt=""><figcaption></figcaption></figure>

☑️ Once you’ve verified you’re able to connect to your local server container and play without issues, you may delete the container 🗑️ to free up resources on your machine for other programs.

✅ You may now proceed to the next step.

<details>

<summary>Troubleshooting and FAQ</summary>

Can’t connect clients to server - `Request timed out.` , `请求超时` , `ConnectionFailed` , or `Port verification failed`

* First, make sure that the container is up, and there are no runtime errors in your logs.
* Please verify that your port values in the `docker run` command match.
* Please ensure that your game client is connecting to the **external port** shown on your container details page, this value will be always randomized due to security reasons.
* Please ensure you’ve renamed your target file and configured game builds as described in step [#id-1-configure-project](#id-1-configure-project "mention").

***

My container is up but I’m not able to connect for several minutes afterwards.

* Once a container is up, your game engine initialization begins. This process may take anywhere from seconds to minutes, and the server doesn’t accept to player connections during this period.
* Consider optimizing your server initialization to decrease this time period.
* Game clients should retry connection in 1 second intervals for a limited amount of time (depending on your initialization duration), after which they should return to matchmaking.
* Consider adding a loading scene so the server can perform initialization (and travel in case of Unreal Engine) at the same time as clients, while synchronizing state of both.

***

`Warning: Could not create socket for bind address`

* Please install Epic’s Steam Subsystem plugin through Fab asset store.
* When using Edgegap Integration Kit (EGIK) with SteamCore source version downloaded from github, Epic’s Steam Subsystem plugin is not included due to Epic Games plugin distribution policies.

***

I connected but my screen is completely dark.

* Verify you have the correct **Game Default Map** set under **Edit / Project Settings / Maps & Modes**.

</details>

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

It’s time to ship your server online! Now that your image can successfully host players, we can upload it to Edgegap and start running it anywhere in the world. In this guide, we’ll be using [**Edgegap’s Container Registry**](https://docs.edgegap.com/learn/advanced-features/edgegap-container-registry) (storage for images).

☑️ **Choose an application name** to label and group similar images on Edgegap.

☑️ **Select the image tag you wish to publish** and **Upload Image**. Completing this step will result in uploading your server image to Edgeap Registry and a new [Application version being created](https://docs.edgegap.com/learn/orchestration/application-and-versions) in your web browser. **Make sure to create your** [**port mapping**](https://docs.edgegap.com/learn/orchestration/application-and-versions#port-mapping) **when prompted,** with the default value&#x73;**.**

{% hint style="success" %}
Found a bug and need to rebuild/publish again? Use **Rebuild from Source** to [#id-2.-build-game-server](#id-2.-build-game-server "mention") and [#id-4.-publish-to-edgegap](#id-4.-publish-to-edgegap "mention") **with the current extension input values quickly.**
{% endhint %}

✅ You may now proceed to the next step.

<details>

<summary>Troubleshooting and FAQ</summary>

`denied: adding 756.6 MiB of storage resource, which when updated to current usage of 4.3 GiB will exceed the configured upper limit of 4.7 GiB` , `failed commit on ref "layer-sha256:--------": unexpected status from PUT request to https://registry.edgegap.com/`

* Seems like you’ve run out of image storage space on [Container Registry](https://app.edgegap.com/registry-management/repositories/list). Consider removing unused build artifacts (if you have any) or optimize server build size. If using a custom Dockerfile or .dockerignore, you might be copying some unneeded files into your image.

***

`You have reached you Application limit of 2` , `Unable to update docker tag/version: You have reached you Application Version limit of 2`

* You’ve reached the limits of our Free tier, please consider upgrading your account. Alternatively, you may remove your existing resources through our [Dashboard](https://app.edgegap.com/).

***

My new application version is not listed in the plugin/extension.

* Please ensure you’ve completed app version create form in the last step.

</details>

## 🚀 5. Deploy to Cloud <a href="#id-5-deploy-to-cloud" id="id-5-deploy-to-cloud"></a>

This is the final step in this guide, after which you will have a server deployed on Edgegap cloud, to which players from anywhere in the world can connect.

☑️ **Choose an application and version** from previous step to deploy.

☑️ Once you’re ready, hit **Deploy to Cloud**, wait to reach [#id-3.-deployment-ready](https://docs.edgegap.com/learn/orchestration/deployments#id-3.-deployment-ready "mention"). Completing this step will result in a [new Deployment being started](https://app.edgegap.com/deployment-management/deployments/list) on your Edgegap account.

☑️ Verify there are no new errors in your console output. Ensure also that your [#container-logs](https://docs.edgegap.com/learn/orchestration/deployments#container-logs "mention") don’t show any errors and your [#container-metrics](https://docs.edgegap.com/learn/orchestration/deployments#container-metrics "mention") don’t indicate 100% resource utilization (vCPU or memory), otherwise new player connections may be rejected, or your server stuck in a restart loop. See troubleshooting steps below to address any issues.

☑️ Now we’ll perform the final test and **connect your Unreal Engine Editor to your cloud deployment**. Grab your **Deployment’s Host** in place of server IP and the Deployment’s **external port**, open Unreal console in game client (tilde `~`) and type `open {host}:{port}` .

<figure><img src="https://3027732442-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsR0dHSFv9ymoC0DO5G8J%2Fuploads%2Fz9xjzvZwKSIp9IeC9qo8%2Fimage.png?alt=media&#x26;token=e3f345ac-848d-4469-b66f-3655cd393cf3" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
The external port of your Deployment on Edgegap cloud will be chosen at random, so that a potential attacker (hacker) is slowed down and detected before they can cause damage.
{% endhint %}

{% hint style="warning" %}
**Disable VPN when testing** for more realistic conditions and receive a [low-latency deployment](https://docs.edgegap.com/learn/orchestration/deployments#server-placement).
{% endhint %}

☑️ Once you verify you’re able to connect to your Deployment without issues and are done testing, **Stop your Deployment** to free up capacity in your account for the next build.

* In case you encounter issues, [inspect Dashboard logs of your deployment](https://app.edgegap.com/deployment-management/deployments/list).
* If you can’t figure out the issue, we’re hanging out in our [Community Discord](https://discord.gg/NgCnkHbsGp) and happy to help.

🙌 Congratulations on your first Deployment on Edgegap! If you’d like to learn more, keep reading.

<details>

<summary>Troubleshooting and FAQ</summary>

Can’t connect clients to server - `Request timed out.` , `请求超时` , `ConnectionFailed` , or `Port verification failed`

* First, make sure that the deployment is Ready, and there are no runtime exceptions or errors in your deployment log. If your deployment stopped, inspect logs in our [Dashboard](https://app.edgegap.com/deployment-management/deployments/list).
* Please verify that your port setting in your server build’s netcode settings matches the internal port in your [App version](https://app.edgegap.com/application-management/applications/list). For plugin builds, the port is set for you automatically. You can change the port mapping by editing the [App version](https://app.edgegap.com/application-management/applications/list) without rebuilding. Find your protocol in your netcode integration.
* Please ensure that your game client is connecting to the **external port** shown on your Deployment details page, this value will be always randomized due to security reasons.
* Please ensure you’ve renamed your target file and configured game builds as described in step [#id-1.-configure-project](#id-1.-configure-project "mention").
* Are you located in China and are using [Smart Fleets](https://docs.edgegap.com/docs/deployment/session/fleet-manager/fleet)? Your connection may be blocked by the Great Firewall. Consider adding a server located in China to your fleet, or using a VPN to connect.

***

My deployment is ready but I’m not able to connect for several minutes afterwards.

* Once a deployment is Ready, your game engine initialization begins. This process may take anywhere from seconds to minutes, and the server doesn’t accept to player connections during this period.
* Consider optimizing your server initialization to decrease this time period.
* Game clients should retry connection in 1 second intervals for a limited amount of time (depending on your initialization duration), after which they should return to matchmaking.
* Consider adding a loading scene so the server can perform initialization (and travel in case of Unreal Engine) at the same time as clients, while synchronizing state of both.

***

`Warning: Could not create socket for bind address`

* Please install Epic’s Steam Subsystem plugin through Fab asset store.
* When using Edgegap Integration Kit (EGIK) with SteamCore Integration Kit (SIK) source version downloaded from github, Epic’s Steam Subsystem plugin is not included due to Epic Games plugin distribution policies.

***

I connected but my screen is completely dark.

* Verify you have the correct **Game Default Map** set under **Edit / Project Settings / Maps & Modes**.
* Verify that the [Unreal Engine version compatibility check has been disabled](#id-2.-configure-game-server-builds) in `DefaultEngine.ini`.

***

My deployment stopped/restarted and I can’t access it’s logs anymore.

* In case the server process crashes due to an exception, our system will attempt restarting the server automatically. Consider testing your server locally to uncover the root cause.
* We only keep logs for the duration of the deployment, if you wish to inspect logs after deployment stops, please [integrate a third party log storage](https://docs.edgegap.com/docs/deployment/endpoint-storage).
* See [#id-5.-deployment-stopped](https://docs.edgegap.com/learn/orchestration/deployments#id-5.-deployment-stopped "mention") to discover all causes for stopping your deployment.

***

My deployment stopped automatically after X minutes.

* Free Tier deployments have a 60 minute limit, please consider upgrading your account.
* All deployments will be terminated after 24 hours of runtime following our server sanitization policy, for infrastructure maintenance, and to prevent racking up unexpected costs when deployment wasn’t shut down properly. For long-running servers, consider using [private-fleets](https://docs.edgegap.com/learn/orchestration/private-fleets "mention") with [persistence](https://docs.edgegap.com/learn/orchestration/persistence "mention").
* See [#id-5.-deployment-stopped](https://docs.edgegap.com/learn/orchestration/deployments#id-5.-deployment-stopped "mention") to discover all causes for stopping your deployment.

***

What will happen if a player leaves my deployment?

* By default, servers don’t reject player connections. Authenticating players is up to your devs, since many different methods and player authentication providers can be used.
* Game clients may store connection information locally to attempt reconnecting in case of unexpected client crashes.
* To allow players to join games in progress, consider using [#backfill](https://docs.edgegap.com/learn/matchmaking/matchmaker-in-depth#backfill "mention") or [Sessions](https://docs.edgegap.com/docs/deployment/session).

***

My server shows 100% CPU utilization after becoming ready.

* This may not be an issue, as game engines tend to perform CPU-heavy operations during server initializations. If the CPU usage doesn’t drop after 2-3 minutes from deployment start, you may need to optimize your server or increase app version resources.
* Reducing tick rate can help control CPU usage due to processing less messages.
* You’re limited to 1.5 vCPU and 3GB of memory (RAM) in Free Tier.
* You may increase allocated resources when creating a new app version. You can duplicate your App version in our Dashboard and adjust these values as needed, without rebuilding your server or image.

***

My deployment is restarting repeatedly and shows error `OOM kill`

* This is caused by exceeding allocated memory amount. Consider optimizing memory usage with object pooling, compression, or removing unneeded objects in your scene.
* You’re limited to 1.5 vCPU and 3GB of memory (RAM) in Free Tier.
* You may increase allocated resources when creating a new app version. You can duplicate your App version in our Dashboard and adjust these values as needed, without rebuilding your server or image.

***

Sometimes, my server’s memory (RAM) usage spikes to a high value, is that a problem?

* As long as you stay within the allocated app version memory amount, this is not an issue.
* Exceeding the allocated app version memory amount will cause `OOM kill` (see above).

***

Will my server performance be impacted by other servers running on the same machine?

* No, our platform ensures that allocated resources will not be used by other studios, or other servers on shared infrastructure. With Edgegap, there are no noisy neighbors.

</details>

## 👉 Next Steps

Once you have a working client/server setup, make sure to **save a copy of your project** (using version control software like git) so you can always trace back your steps in case you run into issues.

Continue reading to learn more about topics related to server lifecycle and discoverability.

### Stop Deployments

Learn about various methods to [stop deployments](https://docs.edgegap.com/learn/orchestration/deployments#id-5.-deployment-stopped) once the match concludes and players leave.

If you followed this guide and built with our Docker Extension, you can simply call method `FGenericPlatformMisc::RequestExit` . We've added a script managing your server process in the packaged image, which will automatically perform a graceful deployment shutdown.

To customize server lifecycle management, modify our [example `StartServer.sh`](https://github.com/edgegap/edgegap-unreal-buildutils/blob/main/StartServer.sh)  script.

{% hint style="info" %}
Prefer managing lifecycle from Unreal? See [#integration-kit](https://docs.edgegap.com/developer-tools#integration-kit "mention") for self-stop API blueprint.
{% endhint %}

{% hint style="warning" %}
Connect your [endpoint-storage](https://docs.edgegap.com/docs/endpoint-storage "mention") to get your deployment logs, otherwise they will be deleted!
{% endhint %}

### Injected Variables

Read useful information like deployment ID, server IP address, server location, and more; by accessing injected environment variables. Each deployment automatically includes:

* [Deployment Variables](https://docs.edgegap.com/learn/orchestration/deployments#injected-environment-variables) - automatically supplied by Edgegap,
* [Matchmaking Variables](https://docs.edgegap.com/learn/matchmaking/matchmaker-in-depth#injected-environment-variables) - automatically supplied by Edgegap when using [matchmaking](https://docs.edgegap.com/learn/matchmaking "mention"),
* [App Version Variables](https://docs.edgegap.com/learn/orchestration/application-and-versions#injected-variables) - custom key-value pairs configurable by you.

**Verify if the current instance is a game client or server** by checking if Edgegap variable is set:

```cpp
if (
  FPlatformMisc::GetEnvironmentVariable(TEXT("ARBITRIUM_REQUEST_ID")).empty()
)
{
  // client code
} else {
  // server code
}
```

### Profiling Servers

To understand and optimize server performance issues on Edgegap, explore [#container-logs](https://docs.edgegap.com/learn/orchestration/deployments#container-logs "mention"), [#container-metrics](https://docs.edgegap.com/learn/orchestration/deployments#container-metrics "mention"), and more [#dashboard-monitoring](https://docs.edgegap.com/learn/orchestration/deployments#dashboard-monitoring "mention") tools at your disposal.

You can also use existing Unreal Engine profiling tools with Edgegap:

* [Configure tracing in your Unreal Engine server](https://dev.epicgames.com/documentation/en-us/unreal-engine/developer-guide-to-tracing-in-unreal-engine) (built-in and custom events):
  * save trace on server disk with `-tracefile`, upload to 3rd party storage and analyze offline,
  * or stream trace data with [#port-mapping](https://docs.edgegap.com/learn/orchestration/deployments#port-mapping "mention") for internal port `1981` over UDP protocol.
* Analyze [Memory Insights](https://dev.epicgames.com/documentation/en-us/unreal-engine/memory-insights-in-unreal-engine) and [Networking Insights](https://dev.epicgames.com/documentation/en-us/unreal-engine/networking-insights-in-unreal-engine) and [#optimize-server-builds](#optimize-server-builds "mention").

### Matchmaking

Starting your Deployments manually, pasting URL and ports will not cut it for a live game.

{% hint style="success" %}
[**Read more about Matchmaking**](https://docs.edgegap.com/learn/matchmaking) **to deploy automatically, just in time**, when players come online.
{% endhint %}

### Optimize Server Builds

**Configure asset chunking to isolate client-only assets from server assets.**

* Explore [Asset Chunking techniques and recommendations](https://dev.epicgames.com/documentation/en-us/unreal-engine/preparing-assets-for-chunking-in-unreal-engine) by Epic.

**Exclude assets and plugins which are client-only, and not required for server to run.**

* Learn about [build-time asset and plugin exclusion](https://dev.epicgames.com/community/learning/tutorials/Kp1k/unreal-engine-build-time-asset-and-plugin-exclusion).

**Review your content cooking strategy.**

* Consider [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) to delay cooking client assets and speed up server builds.

**Implement Level Streaming to reduce runtime memory load.**

* If your design keeps players mostly together in the same map area, [level streaming may cut down your server's memory usage](https://dev.epicgames.com/documentation/en-us/unreal-engine/level-streaming-in-unreal-engine) by more than 60%, and improve client performance!

**Only include what you absolutely need for your server to run.**

* Copying unused files in your images results in image bloat, longer uploads, slower caching speeds, and slower overall server startup. [Review Docker image optimization suggestions](https://docs.docker.com/build-cloud/optimization/#dockerignore-files).

<details>

<summary>Example <code>.dockerignore</code> file to remove extra files.</summary>

```docker
# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app
*.ipa

# These project files can be generated by the engine
*.xcodeproj
*.xcworkspace
*.sln
*.suo
*.opensdf
*.sdf
*.VC.db
*.VC.opendb

# Precompiled Assets
**/SourceArt/**/*.png
**/SourceArt/**/*.tga

# Builds
**/Build/*

# Whitelist PakBlacklist-<BuildConfiguration>.txt files
!**/Build/*/
**/Build/*/**
!**/Build/*/PakBlacklist*.txt

# Don't ignore icon files in Build
!**/Build/**/*.ico

# Configuration files generated by the Editor
**/Saved/*
**/Intermediate/*
**/DerivedDataCache/*
**/Binaries/*
**/Build/*
**/Releases/*
**/Packaged/*
```

</details>

**Consider using** [**multi-stage Docker builds (link)**](https://docs.docker.com/build/building/multi-stage/)**.**

* Separate large server dependencies to a separate image to reuse in multi-stage builds. Docker will cache each layer and simply reuse the previous version and skip uploading this part unless specifically instructed to do so, saving you bandwidth and time waiting for the upload to finish.
* If you’re not sure why one of your Dockerfile commands throws an error, try debugging locally. Create a new stage just before the issue happens (add a second `FROM` command), use `--target` to instruct the build process to stop at the problematic stage, and then `docker exec -it {container} /bin/bash` to enter interactive terminal inside your container. Afterwards, you can use shell commands in your base image to investigate further (e.g. `top` on ubuntu).

### Customize Server Image

We also support adding your own Dockerfile for users who need more control over their images due to build size optimization, extraneous dependencies, or requiring more complex startup process. We’ll now share a few “do it yourself” tips and best practices.

**Always make sure you are working with a functioning server build.**

* Before assuming an issue is related to the custom Dockerfile, ensure your Unity server build can be started, and that the build process in Unity didn’t throw any exceptions or errors.

**Always test locally before uploading.**

* Testing your image locally will save you lots of time while waiting for the upload to finish. It’s also entirely free ✨ as it doesn’t require any Edgegap resources.
* When testing locally, make sure to set your internal port correctly:

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

**Make sure you’ve got the basics down. Every Dockerfile needs a few essential commands:**

* `FROM {image}` is your base image, for Unity projects we usually use a long-term supported Linux, but any Linux-based base image will do. These are usually public images stored on dockerhub. Dockerfile reference here. [Dockerfile reference here](https://docs.docker.com/reference/dockerfile/#from).
* `COPY {source} {destination}` to copy your linux server build from your host machine inside the image, so you can start it later on. [Dockerfile reference here](https://docs.docker.com/reference/dockerfile/#copy).
* `USER {user}` should follow after a [useradd (ubuntu) command](https://manpages.ubuntu.com/manpages/bionic/man8/useradd.8.html) or equivalent, it’s best not to run everything as `root` to be on the safer side. [Dockerfile reference here](https://docs.docker.com/reference/dockerfile/#user).
* `CMD {command}` will be the last line, most likely calling a `StartServer.sh` or some kind of startup script to make sure your server initializes correctly once everything is set up. [Dockerfile reference here](https://docs.docker.com/reference/dockerfile/#cmd).
* do NOT use `VOLUME` - you will not be able to mount any local storage this way on Edgegap, consider our Endpoint Storage feature instead and use an S3 bucket, see [Endpoint Storage](https://docs.edgegap.com/docs/deployment/endpoint-storage),
* `EXPOSE 7777/UDP`  is not required! This will not actually make the internal server port available from outside the container, it's only a hint for the developer and the port needs to be
  * published when testing locally with `docker run <image> -p 7777/udp` ,
  * or mapped in [Edgegap Port Mapping](https://docs.edgegap.com/learn/orchestration/application-and-versions#other-parameters-optional).

**Delay declaration of parameters until latest possible moment. Configurability > composability due to long server build times.** [**Apply this approach to Dockerfile commands to build and upload faster.**](https://medium.com/@esotericmeans/optimizing-your-dockerfile-dc4b7b527756)

* Scenario: you need to define parameters like deployment stage, version, game mode, map, player count per server, backup frequency, or similar.
* Bad solution: creating a separate image for every combination of your parameters. You will spend all of your time rebuilding the images with very little benefits from this approach.
* Better solution - substitute configuration parameters just in time:
  1. deployment parameters - supplied just before the deployment is made - matchmaking selectors passed as environment variables, or your custom session management system passing environment variables at deployment time,
  2. version parameters - shared for all deployments on an app version - deployment stage, artifact tag, third party secrets and endpoints, and similar; then
  3. one single image - contains and loads all configuration options when launched.

**Do NOT run databases on Edgegap deployments.**

* Edgegap deployments are not intended for long-running processes and may be terminated after a long period of runtime without prior notice. A database (even if distributed) running in this manner may be terminated and result in an irreversible loss of data. If you need a database, please consider a third party DBaaS.
* Consider using our [Managed Clusters](https://app.edgegap.com/cluster-management/clusters/list) for hosting databases and long running services.

[^1]: Personal Access Token

[^2]: disable compatibility check

[^3]: use IpNetDriver

[^4]: set client/server tick rates and timeout

[^5]: set server build as default target

[^6]: enable logs

[^7]: don't use checks

[^8]: don't package editor content

[^9]: don't package Slate UI (editor)

[^10]: don't compile CEF3 (editor)

[^11]: create parent directory

[^12]: copy the steamclient.so file

[^13]: allow executing steam client

[^14]: find in your steam publisher portal


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.edgegap.com/unreal-engine.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
