Discover how Edgegap works

Discover how Edgegap works

Nakama

Fish Game

Deploy to Edgegap

Published

Published

Published

Fish Game: Run Heroic Labs' Nakama sample on Edgegap dedicated servers, in Godot 4

Fish Game: Run Heroic Labs' Nakama sample on Edgegap dedicated servers, in Godot 4

Fish Game is Heroic Labs' 2 to 4 player online brawler, made to show off Nakama. Edgegap's fork ports it to Godot 4 and runs every online match on its own dedicated game server.

Nakama keeps doing what it does best: accounts, matchmaking and the leaderboard. When it finds a match, it starts an Edgegap server near the matched players through the Edgegap Fleet Manager for Nakama.

No player hosts the match: a headless Godot server decides hits, deaths, rounds and the winner, then records the win in Nakama and stops itself.

Edgegap's network spans 615+ Edge Cloud locations (learn more). Each server is deployed to the best available location for its players and billed only while the match runs.

Platforms: Windows, macOS and Linux desktop builds. Original game by Heroic Labs; code under Apache 2.0, most art, music and sound under CC BY-NC.

How it works

  1. Players sign in to Nakama with email and press Match. Nakama's matchmaker groups them.

  2. Nakama's Fleet Manager starts an Edgegap deployment near the matched players, using the IP each player signed in from.

  3. The game server boots, listens on UDP port 7777 and tells Nakama it's READY, with its IP and port.

  4. Nakama sends each player the server's address. Players connect over ENet; the server checks each one's Nakama session and lets in only matched players.

  5. The first fish to win 5 rounds wins. The server records the win on the fish_game_wins leaderboard, then tells Nakama to STOP the deployment.

What the fork changed:

Path

What it does

autoload/OnlineMatch.gd

Client: matchmaker ticket, server address notification, ENet connection. Server: lets matched players in.

autoload/EdgegapServer.gd

Dedicated server mode: listens, reports READY, connections and STOP to Nakama, stops itself.

Main.gd, Game.gd, actors/Player.gd, components/Hitbox.gd

Online, the server owns rounds, pickups, hits and deaths.

nakama/

Nakama 3.39 with a Go module: Fleet Manager, matchmaker hook, authoritative leaderboard.

server/Dockerfile

Exports the "Linux Server" preset and runs it with headless Godot.

No credit card required. Free tier includes the resources to deploy a real game server.

No credit card required. Free tier includes the resources to deploy a real game server.

Add Edgegap dedicated game servers to Heroic Labs’ Fish Game, using Nakama for matchmaking in Godot 4.

Fish Game from Heroic Labs' Nakama, running on Edgegap

Step-by-Step Guide

Run the Sample

1. Before you start

  • A free Edgegap account and an API token from Dashboard → User Settings → Tokens. It's organization-wide, so it only goes into Nakama's settings file, never into the game.

  • Godot 4.7 (4.3 or later should work).

  • Docker Desktop, for Nakama and the game server image.

  • A public HTTPS address for Nakama. Edgegap servers call Nakama back, so localhost won't work. For a test, a tunnel is enough (step 3).

  • Clone the fork.

2. Put the game server on Edgegap

Build the image from the repository root and push it to your Edgegap registry. The Container Registry page has your project, username and token:

docker build --platform linux/amd64 -f server/Dockerfile -t registry.edgegap.com/<project>/fishgame-godot:1.0.0 .

docker push registry.edgegap.com/<project>/fishgame-godot:1.0.0

In the dashboard, create the application fishgame-godot and a version 1.0.0:

  • Image <project>/fishgame-godot, tag 1.0.0, with your registry username and token.

  • 0.5 vCPU and 512 MB.

  • One port: name gameport, 7777, UDP.

  • A max duration of 30 minutes. The server also stops itself.

The server needs no environment variables of its own: the Fleet Manager passes it Nakama's callback addresses on every deployment.

3. Run Nakama

