> 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/godot.md).

# Godot - Getting Started

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.

## ✔️ 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).
* Restart your computer after completing the installation.

</details>

<details>

<summary><a href="https://github.com/edgegap/edgegap-godot-plugin">Install Edgegap's Godot Dedicated Servers Quickstart Plugin</a></summary>

This plugin has been tested on, and supports Godot versions 4.x.x and newer.

Option 1) Install from ZIP:

1. [Download the latest ZIP archive.](https://github.com/edgegap/edgegap-godot-plugin/archive/refs/heads/main.zip)
2. Extract ZIP to your project's `addons` folder.

{% hint style="info" %}
To update plugin installed with ZIP delete the old plugin and replace with new ZIP.
{% endhint %}

Option 2) Install from Source:

1. [Install a git client (for example git-scm)](https://git-scm.com/).
2. Clone our plugin repository in your project's `addons` folder.

```
git clone git@github.com:edgegap/edgegap-godot-plugin.git
```

{% hint style="info" %}
To update plugin installed with git, open command line in the plugin folder and run `git pull`.
{% endhint %}

</details>

{% hint style="info" %}
**Enable your new Edgegap Servers Quickstart plugin under Project / Project Settings / Plugins.** A new tab labeled "Edgegap" willl appear in your right-side panel, next to Inspector. If you close the panel later and need to reopen it, you can find the option under Project / Tools / Edgegap.
{% endhint %}

## ⚙️ 1. Connect Account

☑️ Sign in and verify there are no new errors in your Output related to Edgegap's plugin.

✅ You may now proceed to the next step.

## 🔧 2. Build Game Server

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 to accomplish this with our plugin.

☑️ **Validate Export Templates to ensure the plugin correctly set up your linux server template.**

{% hint style="info" %}
**Advanced users** - optionally customize [export template](https://docs.godotengine.org/en/latest/tutorials/export/exporting_projects.html). Caution! This may break your build.
{% endhint %}

☑️ **Add new bootstrap script to your project, to automatically launch as dedicated server.** Create a new node under your main scene, and link the new script under Inspector / Script / Load.

{% tabs %}
{% tab title="Default Bootstrap Example" %}
This is a minimal template script which can be extended to fit your project's needs.

{% file src="/files/VPnqO9AQ7sdi9AuiR9DQ" %}
{% endtab %}

{% tab title="Netfox Forest Brawl Example" %}
This is a customized version of the bootstrap script for [netfox forest brawl](#netfox-forest-brawl-example) sample.

{% file src="/files/LsGF6ftVaaQtVRZFsFiG" %}
{% endtab %}
{% endtabs %}

{% hint style="success" %}
Server builds usually default to port `7777`. If you customize your port please specify the sam~~e~~ in your [Apps and Versions](/learn/orchestration/application-and-versions.md#port-mapping) once you [#id-5.-upload-to-edgegap](#id-5.-upload-to-edgegap "mention").
{% endhint %}

☑️ Once you’re happy with your configuration hit **Build server**, wait for the process to finish and verify there are no new errors in your Output. Completing this step will result in a **new build appearing in your project under folder** `build`**.**

✅ You may now proceed to the next step.

## 🐋 3. Containerize Server

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

☑️ Start by hitting the **Validate Docker** button to ensure you’ve completed [#preparation](#preparation "mention").

<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).
* Restart your computer after completing the installation.

</details>

☑️ 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. `2026.07.30-16.25.00-UTC` .
* **Path to Dockerfile** can be used to customize the recipe for your images.
  * We recommend keeping the default setting for now, you can read more later in section [#customize-image](#customize-image "mention").
* **Optional docker build parameters** can be used to further instruct Docker on finer nuances.
  * We recommend keeping the default setting for now, you can [read more later in Docker docs](https://docs.docker.com/reference/cli/docker/image/build/#options).

{% hint style="info" %}
**Rebuild from Source** will automatically build and containerize, to **speed up your next build**.
{% endhint %}

☑️ Once you’re happy with your configuration hit **Containerize with Docker**, wait for the process to finish and verify there are no new errors in your Output. Completing this step will result in a **new image appearing in your local machine**. You can verify this either in Docker Desktop, in tab Images underneath Local (default), or in docker CLI by running `docker images` .

✅ You may now proceed to the next step.

## 🧪 4. Test Server Locally

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

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

* **Server image tag** from the previous step.
  * Defaults to the last tag you’ve built with the plugin.
  * :cloud: appearing in front of your image name indicates this image has been uploaded.
* **Optional docker run parameters** can be supplied for exposing multiple ports, or running your image on macOS machines.
  * You may publish multiple ports for your container if needed, simply add the parameter `-p {internal port}/{protocol}` for each, for example `-p 8080/tcp -p 7777/udp` to publish and map your server port `8080` to a random external port for TCP connection and server port `7777` to a random external port for UDP connection at the same time. **Find server port configuration in your bootstrap script.**
  * If you’re using a machine with ARM architecture (macOS M1, M2, M3, etc..) you should see this optional parameter included in your Optional docker build parameters: `--platform=linux/amd64` .

☑️ Once you’re happy with your configuration hit **Deploy local container**, wait for the process to finish, and verify there are no new errors in your Output. Completing this step will result in a **new container being started** on your development machine.

{% hint style="info" %}
For more details see Docker Desktop / Containers, or Docker CLI command `docker ps` .
{% endhint %}

☑️ Now it’s time to **connect your Godot Editor game client to your local docker container** to verify your server image is functioning properly. Find your client connection details and input:

* `localhost` or `0.0.0.0` (equivalent in most cases) in place of server IP,
* randomized external port value found in Docker Desktop / Containers.

<figure><img src="/files/hxCzzJZwAV68VDKInc91" 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.

## ☁️ 5. Upload to Edgegap

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**](/learn/advanced-features/edgegap-container-registry.md) (storage for images).

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

* **Application name** on Edgegap can match your image name or be customized.
  * We’ve chosen to copy your image name for now.
* **Application version** on Edgegap can match your tag or be customized.
  * Timestamps are a great option for app version names, e.g. `2024.01.30-16.50.20-UTC` .
  * Multiple application versions may point to the same image tag, such as `v1.1.0` and `dev` .
  * Learn more about [Apps and Versions](/learn/orchestration/application-and-versions.md) later.
* **Server image** from step [#id-3.-containerize-server](#id-3.-containerize-server "mention").

{% hint style="success" %}
Find any image name and tag stored on your machine in **Docker Desktop / Images**.
{% endhint %}

☑️ Once you’re happy with your configuration hit **Upload image and create App version**, wait for the process to finish, and verify there are no new errors in your Output.

☑️ You will be brought to our [Dashboard](https://app.edgegap.com/), where you may configure optional settings. Completing this step will result in a [new Application version being created](https://app.edgegap.com/application-management/applications/list), and your [build artifact being tagged and uploaded to Edgegap’s Container Registry](https://app.edgegap.com/registry-management/repositories/list).

* **Application version** on Edgegap can match your tag or be customized.
  * Timestamps are a great option for app version names, e.g. `2024.01.30-16.50.20-UTC` .
  * Multiple application versions may point to the same image tag, such as `v1.1.0` and `dev` .
  * Learn more about [Apps and Versions](/learn/orchestration/application-and-versions.md) later.

☑️ You will now be prompted to define a Port for your new Application version. Make sure to set the same server port value as in step [#id-4.-test-server-locally](#id-4.-test-server-locally "mention") (defaults to 7777).

✅ You may now proceed to the next step.

## 🚀 6. Deploy to Cloud

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 [/pages/0UXQAhtFuL0FkdoUmYTh#id-3.-deployment-ready](https://docs.edgegap.com/pages/0UXQAhtFuL0FkdoUmYTh#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 [Deployments](/learn/orchestration/deployments.md#container-logs) don’t show any errors and your [Deployments](/learn/orchestration/deployments.md#container-metrics) 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 Godot Editor game client to your cloud deployment**. Find your client connection details and input:

* **Host** **URL** pointing to server's IP,
* **External port** mapping to the [server's internal listen port](/learn/orchestration/application-and-versions.md#port-mapping).

<figure><img src="/files/BwcOdlJqXkoYOKEKZU4u" 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](/learn/orchestration/deployments.md#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.

## 👉 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.

{% hint style="info" %}
If you need help, [please reach out to us over Discord](https://discord.gg/MmJf8fWjnt). For live games support see our [ticketing system](https://edgegap.atlassian.net/servicedesk/customer/portal/3).
{% endhint %}

### Stop Deployments

Once the match ends (or players leave), your deployment can be stopped to save cost. [Running empty or only partially filled can increase your cost unnecessarily!](https://edgegap.com/blog/how-session-fill-rate-affects-your-multiplayer-hosting-costs)

{% hint style="success" %}
Godot Script examples are coming soon!
{% endhint %}

{% hint style="warning" %}
Connect your [Endpoint Storage](/docs/endpoint-storage.md) to save 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](/learn/orchestration/deployments.md#injected-environment-variables) - automatically supplied by Edgegap,
* [Matchmaking Variables](/learn/matchmaking/matchmaker-in-depth.md#injected-environment-variables) - automatically supplied by Edgegap when using [Matchmaking](/learn/matchmaking.md),
* [App Version Variables](/learn/orchestration/application-and-versions.md#injected-variables) - custom key-value pairs configurable by you.

{% hint style="success" %}
Godot Script examples are coming soon!
{% endhint %}

### Session Automation

{% hint style="warning" %}
**Starting your Deployments manually, pasting URL and ports will not cut it for a live game.**
{% endhint %}

Automate popular game flows for managing sessions and scaling on demand with either:

{% columns %}
{% column width="33.33333333333333%" %}
[Matchmaking](/learn/matchmaking.md):

* Shorter Rounds
* On-Demand Matches
* Skill Rating and/or\
  Custom Rules
  {% endcolumn %}

{% column width="33.33333333333333%" %}
[Server Browser](/learn/server-browser.md):

* Persistent or Rounds
* Social Regional Hubs
* Auto-Assign and/or\
  Custom Search
  {% endcolumn %}

{% column width="33.33333333333333%" %}
Custom Backend:

* Migrate Live Games
* [Deploy with v2 API](/docs/api/dedicated-servers.md)
* [Observe Webhooks](/learn/orchestration/deployments.md#webhooks)
  {% endcolumn %}
  {% endcolumns %}

{% hint style="success" %}
Godot Script examples are coming soon!
{% endhint %}

### Optimize Usage

A few tips to get started with optimizing your server usage:

**Higher tick rate means more updates, requiring more CPU usage and data egress.**

* Godot defaults to 60 ticks per second, which works great for fast paced shooters or highly latency-sensitive games. Other genres may get away with 30 Hz or even 15 Hz.
* The hidden cost of higher tick rate is more CPU cycles (per second) to (un)pack data, and recompute server-authoritative properties and procedures. Tread carefully if your game has many players per match (10+), many nodes with colliders, complex physical simulations, or many bot opponents/teammates.
* Test game responsivness with different tick rates in your netcode settings. For ENET, see Project Settings / Physics / Common / Physics Ticks Per Second.

**How to choose the right networking protocol? Make it work first, then make it better.**

* Godot's built-in ENET with default UDP protocol is a great default choice providing performance and compatibility across the biggest range of devices and use cases.
* Some games may want to experiment with TCP, WS, WebRTC or other protocols. This may improve your connection reliability with mobile devices and consoles, especially on public networks (cellular, corporate, e-cafe, hotel wifi, etc...), but it will certainly require extra development efforts. Ask yourself if this is critical for your target audience.
* Using multiple protocols side by side to ensure important updates are delivered with priority can improve player experience for some genres (e.g. MMO), but it comes with a lot of added development effort, and can add tremendous complexity to your project.
* Pick your battles carefully, game development has no shortage of challenges.

### Customize 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. You may optionally supply a path to your custom Dockerfile in step [#id-3.-containerize-server](#id-3.-containerize-server "mention"). 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 server build can be started, and that the build process in your game engine 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, 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](/learn/orchestration/application-and-versions.md#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.
