How to Add Online Lobbies like on Dedicated Game Server to any Unity Multiplayer Game with Edgegap's Server Browser SDK

We will cover every step to add an on-demand multiplayer lobby system to your Unity game using Edgegap's Server Browser SDK, where players are connected to an on-demand dedicated server automatically. The approach works with any netcode. Let's get started!

This integration builds on our dedicated server tutorial. It assumes you already have a Unity project set up for dedicated servers and that you know how to build, containerize, and upload a server to Edgegap. If you haven't, follow that tutorial first.

Part 1 - Install the Server Browser SDK

The Edgegap plugin from the dedicated server tutorial handles building and deploying your game server. The Server Browser is a separate package.

In Unity, from the top navigation bar, select "Window", then "Package Management", and then "Package Manager". Select the "plus" icon, then "Add package from git URL". Paste the SDK's URL.

https://github.com/edgegap/edgegap-unity-sdk.git

Once it's downloaded, find the "Samples" tab in the SDK's detail pane and import the "Server Browser - Auto-Assign" example. This adds two scripts to your project: a server handler and a client handler.

The client handler reserves a seat on the game server and hands your game the server's address to connect to it. The server handler registers your game server with the Server Browser when it starts up and reports available player capacity. Both are wired into the scene in a later step.

The SDK does almost everything for you. What it leaves for you to do is to add the netcode-specific parts: the lines that connect your game to the assigned server, a small handshake that tells the server which players join, and the release that frees their seat when they leave.

Disclaimer

Make sure to add Edgegap's Unity plugin using the "Add project from Git" to ensure you use the latest version of the project.

  1. Select "Window" then "Package Manager"

  2. Click on the "+" icon, then select "Add Project from Git"

  3. Paste Edgegap's Unity plugin URL: "https://github.com/edgegap/edgegap-unity-plugin.git"

  4. Select "Install"

Part 2 - Generate the Integration Code

The integration uses universal prompts that any AI coding assistant can run in any Unity project. The prompts cover two steps: the first has the assistant audit your project to find how it connects and how it sends messages, and the second writes the integration based on that audit. Both prompts are available in the video's comments to copy. The on-screen example uses Mirror Networking's Billiards sample, but the prompts are netcode-agnostic.

The first prompt is read-only and changes nothing. It has the assistant find and report back a few things: how your client connects to a server using a custom address and port, how your netcode sends small custom messages from client to server, how it signals that a client has connected, and how it signals on the server that a player has disconnected so a seat can be returned to the pool. For the Mirror sample, the audit confirms the client connects by calling StartClient on Mirror's NetworkManager, with the address and port set on the active transport, and identifies how Mirror sends a network message and fires its client-connected event.

Read-only, no code changes. My Unity project uses a netcode framework and I'm integrating the Edgegap Server Browser (Auto-Assign), which at runtime gives my client a reserved server's address (an FQDN) and an external port, and which expects my server to confirm each player by a player ID. Find and tell me, with file paths and line numbers: 1) the method that starts a CLIENT connection to a server, what triggers it, and the exact property/field names where the server address and the port are set before connecting, plus the transport in use; 2) how this netcode sends a small custom message from client to server and registers a handler for it on the server (the API names for defining a message, registering a server-side handler, and sending from the client); 3) the event or callback that fires on the client the moment it finishes connecting to the server — and importantly, tell me whether subscribing to it is an assignment that gets reset when the client starts, or an add/subscribe that persists, so I know whether to subscribe before or after starting the client; 4) the event or callback that fires on the server when a player disconnects (so a seat can be released back to the Server Browser) — give the API name, where it's hooked, and how the disconnecting player's connection is identified, so I can map it back to the player ID that was registered on join. To work efficiently, look in these conventional locations first before searching more broadly — most Unity netcodes follow this structure: - The client-connect method is usually on a NetworkManager-style class (the central networking manager). Find that class first, then its "start client" method. - The address is a field on the manager, but the port lives on the active transport component, reached via the manager's transport reference. Identify the transport in use and its port field. - The custom client-to-server message is the netcode's own messaging API — look for its message/RPC registration pattern (a message type, a server-side handler registration, and a client send call). - The client-connected signal is an event or callback on the client object. Check whether it is reset/reassigned when the client starts (which dictates subscribing after start) or persists (subscribe any time). - The server-side disconnect signal is usually an event or virtual method on the same NetworkManager-style class or the server object (an "on server disconnect" callback exposing the connection that left). Find it and tell me how it identifies which connection disconnected. Confirm each against the project rather than assuming, and report what you actually find.

