Решили: у гостя показ мира вне боя ведут два новых звена — отряд встаёт по снимку забега, карта акта едет в ActivityState рядом с ареной и фазой. Оба заведены за узкими швами (IPartyStage, IActMapPresence), а не прямыми ссылками на показ.

Почему: гость заходил в чужую кампанию и видел пустое зелёное поле — ни карты, ни отряда в расстановке. Состояние при этом доезжало исправно; не доезжала команда его показать. Три звена, все про одно:

  • GuestRunState.SnapshotReceived объявлялось с докстрингом «показу пора перечитать забег» и не имело ни одного подписчика — поиск по проекту давал ровно две строки, объявление и вызов;
  • отряд на арену кладёт WorldStageController.PlaceParty(), а зовут его только RunPartyReadyEvent из петли акта (её у гостя нет) и закрытие боя — то есть до первого боя арена пуста;
  • карту открывает петля акта, а в объявлении «где мы» карты не было вовсе: там жили вид занятия, его ограничения, открытость арены и фаза.

«Не видел юнитов в расстановке» оказалось тем же дефектом, а не вторым: паспорта состава уходят по OnUnitSpawned, то есть с началом боя, — а в расстановке стоят тела мира, которые кладёт то самое молчащее звено.

Сказано: «Зашли в компанию. Клиента НЕ кинуло на карту, он видел просто наше зеленное поле. Он также не видел юнитов в расстановке и т.д.» (03.08.2026, сессия 272cfad5).

Грабли:

  • «Отряд готов» нельзя публиковать на каждый снимок: на том же событии сидит звук, для которого оно значит «забег начался» и играет стингер. Снимки приходят на каждое изменение, включая сдвиг бойца в расстановке, — стингер зазвучал бы на каждый шаг. Событие публикуется РОВНО ОДИН раз, дальше тела переставляются напрямую и только при смене отпечатка отряда (состав, киты, позиции).
  • Просьба показать карту обгоняет данные. Забег и объявление «карта открыта» едут разными каналами, порядок между каналами не гарантирован. Пока показ хранил один флаг, обгон гасил намерение НАВСЕГДА. Разделено на «хотим показать» и «показываем»; держит GuestMapVisibilityTests.
  • Прямая ссылка сеанса на показ мира ломает проверяемость. SessionScopeTests собирает состав сеанса в EditMode, и первая же попытка потащила туда весь показ карты со сборщиком тел и сценой. Это и стало доводом за швы: тест их подменяет тремя строками.

Владелец правды: GuestPartyFollower.cs, GuestActivityFollower.ApplyMap, WorldMapController (пара _visible/_drawn), ActivityState.MapOpen, тесты GuestMapVisibilityTests, SessionScopeTests.