🚀 Migration Guide
December 11, 2024 · View on GitHub
Переход с версии 2023.1 на 2024.1
Breaking changes
- При установке в Unity через package manager или manifest.json теперь необходимо указывать дополнительно ?path=Scellecs.Morpeh. Ссылка на установку обновлена в
README.md. - Максимальное количество активных
Worldтеперь ограничено до 256. Если у вас более 256 миров одновременно, постарайтесь объеденить что-то в один мир. Entityтеперь является структурой вместо класса и больше не имеет модификатора partial.default(Entity)зарезервирована как невалидная сущность. Если у вас есть внешние плагины или код, использующий уже несуществующий функционал, возможно, потребуется их обновить. Некоторые данные (например, для плагинов, расширений и т.д.) всё ещё могут быть доступны через internal часть (такие какEntityDataвWorldили классArchetype). ПулингEntityтакже больше не имеет смысла.- Поскольку
Entityтеперь структура и может использоваться в jobs,EntityIdиWorld.TryGetEntityбыли удалены - нативное API теперь напрямую используетEntity. - Методы
EntityExtensions(Entity.Add<T>()и т.д.) помечены как устаревшие из-за возможного удаления в будущих версиях Morpeh. Они будут доступны в текущей версии Morpeh (2024), но могут быть удалены в релизе Morpeh 2025. Рекомендуется использоватьStashAPI, которое гарантированно останется и работает быстрее. Installer,UpdateSystem,FixedSystemи другие системы на основе ScriptableObject теперь помечены как устаревшие из-за возможного удаления в будущих версиях Morpeh. Они доступны в текущей версии Morpeh (2024), но могут быть удалены в релизе Morpeh 2025. Рекомендуется использовать APISystemGroup+ISystem(IFixedSystemи т.д.) для более легкой миграции в будущем.- Функционал для изменения начального размера
Stash<T>теперь является частьюComponentId. ИспользуйтеComponentId<T>.StashSizeперед первым вызовомWorld.GetStash<T>()(включая API EntityExtensions и различные провайдеры / внешний код). ComponentIdиExtendedComponentIdтеперь разделены. С целью уменьшения размера метаданных IL2CPP.ExtendedComponentIdтеперь вырезается из не-UnityEditor сборок, если не указанMORPEH_GENERATE_ALL_EXTENDED_IDS.ExtendedComponentIdможет потребоваться для кода на основе рефлексии, где интерфейсаIStashнедостаточно.- Удален
UniversalProvider. Рекомендуется использоватьMonoProvider.UniversalProviderможет вернуться в форме сгенерированного класса с компонентами, в будущих версиях (т.е. "MonoProviderно с несколькими компонентами"). - Удален
BitMap<T>. При необходимости используйтеIntHashMap<T>или перенеситеBitMap<T>из Morpeh 2023.1 в свой проект. - Удален
UnmanagedList<T>. Поскольку он и так был сломан, это не повлияет на существующие проекты. - Удален
UnmanagedArray<T>. Поскольку он и так был сломан, это это не повлияет на существующие проекты. - Удален
Stash<T>.Empty(). Использовалось для внутренних целей и не должно повлиять на проекты. Если вы где-то это использовали, поменяйте наdefault(T)для того же эффекта. FastList<T>и несколько других коллекций были исправлены для большей надежности и меньшей подверженности ошибкам. Это может повлиять на проекты, которые полагались на предыдущее поведение этих коллекций. Пожалуйста, адаптируйте использование к переименованным методам или новым перегрузкам. Имейте в виду, что HashMaps всё ещё не работают с отрицательными значениями в качестве ключей внутри вызововforeach.bool Stash<T>.Add(Entity entity, in T value)теперь является методомvoidи выбрасывает исключение, если у сущности уже есть компонент. Это решение было принято из-за множества проектов, использующихAddи игнорирующих возвращаемое значение, что приводило к очень сложно обнаруживаемым ошибкам.- Все методы
Stash<T>теперь всегда выбрасывают исключение, если сущность невалидна или операция не имеет смысла (например,Get, если у сущности нет такого компонента), как в Debug, так и в Release режимах. Это может увеличить количество исключений в вашем проекте вместо их тихого игнорирования, как было раньше. Эти исключения должны быть обработаны и исправлены в коде проекта.
New API
- Ознакомьтесь с Changelog для полного списка изменений.
Next Major Version remarks
Мы оцениваем возможность активного использования сорс генераторов в будущих версиях Morpeh, потенциально даже в релизе 2025 года. Это может наложить больше ограничений на то, что мы сможем или не сможем поддерживать.
Одним из вероятных изменений является возможное введение tag стешей (нон-дженерик) для компонентов-тегов, что уменьшило бы накладные расходы IL2CPP, использование памяти и повысило бы общую производительность. Мы хотим сделать это независимым от пользователя, чтобы пользователю не нужно было беспокоиться о конкретной реализации стеша, если это возможно. Из-за этого, возможно, стоит избегать итерации по стешам с компонентами-тегами, так как эта операция может замедлиться из-за необходимости трейлинга нулей, если в качестве типа хранения будет выбран битсет. Это может быть или не быть битсетом (например, если мы используем хэшсет или что-то еще), но общая идея заключается в том, чтобы быть осторожным при итерации по большим стешам с тегами.
Одним из наиболее вероятных изменений является удаление API EntityExtensions в пользу
Stash API. Мы признаем, что EntityExtensions - это очень удобное API, но оно имеет
большие накладные расходы (как CPU, так и объем метаданных IL2CPP) и не является очень гибким,
особенно в контексте реализации стешей для компонентов-тегов, описанных выше.
Мы уже продолжительное время используем в наших проектах совершенно отдельный раннер для систем,
и он хорошо работает, позволяя нам избегать виртуальных вызовов для методов обновления систем,
улучшая общую производительность за счет снижения затрат на неактивные системы (системы, которые не имеют сущностей для обработки, но метод обновления всё равно вызывается).
Это может привести к полному удалению систем на основе ScriptableObject в пользу сгенерированных систем, а также сгенерированных "фичей",
которые заменят SystemGroup. Для более легкой миграции в будущем мы рекомендуем
придерживаться чистых C# систем, реализующих интерфейс ISystem, вместо
систем на основе ScriptableObject.
Провайдеры (EntityProvider/MonoProvider) также могут быть изменены в
будущих версиях. Мы рассматриваем возможность объединения их в один
сгенерированный класс, который позволил бы определять сразу несколько компонентов в одном
провайдере. Это также позволило бы нам создать более прозрачный пайплайн удаления сущностей, так как в настоящее время EntityProvider на самом деле
не удаляет сущности из мира, а просто удаляет с нее свои компоненты.
Это иногда приводит к путанице и неожиданному поведению, когда у сущности есть компоненты, установленные извне провайдеров,
потенциально приводя к утечке неиспользуемых сущностей.
Все описанные выше изменения определенно повлияют на внешние плагины, расширения и другой код, который полагается на внутренности Morpeh или даже некоторые публичные API.
Обратите внимание, что это только планы, и они могут быть или не быть реализованы в будущем. Список также может быть неполным и может не охватывать все планируемые изменения.
Переход с версии 2022.2 на 2023.1
Breaking changes
- Инициализацию
Filterнеобходимо заканчивать методомBuild(), напримерWorld.Filter.With<Component>().Build(). - Удален
ComponentProvider, если вы им пользовались, то можно скопировать его из старых версий или написать свой аналог.
New API
- Как альтернатива Odin Inspector пришел Tri Inspector. Теперь у фреймворка нет платных зависимостей. Вы можете использовать оба варианта на выбор.
- Добавлены аспекты. Это вспомогательные структуры, которые помогают делать срез из набора компонентов на сущностях. Подробнее в ридми.
- Теперь можно полностью очистить стеш от компонентов вызвав
stash.RemoveAll(). Удобно когда вы делаете OneFrame Components и уверены, что в какой-то момент никаких компонентов определенного типа не должно существовать в мире. - Для провайдеров добавлены методы деинициализации по аналогии с инициализацией.
World.JobHandleпозволяет связывать джобы в рамках однойSystemsGroup. Подробнее в ридми.- Добавлены метрики для профайлера, которые позволяют следить за количеством сущностей, количеством архетипов и прочим. Подробнее в ридми.
- Добавлен флаг и метод для проверки, что мир уже удален и он в невалидном состоянии.
World.IsDisposedиWorld.IsNullOrDisposed()соответственно. - Добавлен дефайн
MORPEH_DISABLE_SET_ICONS, чтобы отключать назначение иконок в редакторе у наследников провайдеров, систем и прочего. - Теперь метод
World.Commit()проверяет, что не вызван внутри итерации по фильтру, потому что иначе это приведет к изменению фильтра. - Добавлен флаг
World.DoNotDisableSystemOnExceptionкоторый позволяет не отключать системы, когда они выкидывают исключения в режиме отладки. На релизную версию никак не влияет. - Добавлен метод
Filter.IsNotEmpty().
Odin Inspector
Вы можете продолжать использовать Odin Inspector или перейти на Tri Inspector.
Для этого вам необходимо добавить Tri Inspector по Git URL.
Удалить Odin, и удалить Odin Inspector дефайны из Player Settings.
Переход с версии 2022.1 на 2022.2
Breaking changes
- Минимальная версия Unity поднята до 2020.3.* LTS
- Неймспейсы изменены с
MorpehнаScellecs.Morpeh,Scellecs.Morpeh.Systems,Scellecs.Morpeh.Providers. - Глобалы выделены в отдельный пакет по ссылке https://github.com/scellecs/morpeh.globals.
- Метод
World.UpdateFilters()переименован вWorld.Commit(). - Класс
ComponentsCache<>переименован вStash<>. Все методы для стешей утратили приставкуComponent, теперь простоAdd, Get, Set, Has, Remove. - Фильтры валидируют, что в них нет повторяющих типов. Например на
Filter.With<A>().With<A>()будет выведена ошибка. - Из систем удалено проперти
Filter, вместо этого нужно использоватьWorld.Filter.
New API
- Добавлены
ICleanupSystemподходящие для логики отчистки. По умолчанию вызываются самыми последними в LateUpdate. - Переработан механизм отчистки компонентов. Теперь компонент должен имплементировать
IDisposable, и необходимо единожды вызвать у стеша методAsDisposable, чтобы отчистка происходила. Например самый короткий вариантWorld.GetStash<T>().AsDisposable(). - У
Worldдобавлен методGetReflectionStash, чтобы получать стеш не через дженерик аргумент, а поSystem.Type. - Добавлен дефайн
MORPEH_THREAD_SAFETY, который заставляет ядро валидировать, что все вызовы идут из того же потока в котором мир был создан. Привязку к треду можно изменить через методыWorld.GetThreadId(), World.SetThreadId(). - Добавлено API для плагинов. Для использования нужно имплементировать
IWorldPlugin.
Переход с версии 2020.* на 2022.1
Breaking changes
- Асмдеф и ссылки изменены с
XCrew.MorpehнаScellecs.Morpeh. Неймспейсы те же, что и были. - Все глобалы утратили метод
NextFrame. Вместо него теперь необходимо использовать методPublish, который отправляет событие не в этот кадр, а в следующий как ранее делалNextFrame. Отправить событие в текущем кадре теперь невозможно, оно всегда отложенное. Это изменение связано с тем, что на всех проектах использовалась связка Publish + NextFrame, либо только NextFrame. Entity.IDтеперь возвращает неint, а структуру типаEntityIDв которой содержаться поляidиgen. Это необходимое изменение для работы с Jobs и Burst. Так же добавлен методWorld.TryGetEntity(EntityId entityId, out Entity entity), который позволяет проверить наличие сущности без прямой ссылки на нее.Filter.Lengthудален полностью. Его заменила связкаFilter.GetLengthSlow()иFilter.IsEmpty(). Это изменение связано с тем, что обновление кешированного значения длины для каждого фильтра давало большую нагрузку, а учитывая, что большинству фильтров не требовалось проверка на длину, то это была пустая нагрузка. Важный момент, что длина чаще всего использовалась для проверки на пустоту фильтра. Теперь получение длины дорогая операция, но проверка на пустоту такая же быстрая как и раньше. Это позволило сильно ускорить проекты с большим количеством фильтров.- Кеши компонентов теперь чистят данные после вызова
entity.RemoveComponent()и читать данные по ref из компонента после его удаления теперь нельзя. - Итерирование по
Filterтеперь не гарантирует очередность. Если раньше ваша логика в проекте могла зависеть от того в каком порядке сущности попадают и удаляются из фильтра, то теперь необходимо от этого избавится. - Удален
ComponentsBag. На его замену пришел полный публичный доступ к кешам компонентовComponentsCache.
New API
- Добавлены новые интерфейсы для компонентов
IValidatable,IValidatableWithGameObject. Позволяет вызывать стандартный юнитевский методOnValidateна компонентах, чтобы, например, проинициализровать поля в редакторе. Работает только для компонентов, добавленных через MonoProvider. - Добавлено нативное апи для работы с Job и Burst. Подробно о его работе можно прочитать в ридми. Теперь есть методы
AsNative()для:- Archetype (NativeArchetype)
- ComponentsCache (NativeCache)
- FastList (NativeFastList)
- IntFastList (NativeIntFastList)
- Filter (NativeFilter)
- IntHashMap (NativeIntHashMap)
- World (NativeWorld)
- Добавлен интерфейс
IMorpehLoggerи статический классMLogger. Они позволяют переопределить логирование для Morpeh. Console.WriteLine для окружений кроме Unity по дефолту. - Добавлен дефайн
MORPEH_PROFILING. Добавление его в Player Settings позволяет профилировать нагрузку от систем без Deep Profile. - Теперь
Entity.Dispose()стал публичным методом. Это позволяет уничтожить энтити без прямого доступа к миру. - Отображение нескольких миров в World Browser