Решили: пул перезапусков акта спрашивается только после проверки IBattleSession.CanRestart — признака «есть кому исполнить перезапуск».

Почему: списание попытки стояло прямо в условии while, а исполнимость выяснялась строкой ниже: RequestRestart() отвечал «некому», цикл выходил в поражение, и попытка уже была потрачена. Счётчик в верхней панели уменьшался, не дав игроку ни одного перезапуска. Отвергнутая альтернатива — возвращать попытку при отказе: пул умеет только тратить, возврат пришлось бы изобретать, и он существовал бы ради одной ветки отказа.

Грабли: побочный эффект в условии цикла читается как проверка. _tryConsumeRestart() выглядит вопросом «есть ли попытка», хотя это «дай попытку»; разница видна, только если открыть определение.

Владелец правды: BattleFlow.Run (комментарий у цикла), IBattleSession.CanRestart.