TGViewer
Unity Architect: архитектура unity проектов Unity Architect: архитектура unity проектов @uniarchitect · 5.24K subscribers
Post #163 3.98K
МАШИНА СОСТОЯНИЙ - АДище

Машина состояний — один из самых интуитивно понятных подходов. Нарисовал квадратики, провёл стрелочки, описал условия переходов — готово.

И если для анимаций, поведения противников, состояний предметов и квестов — использование оправдано и обосновано.
То когда состояния начинают просачиваться в глобальное управление — подключениями, сценами, окнами UI — появляется проблема.

Ты не сможешь продумать все возможные события и условия переходов. Рано или поздно это приведёт к зависанию в одном состоянии машины.

Дийкстра рассуждал об этом ещё в 68 году — описывая:
В мультипрограммных системах, где несколько процессов работают параллельно с неопределённым порядком прерываний, возникают часто ошибки невоспроизводимые — зависящие от случайного момента прерывания.


Чуть более простым языком эту проблему можно описать так:
Событие, поступившее конечному автомату в некотором контексте, может не вызвать никакого действия, поскольку автомат не в состоянии однозначно определить, какое именно действие должно быть выполнено, исходя из полученного входного сигнала и текущего состояния машины.
🔸Пример 1: Loading

Сцена Loading — инициализация, подключение к серверу, скачивание конфигов.
Следующее состояние — Meta, главное меню.
Переход Loading → Meta срабатывает по условию: «все конфиги загружены и соединение активно».

Пользователь во время скачивания свернул приложение чтобы прочитать новый пост по архитектуре 😎 и вернулся через 10 минут. Соединение отвалилось по таймауту, часть конфигов скачалась, часть — нет.

Приложение получает OnApplicationPause(false) — «пользователь вернулся». Машина всё ещё в Loading. Но конфиги не все, а соединение мертво.
Перехода «переподключиться» не предусмотрено, потому что автор не заложил комбинацию «Loading + потеря соединения + частичная загрузка + выход из паузы».

Событие пришло, а ни один переход не сработал — игра зависла в Loading навсегда.

🔹Пример 2: Пауза

Цепочка уровней и игровой цикл: открыл уровень → бой → противники убиты → сбор наград → заход в триггер следующего уровня → повторить. Очень легко описать в виде машины.
Помимо этих состояний есть ещё Paused — оно активируется кнопкой окна настроек.

На стадии «заход в триггер следующего уровня» пользователь делает frame-perfext noscope360 в пиксель кнопки настроек и открывает окно, когда не должен 🤣

Машина переходит в Paused, но перехода из Paused обратно в «триггер следующего уровня» не существует — он просто не был прописан.
Окно закрывается, а игра остаётся в Paused навсегда.

🔸И вот ключевой момент

Казалось бы — пойди да пропиши переход, делов на 5 минут.
Но сделав это, где гарантия что в такую же ситуацию не попадёт любое другое состояние машины?

А их нет! Нужно в каждом месте, которое полагается на машину, прописывать обработку всех возможных состояний.

И это большая проблема. Если система так написана, сроки фикса жмут, времени всё переписывать нет — приходится костылить: запрещать или обрабатывать конкретный переход.

🔻Каждое новое состояние или событие мультиплицирует количество переходов, которые нужно определить. N состояний и M событий — это N×M переходов, и если хоть один не определён, есть риск перехода в невалидное состояние.

У приложения и UI события приходят в неопределённом порядке, по кругу, без финальной точки — ровно та ситуация, которую Дийкстра описал как источник невоспроизводимых ошибок.

И могу лишь подтвердить из своего опыта. Такие ошибки всегда самые сложные для исправления т.к. очень сложно всегда найти репро.

🔻Так что пожалуйста, не надо. Вам не нужна машина состояний для "контроля" состояния приложения и окон 🫠

Вредно как со стороны сложности проекта, так и со стороны нашего ментального здоровья.
Развивает параною "а я точно исправил проблему или опять какой-то кейс не покрыл" 😵‍💫

Делитесь своими историями исправления сложных багов в комментах, уверен у каждого есть пачка таких 🫡

Ставь 👍 если тебе заходит такого рода контент!
Ты знаешь кому переслать эту статью 💪

#проект_в_разработке@UniArchitect
#проект_с_нуля@UniArchitect
  • 👍 14
  • 🤨 9
  • 🤔 1
More from @uniarchitect
  1. Jul 24, 2026Post #199
  2. Jul 12, 2026AI НЕ ДЕЛАЕТ ВАС ПРОДУКТИВНЕЕ Незыблемый факт: AI уже очень хорош в маленьких задачах. Нап…
  3. Jul 9, 2026Post #196
  4. Jul 7, 2026UNITY BUILD PIPELINE ПО КИРПИЧИКАМ Полгода назад я решил попробовать активность в блоге, г…
  5. Jul 4, 2026ПРОКЛЯТИЕ ПЕРЕИСПОЛЬЗУЕМОСТИ Делюсь болью. Я последние 5 лет на разных уровнях у разработч…
  6. Jun 29, 2026AI КАК РЕДАКТОР, А НЕ АВТОР Это вторая статья из серии про AI. Первая тут. Когда я запуска…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →