К содержимому
Валидация
На этой странице

Валидация

Как SDK проверяет уровень по правилам формата, чинит то, что можно починить, и сообщает о том, что нельзя

Валидацию вы вызываете сами. В сохранение и загрузку она не встроена

Где её запускать, решает игра. Открытие уровня в редакторе сообщает о проблемах, а воспроизведение проверку пропускает. Поэтому валидации ждёт автор, а игрок - никогда

Автор уровней встречается с валидацией, когда предлагает уровень сервису. Подробнее - Профили публикации

Как вызвать

ValidationFacade - единая точка входа. Вызывающему не нужно знать, сколько проходов существует:

var facade = new ValidationFacade();
var report = facade.Validate(level);

if (report.HasErrors)
    Console.WriteLine(report);
МетодЧто делает
Validate(root, settings)проверяет любой корень: Level, LevelMeta, UserSettings, отдельный Prefab или EffectData. Проход по графу запускается только для Level
ValidateAndFix(root, analyzerSettings, fixerSettings)чинит то, что можно, и сообщает об оставшемся
ValidateForPublish(meta, profile, level, now, payload, settings)все три прохода сразу, ничего не чинит. level может быть null, чтобы оценить только метаданные

ValidationReport содержит RuleIssues и GraphIssues:

  • IsValid - находок нет совсем
  • HasErrors - есть хотя бы одна находка группы Error

Серьёзность

Каждое правило относится к RuleGroup:

  • Error - файл нельзя сыграть в том виде, как он записан
  • Warning - играется, но не так, как задумано (содержимое, которое никогда не появится, битая ссылка с запасным вариантом). Или единственная починка разрушительна
  • Advice - воспроизведение не меняется

Три прохода

ПроходЧто спрашиваетНа чём работает
RuleAnalyzerкаждое ли значение в своём диапазоне, не null, известный член перечислениялюбой корень
LevelGraphAnalyzerсогласуются ли объекты друг с другомтолько Level
PublishReadinessAnalyzerможно ли отдать уровень чужим людям по данному профилюLevelMeta, по желанию Level

Правила

Тип включается в проверку маркером [RuleContainer]. Его свойства несут атрибуты правил:

  • [RuleNotNull], [RuleInRange], [RuleMinValue], [RuleEnumValid], [RuleCollectionMaxCount] и другие
  • [RuleEnumFlagsValid] - для флаговых перечислений
  • [RuleOptional] - для поля, которое может отсутствовать

Сами пределы - константы в таблицах Rules/: FrameRules, ValueRules, LevelRules и другие. Например, LevelRules.MaxObjects равен 262 144

Обход всех контейнеров правил генерирует BH.SDK.Roslyn, без рефлексии. На больших уровнях это примерно вдвое сокращает его время

Исправления

Каждый атрибут правила умеет чинить своё значение (Fix). RuleFixer применяет починки в обратном порядке трассы: починка может сдвинуть более глубокие находки. ValidateAndFix повторяет проход, пока результат не перестанет меняться

Проход по графу идёт после починок. Починка сама может создать проблему в графе, например новый id, совпавший с существующим

Находки графа не чинятся никогда: DuplicateObjectId, MissingParent, ParentCycle, PrefabRemapBroken, IdCounterNearExhaustion и остальные. Каждая такая починка - решение о содержимом (какой из двух объектов сохранит свой id). Догадка переписала бы уровень

Внимание

ValidateAndFix меняет объект, который вы передали. Запускайте его на копии, если вам нужен оригинал, например чтобы показать автору, что именно изменилось