Формат моделей и 3D-композиция
FOnline использует описания моделей .fo3d, чтобы собрать на клиенте запечённые 3D-меши, преобразованные исходные анимации, выбираемую слоями экипировку, дочерние модели, частицы, переопределения материалов и объёмы отсечения.
Это руководство описывает авторинг и runtime-модель. Точный контракт текущей ревизии приведён в сгенерированных справочниках токенов, ресурсов и лимитов, правил валидации и в канонической JSON-модели.
Область и авторитетные источники
Контрактом владеют:
Source/Tools/ModelMeshBaker.cppиSource/Common/ModelMeshData.*для импорта и проверки мешей.fbx/.obj, а также mesh-only payloadLFMODMSH;Source/Tools/ModelSourceLoader.*,Source/Tools/ModelAnimationConverter.*иSource/Common/ModelAnimationData.*для извлечения исходного скелета и клипов, анализа совместимости, преобразования Ozz и нативного rig payload;Source/Tools/ModelInfoBaker.cppдля разбора.fo3d, раскрытия include, проверки зависимостей и исходников, сериализации model info, создания runtime rig и метаданных анимации;Source/Client/ModelManager.*,ModelHierarchy.*,ModelInformation.*,ModelInstance.*иModelAnimation.*для строгой runtime-загрузки, общих неизменяемых данных, композиции и позы экземпляра, контроллеров анимации и рисования;Source/Frontend/Rendering.hи сгенерированный CMake-интерфейс проекта для compile-time лимитов моделей;- тесты baker, mesh data, source loader, animation data/converter/runtime, совместимости скелета, Ozz и client engine как исполняемые примеры грамматики, форматов, преобразования, загрузки и ошибок.
Это переиспользуемая документация движка. Встраивающий проект владеет конкретными именами моделей, значениями слоёв, enum анимаций, художественными правилами, экипировкой, игровыми таймингами и сценами визуальной проверки.
Полная машинная модель генерируется из BuildTools/ModelFormatInterface.json. Генератор напрямую сравнивает документированный набор токенов с ModelDescriptionParser::ParseToken; расхождение парсера и документации останавливает проверку.
Обзор конвейера
Конвейер моделей состоит из двух упорядоченных baker и общих модулей загрузки и преобразования:
ModelMeshBakerс порядком4импортирует.fbxи.objи записывает версионированный mesh-only ресурсLFMODMSHпо тому же пути и с тем же расширением. Клипы и изменяемая поза в этот payload не входят.ModelInfoBakerс порядком6разбирает конкретные.fo3d, проверяет ссылки и свежесть исходников, загружает выбранные скелеты и клипы черезModelSourceAssetCache, преобразует канонический runtime rig и записываетLFMODINFс обязательным payloadLFOZZRIGпо пути.fo3d. Он также создаётModelAnimationInfo.foinfoдля общих длительностей и границ.
Клиент не разбирает авторский текст, FBX или OBJ. ModelManager загружает общие иерархии мешей, ModelInformation строго читает неизменяемое описание и rig, а каждый ModelInstance владеет изменяемыми контроллерами, матрицами позы, дочерними объектами, частицами и render-композицией. Старые payload без заголовка и частичные fallback для rig отклоняются.
Файлы с basename TEMPLATE_ предназначены только для include. Они влияют на конкретные описания и timestamps запекания, но не создаются как самостоятельные .fo3d-ресурсы или секции ModelAnimationInfo.foinfo.
Контракт исходного меша
Поддерживаемые входы
Текущий ModelMeshBaker сканирует только:
.fbxдля скелетных и статических мешей, skinning, имён diffuse-текстур материалов, исходных скелетов и анимационных клипов;.objдля статических моделей, присоединяемых объектов и объёмов отсечения.
Устаревшие .x и .3ds не являются текущими входами. ModelMeshBaker не выберет файл с таким расширением.
Поведение импорта
Mesh baker и source loader используют закреплённую версию ufbx, но имеют разных владельцев. Первый выдаёт иерархию, bind, vertices, indices, skin и materials; второй извлекает проверенные данные skeleton/TRS/clip для преобразования анимации. Встроенные файлы игнорируются, skinning вычисляется, веса очищаются, а отсутствующие normals обрабатываются детерминированно.
Требования к исходникам:
- faces должны быть заранее триангулированы;
- конкретная модель должна содержать хотя бы один drawable mesh;
- имена nodes становятся именами bones, а nodes с геометрией — именами drawable meshes;
- используйте один material на drawable node, если важно детерминированное владение текстурой;
- файловая текстура
DiffuseColorпервого material становится texture slot0; - имена текстур сохраняются без исходной директории и затем разрешаются относительно запечённого меша;
- используется только первый skin deformer;
- число skin clusters должно помещаться в
FO_MODEL_MAX_BONES; - у вершины сохраняются только
FO_MODEL_BONES_PER_VERTEXвлияний, после чего веса нормализуются; - меш без skin получает детерминированную привязку к одной кости;
- имена animation stacks являются clip names для
Anim, но клипы загружаются из исходника и входят в rig model info, а не вLFMODMSH; - прямые
.fbx-attachments должны содержать только rest pose; если у присоединённого исходника есть клипы, используйте дочерний.fo3dс явнымиAnim; - внешние animation sources должны содержать только hierarchy и animation. Drawable geometry запрещена, кроме точного файла с временным исключением
AllowAnimationGeometry.
Source loader отклоняет не-конечные transforms, дубликаты clip names без учёта регистра, неверные durations и key times, превышение лимитов и глубины, а также некорректные отношения skeleton. Animation sources могут добавлять совместимые канонические joints без физического ModelBone; физические meshes и cuts остаются в базовой иерархии.
Текущие лимиты по умолчанию:
| Опция проекта | Runtime-константа | По умолчанию |
|---|---|---|
FO_MODEL_LAYERS_COUNT |
MODEL_LAYERS_COUNT |
30 |
FO_MODEL_MAX_TEXTURES |
MODEL_MAX_TEXTURES |
8 |
FO_MODEL_MAX_BONES |
MODEL_MAX_BONES |
54 |
FO_MODEL_BONES_PER_VERTEX |
MODEL_BONES_PER_VERTEX |
4 |
Это контракты бинарной формы и shader layout. При переопределении проект обязан использовать одинаковые значения в client binaries, запечённых моделях, Critter.ModelLayers, effects и packages.
Лексический синтаксис
.fo3d представляет собой последовательность токенов, разделённых whitespace:
#и;начинают комментарий;- quoted strings и escape syntax отсутствуют;
- paths и names не могут содержать whitespace;
- в одной строке может быть несколько directives;
- directive забирает обязательные arguments, затем разбор продолжается со следующего token;
- неизвестный token или отсутствующий argument является ошибкой запекания;
- integer arguments принимают числа, явные booleans или enum names из metadata resolver;
- float arguments должны быть конечными числами.
Компактная запись допустима:
Layer 1 Value 2 Attach Hat.fbx Link Head RotY 180 Texture 0 Hat.tga
Для сопровождения размещайте structural selectors (Layer, Value, Root, Attach) перед относящимися к ним modifiers.
Минимальные описания
Минимальная статическая модель:
Model Props/Crate.obj
Скелетная модель с анимациями и attachment, выбранным слоем:
Model Characters/Human.fbx
RotationBone Spine
Anim CritterStateAnim.Unarmed CritterActionAnim.Idle ModelFile Idle
Anim CritterStateAnim.Unarmed CritterActionAnim.Walk ModelFile Walk
Layer 1
Value 1
Attach Items/Hat.fbx Link Head
Enum names зависят от metadata встраивающего проекта. Числа в тестах движка доказывают поведение parser, но не являются рекомендуемым словарём проекта.
Include и шаблоны
Include разбирает другой файл inline:
Include TEMPLATE_Humanoid.fo3d mesh Human.fbx scale 0.9
После path идут пары name/value. До tokenization каждое буквальное %name% в подключаемом тексте заменяется значением:
# TEMPLATE_Humanoid.fo3d
Model %mesh%
Scale* %scale%
Правила include:
- path задаётся относительно файла, содержащего
Include; - пути
Model,AttachиCutв подключённом тексте задаются относительно include-файла; - внешний файл
Animпозднее разрешается относительно итогового конкретного.fo3d; - include arguments занимают остаток строки, поэтому следующую directive на той же строке размещать нельзя;
- replacements являются простой заменой текста, а не token-aware операцией;
- включённый текст разделяет parser state с вызывающим файлом;
- рекурсивные include отклоняются;
- самый новый timestamp во всём include graph управляет incremental rebake.
Предпочитайте самодостаточные шаблоны, явно устанавливающие Root, Layer, Value и Mesh. Скрытая зависимость от состояния вызывающего файла затрудняет работу людей, ИИ и валидаторов.
Состояние парсера
Parser отслеживает выбранные Layer, Value, текущий link для modifiers и текущий selector Mesh для Texture и Effect.
В начале файла текущим link является default root, поэтому top-level transforms и materials применяются к базовой модели даже без Root.
Layer или Value изменяет selector, очищает Mesh и переводит текущий link на dummy object. После выбора пары layer/value запишите Root, Attach или AttachParticles до transform, material, disable или cut. Modifiers при активном dummy link разбираются, но отбрасываются.
Directive для возврата Layer к начальному -1 нет. Все default-root declarations должны идти до первого Layer либо в более раннем include.
Root также очищает Mesh. Attach и AttachParticles создают link и очищают Mesh. Размещайте Mesh после selector link, к которому он относится.
Link сохраняется только для не-default и не-dummy link. На default root он игнорируется. Link у layer Root сериализуется, но дочернего объекта для присоединения нет; не задавайте его.
Слои и значения
Layer выбирает индекс фиксированного массива:
0 <= layer < FO_MODEL_LAYERS_COUNT
Value выбирает точное целое, определённое проектом. Ноль означает inactive и не может создать layer entry Root, Attach или AttachParticles.
В runtime ModelInstance::PlayAnim копирует или повторно использует массив слоёв, применяет точные overrides AnimLayerValue, сбрасывает модель к default root, находит совпавшие пары Layer/Value, применяет root modifiers и materials, создаёт или сохраняет children и particles, удаляет больше не выбранные элементы и перестраивает combined meshes при изменении композиции.
Layer value — это состояние render-композиции, а не только косметические metadata. Оно может менять transforms, animation speed, geometry, materials, effects, cuts, child models, particles и batching. Семантика каждого layer/value принадлежит документации и тестам проекта.
Модификаторы корня
Без выбранного layer Root выбирает default link базовой модели:
Root
Scale 0.9
RotX 90
При выбранной ненулевой паре layer/value он создаёт условный root modifier:
Layer 3
Value 2
Root
DisableMesh Torso
Texture 0 Armor.tga
Условные root links могут добавлять transforms и speed multipliers, переопределять textures/effects, отключать layers и meshes, добавлять cuts. Дочернюю модель они не создают.
Присоединение моделей
Attach требует выбранного layer и ненулевого value:
Layer 1
Value 4
Attach Weapons/Rifle.fo3d Link RightHand
Путь дочернего объекта задаётся относительно declaring file.
Присоединение к одной кости
При Link <bone> весь child становится дочерним объектом одной проверенной кости:
Attach Hat.fbx Link Head
Rotation, translation, scale, speed, materials, disables и cuts этого link применяются внутри child instance.
Общий скелет
Без Link runtime сопоставляет одноимённые кости child и parent:
Attach ArmorTorso.fbx
Используйте это только для одежды и частей тела, созданных под один skeleton. Если общих bones нет, runtime creation завершается ошибкой.
Дочернее описание или прямой меш
Используйте Attach child.fo3d, когда child нужны собственные base mesh, layers/attachments, default material/effect policy, cuts, animations или rendering flags. Для простой запечённой иерархии достаточно прямого .fbx / .obj. Дочерний .fo3d запекается самостоятельно; parent проверяет существование descriptor и bone из Link.
У direct attachment нет description-level коррекции scale. Maximum-axis extent его static bounds должен оставаться в диапазоне Baking.ModelAttachmentMinExtent .. Baking.ModelAttachmentMaxExtent; иначе bake завершается ошибкой с измеренным extent и limit. Используйте child .fo3d, если composition требует явного scale. Mesh nodes с отрицательным transform determinant раньше отклоняет ModelMeshBaker: reset/freeze mirrored geometry к положительному transform до export, не рассчитывая на переворот normals и winding в baker-е.
Присоединение частиц
AttachParticles выбирается слоем:
Layer 8
Value 1
AttachParticles Particles/Jet.spk Link Backpack
MoveY 0.15
RotY 90
Particle path является глобальным путём запечённого ресурса, а не путём относительно .fo3d. Ссылайтесь на созданный .spk или .efk, а не на авторский .spark или .efkproj. Всегда задавайте корректную bone в Link: runtime-создание частиц требует её.
MoveX/Y/Z и RotY определяют placement частицы. Instance живёт, пока активна точная пара layer/value, и удаляется при изменении композиции. XML, SPARK objects, renderer fields, effects/textures, runtime cache и визуальная проверка принадлежат формату частиц. Частицы на bones используют прямой путь 3D-композиции, а не selector atlas/direct-scene у ParticleSprite.
Преобразования и скорость
Поля link: RotX/Y/Z в градусах, MoveX/Y/Z в координатах модели, ScaleX/Y/Z и playback multiplier Speed. Scale задаёт все три оси.
У каждого поля есть assignment, additive и multiplicative формы:
Scale 0.9
Scale+ 0.1
Scale* 1.5
RotY 90
RotY+ 15
RotY* 0.5
Для форм + и * действует особая инициализация: если поле равно нулю, operand становится его значением; иначе выполняется обычное сложение или умножение. Поэтому template может использовать Scale* 0.9 или Speed* 1.2 без предшествующего assignment, а порядок declarations наблюдаем.
В runtime ноль означает identity/no contribution. Ненулевые transforms перемножаются с текущим model transform. Отрицательный итоговый Speed запрещён при запекании; ноль означает отсутствие вклада в скорость.
Меши, текстуры и эффекты
Mesh выбирает drawable node:
Mesh Torso
Texture 0 Armor.tga
Effect Effects/Armor.fofx
Mesh All очищает selector, и следующие material directives применяются ко всем drawable meshes текущей модели link. Subset устарел: parser забирает argument и пишет warning, но ничего не выбирает.
Текстуры
Texture 0 Diffuse.fofrm
Слоты находятся в [0, FO_MODEL_MAX_TEXTURES). Mesh выбирает отрисовываемые меши,
пути разрешаются относительно файла меша. Безусловный Texture слота 0 заменяет
импортированную diffuse-текстуру, чей исходник может быть поглощён рецептом.
Baker проверяет действующие умолчания; runtime загружает их для включённых мешей
после переопределений и привязки вложенных моделей.
Текстура требует опубликованный выход SpriteInfo с одним направлением и одним
кадром. FOFRM Size позволяет запечь уменьшенный вариант большого источника,
поставляя только корневой выход. Направление выбирается явно через FOFRM InputDir.
Обрезанный sprite mesh восстанавливает полный логический холст до загрузки,
сохраняя UV изображения. TextureAnimation не поддерживается и вызывает ошибку
неизвестной директивы; многокадровые ресурсы текстур отвергаются при выпечке и в runtime.
Во вложенной модели Parent или Parent_<mesh> наследует текущую статическую
текстуру родителя в том же слоте. При нескольких мешах родителя задавайте суффикс
имени меша. В корне Parent запрещён.
Пересоберите согласованные бинарники и принудительно перепеките описания моделей и метаданные для LFMODINF schema 5/runtime 0.0.76: переопределения больше не хранят флаг анимации. Прежние описания отвергаются; остальные схемы моделей и изображений прежние.
Эффекты
Effect Effects/SkinnedArmor.fofx
Effect paths являются глобальными baked-resource paths. Parent и Parent_<mesh> копируют текущий effect родителя по тем же правилам. Meshes объединяются в draw batch только при совместимых effect, texture set и bone capacity, поэтому material overrides могут менять batching и требуют измерения на типичных композициях.
Отключение слоёв и мешей
DisableLayer принимает layer indices через дефис:
DisableLayer 5-6-7
При активном link эти slots пропускаются внутри model instance.
DisableMesh принимает drawable node names через дефис, а DisableMesh All сохраняет wildcard и отключает все meshes:
DisableMesh Hair-HelmetBase
Используйте отключения для взаимоисключающей композиции, но явно документируйте project ownership слоёв. Циклическая и зависящая от порядка политика плохо тестируется.
Объёмы отсечения
Cut удаляет geometry из выбранных слоёв combined mesh:
Cut CutVolumes/Helmet.obj All HeadVolume - - -
Шесть arguments:
- path
.fbx/.objcut volume относительно declaring file; - target layers через дефис либо
All; - drawable shape names из cut file через дефис либо
All; - первая unskin bone либо
-; - вторая unskin bone либо
-; - unskin shape,
~shapeдля reversed behavior либо-.
All для layers раскрывается во все compile-time layers, кроме текущего выбранного. В default-root scope включаются все layers. All для shapes выбирает все drawable shapes, кроме отдельно указанного unskin shape.
Runtime классифицирует cut shape по числу запечённых vertices: ровно 36 означает axis-aligned box bounds, любое другое число — sphere radius по X extent. Это правило формата движка, а не общий mesh heuristic. Создавайте простые специализированные cut assets и проверяйте результат визуально.
Обе unskin bones задаются вместе; unskin shape требует обеих. Все bones и drawable shapes проверяются при запекании. Любой cut отключает обычный culling composed model, поэтому это correctness feature с render cost.
Управление рендерингом
Автоматический layout model sprite
DrawSize и ViewSize удалены. ModelInfoBaker пишет aggregate bounds, project-selected preview view/name bounds и per-animation bounds в ModelAnimationInfo.foinfo версии 2. Клиент проецирует их для каждого направления, расширяет с учётом children и layers и вычисляет offscreen frame, visual anchor, lighting envelope и interaction/view rectangle.
Каждый non-particle child link сериализует проверенный root-space AABB; default
link и particle links не содержат geometry payload. При расчёте envelope baker
учитывает disabled meshes, nested descriptions, link transforms и sampled
animations родителя. Runtime framing объединяет bounds активных animations с
envelopes выбранных links и проецирует только их corners без per-frame
weighted-vertex sweep. Live particles всё ещё могут вызвать ограниченный
expansion/rerender при выходе за baked geometry envelope. Авторы настраивают
source transforms, animation reach, attachments и Render.ModelProjFactor, а
не фиксированные пиксельные прямоугольники в .fo3d.
Проверяйте все направления и типичные animations в видимом клиенте. Для диагностики clipping, пустого пространства, polygon edges и crop placement используйте Game.DumpAtlases() или Dump atlases в Mapper. Бинарный и runtime-контракты описаны в Baking Pipeline и Frontend и рендеринг.
Прочие флаги
DisableShadowотключает тень модели.DisableAnimationInterpolationвыбирает nearest-key sampling.DisableBackwardAnimвыбирает forward walk/run вместоWalkBack/RunBackи совмещает look direction с движением.RotationBone <bone>включает movement overlay controller и directional rotation torso/head.FastTransitionBone <bone>сбрасывает transition state нового child на указанной link bone.
Граница анимации
Animation directives .fo3d:
Anim <state> <action> <ModelFile|animation-source> <clip|~clip|Base>
AnimSpeed <state> <action> <positive-factor>
AllowAnimationGeometry <external-animation-file>
AnimLayerValue <state> <action> <layer> <value>
StateAnimEqual <from> <to>
ActionAnimEqual <from> <to>
FastTransitionBone <bone>
RotationBone <bone>
DisableAnimationInterpolation
DisableBackwardAnim
Model Animation описывает first-entry-wins tuples, ModelFile/Base/~clip, совместимость skeleton и rig conversion, one-step aliases, effective duration, common и loaded-client lookup, substitutions и validation.
AnimLayerValue применяется к точной запрошенной паре до model composition. Alias resolution относится к animation lookup; не считайте, что alias также переписывает key для layer override.
AllowAnimationGeometry — узкий migration aid. Он называет один точный внешний файл из Anim, разрешается от конечного .fo3d, используется только baker validation и не сериализуется. Duplicate paths/targets, невыбранные файлы и оставшиеся после удаления geometry исключения являются ошибками. Исправьте export, сохранив необходимую helper/bone hierarchy, и удалите исключение в той же миграции.
3D skeletal animation отделена от 2D-контракта Motion в Sprite Root Motion.
Runtime-загрузка и кеширование
ModelManager::CreateModel(name) принимает запечённый .fo3d с полной composition semantics либо baked mesh path с простой rest-pose model без declarations и animation controller.
Descriptions и mesh hierarchies кешируются по resource name. Неизменяемые clips, remaps, bindings и canonical skeleton принадлежат ModelInformation; mutable timelines, poses, matrices, children и procedural transforms — каждому ModelInstance. При смене слоёв активные children повторно используются по stable baked link id, а переставшие совпадать children и particles удаляются.
Combined mesh generation объединяет совместимые видимые meshes, пока effect, textures или bone capacity не требуют нового batch. Cuts применяются после объединения parent и child meshes.
Не изменяйте и не разбирайте binary payload запечённых .fo3d, .fbx или .obj из project scripts. Их layout является приватным контрактом baker/runtime.
Поведение при ошибках
ModelInfoBaker отклоняет или сообщает: отсутствующий Model; недоступные, устаревшие или malformed baked meshes и sources; primary mesh без drawable geometry; отсутствующие textures/effects/particles/children/cuts; неверные layer/texture indices; нулевые layer values для Root/Attach; отсутствующие bones или meshes; malformed includes; invalid/non-finite numbers; отрицательный Speed; неположительный AnimSpeed; неизвестные enums, clips или несовместимые skeleton; attached FBX с clips; внешнюю animation geometry без точного временного исключения; mirrored mesh nodes; direct FBX/OBJ attachments вне настроенного диапазона Engine world units; неверные cut combinations; неизвестные tokens.
Runtime повторяет критические binary и range checks. Runtime exception означает повреждённые или устаревшие baked data либо пробел в validation; не ловите её для тихой подстановки несвязанной модели.
Предупреждение об устаревшем контенте
Не выводите текущую поддержку из старых FOnline-проектов:
.xи.3dsне выбираются текущим mesh baker;AnimEqualзаменён наStateAnimEqualиActionAnimEqual;CalculateTangentSpace,RenderFrameиRenderFramesне являются текущими tokens;Subsetоставлен только как warning path и ничего не выбирает.
Сначала переведите legacy assets на текущие source formats и grammar, затем проверяйте против текущей ревизии Engine. Старый проектный контент — свидетельство исторического использования, а не нормативная спецификация.
Практики авторинга
- Размещайте default-root declarations до первого
Layer. - Оставляйте у concrete description ровно один намеренный итоговый
Model. - Начинайте include-only files с
TEMPLATE_. - Пусть template явно задаёт selector context.
- Используйте enum names и project layer constants из metadata.
- Документируйте каждый layer index, allowed value, owner и конфликтующий layer.
- Делайте отдельный drawable node для независимо заменяемого material/effect.
- Используйте direct mesh для простого prop, а child
.fo3dдля переиспользуемой композиции. - Всегда задавайте
Linkу particle attachment. - Соблюдайте регистр paths, bones, meshes, animation stacks и effects.
- Делайте cut volumes простыми и специализированными.
- Проверяйте матрицу сочетаний layers, а не только каждый attachment отдельно.
- Экспортируйте external animations без drawable geometry, сохраняя нужную hierarchy.
- Считайте каждый
AllowAnimationGeometryвременным долгом с владельцем ремонта. - После изменений loader, converter, mesh wire или animation sources выполняйте force bake и затем incremental bake.
Для ИИ-авторинга фиксируйте parser state перед каждым modifier:
current layer = 3
current value = 2
current link = Attach Armor.fo3d
current mesh = Torso
next directive = Texture 0 Parent_Torso
Если состояние нельзя назвать однозначно, разбейте компактную строку и явно задайте selectors.
Процесс проверки
-
Перегенерируйте и проверьте справочник:
python BuildTools\docs_model_format.py --write python BuildTools\docs_model_format.py --check python -m unittest BuildTools.tests.test_docs_model_format -
Запустите focused Engine tests:
.\Binaries\Tests-Windows-win64\LF_UnitTests.exe "ModelBaker*" -
Перезапеките встраивающий проект:
cmake --build Build\Auto --config RelWithDebInfo --target BakeResources - В видимом клиенте проверьте framing/anchors/crop bounds, все layer/value, оба вида attachment, particles, inheritance textures/effects, disables, cuts, idle/movement/turn/backward/action animations, shadows и interpolation.
- Зафиксируйте project-specific layer semantics, ожидаемые screenshots и regression routes в документации проекта.
Чистый bake доказывает grammar, asset closure, enums/ranges и serialization. Он не доказывает качество позы, scale, clipping, материалы, blending, cut geometry, interaction bounds или performance.
Маршрутизация изменений
- При изменении
.fo3dtokens, parser state, include, path rules или validation обновите руководство,BuildTools/ModelFormatInterface.json, generated outputs и focused tests. - При изменении импорта
.fbx/.obj, skinning, materials, animation conversion или model limits обновите asset/limit contract и native mesh-baker tests. - При изменении layers, attachments, particles, transforms, materials, cuts, batching или flags обновите composition/runtime sections и проверьте видимый client scene.
- Animation tuples, aliases, speed, duration и script lookup принадлежат также Model Animation.
- 2D frame offsets и sprite phase принадлежат Sprite Root Motion.
- Каталоги моделей и семантика слоёв принадлежат только документации встраивающего проекта, которая ссылается на этот контракт.