Каталоги набора правил
На этой странице вы добавляете в набор правил готовые записи (заклинания, снаряжение, классовые особенности), которые редактор листа предлагает в окне выбора, чтобы игрокам не приходилось вводить длинные списки вручную. Здесь описаны заголовок каталога, записи, значения, поддерживаемые набором правил, команды листа и команда использования. Страница предназначена для авторов наборов правил. Прежде чем начать, прочитайте Создание наборов правил Game Mode.
Построчно вводить длинный список заклинаний или таблицу снаряжения долго. Каталог – именованная коллекция готовых записей в наборе. Редактор предлагает их в выборе каждой питаемой каталогом таблицы; выбор заполняет строку.
Каталоги необязательны. Набор может иметь до двенадцати; Engine не знает их назначения: все ID, столбцы, фильтры и слова поступают из файла.
Заголовок
Заголовок находится в catalogs верхнего уровня рядом с gm.
"catalogs": [
{
"id": "knacks",
"label": "Knacks",
"feeds": ["knacks", "tricks"],
"filters": [
{ "id": "grit", "label": "Grit cost", "type": "number" },
{ "id": "road", "label": "Road", "type": "text" },
{ "id": "callings", "label": "Calling", "type": "tags", "startFrom": { "field": "calling" } }
],
"units": { "distance": { "label": "paces", "perCell": 2 } },
"entries": []
}
]idиlabel: ID соответствует правилам идентификаторов листа; подпись называет окно выбора.holds:"rows"(по умолчанию и во всех каталогах до этого выпуска),"creatures"или"items". Каталог существ – читаемый боем бестиарий, а каталог предметов перечисляет то, что несет отряд. Ни один из них ничего не пишет в лист, не объявляетfeedsи не предлагается в окне выбора. См. Существа и Предметы ниже.feeds: от одного до восьми списков листа, куда могут писать записи. Обязательно для каталога строк и запрещено для каталогов существ и предметов. Запись не пишет в неуказанный список или значение, недопустимое для его столбцов.filters: необязательно, до восьми фильтров выбора. Фильтр –number, значениеtextилиtags(несколько слов).startFromназывает поле листа, с которым открывается выбор: персонаж с Calling Tinker сначала видит записи Tinker.units: необязательно. Значение дальности или размера области вmechanicsзаписи для вашей системы.
Запись
{
"id": "road-sense",
"label": "Road Sense",
"summary": "You read a road the way other people read a face.",
"filters": { "grit": 0, "road": "Ash Flats", "callings": ["Scout", "Courier"] },
"rows": [
{
"list": "knacks",
"values": { "name": "Road Sense", "notes": "Sneak to notice where a road turns bad." }
}
]
}id: строчные буквы, цифры и одиночные дефисы; уникально внутри каталога.labelиsummary: отображаемое в выборе. Сводка необязательна, одна строка до 300 символов.filters: значения объявленных заголовком фильтров.numberпринимает число,textодну строку,tagsсписок строк.rows: записываемое при выборе, от одной до шести строк.list– один изfeeds, а ключиvalues– ID столбцов списка.creature: противник вместо строк в каталоге, чейholdsсодержит существ. У записи ровно одно изrowsиcreature; у существа нетmechanics, оно описывает поведение собственными действиями.
Каждое значение проверяется по столбцам целевого списка, поэтому неверное имя столбца или число вне диапазона сообщается вместе с исходной записью. Записи внутри файла набора проверяются при загрузке, для импортируемого файла – при импорте. Отдельный каталог пакета проверяется при первом запросе окна выбора; ошибочный файл показывает там причины вместо записей.
Одна запись, несколько списков
Особенность с ограниченными использованиями – две строки: сама особенность и счетчик. Выбирается она по-прежнему один раз.
{
"id": "last-ember",
"label": "Last Ember",
"rows": [
{
"list": "knacks",
"values": { "name": "Last Ember", "notes": "Spend 1 Grit to give a downed friend 3 Grit back." }
},
{ "list": "tricks", "values": { "name": "Last Ember", "uses": 1, "recharge": "camp" } }
]
}Значения, обновляемые набором
После выбора числа строки принадлежат игроку. Полезное исключение – следующий за персонажем максимум: использования по значению характеристики или ресурс класса, растущий с уровнем. Строка может назвать до четырех числовых столбцов в карте scaled, и редактор поддерживает их значения.
{
"list": "tricks",
"values": { "name": "Last Ember", "uses": 1, "recharge": "camp" },
"scaled": { "uses": { "from": { "abilityScore": "heart" } } }
}- Ключ – один из столбцов
numberсписка. from– обычная ссылка на значение из того же закрытого словаря. Сложное вычисление становится объявленной листом величинойderived, на которую указываетfrom("from": { "derived": "lay_on_hands_max" }). Новая арифметика не добавляется.tableнеобязательно. Ищет значение ссылки в таблице ступеней, например число по уровню:"scaled": { "max": { "from": { "field": "level" }, "table": [[1, 2], [3, 3], [6, 4]] } }.valuesпо-прежнему должно иметь обычное число столбца; строка без него отклоняется. Оно используется до появления листа и сохраняется в листе без указанной ссылки.- Строка с
scaledдолжна быть единственной строкой записи для этого списка, чтобы отмеченная строка листа всегда соответствовала одной спецификации, либо (Capability API 1.92) каждая строка, которую запись пишет в этот список, должна нести собственное имя в столбце имени списка (nameColumnего запасов, иначе его первый текстовый столбец). Тогда строка листа сопоставляется со своей спецификацией по этому имени, поэтому одна черта может давать два использования, каждое из которых растет само по себе; строку, переименованную игроком, оставляют без изменений.
Значение вычисляется при редактировании, никогда при чтении: сохраненная строка всегда содержит показанное число. Оно ограничивается min и max столбца и округляется вниз для целых значений. В примере Heart 3 дает три использования, Heart 0 и ниже – ни одного. Строка остается с 0 использований; счетчик с максимумом 0 не является запасом, поэтому тратить в игре нечего.
Масштабируемые столбцы пакета требуют Capability API 1.23. Импортируемый набор сообщества проверяет читающий Engine, поэтому ничего дополнительного не нужно.
Выбранные строки являются копиями
Выбранная строка копируется в лист с дополнительным ключом _catalog, содержащим <catalog id>/<entry id>. ID столбцов начинаются буквой, поэтому ключ не может совпасть с вашим.
Копия принадлежит персонажу. Игрок может менять ее содержимое, лист работает без установленного набора, а публикация новой версии никогда не переписывает чужого персонажа. Метка позволяет окну выбора показать уже имеющееся и используется обновлением ниже.
Обновление из набора правил
Выбранная строка сохраняет метку, поэтому редактор листа может сообщить игроку, что ваш новый текст отличается от содержимого строки. Короткая строка под списком показывает число строк с обновленным текстом, а кнопка Review (просмотреть) сопоставляет для каждой содержимое листа и набора правил, с флажком выбора. До нажатия Update selected (обновить выбранное) ничего не записывается; затем меняются только различающиеся столбцы отмеченных строк. Все остальное, включая метку, сохраняется.
Область сравнения намеренно узкая:
- Существующие значения сравниваются только в столбцах
text,longtext,diceиenum. Значенияnumberиbooleanпринадлежат игроку и сохраняются, включая 0 и false. Еще отсутствующий в строке столбец можно предложить с типизированным значением, в том числе числом или переключателем. Масштабируемый столбец исключен: он уже следует за листом. - Только столбцы, заданные вашей записью. Пропущенный в ней столбец никогда не меняется, что бы ни хранилось в листе.
- Значение, которое сам столбец не примет, например больше не предлагаемый вариант
enumили текст длиннееmaxLength, пропускается, а не записывается. - Строка сопоставляется с породившей ее строкой записи по позиции среди строк с той же меткой в данном списке, пока их на листе столько же, сколько пишет запись. Иначе это работает только для записи, которая пишет одну строку в этот список. Если игрок удалил одну из двух строк записи, ее оставляют без изменений, не пытаясь угадать.
- Строка, чьей записи больше нет в каталоге, остается без изменений и без уведомления.
Таким образом, новый текст или название записи могут попасть к уже выбравшим ее персонажам, если те примут обновление. Изменить таким способом смысл числа нельзя и не получится: как только строка принадлежит игроку, этот столбец тоже его.
Команды листа: постоянное развитие
Набор может разрешить изменения постоянной сборки персонажа через sheet.advancement:
"advancement": {
"fields": ["xp", "level", "humanity", "discipline"],
"abilities": true,
"skills": true,
"saves": true,
"text": "Award XP at the end of a session; change other values only when earned."
}Указывайте только id полей, которые ваш лист объявляет числовыми или текстовыми (text или longtext), не больше 24. Логические значения разрешают соответственно все характеристики, навыки или спасброски; если значение опущено или равно false, разрешения нет. Пустой набор разрешений, неизвестное поле, неподдерживаемый тип поля или неизвестный ключ отклоняются при импорте. text – необязательное указание длиной не больше 400 символов, безопасных для промпта. Без advancement существующие команды работают как прежде, а любой запрос advance отклоняется.
[sheet: op="advance" field="xp" by="250" who="party"]
[sheet: op="advance" field="xp" to="1200"]
[sheet: op="advance" field="humanity" by="-1"]
[sheet: op="advance" field="discipline" to="Auspex"]
[sheet: op="advance" ability="str" by="1"]
[sheet: op="advance" ability="str" to="16"]
[sheet: op="advance" skill="stealth" tier="expert"]
[sheet: op="advance" save="will" tier="trained"]Называйте ровно одну цель. Поля и характеристики принимают ровно одно из by или to; текст принимает только to. Имена и уровни сопоставляются с id или подписями без учета регистра. Навыки и спасброски принимают любой уровень, объявленный в resolution.proficiencyTiers. Числовые поля соблюдают integer, min и max; характеристики соблюдают свои целочисленные пределы; текст соблюдает maxLength. Недопустимое значение отклоняется с причиной bad-amount, которая называет предел, и никогда молча не обрезается. Выключенное развитие, неразрешенные цели, неизвестные имена и неизвестные уровни тоже отклоняются. Переписанная пометка несет result и новое значение в now. Опустите who для игрока или используйте who="party" для каждой однозначной карточки отряда; частичные отказы называют карточки, которые не удалось развить.
Engine сохраняет сборку в карточке игры через то же хранилище метаданных, что и правку игрока, сохраняя версию листа и пересчитывая производные значения по новой сборке. Карточки библиотеки не меняются. Как и с текущими командами, альтернативный свайп или повторно сгенерированный ответ начинается до изменений уходящего ответа. Каждый ответ записывает свою итоговую сборку, включая ответы без развития. Выбор свайпа восстанавливает его снимок; удаление последнего ответа открывает предыдущий снимок. Удаление более старого ответа оставляет в силе более поздний снимок, пока не будет удален этот более поздний ответ. Продолжение обновляет снимок того же ответа. Отмена меняет только значения, все еще совпадающие с записанным результатом, поэтому более поздние правки игрока сохраняются, а несвязанные правки не мешают отменить начисление XP.
Команда use: Game Master платит заданную вами цену
В ходе повествования Game Master обновляет каждый лист командами [sheet: ...]: spend, restore (heal означает то же самое), damage, temp, track, condition, note и rest. Набор правил с каталогами получает еще одну:
[sheet: who="Mira" op="use" name="Fireball"]
[sheet: who="Mira" op="use" name="Fireball" pool="3rd-level slots"]op="cast" означает то же, что op="use", а spell= – то же, что name=. Поэтому привычная Game Master формулировка работает, хотя формату не нужно знать слово "заклинание".
Имя сопоставляется без учета регистра со строками листа этого персонажа, полученными из одного из ваших каталогов. Строка отзывается на имя, показанное Game Master (столбец имени sheetSummary для списка, затем pools.nameColumn списка, затем его первый текстовый столбец), и на label исходной записи, поэтому переименование строки игроком не лишает ее доступа. Отклоняется как имя без совпадений, так и имя, соответствующее двум разным записям.
Что расходуется:
- Каждое слагаемое
mechanics.costзаписи. Слагаемое с именем текущего запаса оплачивается из него; с именем ГРУППЫ запасов – из первого запаса этой группы в порядке объявления, способного покрыть цену. Автоматического перехода к более высокому запасу нет: группа не всегда представляет лестницу. - Плюс единица из каждого запаса в строке списка, записанного той же записью, например счетчика использований способности. Это вторая строка записи
Last Emberвыше. Счетчик с максимумом 0 не имеет доступных использований, поэтому команда отклоняется, а не проходит бесплатно.
pool= – применение на более высоком уровне: та же единственная цена оплачивается из другого запаса той же группы. Оно допускается, только если в цене ровно одно слагаемое, а указанный запас входит в его группу или платит за нее. Все остальное отклоняется без переосмысления.
Запас, который платит за другую группу (Capability API 1.171). pays текущего запаса называет до четырех других групп, цены которых он тоже может оплачивать, на своем уровне (его level или место в собственной группе) и никогда за цену более высокого уровня, чем его собственный. Ячейки договора в 5e платят за заклинания, цена которых указана в ячейках заклинаний, как может мультиклассовый колдун:
{
"id": "pact_slots",
"label": "Pact Slots",
"group": "pact",
"max": { "field": "pact_slot_count" },
"level": { "field": "pact_slot_level" },
"pays": ["slots"]
}Бой предлагает такой запас рядом с более высокими запасами собственной группы заклинания, и оплата из него усиливает заклинание на столько ступеней, на сколько его уровень выше уровня заклинания: ячейка договора 3-го уровня платит за Magic Missile так же, как ячейка 3-го уровня. Использование, чей собственный запас пуст, все равно предлагается и оплачивается только из более высокого запаса или из запаса, который за него платит, поэтому заклинание 1-го уровня творится ячейкой 2-го уровня, когда ячейки 1-го уровня закончились. targetsPerCostStep (1.171, от 1 до 10) в mechanics записи добавляет столько целей за каждую ступень повышения оплаты, но не больше 20: Hold Person – это "targetCount": 1, "targetsPerCostStep": 1.
Все или ничего. Если любую часть оплатить нельзя, вся команда отклоняется, ничего не меняется, а игрок получает сообщение. Запись вообще без цены, например заговор или пассивная способность, принимается и ничего не меняет.
Встроенный каталог или отдельный файл
Небольшой каталог размещается прямо в ruleset.json, в entries заголовка. Большой живет в собственном файле, который заголовок указывает через asset. У каталога ровно один из этих вариантов.
{ "id": "knacks", "label": "Knacks", "feeds": ["knacks"], "asset": "catalogs/knacks.json" }Путь всегда имеет вид catalogs/<the catalog's id>.json. Сам файл выглядит так:
{ "schemaVersion": 1, "catalog": "knacks", "entries": [] }Отдельные файлы каталогов поставляются в пакете: опубликованном через официальный каталог или в файле пакета набора правил, который вы импортируете сами (см. Как поделиться набором правил). Пакет перечисляет файл в contributions.assets.paths рядом с ruleset.json и требует Capability API 1.21. Каталог существ, встроенный или отдельный, требует Capability API 1.27, а каталог предметов – 1.49. Набор правил, импортируемый одним файлом или публикуемый через репозиторий GitHub, хранит каталоги внутри, поэтому они должны уместиться в ограничение 512 KB на весь файл набора правил. Этого хватит на несколько сотен коротких записей.
Ограничения: 12 каталогов на набор правил, 2000 записей на каталог в обоих вариантах и 2 MB на отдельный файл каталога. Пакету, у которого ruleset.json больше 256 KB или файл каталога больше 1 MB, нужно Capability API 1.340, которое подняло оба ограничения.