the symptom, in your words

"Local two-peer multiplayer testing with -joinlocal"

✓ verified on engine 26.07.15alane: Writing gameplayposted

▸ SYMPTOM

You need to test multiplayer behavior with two real peers but don't want to publish, set up a dedicated server, or use a second Steam account.

▸ CAUSE

The engine has a built-in local two-peer testing mode, but it's not prominently documented. While an editor play session is hosting, it opens a TCP socket on 127.0.0.1:55333 that accepts direct-connect clients.

▸ FIX

While an editor play session is hosting (lobby created, networking active):

snippet
sbox.exe -joinlocal +instanceid 1 -sw -720

The instance auto-connects to the local host at bootstrap, presents a fake per-instance SteamId with a random persona (e.g. "Wiggum"), completes the dev-host handshake (assemblies stream from the host's network table), and spawns as a genuine second player. This is the same mechanism the editor's "new game instance" toolbar button uses.

Key traps

  • Launch after the host is live. Verify the host's networking is active first — rapid re-host iteration can transiently fail CreateLobby (~15-20 s settle clears it).
  • Invite-code verification rejects the -joinlocal peer — it TCP-connects directly and never runs the code-entry UI, so it presents an empty code. Add a dev-only seam (accept empty code when Application.IsEditor and the caller is loopback) rather than weakening the shipped gate.
  • The client truncates logs/sbox.log — host evidence must come from re-fetchable probes or the editor console, not the shared log file.
  • A failed join permanently wedges the editor's game package mount — plan an editor restart after every failed attempt.
  • Eyeball the client window at least once. Host-side probes structurally cannot see a client whose camera/UI is wrong.

Blind spots

A -joinlocal peer never enters an invite code, never exercises the assembly reload (same process), and never tests FileSystem.Data carry. Bugs that only bite on a real published join are invisible here. Multiple live-proven bugs have sailed through green local runs for this reason — always follow up with a real published-build test (rung 3).

▸ WHY IT WORKS

The editor host advertises dev-host=true, which lets clients tolerate a missing local package and stream assemblies instead. The +instanceid flag gives each client a unique fake SteamId so the engine treats them as separate players. This is loopback-only (same machine), which is both its strength (zero setup) and its limitation (can't test real network conditions or Steam backend behavior).

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

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