Using Photon Fusion with Gameye
Photon Fusion is a Unity networking library with client-side prediction, data compression, and lag compensation. Its Dedicated Server mode runs an authoritative server with no player host.
Gameye is officially documented as a hosting provider in Photon’s own technical docs. You build a Fusion Dedicated Server for Linux, wrap it in a Docker container, and Gameye handles deployment and lifecycle globally.
Prerequisites
Section titled “Prerequisites”- Unity project using Photon Fusion with Dedicated Server mode
- A Gameye API token (request sandbox access)
- Docker Hub account for publishing your server image
- Gameye application configured with your image during onboarding
Step 1: Build your Fusion Dedicated Server
Section titled “Step 1: Build your Fusion Dedicated Server”Follow Photon’s Fusion Dedicated Server sample to produce a headless Linux server build from your Unity project. The build should target Linux 64-bit (IL2CPP or Mono), with no display or audio.
Test the binary locally before containerising:
./FusionDedicatedServer.x86_64 -batchmode -nographics -s my-session -r euIf the server starts and logs “Server ready” (or your equivalent), it’s ready to containerise.
Step 2: Create the Docker image
Section titled “Step 2: Create the Docker image”Follow Photon’s Fusion Dedicated Server Docker Image guide to wrap the Linux build in a Docker container.
The minimal Dockerfile pattern:
FROM ubuntu:22.04RUN apt-get update && apt-get install -y --no-install-recommends \ libssl3 ca-certificates \ && rm -rf /var/lib/apt/lists/*RUN useradd -ms /bin/bash gameserverUSER gameserverWORKDIR /home/gameserverCOPY --chown=gameserver:gameserver Build/ ./EXPOSE 7777/udpENTRYPOINT ["./FusionDedicatedServer.x86_64", "-batchmode", "-nographics"]The -s (session name) and -r (Photon region) arguments are not hardcoded in the Dockerfile — they are passed at session start time via the Gameye args field. This means one image works across all regions and session names.
Build and push to Docker Hub:
docker build -t yourdockerhubuser/fusion-server:1.0.0 .docker push yourdockerhubuser/fusion-server:1.0.0Step 3: Start sessions via the Gameye API
Section titled “Step 3: Start sessions via the Gameye API”When your matchmaker or backend decides a match is ready, call POST /session with your Fusion-specific arguments:
curl -X POST https://api.gameye.io/session \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "location": "eu-west", "image": "your-fusion-server", "version": "1.0.0", "args": ["-s", "my-match-session", "-r", "eu"], "labels": { "matchId": "abc123" }, "ttl": 3600 }'The -s value is the Fusion game session name your client uses to join. The -r value must match the Photon region code for the target Gameye region — see the region mapping table below.
Session response
Section titled “Session response”Gameye returns the connection details in under 0.5 seconds:
{ "id": "session-abc123", "host": "185.x.x.x", "ports": [ { "type": "udp", "container": 7777, "host": 34521 } ]}host is the public IP of the server. The host value in ports is the external port players connect to — it will not be 7777 unless you are using host networking mode. Pass both values to your players.
Step 4: Connect game clients
Section titled “Step 4: Connect game clients”In your Unity client, use the Fusion NetworkRunner.StartGame call with the server address returned by Gameye:
var args = new StartGameArgs { GameMode = GameMode.Client, SessionName = "my-match-session", // matches the -s argument Address = NetAddress.CreateFromIpPort( "185.x.x.x", // host from session response 34521 // host port from session response ), Scene = SceneRef.FromIndex(sceneBuildIndex), SceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>()};
await runner.StartGame(args);The client connects directly to the Gameye-hosted server — Photon relay is not in the data path for a Dedicated Server session.
Region mapping
Section titled “Region mapping”Select the Gameye region that corresponds to your target Photon region to minimise relay latency. The -r argument passed to the server must match.
Gameye location | Photon region | -r argument |
|---|---|---|
eu-west, eu-south | Europe | eu |
na-east, na-central | USA East | us |
na-west | USA West | usw |
sa-east | South America | sa |
asia-east | Asia | asia |
asia-northeast, oce-east | Japan | jp |
If you let players choose their region or use latency-based selection, derive the -r argument from the chosen Gameye location using this table before calling POST /session.
Session lifecycle
Section titled “Session lifecycle”Fusion Dedicated Servers shut down when the last player disconnects or when your game logic calls runner.Shutdown(). When the Unity process exits, Gameye detects the container stop and reclaims the compute — billing stops at that point.
You can also terminate a session explicitly from your backend:
DELETE https://api.gameye.io/session/session-abc123Authorization: Bearer YOUR_API_TOKENThe ttl field in POST /session sets a hard maximum session lifetime in seconds. It acts as a backstop for sessions where the server process fails to exit cleanly — useful for preventing runaway billing on crash loops.