Skip to content

Instantly share code, notes, and snippets.

@becked
Last active February 7, 2026 19:05
Show Gist options
  • Select an option

  • Save becked/ebdbed895655c80fe2674b3f8f8e5ee4 to your computer and use it in GitHub Desktop.

Select an option

Save becked/ebdbed895655c80fe2674b3f8f8e5ee4 to your computer and use it in GitHub Desktop.

Old World: Spectator Games Disappear From Browser

TL;DR

The host stops verifying its Unity Relay allocation once all player slots are filled. The Relay eventually expires. The next person who browses games triggers permanent deletion of the game listing from DynamoDB. Spectator games are the only case where this matters — they need to remain joinable after all player slots are taken.

Bug Location

UnityTransportComponent.OnUpdate() — host match verification loop:

if (!instance.AreAllPlayersConnected() && createdMatch != null)
{
    VerifyHostMatch(OnLocalServerListed);  // keeps relay alive, recreates if expired
}
else
{
    Debug.Log("All players connected - skipping match verification");
}

GameServerBehaviour.AreAllPlayersConnected() — only counts player slots, not observers:

return connectedPlayers.Count == base.LocalGame.getNumHumans();

Chain of Events

  1. Game created with GAMEOPTION_ALLOW_OBSERVE. Host creates Unity Relay allocation, stores join code in DynamoDB.
  2. All human player slots fill. AreAllPlayersConnected()true.
  3. Host stops calling VerifyHostMatch() (30-second periodic check skipped).
  4. VerifyHostMatch normally: (a) heartbeats the Relay via GetJoinCodeAsync/JoinAllocationAsync, (b) recreates the allocation if expired, (c) updates DynamoDB with fresh join codes.
  5. Relay allocation expires. Existing player connections persist (established transport), but the join code in DynamoDB is now dead.
  6. Any client browses the game list → VerifyGames()VerifyJoinCode() tests the dead join code → fails.
  7. Game permanently deleted from DynamoDB (DeleteNetworkServerData + DeleteNetworkGameData).
  8. Game gone from browser forever. No new spectators can find it.

Secondary Issue

NetworkGameStruct in DynamoDB has no observe field. RegisterNetworkGameData only reports numFreeSlots (player slots). Full games (numFreeSlots == 0) sort to bottom of browser with no indication spectators are welcome.

Fix

The verification skip condition needs to account for observer-enabled games:

if ((!instance.AreAllPlayersConnected() || gameAllowsObservers) && createdMatch != null)

Key Files

File What
UnityTransportComponent.cs:65-89 Host verification loop (the bug)
UnityTransportComponent.cs:146-201 OnLocalServerListed — relay recreation logic
UnityTransportComponent.cs:470-510 VerifyGames — browser-side verification that triggers deletion
UnityTransportComponent.cs:546-570 VerifyJoinCode — tests relay join code validity
GameServerBehaviour.cs:1368-1374 AreAllPlayersConnected — player-only check
GameServerBehaviour.cs:1387-1436 RegisterNetworkGameData — no observe flag in browser data
CloudStorageAWS.cs:1021-1078 DynamoDB write (no TTL, deletion is explicit)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment