Решили: «идёт показ боя» и «игрок в боевом узле забега» — два РАЗНЫХ понятия, и их надо расщепить.
Заводим презентационный сигнал BattleStagePresence (мир): «на сцене идёт бой, его надо кадрировать».
Он ортогонален часам забега IBattleClock.
- Камера входит в Action по ДВУМ триггерам: часы в
Fighting(живой забег) ИЛИBattleStagePresenceна-сцене (повтор). Живые бои не трогаются ни на кадр — они по-прежнему идут через часы. - Часы забега остаются как есть: их читают навигатор ввода, забеговый звук и панель забега; про показ повтора они не знают.
- Живой бой поднимает оба (часы Fighting для забега + сцена для показа — совпадают, как и раньше).
- Повтор поднимает только сцену: камера кадрирует, а забеговый UI/ввод/звук спят.
Почему: BattlePhase.Fighting сегодня значит СРАЗУ две вещи, и совпадают они лишь потому, что бой у
нас бывает только внутри забега. Повторы (фон меню, а дальше пересмотр боя, спектейт) эту склейку
ломают: бой показывается, но игрока в забеге нет. Если погнать общие часы в Fighting ради камеры —
навигатор уведёт ввод в боевой контекст (кнопки меню отвалятся), а забеговый звук врубит боевую
музыку поверх меню (подтверждено: часы читают UiNavigator, RunAudioPresenter, панель). Новое
значение-режим в тех же часах не спасло бы: его всё равно прочитали бы навигатор и звук, и понятие
растеклось бы по «а это не считается» в каждом. Отдельный сигнал показа держит границу в одном месте.
Сказано: «У нас ведь не только тут будут повторы, а потом еще могут быть реплеи, пересмотр боя и т.д… У нас вот есть часы в Fighting, а нельзя сделать какой-то иной режим? Или как наиболее корректно?» (04.08.2026, сессия 0768278b). Направление — его: расщепить, а не перегружать часы.
Грабли:
- У повтора нет живых юнитов в симе — он простаивает, юниты живут в ленте. Поэтому источник фокуса
камеры берётся из ЛЕНТЫ (
TapeFocusPointSourceпо кадру плейбека), а неCombatFocusPointSource(тот читаетCombatSimulation.Units— у повтора пусты). Без этого камера в Action кадрирует пустоту. BattleStagePresenceдержит ДИРЕКТОР меню на всё время фона, а не поduel-скоуп: смена дуэли пересоздаёт скоуп, и Enter/Exit на скоупе мигал бы камерой Overview↔Action между дуэлями. Фокус же привязывается поduel (свой плейбек), камера при этом остаётся в Action.- Арена — событием, вне часов:
ArenaRevealRequestуже развязано, повтор его просто публикует.
Владелец правды: Presentation/BattleStagePresence.cs, Presentation/Camera/CameraModeController.cs
(второй триггер Action), Presentation/TapeFocusPointSource.cs, Game/Flow/MenuBattleDirector.cs.