The second prompt has the assistant make the change based on that audit. It does three things. First, it creates a small standalone connector script which, on the server, listens for each player's ID and confirms their reservation, and on the client, sends that ID up once connected. Second, it adapts the Server Browser client handler to connect to the server using the address and port the Server Browser hands back, starting the client through your netcode. Third, it releases the player's seat when they disconnect, so the server frees up space for new players instead of filling up over time.

Using what you found in the audit, make two changes for the Edgegap Server Browser Auto-Assign integration. Do NOT subclass or replace my netcode's manager — keep it as-is. (1) Create a standalone MonoBehaviour connector named EdgegapPlayerConnector in Assets/Scripts/ (global Assembly-CSharp) with a public static Instance singleton and DontDestroyOnLoad. It defines a small network message carrying a string playerId. On the server, in Start(), it registers the server-side handler for that message; the handler stores the connection-to-playerId mapping and calls ServerBrowserServerHandler.Instance.OnPlayerJoined(playerId) (null-guard Instance). It exposes a public method SubscribeClientConnected() that subscribes to the client-connected event you identified and, when fired, sends the message carrying ServerBrowserClientHandler.Instance.LocalPlayerId. If the audit found that the connected event is reset when the client starts, this method must be safe to call AFTER the client has started. (2) In the Edgegap sample ServerBrowserClientHandler.cs: make LocalPlayerId a non-serialized field generated at runtime in Awake only if empty (a new GUID string), and replace any hardcoded placeholder player id in the seat-reservation call with LocalPlayerId; then, in the block that runs when seats are reserved, connect using my netcode — set the assigned server's FQDN as the network address, read the external port (it is a string — convert it to the type my transport expects) and set it on the active transport, start the client connection using the method/fields from the audit, and immediately after starting the client call the connector's SubscribeClientConnected(). Return the complete connector file and the full updated ServerBrowserClientHandler.cs. (3) Additionally, wire the seat release on disconnect, using what the audit found in item 4. The Server Browser reserves a seat when a player joins and registers via ServerBrowserServerHandler.Instance.OnPlayerJoined(playerId); it must also release that seat when the player leaves, or seats leak and the instance eventually reports zero available seats. On the server, subscribe to the netcode's server-side disconnect event identified in the audit (subscribe in the same place the server-side message handler is registered, and unsubscribe on teardown). In that disconnect handler, look up the playerId you stored for the disconnecting connection when it joined, and if found, call ServerBrowserServerHandler.Instance.OnPlayerAbandoned(...) to free the seat, then remove that entry from your connection→playerId mapping. Before writing the OnPlayerAbandoned call, read its actual signature from the Server Browser SDK source (it may take a slot name such as "main", a player ID, or both) and use it correctly — do not assume. Guard against the player not being in the mapping, and do not throw if the SDK handler instance is missing.

The same approach works for other netcodes: the audit adapts to whatever project you use, and the edit applies the changes accordingly.

One netcode-specific detail is worth calling out, because the audit catches it for you. In Mirror, the client-connected event is reset when the client starts, so the connector subscribes to it after the client starts, not before. The audit surfaces this and the edit handles it.

Part 3 - Add the Scripts to the Scene

The code exists, but in Unity a script does nothing until it's attached to a game object.

First, create an empty game object and name it "Test-Connector". Add the connector script the assistant generated. Next, create another empty object for the server handler and add the "Server Browser Server Handler" component, leaving its fields empty for now. Then add one more empty game object, name it "Server Browser Client Handler", add the script of the same name, and leave its component fields blank as well. These fields are filled with details from the platform in the next step.

Part 4 - Create a Server Browser

On the Edgegap platform, open "Server Browser" and create a new one. Give it a name for your own reference, such as "quickstart", and choose the "Simple Example" configuration. Start the Server Browser and give it a moment to come online. On the free tier, the browser automatically stops after a few hours, which is fine for testing.

Once it's online, review its details. You'll see an API URL and two separate tokens: a server token and a client token. All three are needed, and the two tokens do different jobs, so be careful not to mix them up.

