FOnline Engine
Current master GitHub
Документация Docs/ru/how-to/content/particle-format.md

Авторинг и runtime частиц

FOnline предоставляет два опциональных backend частиц за единым клиентским runtime: SPARK и Effekseer. У них разные инструменты авторинга и исходные форматы, но оба компилируются ParticleBaker, представляются как спрайты частиц и управляются через общий фасад ParticleSystem.

Используйте это руководство для переиспользуемого поведения Engine. Точный опирающийся на исходники контракт находится в справочнике particle-format и канонической JSON-модели. Операционный workflow Mapper/SPARK/Effekseer/Viewer и версионированные снимки описаны в инструментах авторинга частиц. Встраивающий проект должен отдельно документировать включённый backend, каталог частиц, визуальную политику, provenance ресурсов, бюджеты производительности и сцены приёмки.

Выбор при сборке

Оба backend по умолчанию выключены (OFF). Выберите их явно до генерации проекта:

SetOptionValues(
    FO_SPARK_PARTICLES ON
    FO_EFFEKSEER_PARTICLES OFF
)

Опции независимы:

  • FO_SPARK_PARTICLES включает запекание .spark, runtime-загрузку .spk и SPARK-подредактор Mapper.
  • FO_EFFEKSEER_PARTICLES включает компиляцию .efkproj и runtime-загрузку .efk.

CreateParticleRuntimeBackends выступает единой точкой композиции, учитывающей включённые функции. Backend-neutral ParticleManager, ParticleSystem, ParticleSprite и preview Mapper не выбирают backend сами: они обнаруживают runtime-расширения, объявленные включёнными backend.

Не включайте backend только потому, что Engine умеет его собирать. Production-проект должен поставлять только backend, покрытые его контентом, платформами, упаковкой, производительностью и видимыми rendering-тестами.

Конвейер ресурсов

Авторские и runtime-формы намеренно различаются:

Backend Авторский исходник Запечённый runtime Runtime-ссылка
SPARK XML .spark .spark -> .spk .spk
Effekseer XML .efkproj .efkproj -> .efk .efk

Авторские файлы .spk и .efk отклоняются. Сгенерированные бинарные файлы принадлежат только baking output и пакетам; все редактируемые изменения возвращаются в .spark или .efkproj.

ParticleBaker участвует в обычном полном и целевом запекании. Runtime-запрос никогда не откатывается к авторскому файлу. Если backend выключен, его исходный формат не запекается, а runtime-расширение не объявляется ParticleSpriteFactory.

Обе запечённые формы содержат обязательные измеренные bounds. Baker симулирует детерминированный instance, отдельно записывает прямоугольник позиций частиц и наибольший радиус билборда, обращённого к камере, и хранит результат в .spk или в trailer Engine, добавленном к .efk. Runtime-framing спрайта и видимость модели используют эти значения вместо авторского draw rectangle. Перезапеките частицы после обновления на ревизию, вводящую или меняющую этот контракт: старый .efk без валидного bounds trailer отклоняется.

Инкрементальное запекание Effekseer

Проекты Effekseer могут ссылаться на текстуры, модели, кривые и другие файлы. После успешной компиляции baker сохраняет snapshot проекта и зависимостей в baking cache. Изменённая, удалённая или переименованная зависимость инвалидирует каждый ссылающийся на неё проект, не пересобирая несвязанные эффекты.

Snapshot следует за физическим directory source, выбранным для проекта. Поэтому исходники Effekseer должны поступать из directory-backed resource source, а пути зависимостей должны оставаться относительными и внутри этого source. После изменения поведения EffekseerCompiler принудительно выполните полное запекание ресурсов, чтобы обновить все сгенерированные .efk.

Авторинг SPARK

Файл .spark представляет собой граф объектов SPARK, сериализованный в XML. Обычный граф содержит один System, один или несколько Group, эмиттеры, модификаторы и принадлежащий Engine SparkQuadRenderer. Baker:

  1. загружает исходник через vendored XML-loader SPARK;
  2. проверяет пути текстур renderer;
  3. сериализует граф в детерминированные бинарные данные .spk.

Используйте только типы объектов, зарегистрированные сборкой Engine и показанные редактором SPARK в Mapper. Тип upstream SPARK не становится авторским контрактом FOnline только потому, что его реализация есть в зависимости.

