the symptom, in your words

"A dedicated server never creates a Steam lobby, so lobby-based join code does nothing"

✓ verified on 26.07.22
lane Writing gameplayposted

▸ SYMPTOM

You reuse the lobby-creation code that works for editor-hosted or standalone-hosted play, and run the same binary as a dedicated server. Nothing joinable appears. There is no lobby to query and no lobby id to read off a LobbyInformation, because the object was never created.

▸ CAUSE

Networking.CreateLobbyAsync branches on Application.IsDedicatedServer. On a dedicated server it goes straight into CreateDedicatedServer, then DedicatedServer.Start, which drives ISteamGameServer and never touches the lobby socket. A dedicated server process creates no Steam lobby at all.

The joinable identity comes from Sandbox.Utility.Steam.SteamId instead. A Steam callback sets that value asynchronously, and the callback lands after the server's own launch log line. So a launch script that logs "server ready" and immediately reads the SteamId can read it before it exists.

▸ FIX

Give a dedicated-server bring-up its own path, separate from the lobby-creation code the game already has for peer-hosted play:

  1. Do not expect a lobby id from a dedicated server. There is no lobby to query.
  2. Read the joinable identity from Sandbox.Utility.Steam.SteamId.
  3. Poll for it. Run a short repeated poll for a few seconds and log the SteamId once it becomes non-zero. Game code gets no event or callback surface for "the Steam ID is now ready", so a poll is the only signal.
  4. Join by direct connect. Use the polled SteamId or an IP. Lobby-browser discovery cannot find a dedicated server, because the Steam lobby it would discover was never created.

▸ WHY IT WORKS

The dedicated-server branch was designed around ISteamGameServer, not the Steam lobby system, so every part of a lobby-based flow has no target on that binary. Reading SteamId matches the identity the dedicated path actually publishes. The poll covers the async callback timing, and direct connect matches the fact that discovery depends on the exact object (the lobby) that this process never makes.

Verified on engine 26.07.22: seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?
changelog
  • Published

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord