Vortex — вход в систему
Что это?
Vortex — это готовая среда для разработки приложений на Unity. Не библиотека, не набор утилит, а оформленный каркас, в котором уже заранее решено:
- как устроен жизненный цикл приложения,
- где лежат данные,
- как UI получает то, что показывает,
- как одна часть приложения узнаёт об изменениях в другой,
- как считается время и выполняется асинхронный код,
- как должны выглядеть редакторские инструменты.
Vortex подходит для любого приложения — игры, утилиты, инструмента, симулятора, конфигуратора. Для игр дополнительно есть готовый Sdk-слой (состояния игры, квесты, мини-игры, save/load), но он опционален.
Проще говоря: ты не строишь архитектуру с нуля — ты добавляешь свою логику в уже работающую систему.
Ключевая идея
Системы не знают друг о друге напрямую. Они общаются через данные.
Это значит:
- нет жёстких ссылок между модулями;
- никто не «находит» соседа через
FindObjectOfTypeили DI-контейнер; - любой модуль либо публикует данные в общую шину, либо читает их оттуда по типу.
Такой подход даёт два эффекта сразу: модули остаются независимыми (можно выкинуть/заменить), и при этом они автоматически видят актуальное состояние приложения.
Что уже есть «из коробки» (универсальное ядро)
Это базовый набор, на котором строится любое приложение в Vortex — вне зависимости от того, игра это или нет.
| Подсистема | Что закрывает |
|---|---|
Database |
Шина данных всего фреймворка. Хранилище Record-ов, поиск по типу или GUID. |
App |
Жизненный цикл приложения, состояния (AppStates), события OnStateChanged / OnStarting / OnStart / OnExit. |
UIProvider |
Открытие/закрытие UI по условиям, без прямых ссылок на префабы из логики. |
ReactiveValue<T> |
Подписки на изменения значений (IntData, BoolData, FloatData, StringData). |
TimeController / Timer |
Контроль времени, отложенные действия, накопление вызовов. |
Settings |
Настройки приложения с откатом и пресетами. |
Save |
Сохранение/загрузка состояния через ISaveable. |
AudioProvider |
Музыка/звуки/каналы громкости через шину. |
Localization |
Локализация и переключение языков. |
LogicChains |
Пошаговые цепочки логики из ScriptableObject. |
EditorTools |
Атрибуты и Odin-drawer'ы для удобного инспектора. |
Всё это — один согласованный набор, не набор независимых пакетов. Они рассчитаны друг на друга.
Что добавляется для игр (Sdk-слой)
Если делается именно игра, поверх ядра подключается опциональный Sdk-слой:
| Подсистема | Что добавляет |
|---|---|
GameController |
Состояние конкретной игровой сессии (NewGame / Load / Save), реестр модулей сессии. |
Quests |
Жизненный цикл квестов, условия активации, награды, save-points. |
MiniGames |
Каркас мини-игр со статистикой, паузами, cheat-handler'ами. |
Sdk не обязателен. Утилиту или инструмент можно собрать только на ядре.
Как строится логика
Любая фича в Vortex живёт по одной схеме — это работает и для игровой механики, и для экрана настроек, и для бизнес-инструмента:
Controller → Data → View
▲
│
(View → Controller через extension-методы или handler'ы)
- Controller — статический класс или Singleton. Решает, что делать.
- Data —
RecordвDatabase(илиIGameDataвGameModelдля игр). Хранит состояние. - View —
MonoBehaviour, который читаетDataи подписывается на изменения. Сам решений не принимает.
Когда пользователь что-то нажимает, View не меняет данные напрямую — он вызывает extension-метод контроллера, который уже всё пересчитывает.
Архитектура в одном взгляде
Три картинки, которые в сумме описывают весь Vortex. Если запомнить их — остальное складывается.
1. Поток управления от ввода до отрисовки
Полный цикл «что произошло у пользователя — как это отразилось на экране»:
[Внешний ввод] ← клик, gamepad, сенсор, сетевое событие
│
▼
[View / Handler] ← MonoBehaviour ловит ввод, никаких решений не принимает
│
▼
[Extension-метод / Bus] ← обращение к контроллеру через шину, не прямой ссылкой
│
▼
[Controller] ← вычисляет, валидирует, решает
│
▼
[Reactive Data] ← Set() на ReactiveValue, новое значение в шине
│
▼
[OnUpdate event] ← подписчики (включая View) получают уведомление
│
▼
[View update] ← перерисовывается то, что показывается пользователю
Поток строго однонаправленный. View никогда не пишет в Data напрямую — только сообщает контроллеру о намерении. Контроллер мутирует Data. ReactiveValue уведомляет View. Цикл замкнут через события, а не через прямые вызовы.
2. Слой шин — как системы общаются
Каждая системная подсистема Vortex (Inventory, Audio, Localization, Video, Save…) построена по одному шаблону:
Контроллер-фасад Подменяемая реализация
┌─────────────────┐ ┌─────────────────────┐
│ Inventory │ ─── IDriver ─────▶ │ InventoryDriver… │
│ (статический │ │ • Local │
│ публичный API) │ │ • Network │
└─────────────────┘ │ • Test / Mock │
▲ └─────────────────────┘
│ ▲
│ │
Любой код проекта DriverConfig.asset
(стратегии, View, (выбор реализации
handler'ы) обращается в инспекторе)
через шину
Контроллер — это тонкий фасад с фиксированным контрактом, доступный отовсюду. За ним стоит подменяемый драйвер. Меняешь реализацию в DriverConfig — меняется поведение системы целиком, остальной код не правится.
Это и есть Vortex-аналог dependency inversion: вызовы идут на стабильный контракт шины, а не на конкретный класс реализации.
3. Сборка приложения из пакетов
Vortex собирается не «вручную в коде», а из набора подключённых пакетов на этапе runtime/editor composition:
Config-ассеты в проекте Пакеты с реализацией Собранная среда runtime
┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
│ DriverConfig │ │ ru.vortex.unity.… │ │ Контроллеры готовы │
│ DatabaseSettings │ ──── + ──── │ ru.vortex.sdk.… │ ────▶ │ Драйверы привязаны │
│ AudioChannelsConfig │ │ ru.vortex.steam.… │ │ Шины эмитят │
│ SdkSettings │ │ ru.vortex.nani.… │ │ Сцена работает │
└──────────────────────┘ └──────────────────────┘ └──────────────────────┘
│ │
│ │
Геймдиз выставляет в Разработчик включает
инспекторе SO-конфигов нужные пакеты в SdkSettings
Контейнер на регистрации не нужен — конфигурация хранится в ScriptableObject-ассетах. Каждый пакет автономен: подключил — работает, выключил тогл в SdkSettings — отвалился вместе со своими зависимостями.
Это package-composition-first архитектура: компонуем приложение не кодом, а конфигурацией ассетов.
Запомнить три картинки достаточно, чтобы понимать, где живёт что в Vortex. Дальше каждый пакет конкретизирует свой кусок этой общей схемы.
Где лежат данные
1. Database — шина для любого приложения
Это глобальный реестр Record-ов. Сюда попадает всё, к чему должен иметь доступ любой пакет:
// Получить пресетные данные по GUID:
var preset = Database.GetRecord<ItemPreset>(itemGuid);
// Получить новую копию из пресета (для multi-instance):
var instance = Database.GetNewRecord<ItemData>(itemGuid);
Database — единственное хранилище, которое нужно для любой не-игровой задачи (утилита, инструмент, конфигуратор).
2. GameModel — состояние игровой сессии (только для игр)
Если используется Sdk-слой, для данных текущей игры есть отдельный контейнер. Модули просто описывают свои IGameData (HP игрока, прогресс квестов, инвентарь) — регистрировать их вручную не нужно:
// 1. Описываем данные модуля — достаточно реализовать IGameData:
public class InventoryData : GameModel.IGameData
{
public List<ItemId> Items = new();
}
// 2. Никакой ручной регистрации не требуется.
// GameModel (ComplexModel) при старте сессии сам находит все реализации
// IGameData рефлексией и создаёт по экземпляру каждой.
// 3. Читаем из любого места по типу:
var inventory = GameController.Get<InventoryData>();
inventory.Items.Add(itemId);
GameController.Get<T>() требует, чтобы T реализовывал GameModel.IGameData (маркер-интерфейс) и имел конструктор без параметров — этого достаточно, чтобы данные автоматически попали в сессию.
Шаблоны (.vtp)
В Vortex есть система шаблонов — файлы .vtp, в которых заранее упакована структура конкретного типа фичи: папки, скрипты, заготовки контроллера/данных/view.
Развернул шаблон → получил готовый каркас модуля. Дальше пишешь только специфичную логику.
Шаблоны работают для любых модулей, не только игровых. Особенно удобно для типовых вещей вроде мини-игр: один шаблон — и у тебя уже есть MiniGameController, MiniGameData, view-контейнер, handler'ы — всё подключённое к GameController.
Что ты на самом деле делаешь
В Vortex разработчик не строит инфраструктуру. Он:
- описывает данные (
RecordилиIGameData); - пишет логику (контроллер);
- вешает view, который подписывается на данные;
- публикует данные в
Database(для игровой сессииIGameDataподхватываетсяGameModelавтоматически).
Всё остальное — состояния, время, UI, реактивность — уже работает.
Что это даёт
- Скорость: типовые задачи закрыты, не надо каждый раз изобретать.
- Предсказуемость: все модули устроены одинаково — открыл папку и понял, где что.
- Масштабируемость: новые механики и фичи добавляются как ещё один модуль, не ломая существующие.
- Чистота: нет «магических» зависимостей и DI-графов, потоки данных видно невооружённым глазом.
- Универсальность: одна и та же архитектура подходит и для игры, и для редакторского инструмента, и для приложения-конфигуратора.
Цена
- Нужно принять правила: данные через шину, логика в контроллере, view только отображает.
- Нельзя «делать как привык» — попытка прокинуть прямую ссылку между двумя контроллерами сразу заметна и обычно означает, что данные не там.
- Требуется дисциплина: данные, действия и отображение — это три разные сущности, их не смешивают в одном
MonoBehaviour.
Когда это оправдано
Vortex имеет смысл, если:
- проект нетривиальный (несколько систем, несколько сцен, сохранения, настройки);
- есть несколько независимых модулей (механики в игре, экраны в инструменте, режимы в утилите);
- ожидаются рост и изменения на длинной дистанции;
- важна скорость добавления новых фич силами небольшой команды.
Для прототипа на пару экранов — overkill. Для проекта, который будет жить год+ — окупается за первый месяц.
Коротко
Vortex — это среда для любого Unity-приложения, в которой базовые инфраструктурные задачи уже решены, а разработчик работает только с логикой и данными, не связывая систему вручную. Для игр поверх ядра подключается опциональный Sdk с готовыми game-специфичными инструментами.
Дальше:
Vortex/Core/— слой ядра (чистый C#).Vortex/Unity/— Unity-адаптация.Vortex/Sdk/— опциональный игровой Sdk (GameController, Quests, MiniGames).Vortex/*/README.ru.md— документация по конкретным системам.