Copy nakama/.env.example to nakama/.env and fill it in:

  • EDGEGAP_API_TOKEN: your Edgegap API token, with its token prefix.

  • EDGEGAP_APPLICATION, INITIAL_EDGEGAP_VERSION, EDGEGAP_PORT_NAME: the application, version and port name from step 2.

  • NAKAMA_ACCESS_URL: Nakama's public HTTPS address.

  • NAKAMA_HTTP_KEY: a long random string.

To test on your own machine, a Cloudflare quick tunnel gives Nakama a public address. Put the https://….trycloudflare.com address it prints in NAKAMA_ACCESS_URL:

docker run -d --name fishgame-tunnel cloudflare/cloudflared:latest tunnel --no-autoupdate --url http://host.docker.internal:7350

Then start Nakama and Postgres:

docker compose -p fishgame -f nakama/docker-compose.yml up -d --build

4. Play a match

Point the game at Nakama, either in the defaults at the top of autoload/Online.gd or on the command line:

godot --path . -- --nakama-host=your-tunnel.trycloudflare.com --nakama-port=443 --nakama-scheme=https

Players should reach Nakama through its public address too: Edgegap uses the IP each player signs in from to put the server near them.

Start two copies of the game, pick Online, create an account in each, and press Match in both. After "Match found! Starting a game server...", both land on the ready screen of the same Edgegap server. The first fish to win 5 rounds wins and gets +1 on the leaderboard. Then the deployment stops on its own.

5. Add it to your own Godot and Nakama game

The fork is a working reference: your coding agent can copy its tested files instead of writing them from scratch. Four changes make a Godot game run on Edgegap with Nakama:

  1. Nakama starts the servers. Add the Edgegap Fleet Manager for Nakama to your Nakama Go module, and a matchmaker hook that creates an Edgegap deployment for each match (the fork's nakama/ folder).

  2. The game runs headless as the server. When Godot runs headless, the game starts in server mode, listens on a fixed UDP port and owns the game rules: hits, deaths, rounds, results (autoload/EdgegapServer.gd, Game.gd).

  3. The server reports to Nakama. It sends READY with its IP and port, the connected players every 5 seconds, and STOP when the match ends, so Nakama ends the deployment and billing stops.

  4. The client waits for its server. After matchmaking, the client receives the server's address in a Nakama notification, connects over ENet, and the server checks its Nakama session before letting it in (autoload/OnlineMatch.gd).

Then containerize the server with the fork's server/Dockerfile as a model, and create the app version as in step 2.

With your agent:

"Load the edgegap skill, then edgegap-nakama and edgegap-godot. Using github.com/edgegap/backend-game-sample-godot-nakama-fishgame as the reference, add the Edgegap Fleet Manager to my Nakama module, a headless server mode to my Godot game that reports READY, connections and STOP to Nakama, and a client that connects to the address Nakama sends after matchmaking."

For each step in detail, by hand, see the Nakama integration guide.

6. How Nakama matches players and stops servers

Nakama's matchmaker groups the players, and its Fleet Manager plugin starts the Edgegap server and tells each player where to connect. You don't need Edgegap's matchmaker for this sample.

The server asks Nakama to stop its deployment, which ends billing:

  • when the match is won, after recording the win;

  • when fewer than 2 players are left mid-match;

  • when everyone leaves;

  • when nobody joins within 60 seconds;

  • after 20 minutes.

To add the same setup to your own Nakama game, follow the Nakama integration guide.

Known limits

  • No online play in the browser. ENet uses UDP, which browsers can't open. A web build would need Godot's WebSocket peer and a WS port with TLS Upgrade.

  • Movement is still client-owned. The server decides hits, deaths, pickups, rounds and wins, but each player sends their own fish's position, as in the original. For a competitive game, move movement to the server with client-side prediction.

  • No private matches by ID. Every match comes from the matchmaker. The Fleet Manager's instance_create and instance_join calls could bring them back.

What was tested

Tested end to end on Edgegap on 20 October 2026. The fork ships 3 tests in tests/:

  • Local play: godot --path . --script res://tests/smoke_test.gd loads the map; fish land, pick up, swing and throw without errors.

  • Network, local server: godot --headless --path . -- --test-auto-hit, then run the network test client twice (command in EDGEGAP.md).

  • End to end on Edgegap: set FISHGAME_TEST_AUTO_HIT=true in nakama/.env, then run the network test client twice against your Nakama. The server hits one fish per round, so matches finish on their own. Leave it off for real games.

For netcode work without Nakama or Edgegap: godot --headless --path . starts a server, and godot --path . -- --connect=127.0.0.1:7777 connects a client to it.

Frequently Asked Questions

Questions about running Fish Game with Nakama and Edgegap.

Can Nakama start dedicated game servers?

Yes. With the Edgegap Fleet Manager for Nakama, Nakama's matchmaker starts an Edgegap server near the matched players and sends them its address. The server reports back to Nakama and stops when the match ends.

How do I make a Godot game server-authoritative with Nakama?

Run a headless Godot server per match that owns hits, deaths, rounds and results, and let Nakama handle accounts, matchmaking and leaderboards. Fish Game does this: players can't post wins themselves.

Does Fish Game work in Godot 4?

Yes. Edgegap's fork ports Heroic Labs' original Godot 3 game to Godot 4.7, and 4.3 or later should work. The original peer-hosted version stays on Heroic Labs' GitHub.

Can the Fish Game web export play online?

Not yet. The game uses ENet over UDP, which browsers can't open. A web build would need Godot's WebSocket peer and a WebSocket port with TLS Upgrade on Edgegap.

Clients

Learn more from clients who integrated Edgegap

31 case studies are available from studios that moved to Edgegap from another platform.

Key reasons why they chose Edgegap

Discover the impact of Edgegap's automated game server orchestration for a flawless multiplayer experience.

Cost

Pricing

Pricing

Optimize costs and performance with hybrid orchestration

Optimize costs and performance with hybrid orchestration

Optimize costs and performance with hybrid orchestration

Edge Cloud

On-Demand

$0.00115

/ vCPU

/ MINUTE

Billed by the Minute, Only on Usage

Pay only when players play. 0 active servers = $0

Deploy game servers worldwide, per instance, to all 615+ edge cloud locations. Zero commitment.

Simply add a credit card.

Edge Cloud

On-Demand

$0.00115

/ vCPU

/ MINUTE

Billed by the Minute, Only on Usage

Pay only when players play. 0 active servers = $0

Deploy game servers worldwide, per instance, to all 615+ edge cloud locations. Zero commitment.

Simply add a credit card.

Private Fleet (Bare Metal)

Reserved Capacity

$0.0261

/ vCPU

/ HOUR

Billed Monthly, Always On

$280 per host/month (12 mo rate), or $350 monthly

Optimize the cost effectiveness of your game server with egress-free hosting of Private Fleets.

Persistent, available 24/7, exclusive to your studio.

Private Fleet (Bare Metal)

Reserved Capacity

$0.0261

/ vCPU

/ HOUR

Billed Monthly, Always On

$280 per host/month (12 mo rate), or $350 monthly

Optimize the cost effectiveness of your game server with egress-free hosting of Private Fleets.

Persistent, available 24/7, exclusive to your studio.

Your bill varies per rate and usage; which can vary per game type, player count, & more.

Your bill varies per rate and usage; which can vary per game type, player count, & more.

Model your usage with our estimate calculator ->

Model your usage with our estimate calculator ->

Edgegap's features & price: detailed comparison between Edge Cloud & Private Fleets

Edgegap's features & price: detailed comparison between Edge Cloud & Private Fleets

COMPARE

Free Trial

Edge Cloud

Private Fleets

FEATURES

Analytics & Monitoring

Billing Alarms

Click to Expand

28 more rows

Unlocks

Capabilities are unlocked when a credit card is added to the account.

COMPARE

Free Trial

Edge Cloud

Private Fleets

FEATURES

Analytics & Monitoring

Billing Alarms

Click to Expand

28 more rows

Unlocks

Capabilities are unlocked when a credit card is added to the account.

COMPARE

Free Trial

Edge Cloud

Private Fleets

FEATURES

Analytics & Monitoring

Billing Alarms

Click to Expand

28 more rows

Unlocks

Capabilities are unlocked when a credit card is added to the account.