> 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/unity-netcodes/playfab-mps-mirror.md).

# PlayFab MPS Mirror

PlayFab's Unity Mirror Multiplayer Servers sample, moved to Edgegap: no GSDK, servers started on request near the players, and an allocator tool on the Edgegap API.

Explore how to move a game server from **PlayFab Multiplayer Servers** (MPS) to **Edgegap** with the [PlayFab MPS Mirror sample](https://github.com/edgegap/backend-game-sample-unity-mirror-playfab-mps), a fork of Microsoft's [MpsSamples](https://github.com/PlayFab/MpsSamples) where the `UnityMirror` sample runs on Edgegap.

There is no matchmaker in this sample. You start a server with a small command-line tool, the counterpart of PlayFab's `MpsAllocatorSample`, and connect clients to the address it prints. The server stops itself when the players leave.

This sample shows:

* **Unity 2021.3.45f2** server and client on **Mirror** (Telepathy, TCP 7777), the server built as a Linux dedicated server with the [Edgegap Unity plugin](https://github.com/edgegap/buildtool-unity-plugin),
* **no GSDK**: the server listens on a fixed port at startup, with no agent, heartbeat or ready call,
* **EdgegapAllocatorSample**: a .NET console app that starts a server near the players and waits for its address, lists versions and deployments, and stops a deployment, using the [Edgegap API](/docs/api/dedicated-servers.md),
* **server self-stop**: the server stops its own deployment when nobody joins, or after everyone has left.

{% hint style="info" %}
Verified on Edgegap on 29 October 2026: the allocator started a server in Toronto within seconds, two Windows clients connected, and the server stopped its own deployment after they quit.
{% endhint %}

{% hint style="success" %}
Using PlayFab Matchmaking? [Deploy from PlayFab](/docs/tools-and-integrations/playfab-bridge.md) starts an Edgegap server for every match.
{% endhint %}

## 🗺️ From MPS to Edgegap

| PlayFab Multiplayer Servers                                 | Edgegap                                                                                                                                                                   |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GSDK `Start`, `ReadyForPlayers`, listen on `OnServerActive` | Listen on the fixed port 7777 at startup (`EdgegapServer.cs`).                                                                                                            |
| Port from `GetGameServerConnectionInfo`                     | A fixed internal port on the app version. Edgegap maps it to a public port.                                                                                               |
| `UpdateConnectedPlayers`                                    | Not needed. The server only counts players to know when to stop.                                                                                                          |
| `OnShutDownCallback`                                        | Edgegap sends SIGTERM. Players get the same `ShutdownMessage` when Unity quits.                                                                                           |
| Build, VM size, servers per VM, standby servers             | App version: the image, 0.5 vCPU / 1 GB per server, port `gameport` TCP 7777. Nothing is pre-provisioned.                                                                 |
| `RequestMultiplayerServer`                                  | `POST /v2/deployments` with the players' IPs or coordinates (`EdgegapAllocatorSample`).                                                                                   |
| The server runs until MPS shuts it down                     | The server stops its own deployment through `ARBITRIUM_DELETE_URL`, [injected into every deployment](/learn/orchestration/deployments.md#injected-environment-variables). |

## ✔️ Preparation

Before we start, you will need:

* Unity `2021.3.45f2` with **Linux Build Support** and **Linux Dedicated Server Build Support**,
* [Docker Desktop](https://www.docker.com/products/docker-desktop/), running,
* the [.NET SDK](https://dotnet.microsoft.com/download) 8 or newer, for the allocator,
* the sample project - [download from GitHub](https://github.com/edgegap/backend-game-sample-unity-mirror-playfab-mps),
* an Edgegap API token from [Dashboard → User Settings → Tokens](https://app.edgegap.com/user-settings?tab=tokens). It stays on your machine or in your backend, never in a game client.

## ⚡ Deploy and Connect

### 1. Build and Upload the Server

Open `UnityMirror/UnityServer` in Unity, then **Tools → Edgegap Server Hosting**:

1. **Sign in with Edgegap**, then **Build server**.
2. **Containerize with Docker**: image name `mps-unity-mirror`, image tag empty (the plugin uses the current UTC time).
3. Optional local check: run parameters `-p 7777:7777/tcp`, then **Deploy local container**.
4. **Upload to Edgegap**: application `mps-unity-mirror`, then **Upload image and Create app version**. In the version form, set one port named `gameport`, 7777, **TCP**, 0.5 vCPU / 1 GB and a max duration of 60 minutes. If the form asks for registry credentials, use the username and token from the dashboard's **Container Registry** page.

From the command line, for CI or scripted tests:

```bash
"<Unity>" -batchmode -projectPath UnityMirror/UnityServer -executeMethod EdgegapPluginBuild.BuildServer -logFile build-server.log
```

### 2. Start a Server

Run the allocator with your token, application and version:

```bash
cd EdgegapAllocatorSample
export EDGEGAP_API_TOKEN="token xxxxxxxx" EDGEGAP_APP=mps-unity-mirror EDGEGAP_VERSION=<version name>
dotnet run -- deploy <your public IP>
```

It prints the client argument, for example `-server 1a2b3c.pr.edgegap.net:31202`, once the server is ready. Without arguments, `dotnet run` opens a menu to list versions and deployments, or stop a deployment.

### 3. Connect Clients

Build `UnityMirror/UnityClient` for Windows, then start it with the address:

```bash
"<Unity>" -batchmode -quit -projectPath UnityMirror/UnityClient -buildTarget Win64 -buildWindows64Player Builds/Client/win64/Client.exe
UnityMirror/UnityClient/Builds/Client/win64/Client.exe -server <host>:<port>
```

Quit the clients: the server stops its deployment 30 seconds after the last player leaves, or 120 seconds after start if nobody joins.

{% hint style="info" %}
The free tier runs one deployment at a time: stop other deployments before you test.
{% endhint %}

## 🔧 Known Limits

* **No matchmaker.** Servers are started from the allocator or the dashboard. For players, start them from your backend, or use [Deploy from PlayFab](/docs/tools-and-integrations/playfab-bridge.md) or the [Edgegap Matchmaker](/learn/matchmaking.md).
* **The server doesn't check who connects.** For production, pass the expected players to the deployment as environment variables, and reject others.
* **Edgegap Unity plugin 3.2.1** prints the environment before the server starts, so the deployment logs show its self-stop token. Remove `env;` from the plugin Dockerfile's `CMD` if your logs are shared.