Редактор декодирует preview текстур через тот же версионированный reader SpriteResource, что и runtime-путь изображений. Он требует ровно одно направление и один кадр, отклоняет записи shared frame и восстанавливает логическое изображение при mesh cropping. Не дублируйте magic values запечённого спрайта или приватные смещения байтов в parser инструмента.

Пути и rendering

SparkQuadRenderer хранит имена эффекта и текстуры FOnline, размеры атласа, данные ориентации и маршрут DrawInScene. Пути текстур должны:

  • быть относительными;
  • не содержать табуляцию или управляющие символы строки;
  • оставаться внутри resource source, которому принадлежит .spark.

Используйте атласный маршрут для обычных спрайтов частиц. Используйте DrawInScene, когда эффект должен разделять со сценой проекцию карты и поведение depth. Если любой renderer системы запрашивает direct-scene drawing, весь спрайт частиц использует этот маршрут.

Ручного атрибута draw size нет. Запекание запускает временную копию на всём ограниченном моделируемом lifetime и отклоняет SPARK-систему, которая так и не создала видимую частицу. Измеренные прямоугольник позиций и радиус билборда автоматически определяют кадр атласа. Состояние эффектов и декодирование изображений описаны в формате эффектов и форматах изображений и спрайтов.

Авторинг Effekseer

Создавайте эффекты Effekseer как текстовые файлы .efkproj в поставляемом standalone Effekseer Editor. Его Windows-payload собирается вне обычного target graph Engine:

$env:FO_OUTPUT = (Get-Location).Path
python BuildTools\buildtools.py build-auxiliary effekseer-editor Release

Точные аргументы являются частью CLI BuildTools и могут оборачиваться tasks встраивающего проекта. Редактор авторинга не является runtime-зависимостью и не должен попадать в production-пакеты игры.

EffekseerCompiler читает XML проекта в фиксированном поддерживаемом профиле, создаёт raw-данные SKFE, а ParticleBaker проверяет результат через vendored Effekseer Core перед публикацией .efk. Поддерживаются графические узлы Sprite, Ring, Ribbon, Track и Model; Root и None могут организовывать граф. Callback-renderer поддерживают:

  • смешивание Normal, Add и Sub;
  • ближайшую или линейную фильтрацию и wrapping Clamp или Repeat;
  • depth test/write для каждого узла с depth-вариантами эффекта Engine;
  • стабильную сортировку по глубине камеры для Sprite и Ring;
  • статические Model-ресурсы и culling граней отдельных моделей;
  • искажение сцены на Sprite-узлах через отложенный snapshot фона.

Неподдерживаемые функции fail closed, а не деградируют молча. Runtime отклоняет GPU-частицы, normal textures, звуки, custom materials, внешние кривые, процедурные модели, смешивание Multiply, mirrored wrapping, расширенные texture/material slots, soft particles, falloff, flipbook interpolation, Z-сортированные strips или models и искажение на любых узлах, кроме Sprite. Ссылочная статическая модель также должна пройти валидацию Engine.

Preview редактора доказывает только поведение авторского инструмента. Runtime FOnline использует CPU-симуляцию Effekseer с принадлежащими Engine callback geometry, эффектами, текстурами, depth и graphics backend. Всегда повторяйте проверку в Mapper и реальной клиентской сцене.

Workflow Mapper

В Mapper есть два разных инструмента частиц:

  • Particle preview backend-neutral. Он показывает запечённые ресурсы .spk и .efk, объявленные включёнными backend, и запускает их через те же ParticleSystem и renderer, которые использует клиент.
  • SPARK particle editor просматривает raw-исходники .spark, редактирует их граф, сохраняет XML, перезапекает соответствующий .spk, инвалидирует кэши и пересоздаёт preview.

Preview поддерживает фильтрацию ресурсов, размещение на гексе под мышью или в центре карты, restart, удаление, явный seed, временные scale и offset и опциональный prewarm. Его временный MapSprite не сериализуется и не должен менять карту.

Для .efkproj используйте standalone Effekseer Editor: Mapper не редактирует эти исходники. Тем не менее Mapper остаётся обязательным финальным preview авторинга, потому что он испытывает сгенерированный .efk и реальный rendering bridge FOnline. Полный операторский workflow описан в инструментах авторинга частиц, а детали автоматизации и интеграции — в инструментах Mapper.

Runtime-контракт

