Решили: экраны, открытые поверх главного меню (режим, дом, профиль, настройки), кладутся как
ScreenKind.Page, а цепочку целиком снимает тот, кто её растил; сеанс владельца открывается перед
входом в ЛЮБОЙ режим, а не только в Кампанию.
Почему: прежний путь клал их модалками и прятал панель меню руками —
menuPanel.style.display = None перед PushScreen. Отвергнут потому, что не работает по
устройству: UiNavigator.SyncVisibility пересчитывает видимость всего стека на каждый Push и Modal
«не прячет ничего структурно» — значит следующей же строкой возвращает меню в Flex. Меню
воскресало под новым экраном, и оба читались одним слипшимся листом (скриншот Макса 04.08.2026).
Page скрывает под собой всё сам, и ручная синхронизация уходит вместе с классом задачи, а не
чинится ещё одним флагом.
Второе — сеанс. GameFlow.PlayAsync открывал его только для Кампании, потому что открывал его
RequireRun(), а площадке забег не нужен. Но мероприятие рождается ВНУТРИ сеанса: вход в Ристалище
и в PvP упирался в SessionHost.CreateChild → null и синий экран. Открывать сеанс на буте (как
обещал текст ошибки) нельзя — роль выбирается входом в режим, поэтому сеанс открывает вход, просто
теперь всякий.
Сказано: «Когда пытаюсь зайти в ристилище - “[SessionHost] - сеанс не открыт → дочернему скоупу рождаться не от кого.” и синий экран. Наверное с PVP также?» (04.08.2026, сессия 60e7fc08).
Грабли: резолв главного меню снимает ТОЛЬКО экран меню — всё, что лежит выше, переживает его и
осталось бы висеть поверх мира весь забег. Прежний код обходился одним Pop(), потому что экран
поверх меню был ровно один; с цепочкой «режим → дом» этого хватать перестало. Отсюда список
overMenu и CloseOverMenu() в ShowMainMenuAsync: снимает всю цепочку разом, а не верхний лист.
Владелец правды: MenuRouter.ShowMainMenuAsync, MenuRouter.BuildNewGameScreen,
GameFlow.PlayAsync, тест SceneWiringTests (разводка UXML новых экранов).