> 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/sample-projects/godot/arena-shooter.md).

# Arena Shooter

Host a Godot 4 multiplayer arena shooter on Edgegap with dedicated servers and matchmaking, using the Edgegap Arena Shooter sample.

Explore how to host Godot projects on Edgegap using techniques from the [Super Star Fighter](https://github.com/DumpsterFireLabs/SuperStarFighter) top-down arena shooter by Dumpster Fire Labs.

Players press **FIND MATCH**, the [Edgegap Matchmaker](/learn/matchmaking.md) groups them and starts a dedicated server near them, and the server stops itself when the match is over.

This sample shows:

* **Godot 4.7.2** game with GDScript, exported as a headless Linux dedicated server,
* **server-authoritative netcode** over one WebSocket port - the server runs the whole simulation, and clients connect with `wss://`,
* **Edgegap Matchmaker** integration - the client creates a ticket, waits for a server, then joins it,
* **server self-stop** - the server stops its own deployment after the match, or when nobody joins,
* **NPC fill** - NPCs take empty seats, so a solo player still gets a match.

{% hint style="success" %}
See [EDGEGAP.md](https://github.com/edgegap/godot-sample-arena-shooter/blob/main/EDGEGAP.md) in the sample repository for the full list of Edgegap files and server settings.
{% endhint %}

## ✔️ Preparation

Before we start, you will need:

* Arena Shooter Sample project (modified for Edgegap) - [download from GitHub](https://github.com/edgegap/godot-sample-arena-shooter),
* Godot 4.7.2 - the sample downloads its own copy (see below),
* Python 3 - to run the sample's build script.

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

☑️ Download the pinned Godot version and export templates into the ignored `.tools` folder, from PowerShell in your repository root:

{% code collapsedlinecount="10" %}

```powershell
.\tools\bootstrap.ps1
```

{% endcode %}

Nothing is installed system-wide.

## ⚡ Deploy and Connect

### 1. Build the Server Image

☑️ To get started, you'll need to [create a free account with Edgegap](https://app.edgegap.com/auth/register). No credit card required.

☑️ Find your [Container Registry](/learn/advanced-features/edgegap-container-registry.md#getting-your-credentials) project name and credentials, then log in with `docker login registry.edgegap.com`.

☑️ Export the Linux dedicated server, then build and push your image:

{% code collapsedlinecount="10" %}

```bash
python tools/build.py bootstrap
python tools/build.py build server-linux-x64 --skip-gate
docker build --platform linux/amd64 -f edgegap/Dockerfile -t registry.edgegap.com/<project>/arena-shooter:<tag> builds/beta-19/server-linux-x86_64
docker push registry.edgegap.com/<project>/arena-shooter:<tag>
```

{% endcode %}

{% hint style="danger" %}
:x: **DO NOT - overwrite existing tags or use `latest` tag** - this will deploy an outdated cache.\
:white\_check\_mark: **DO - always increase your version tag** and deploy the new build.
{% endhint %}

Your server listens on WebSocket port `7000`. Outside an Edgegap deployment, it behaves exactly like the upstream game.

✅ You may now proceed to the next step.

### 2. Create an App Version

☑️ [Create an application](https://app.edgegap.com/application-management/applications/list) named `godot-arena-shooter`, and a version named `v1` with:

* your `registry.edgegap.com/<project>/arena-shooter:<tag>` image,
* your Container Registry username and token, so Edgegap can pull your image,
* resources 0.5 vCPU and 1 GB memory,
* [port](/learn/orchestration/application-and-versions.md#port-mapping) `7000`, named `gameport`, protocol **WS**, with **TLS Upgrade** enabled.

{% hint style="warning" %}
Clients connect with `wss://`, so **TLS Upgrade must be enabled**, otherwise clients can't connect. See [Websockets (WS) and Secure Websockets (WSS)](/learn/orchestration/deployments.md#websockets-ws-and-secure-websockets-wss).
{% endhint %}

Optionally, set environment variables on your app version:

* `EDGEGAP_NPC_FILL` - fill the match with NPCs up to this many ships (default `4`, `0` disables NPCs),
* `EDGEGAP_START_GRACE` - seconds to wait for all matched players after the first one joins (default `30`),
* `EDGEGAP_JOIN_TIMEOUT` - seconds before an empty server stops itself (default `120`),
* `EDGEGAP_ROUNDS_TO_WIN` - rounds needed to win the match (default `3`).

✅ You may now proceed to the next step.

### 3. Create a Matchmaker

☑️ Open [Matchmaker](https://app.edgegap.com/matchmaker-management-v2/matchmakers/list) page in dashboard and click **Create**.

☑️ Upload `edgegap/matchmaker-config.json` from the sample. Change `application.name` and `application.version` if yours are different.

The config has one `casual` profile for 2 to 4 players. After 30 seconds of waiting, a single player can be matched alone.

☑️ Click **Create and Start**, and wait for your matchmaker to be ready.

☑️ Copy your matchmaker's **API URL** and **Auth Token**.

✅ You may now proceed to the next step.

### 4. Connect the Client

☑️ Paste your matchmaker URL and Auth Token into `src/client/edgegap/edgegap_settings.gd`:

{% code collapsedlinecount="10" %}

```gdscript
const MATCHMAKER_URL := "https://<your-matchmaker-url>"
const MATCHMAKER_AUTH_TOKEN := "<your-auth-token>"
```

{% endcode %}

You can also set `EDGEGAP_MATCHMAKER_URL` and `EDGEGAP_MATCHMAKER_TOKEN` environment variables when launching your client.

{% hint style="info" %}
The Auth Token belongs to your matchmaker and gives no access to your Edgegap account, so it's safe to ship in game clients. **Never put your Edgegap API token in the client.**
{% endhint %}

☑️ Build a Windows client with `python tools/build.py build windows --skip-gate`, or run `.\tools\start-client.ps1`.

☑️ Start two clients and press **FIND MATCH** in both.

Both clients get the same server and join it. The match starts when every matched player is in, or 30 seconds after the first one joined, with NPCs in empty seats.

🙌 Congratulations on your first matchmade Deployment on Edgegap!

## 🔄 Match Lifecycle

1. Client creates a ticket with `casual` profile, then checks it every 2 seconds until a server is assigned.
2. Matchmaker deploys `godot-arena-shooter` near the players. Server reads how many players were matched from [`MM_TICKET_IDS`](/learn/matchmaking/matchmaker-in-depth.md#injected-variables).
3. Client joins `wss://<host>:<external port>` through the game's Direct Connect code. The lobby password is the deployment's request ID, so only matched players get in.
4. Server starts the match and fills empty seats with NPCs, up to 4 ships.
5. 20 seconds after final results, server calls `ARBITRIUM_DELETE_URL` to stop its deployment. It also stops if nobody joins within 120 seconds, or if everyone leaves for 30 seconds.

Each deployment runs one match. After a match, players press **FIND MATCH** again.

See [Matchmaking](/learn/matchmaking.md) and [Deployments](/learn/orchestration/deployments.md) to learn more.

## 🎵 Changes from Upstream

The upstream asset license reserves the game's name, music and studio logo for unmodified builds. This fork is renamed to Edgegap Arena Shooter, with music and logo removed. Sound effects are generated in code and still play.
