Решили: выключенный узел петли оживает при подключении — как открылся бы новый сокет у Steam.
Почему: игра, принимая приглашение посреди своей сессии, сперва рвёт своё соединение и только потом идёт в гости. У настоящего транспорта это два разных сокета, и путь работает. В петле же узел после выключения оставался мёртвым навсегда: сеанс уходил в «подключаюсь» и там застревал.
Что из этого важнее самого фикса. Петля — не заглушка, а модель провода, и расхождение модели с проводом прикрывает от проверки ровно тот путь, ради которого модель заводили. Здесь оно спрятало бы приём приглашения из своей игры — сценарий, который Макс назвал отдельно («присоединиться должно корректно работать, где бы игрок ни находился»). Тот же принцип уже был записан у предела сообщения: петля врёт теми же 512 КБ, что Steam, потому что шов, где в тестах проходит то, что в игре уезжает в тишину, хуже отсутствующего.
Грабли: сценарий «из открытого места» проходил сразу, а «из своей поднятой сессии» падал — и разница между ними была не в игре, а в том, был ли до этого поднят транспорт. Искать это в игровом коде можно долго.
Владелец правды: Net/Transport/LoopbackNetwork.cs (ReviveNode и комментарий при нём), тест
CoopJoinFromAnywhereTest.