# Schemas — описания действий, команд и полей данных Schemas — это библиотека: она позволяет каждому моду описать в виде данных, что принимают его сценарные действия, как выглядят его команды DSL и какие поля есть у его видов данных. Из такого описания инструменты собирают формы, списки выбора и проверки, так что автор заполняет форму вместо того, чтобы держать в голове имена параметров, а ошибка находится ещё до запуска игры. У мода нет своего окна. Всё, что из него видно, показывают другие инструменты: - **Schema Tools** — палитра команд и окно «Редактор данных»; - **Validator** — неизвестные или недостающие параметры и битые ссылки в своём отчёте; - **редакторы предметов и персонажей** — поля, которые другие моды добавляют к предметам и персонажам. ## От описания к форме и проверке ```text items_base/schemas/items_base.json описание — рядом с кодом действия │ ▼ каталог схем (все моды, по порядку загрузки) │ ├──► форма в палитре команд по полю на каждый параметр ├──► строка сценария action item.remove id=… count=… └──► проверка тот же вердикт в палитре и у валидатора ``` Items Engine описывает своё действие `item.remove` так: ```json { "Id": "item.remove", "Name": "items/schema/remove", "Description": "items/schema/remove_desc", "Category": "items", "Params": [ { "Key": "id", "Type": "ref", "Kind": "item", "Required": true, "Name": "items/schema/field/item" }, { "Key": "count", "Type": "int", "Default": "1", "Name": "items/schema/field/count" } ] } ``` Палитра команд RPG Plus показывает его как форму: **Item** — список предметов игры (тип `ref`, вид `item`), **Count** — число, в котором уже подставлена 1. Пока предмет не выбран, проверка сообщает, чего не хватает: ![Палитра команд с выбранным Remove item: описание, «Описано модом items_base», поля Item (пусто) и Count (1), строка сценария «action item.remove» и ошибка «'item.remove' требует 'id'».](assets/palette-item-remove.jpg) У `stat.archetype` из Stats Engine обязательных параметров нет, поэтому та же пустая форма считается верной: ![Палитра команд с выбранным Give an archetype: поля Archetype и Who, строка «action stat.archetype» и «Со строкой всё в порядке».](assets/palette-archetype.jpg) Каждое действие и команда, описанные загруженными модами, попадают в список палитры, сгруппированный по категориям; в подвале — счётчик: ![Вся палитра команд: список действий и команд по категориям (Battle, Characters, Items, Quests, Stats, World, Dialog, Flow) и «Описано: 25 действий, 10 команд».](assets/palette.jpg) ## Файлы схем Мод кладёт в `schemas/.json` до трёх списков: - `Actions` — сценарные действия (`action key=value …`): их параметры; - `Commands` — команды DSL вроде `check` или `select`: позиционные значения и именованные параметры; - `Kinds` — виды данных (`item`, `character`, `shop`…): поля их сущностей, папка для новых файлов и шаблон нового id. Имена и описания — ключи перевода в собственной локализации мода, поэтому формы говорят на всех языках игры. Типы полей: `text`, `locale` (текст на всех языках), `int`, `number`, `bool`, `choice` (с `Options`), `ref` и `ref_list` (идентификаторы вида), `who`, `picture`, `formula`, `condition`, `scene`, `flag`, `label`, `list` (список объектов со своими полями), `values`, `map`, `json`. Неизвестный тип правится как текст. ## Несколько модов описывают один вид Файлы читаются в порядке загрузки модов: - действие или команда, описанные заново, **целиком заменяются** более поздним модом; - вид **сливается по полям**: поле с тем же ключом заменяется, новые поля добавляются. Так Equipment добавляет свои поля к `item` из Items Engine, не трогая чужой файл: ```json { "Kind": "item", "Fields": [ { "Key": "Equip", "Type": "text", "Name": "equipment/schema/field/equip" }, { "Key": "Archetypes", "Type": "ref_list", "Kind": "archetype", "Name": "equipment/schema/field/archetypes" } ] } ``` Каждое поле помнит, какой мод его описал («Описано модом items_base» в палитре). Битый файл схемы сообщается в отчёт и пропускается; остальные файлы продолжают работать. Правило простое: каждый мод описывает свои действия, команды и виды — рядом с их кодом. Описать чужое действие можно, чтобы его поправить, — и тогда побеждает порядок загрузки. ## О чём сообщает проверка - **нужен параметр** — отсутствует обязательный параметр (ошибка); - **неизвестный параметр** — в строке назван параметр, которого описание не знает (предупреждение); - **плохое значение** — не целое число, не число, не из списка вариантов (ошибка, а для да/нет и вариантов — предупреждение); - **неизвестная ссылка** — идентификатор называет предмет, персонажа или другую сущность, которую не определяет ни один загруженный мод (ошибка). Валидатор сообщает то же самое как `SCHEMA_MISSING_PARAM`, `SCHEMA_UNKNOWN_PARAM`, `SCHEMA_BAD_VALUE` и `SCHEMA_UNKNOWN_REF`. Проверка знает только то, что сказано в описаниях: строка, которую она приняла, всё равно может сделать в игре нечто неожиданное. ## Если что-то пошло не так 1. **Действия нет в палитре.** Ни один загруженный мод его не описал; в сценариях действие всё равно работает. 2. **Поле выглядит как обычное текстовое поле.** Его тип неизвестен или поля вообще нет в описании (тогда «Редактор данных» показывает его среди прочих полей как JSON). 3. **Форма игнорирует вашу схему.** Мод, стоящий позже по порядку загрузки, описал то же действие и заменил ваше.