Build for the web
Build a Unity Web client that joins a Nebula mesh from a browser over WebRTC, and let the gateway serve it.
To let players join from a browser, build a Unity Web client with nebula build --web. A browser cannot open UDP sockets, so a web client connects to the gateway over WebRTC data channels instead. The gateway is the process that accepts client connections. It accepts web clients and UDP clients at the same time. Workers, the orchestrator, and your gameplay code treat a web client like any other client.
Before you start:
- Install Web Build Support for your Unity version in Unity Hub.
- Set up the project with
nebula initand build the host player withnebula build. The local mesh runs from that build.
Build and play locally
Build the web client
nebula build --webThe CLI builds a Unity Web player into Builds/Web. The first web build re-imports the project's assets for the Web platform, which can take a long time for a large project. The build uses gzip compression, because browsers accept Brotli-compressed files only over HTTPS.
Start the mesh
nebula startThe gateway serves the web build from the Web folder next to its own build folder. nebula start prints the address, for example web client http://127.0.0.1:7000/.
Open the game in a browser
Open http://127.0.0.1:7000/. The page connects back to the gateway that served it. If your scene includes NebulaTitleScreen, the address field already contains the page's address. Select Connect.
After you change game code, run nebula build --web again and reload the page. You do not need to restart the mesh.
How a web client connects
- The client sends a WebRTC offer to
/nebula/rtcon the gateway's web port, over HTTPS when the page itself was loaded over HTTPS and over HTTP otherwise. The gateway replies with its addresses and its certificate fingerprint. - The browser sends WebRTC traffic straight to the gateway's UDP WebRTC port. No STUN or TURN server takes part.
- The client opens two data channels. The reliable, ordered channel carries
Delivery.ReliableOrderedmessages. The second channel does not retransmit lost messages and carriesDelivery.Sequencedmessages, dropping any message that arrives after a newer one.
Both channels carry the same Nebula messages as a UDP connection. The round-trip time (RTT) a web client reports comes from the browser's connection statistics. When the browser does not report one, the client measures RTT with its ping messages.
| Port | Default | Purpose |
|---|---|---|
TCP WebPort | 0, which uses the same number as GatewayPort (7000) | WebRTC offers and answers, and the web build's files. A web client connects to this port. |
UDP WebRtcPort | 0, which uses GatewayPort + 1 (7001) | WebRTC data channel traffic. |
UDP GatewayPort | 7000 | UDP clients. |
If the gateway cannot open either web port, it logs a warning and turns web clients off. UDP clients can still connect. Set WebClients to false, or pass -nebula-web false, to turn web clients off yourself.
Choose the gateway a web client uses
A web client has no command line. It reads the same options from the page's query string, without the leading dash:
http://127.0.0.1:7000/?nebula-name=Player&nebula-connect- Without
nebula-gateway, the client uses the address and port that served the page. It does this only whileNebulaConfig.GatewayAddressis127.0.0.1orlocalhost. SetGatewayAddressto your gateway's address when another server hosts the web build. nebula-gateway=<address:port>selects a gateway. Use the gateway's web port, not its UDP port.nebula-connectconnects at startup and keepsNebulaTitleScreenhidden.nebula-name=<name>sets the display name. A web client without it usesplayer.
NebulaClient.ConnectTo works the same way in a web build. Pass the gateway's web port. See Connecting clients.
Serve HTTPS for hosted pages
A page loaded over HTTPS, such as a build on Unity Play or itch.io, sends its WebRTC offer over HTTPS too, and the browser refuses a plain HTTP gateway. To serve the gateway's web port over HTTPS, start the gateway with -nebula-web-tls acme:
- The gateway requests a certificate for
GatewayAddress(the address in-nebula-gateway) from Let's Encrypt. It proves control of that address by answering on TCP port 80, which must be reachable from the internet. - For an IP address, Let's Encrypt issues a certificate that lasts about six days. The gateway renews it at half its lifetime without a restart.
- The gateway keeps the certificate and its ACME account key in
-nebula-web-tls-dir(default: atlsfolder next to the gateway), so a restart reuses them. - For the first few seconds after the gateway starts, before the first certificate arrives, HTTPS connections fail.
nebula deploy turns HTTPS on for you. Clients then connect to <orchestrator public ip>:7000 from any HTTPS page. To use another ACME certificate authority, pass -nebula-acme-directory <url>. To register a contact address, pass -nebula-acme-email <address>.
Serve the web build from another server
The gateway serves the folder you pass with -nebula-web-root <folder>. Without that option, it looks for a Web folder next to its executable, then next to its build folder.
To host the files elsewhere, configure your server to send Content-Encoding: gzip with every .gz file in the build. The gateway's /nebula/rtc endpoint accepts requests from pages on other origins.
A page served over HTTPS needs a gateway that serves HTTPS. See Serve HTTPS for hosted pages.
Deploy the web client
A deployment never ships the web build: deployed gateways carry game traffic only, and their public address serves nothing over HTTP but WebRTC signaling and a health check. Host Builds/Web where you host the rest of your game (Unity Play, itch.io, your own CDN) and point the page at the deployed gateway with the query string above, for example ?nebula-gateway=<gateway address>. A page served over HTTPS needs the gateway's web port over HTTPS too; see Serve HTTPS for hosted pages.
The orchestrator firewall allows TCP on the gateway port, UDP on the gateway port plus one, and TCP port 80 for certificate validation. Each deployment adds any missing required rules without removing rules you added. See Deploy to Hetzner Cloud.
Limitations
Web clients are not authenticated
WebRTC encrypts data channel traffic with DTLS, but the gateway accepts every offer. Anyone who can reach the web port can connect, just as with UDP clients.
- A network that blocks outbound UDP stops web clients from connecting. The gateway has no TCP or TURN fallback.
- The gateway offers IPv4 addresses only.
- Only the standalone
nebula-gatewayaccepts web clients. A gateway running inside a Unity process does not. - Browsers slow down pages in background tabs. A web client in a hidden tab can fall behind and correct its prediction when it becomes visible again.