ParticleRuntimeBackend владеет маршрутизацией расширений, созданием ресурсов и инвалидацией кэша. ParticleRuntimeSystem владеет специфичной для backend симуляцией и отрисовкой. ParticleSystem добавляет общий фасад времени и управления:

  • Setup применяет проекцию, world transform, offset позиции/вида, look direction, scale, угол камеры карты и projection tilt;
  • Respawn(seed) поддерживает детерминированное воспроизведение;
  • Prewarm продвигает эффект вперёд до обычного воспроизведения;
  • SetScale повторно применяет runtime-setup без замены эффекта;
  • GetBakedBounds предоставляет валидированные прямоугольник позиций и радиус билборда;
  • GetLiveBounds возвращает трансформированные baked bounds только пока частицы видимы;
  • ComputeSpriteFrame проецирует baked bounds через камеру карты и выводит выделение спрайта, offset эмиттера и world transform;
  • GetDrawInScene выбирает атласный или direct-scene rendering route.

ParticleBounds3D намеренно разделяет две величины. Прямоугольник позиций следует за полным размещением эмиттера. Радиус билборда следует за scale размещения, но остаётся обращённым к камере, поэтому callers добавляют его как padding плоскости вида и не вращают как ещё одну точку world space. Прикреплённые к модели частицы расширяют кадр модели только пока backend сообщает о живых частицах или instances.

Одинаковый seed детерминирован только с тем же ресурсом, ревизией backend, setup и последовательностью обновлений. Не используйте seeded replay как межверсионное обещание визуальной совместимости.

Effekseer сейчас использует direct-scene rendering. SPARK может использовать атласный или direct-scene route. Оба маршрута всё равно зависят от состояния эффекта, image resources, настроек камеры и draw order встраивающего проекта.

Интеграция

ParticleSpriteFactory предоставляет все включённые runtime-расширения обобщённому загрузчику спрайтов. Поэтому спрайт карты или клиентский скрипт ссылается на запечённый путь .spk или .efk и получает обычную маршрутизацию частиц.

Клиентские script exports предоставляют seeded playback, prewarm и управление scale. Critter.RunParticle запускает живую частицу на кости модели в сборках с 3D.

Описания моделей прикрепляют запечённую частицу через AttachParticles:

Layer 8
Value 1
AttachParticles Particles/Jet.spk Link Backpack
MoveY 0.15
RotY 90

Model baker проверяет наличие запечённой частицы и валидность целевой кости. Клиент создаёт независимую runtime-систему и обновляет её transform из владеющего сустава. Полная грамматика прикреплений описана в формате моделей.

Production-практики

  • Выбирайте один backend, если миграция или сравнение не имеет явной даты окончания. Каждый дополнительный backend умножает работу по пакетам, платформам, тестам и поддержке.
  • Храните авторские исходники и зависимости вместе со стабильными относительными путями. Никогда не редактируйте вручную и не версионируйте сгенерированные .spk и .efk.
  • Используйте явные seeds в preview и regression-сценах, чтобы визуальные сравнения были воспроизводимы.
  • Отделяйте быстрый preview авторинга от приёмки. Проверяйте gameplay lifetime, transforms, depth, clipping, видимость и стоимость кадра в репрезентативной клиентской сцене.
  • Записывайте provenance и лицензии ресурсов во встраивающем проекте. Vendored runtime не дают прав на сторонние образцы частиц.
  • Определяйте бюджеты активных систем, эмитированных частиц, callback geometry, overdraw, площади атласа, памяти текстур и времени prewarm.
  • Считайте warnings, отсутствующие текстуры, неподдерживаемые capabilities, non-finite geometry и устаревший dependency output блокерами релиза.

Валидация

После изменения контракта частиц или документации:

python BuildTools\docs_particle_format.py --write
python -m unittest BuildTools.tests.test_docs_particle_format
python BuildTools\docs_contract_diff.py --base-ref <base>

После изменения native-кода частиц сконфигурируйте обе соответствующие feature lane и запустите сфокусированные native-тесты, включая Test_ParticleBaker.cpp, а для изменений runtime Effekseer — Test_EffekseerParticleRuntime.cpp.

Затем встраивающий проект должен:

  1. перезапечь затронутые ресурсы;
  2. запустить свою particle/content validation;
  3. проверить запечённый ресурс в Mapper;
  4. проверить в видимой клиентской сцене все затронутые маршруты спрайтов, карт, скриптов и model bone;
  5. сравнить производительность с документированным production-бюджетом.

Чистое запекание доказывает конвертацию исходника и статическую валидацию. Оно не доказывает, что эффект выглядит правильно, интегрируется с gameplay timing или укладывается в production-бюджет кадра.

Введите запрос.