Back in Unity, add this information to both handlers. On the server handler, paste the API URL and the server token. On the client handler, paste the same API URL and the client token. Use the appropriate token for each handler, as accidentally swapping them will create connection errors. Finally, save the scene.

The server token only ever lives in the headless server running on Edgegap, never on a player's machine. Pasting it directly into the component keeps this tutorial simple, but in a production architecture you'd set it as an environment variable in your app version, which overrides the inspector value and keeps your token out of your project's files.

Part 5 - Build and Deploy the Server

A new app version is required. This step is easy to overlook but is essential: the server handler reads the URL and token information from the component fields you just filled, and previously uploaded game servers are missing this information. Building and uploading the server is therefore mandatory.

Open the Edgegap hosting plugin and build, containerize, and upload your server exactly as in the dedicated server tutorial, either individually or using the "build from source" button, which runs all of these steps in one shot.

With the server uploaded, create a scaling policy on the Server Browser. Name it "on-demand", set "Minimum Active Instances" to one, point it at the application and version you just uploaded, and leave "Private Hosts" empty so it deploys to the cloud. The minimum of one active instance is what keeps a single server alive and ready at all times — this is your on-demand lobby. Save the policy as active, and within a minute it deploys the server automatically to Edgegap's network. In the deployment logs, you should see the server register, report healthy, and show that it's discoverable with its seats available. Your on-demand multiplayer lobby is now live.

Part 6 - Testing

To test with two players, use Unity's Multiplayer Play Mode, which is covered in the dedicated server tutorial. On play, each player reaches out to the Server Browser, reserves a seat, is handed the server's address, and connects automatically — no one types an address. On the server side, each player is confirmed and a seat is taken. Both players are placed into the same cloud server, with each player's actions replicated in the other's game scene.

A note for production: a freshly assigned server may still be starting up for a moment, so you'd add a retry function that checks the connection a couple of times, a few seconds apart, to cover that gap. This tutorial deploys to Edgegap's cloud network as a simple way to test in development; if you prefer to deploy to fleet-like solutions during development, see the documentation.

Part 7 - Next Steps

The Simple Example used here is a starting point. From there, you can evolve your Server Browser integration in a couple of directions.

Our documentation covers additional functionality, such as the ability to search and browse servers by parameters including region, capacity, or game mode, so players can pick a specific server rather than being auto-assigned. You can also pin your server to a reserved fleet or Private Fleet instead of the cloud by adding host IDs to the scaling policy.

You can also join our community on Discord to ask our dev team and other studios for help adapting the Server Browser to your game.

Code Deep Dive: What to Add and Why

This optional deep dive covers the actual code, for those who want to understand the integration. The changes are specific to the Mirror sample, but the idea is universal for any netcode: take the address and port the Server Browser gives you, hand them to your networking system, and connect — then tell the server which players just joined so it confirms the reservation.

The first piece is the connect flow. Once the client is talking to the server, the Server Browser still needs to know the players actually arrived so it can confirm their seat reservation and keep its seat count accurate. That's the second piece: once connected, the client sends its player ID to the server, and the server reports it to the Server Browser.

The connector defines a small network message that carries the player's ID — the same ID the client used to reserve its seat. On the client side, once connected, it sends that ID up to the server. There's one Mirror detail worth repeating here: it subscribes to the connected event after starting the client, because Mirror resets that event when the client starts.

In the client handler, the player ID is generated fresh at runtime, so every player — including simulated ones — gets a unique ID.

The heart of the integration is the seat-reservation response. When the Server Browser reserves a seat, it hands back the server address and port. You set those on Mirror's NetworkManager and its transport, start the client, and then subscribe for the connected event so the ID can be sent. The port is read off the active transport in a netcode-neutral way, so the same shape carries over to other netcodes — only the exact address, transport, and start-client call are Mirror-specific.

One last note for production: instead of pasting the server token into the component directly, you can set it as environment variables in your app version — SB_BASE_URL and SB_SERVER_TOKEN — which override the component's values, so your token never lives in your project's files.

That is all for Edgegap's Server Browser, which empowers game developers to run persistent dedicated servers and place players into them automatically, with just a small amount of code, in a lobby-like system.

Get your Game Online Easily & in Minutes

Start Integrating Now!

Get your Game Online Easily
& in Minutes