98 lines
8.4 KiB
Markdown
98 lines
8.4 KiB
Markdown
# 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. Пока предмет не выбран, проверка сообщает, чего не хватает:
|
||
|
||

|
||
|
||
У `stat.archetype` из Stats Engine обязательных параметров нет, поэтому та же пустая форма считается верной:
|
||
|
||

|
||
|
||
Каждое действие и команда, описанные загруженными модами, попадают в список палитры, сгруппированный по категориям; в подвале — счётчик:
|
||
|
||

|
||
|
||
## Файлы схем
|
||
|
||
Мод кладёт в `schemas/<mod>.json` до трёх списков:
|
||
|
||
- `Actions` — сценарные действия (`action <id> 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. **Форма игнорирует вашу схему.** Мод, стоящий позже по порядку загрузки, описал то же действие и заменил ваше.
|