Конструктор персонажей набора правил

На этой странице вы добавляете пошаговый конструктор, который создает персонажа по шагам, от расы и класса до показателей, владений, заклинаний и снаряжения. Она предназначена для авторов наборов правил. Прежде чем начать, прочитайте Создание наборов правил Game Mode.

Лист может объявить sheet.builder (Capability API 1.86). Тогда редактор листа – в редакторах персонажа и персоны и в Edit sheet (редактировать лист) игры – открывается на виде Guided (пошагово) рядом с полной формой (All fields, все поля): шаги вверху, у каждого значок с числом выборов, которых он еще ждет, кнопки Back (назад) и Next (далее), которые никогда не блокируют переход (игрок может оставить выборы на потом), а рядом – персонаж в текущем виде: то, что записали шаги, показатели, значения, которые называет gm.sheetSummary (класс доспеха, бонус мастерства), и спасброски и навыки, которыми он владеет.

"builder": {
  "tier": "proficient",
  "steps": [
    { "id": "race", "label": "Race", "kind": "catalog", "catalog": "races", "field": "race" },
    { "id": "subrace", "label": "Subrace", "kind": "catalog", "catalog": "races", "min": 0,
      "within": { "step": "race", "filter": "parent" } },
    { "id": "class", "label": "Class", "kind": "catalog", "catalog": "classes", "field": "class" },
    { "id": "level", "label": "Level", "kind": "fields", "fields": ["level", "background"] },
    { "id": "scores", "label": "Ability Scores", "kind": "abilities", "methods": {
      "pointBuy": { "budget": 27, "costs": [[8, 0], [9, 1], [10, 2], [11, 3], [12, 4], [13, 5], [14, 7], [15, 9]] },
      "standardArray": [15, 14, 13, 12, 10, 8],
      "roll": { "count": 4, "sides": 6, "keep": 3 },
      "manual": true } },
    { "id": "skills", "label": "Proficiencies", "kind": "trained" },
    { "id": "gear", "label": "Equipment", "kind": "startingGear" }
  ]
}

До 32 шагов, каждый вида { id, label, kind, ... }; пакет с больше чем 16 шагами объявляет Capability API 1.112, а с больше чем 24 – Capability API 1.768:

Каталожный шаг может также нести stamp (Capability API 1.108) – от 1 до 4 значений столбцов, записываемых в каждую добавляемую им строку, например "stamp": { "class": "wizard" } на шаге заклинаний волшебника и "stamp": { "class": "cleric" } на шаге жреца. Каждый ключ должен быть столбцом в каждом списке, который питает каталог; значения – строки, числа или логические значения. Штамп заменяет начальное значение каталога. Существующие строки и последующие правки в All fields остаются за игроком. С Capability API 1.130 значение штампа может вместо этого быть объектом, чей fromWithin – это "id", "label" или id фильтра, объявленного родительским каталогом: он читает первого подходящего родителя в порядке выбора, один раз записывает строку или число при добавлении строки и оставляет этот столбец без штампа, если родитель не найден или его фильтр отсутствует либо является массивом.

  {
    "id": "spells",
    "label": "Spells",
    "kind": "catalog",
    "catalog": "spells",
    "within": { "step": "class", "filter": "class_ids" },
    "stamp": { "class": { "fromWithin": "label" } }
  }

Шаг начального снаряжения может нести "strict": true (Capability API 1.109). В режиме только допустимого, который действует по умолчанию, он предлагает только снаряжение, чье fits читается истинным в текущем листе без текущего состояния, плюс снаряжение без fits; списка прочего снаряжения нет. Для 5e поставьте fits: { "value": { "field": "wizard_level" }, "atLeast": 1 } на набор волшебника и соответствующее поле уровня класса на набор каждого другого класса; не ставьте fits на набор послушника, чтобы он подходил всем. Свободная правка снова предлагает все наборы. Выбор снаряжения в инвентаре снимает выделение, которое перестает подходить после смены класса или выхода из свободной правки, и объясняет почему; он также проверяет соответствие, прежде чем взять снаряжение. Если подходящего снаряжения нет, шаг показывает пустое состояние, а Next остается доступным. Шаги без strict по-прежнему предлагают все наборы. Режим действует только на каждом экране, не записывается с сохраненной сборкой и не отправляется на сервер.

То, что дает выбор, – это grants его записи, которые читает только конструктор:

{
  "id": "half-elf",
  "label": "Half-Elf",
  "grants": {
    "abilities": { "add": { "cha": 2 }, "choose": [{ "count": 2, "amount": 1, "except": ["cha"] }] },
    "trained": { "skills": [], "saves": [], "choose": [{ "what": "skills", "count": 2 }] },
    "sets": { "speed": 30 }
  }
}

Отмена выбора забирает то, что выбор дал, и только это: его увеличения (насколько пределы показателя позволили их поднять), владение, значения полей и строки. То, что уже было в листе от самого игрока (навык, которым он овладел вручную, строка, добавленная из выбора каталога), остается за ним, а правка в All fields держится, пока не изменится собственный ответ конструктора на это значение. Запись, выбранная на двух шагах из одного каталога, дает прибавку один раз, а запись, которую скрывают слои игры, по-прежнему считается давшей то, что дала. Поле, которое выбор задает (sets), записывается, только пока оно еще пустое или пока за него уже отвечает конструктор, поэтому уровень, введенный вручную, никогда не перезаписывается; значение, за которое отвечает конструктор и которое игрок меняет на собственном шаге полей, остается за конструктором и уходит, когда более поздний выбор его больше не требует. Выборы игрока хранятся рядом с листом, поэтому шаг можно открыть позже.

Поэтапное распределение рейтингов (Capability API 1.152). Шаг allocate покупает одну точку за очко со своим бюджетом и пределами при создании. Он не меняет метод и сохраненные ответы единственного шага abilities. Используйте отдельные шаги для атрибутов, добродетелей и более поздних свободных очков:

{
  "id": "attributes",
  "label": "Attributes",
  "kind": "allocate",
  "priorities": [7, 5, 3],
  "annotations": true,
  "groups": [
    {
      "id": "physical",
      "label": "Physical",
      "targets": [{ "ability": "strength" }, { "ability": "dexterity" }, { "ability": "stamina" }],
      "base": 1,
      "min": 1,
      "max": 5
    },
    {
      "id": "social",
      "label": "Social",
      "targets": [{ "ability": "charisma" }, { "ability": "manipulation" }, { "ability": "appearance" }],
      "base": 1,
      "min": 1,
      "max": 5
    },
    {
      "id": "mental",
      "label": "Mental",
      "targets": [{ "ability": "perception" }, { "ability": "intelligence" }, { "ability": "wits" }],
      "base": 1,
      "min": 1,
      "max": 5
    }
  ]
}

Групп от 1 до 12, у каждой стабильные id, label и от 1 до 120 целей. Цели не повторяются в пределах всего шага. Цель называет ровно одно существующее { ability }, числовое { field }, { skill }, { save } или { bonus }; бонус – это числовая запись build.bonuses для существующего навыка или спасброска. Группы используют ровно один режим бюджета: priorities содержит по одной неотрицательной целой доле на группу (повторы разрешены), или каждая группа объявляет budget: Ref. Приоритетные места назначаются явно, а назначение занятого места меняет группы местами. Порядок массива называет основной, второстепенный, третичный и далее нумерованные приоритеты; ставьте большие доли первыми, если эти названия должны следовать размеру. Бюджеты не больше 1 200 000 очков.

base необязателен; min и max обязательны. Каждый принимает целое число или нетекущую Ref, например { "derived": "archetype_floor" }. Рейтинги должны вычисляться в целые числа от 0 до 10 000 и укладываться в пределы хранения цели или в ее карту уровней. Первая база заменяет значение по умолчанию пустой цели, сохраняя существующие показатели метода и прибавки; более поздняя база – нижний предел для предыдущих этапов. Без базы этап начинается с существующего рейтинга. Равные min и max фиксируют показатель при создании: base: 0, min: 0, max: 0 выражает фиксированную Appearance. Минимумы не покупают точки автоматически. Бюджеты и пределы могут использовать существующие производные операторы, но не могут читать цели, изменяемые этим или более поздним шагом, даже через производные значения. Условия свободных прибавок тоже не могут читать рейтинги в группе распределения, которую они могут менять, включая связанные группы на других этапах. Формульные цены не поддерживаются: каждое оплачиваемое повышение стоит одно очко. Невычисленный или недопустимый источник показывается как not configured.

Целям-навыкам и целям-спасброскам нужен sheet.builder.ratingTiers, отдельно для каждой цели:

"ratingTiers": [
  { "target": { "skill": "athletics" }, "tiers": ["none", "trained", "expert"] },
  { "target": { "save": "will" }, "tiers": ["none", "trained"] }
]

Индекс в массиве – числовой рейтинг. Карты содержат от 1 до 12 существующих возрастающих предлагаемых id уровней, начиная с необученного уровня набора; они никогда не выводятся из бонусов уровней. Разные цели могут использовать разные карты. Цели с разными пределами при создании помещайте в разные группы.

grants.ratings каталога дает свободные точки до всех оплачиваемых этапов:

"ratings": [
  { "target": { "skill": "athletics" }, "add": 1 },
  { "target": { "save": "will" }, "set": 1 }
]

У каждой прибавки либо положительный add, либо неотрицательный set, но никогда не оба. Все прибавки set – нижние пределы: побеждает наибольшая, затем складываются все прибавления, останавливаясь на пределе хранения цели. Поэтому две свободные прибавки ранга доводят до второго ранга, не расходуя оплачиваемый бюджет. Существующее владение и прибавки полей и характеристик применяются до этих прибавок рейтингов. Выборы записей по-прежнему только пишут строки; они никогда не применяют прибавки выбранной записи рекурсивно.

Интерфейс показывает базовый или предыдущий, свободный, купленный и итоговый рейтинги, диапазон при создании и оставшийся бюджет. Плюс отключен на пределе, без бюджета или пока недопустимые покупки или ручные переопределения требуют внимания. Недорасход, недостижимые минимумы и переопределения получают значки; Back и Next остаются доступными. Переназначение приоритета сохраняет сохраненные повышения группы. Группа с перерасходом становится неактивной целиком; покупка выше предела цели становится неактивной для этой цели. Уменьшите или очистите эти ответы, чтобы исправить их, или верните прежнюю долю, чтобы снова их активировать. Более поздние этапы могут превышать более ранние пределы при создании. All fields остается свободной правкой, где переопределения показываются явно, а не обрезаются правилами создания.

Сохраненный builder.allocations[stepId] хранит индексы приоритетных мест по id группы, оплаченные повышения bought и необязательные notes по стабильным ключам целей kind/id (например, ability/strength). annotations: true предлагает до 1000 символов на цель для пояснений о наследии или специализаций; конструктор этот текст не оценивает. Примененные повышения принадлежат каждому этапу отдельно. Повторное открытие никогда не выдает прибавки заново и не пополняет ресурсы, а описание существующего листа записывает выборы, не переписывая его, в том числе когда описание заканчивается. Отмена выбора пересчитывает свободные рейтинги и оплаченные этапы, сохраняя ручные отличия.

Общие бюджеты и покупки с ценой (Capability API 1.153). Объявите до 12 запасов создания в sheet.builder.pools. Несколько шагов spend могут использовать один запас; отдельные запасы держат очки профессии и личных интересов независимыми. Бюджеты – нетекущие ссылки на значения, включая существующие вычисления sum, scale, multiply, min, max, stepTable, enumTable и listSum. Их вычисленное значение должно быть конечным и от 0 до 100 000. Отсутствующий источник показывается как "not configured".

{
  "pools": [
    { "id": "occupation", "label": "Occupation", "budget": { "derived": "occupation_points" }, "creditLimit": 0 },
    { "id": "interest", "label": "Personal interest", "budget": { "derived": "interest_points" } }
  ],
  "steps": [
    {
      "id": "occupation_skills",
      "label": "Occupation skills",
      "kind": "spend",
      "pool": "occupation",
      "offers": [
        {
          "id": "accounting",
          "label": "Accounting",
          "target": { "field": "accounting_value" },
          "cost": { "flat": 1 },
          "min": 5,
          "max": 99
        }
      ]
    }
  ]
}

У каждого шага до 120 предложений со стабильными id и label. Цели подчиняются тому же требованию ровно одного из ability, числового field, сопоставленного skill/save или bonus, что и этапы распределения. Покупки строк списков зарезервированы для функции идентификации строк (F4); этот API не определяет строки по положению в массиве. Пределы должны укладываться в пределы хранения цели. Начальные рейтинги и свободные прибавки сохраняются и никогда не оплачиваются повторно: у Background с двумя свободными и пятью оплаченными точками их семь.

Цена – ровно одно из следующего:

Необязательный overrides: [{ "when": { "derived": "career_affinity" }, "cost": { "perRank": 2 } }] содержит не больше 12 записей. Побеждает первое положительное условие. Условия читают лист до покупок; если ничего не подошло, используется базовая цена. Бюджеты и условия не могут читать покупаемые цели, в том числе через производные значения, и не могут зависеть от более поздних выборов. Свободные прибавки и этапы распределения применяются до покупок с ценой.

Цены имеют положительную наценку, кроме явно объявленных кредитов. Для недостатка, рейтинг которого растет, используйте "credit": true, "cost": { "flat": -1 }. Для снижения от объявленной базовой линии используйте "credit": true, "baseline": 10, "min": 6, "max": 10, "cost": { "flat": 1 }: покупка снижает 10 до 9 и записывает кредит в одно очко. Начальное значение должно совпадать с базовой линией. У цели с кредитом только одно предложение во всем конструкторе, что исключает циклы покупки и кредита.

По умолчанию у запасов нулевой кредит. Задайте creditLimit – максимальный общий кредит – и при желании добавьте до 12 caps: [{ "filter": "flaw", "maxCredit": 2 }]. Фильтры называют tags: ["flaw"] предложения, поэтому у кредитов недостатков и изъянов могут быть отдельные пределы. Пределы считают валовой кредит независимо от положительных трат. Число отдельных причуд по-прежнему ограничивается выборами или строками.

Подсчитываемые строки и строки, подходящие под условие (Capability API 1.205). listSum может нести where: { "column", "equals" }, чтобы читать только строки, у которых значение ячейки равно указанному (пустая ячейка читается как значение столбца по умолчанию), и count: true вместо column, чтобы считать строки, а не складывать столбец. Пирамида талантов Genesys – это два производных счетчика и правило создания:

{
  "id": "tier2",
  "label": "Tier 2 talents",
  "op": "sum",
  "of": [{ "listSum": { "list": "talents", "count": true, "where": { "column": "tier", "equals": 2 } } }]
}

с правилом, чей value читает tier2, а max читает число талантов 1-го уровня минус один.

Цены строк, вычисляемые для каждой строки (Capability API 1.206). Объектная cost шага строк может умножать свой column на times и прибавлять add, поэтому { "column": "tier", "times": 5 } оценивает талант Genesys в 5 XP за уровень; add сам по себе – фиксированная цена, записанная объектом. overrides (до 4) дает цену, используемую вместо обычной, когда производное значение, названное префиксом и собственной ячейкой строки, читается в листе больше 0: { "add": 5, "overrides": [{ "derived": { "prefix": "affinity_", "cell": "ability" }, "cost": 4 }] } оценивает Charm из Exalted в 4 Bonus Points, когда affinity_<its Ability> больше 0. У ячейки-перечисления должно быть производное значение для каждого значения, которое она может принимать.

Предложения без цены (Capability API 1.207). cost предложения траты (или переопределения) может быть { "unpriced": true }, пока источник не указал цену: предложение показывается с пометкой, впустую задерживает запас и никогда не покупается. Покупка, сохраненная по цене, которая позже становится неуказанной, становится неактивной и сохраняется для исправления.

Больше полей (Capability API 1.208). Лист может объявить до 240 полей; до 1.208 предел – 160. Это место нужно для рангов навыков, рангов категорий, потенциалов и сумм Rolemaster.

Броски, записываемые в характеристику (Capability API 1.209). Бросок шага roll может называть ability вместо field (ровно одно из двух). Результат ограничивается собственными пределами характеристики. С gain проверка бросается против показателя, и только результат выше него добавляет прирост, который конструктор затем хранит как увеличение: повторный бросок или покупка показателя сохраняет улучшение сверху. Без gain результат записывается как введенный вручную показатель и хранится, пока не изменится собственный ответ конструктора на этот показатель. Вычисляемую характеристику бросать нельзя, а каждую характеристику на шаге бросают не больше одного раза.

Вычисляемые столбцы списков (Capability API 1.210). Числовой столбец может называть sum: до шести других числовых столбцов той же строки, которые складываются (пустая ячейка читается как значение своего столбца по умолчанию) и ограничиваются min и max столбца. Ячейка показывается только для чтения, заполняется при каждом чтении сохраненного листа и читается суммами, проверками строк и всем остальным, как введенная ячейка. Вычисляемый столбец не бросается и никогда не складывает другой вычисляемый столбец. Рейтинг специализации CoC – это "sum": ["base", "occupation", "interest"].

Частичные увеличения показателей (Capability API 1.211). abilities.choose прибавки может называть partialFrom. Показатель, который к моменту выбора уже на этой отметке или выше, получает частичное увеличение, а два частичных дают amount один раз. Выборы учитываются в том порядке, в котором их делает конструктор, после всех полных увеличений, поэтому более поздние повышения Pathfinder 2e читаются как "amount": 1, "partialFrom": 4: модификатору +4 нужно два повышения, чтобы дойти до +5. Это сочетается с upTo.

Проверки строк в стойке (Capability API 1.212). Запись checks[] списка может называть stance – одну из resolution.stances пула костей. Тогда проверка каждой строки идет в этой стойке, как и навык, который перечисляет стойка: занятия Stewpot считают кости по способу STILLNESS. Напоминание Game Master называет строки вместе с навыками стойки.

Специализации характеристик (Capability API 1.213). contextual списка может задавать "abilities": true. Тогда его ячейка skill может называть характеристику (по id, подписи или сокращению), а не только навык, и строка применяется к любой проверке с этой характеристикой: к чистой проверке характеристики, к навыку, чья это собственная характеристика, или к навыку, который with= на нее переключает. Специализация атрибута в World of Darkness "Strength: lifting" – это строка с именем "lifting", в ячейке навыка которой написано "Strength".

Отключенная отмена (Capability API 1.214). Контекстная check (в contextual списка или в mechanics.contextual записи) может задавать "cancel": false. В броске, к которому она применена, грани не выше resolution.cancel.upTo не отнимают успехов; критический провал их по-прежнему учитывает. Чтобы отключать, у набора должна быть resolution.cancel.

Предметы, доступные без ношения (Capability API 1.215). grants.itemAccess записи каталога перечисляет до 48 предметов набора (<catalog>/<entry>, но никогда не услугу). Выбор записи в пошаговом конструкторе открывает их персонажу: лист и блок листа для Game Master показывают их как не носимые, и в сумку ничего не попадает. Game Master добавляет предмет в инвентарь, когда его берут, как персонаж Blades объявляет нагрузку в начале дела.

Точки строк при создании (Capability API 1.216). Группа allocate может называть rows – до четырех пар {list, column}: точки в этом числовом столбце по всем строкам списка учитываются в бюджете группы наравне с ее целями. Строки правятся в списке; группа, где точек строк больше бюджета, ждет игрока. Переопределение цены шага строк может давать times – ставку за единицу для столбца цены – вместо плоской cost. Строки Craft из Exalted относят "dots" к 28 точкам Ability и оценивают "bought" точки по times: 2 с переопределением на times: 1, где задано affinity_<ability>; вычисляемый столбец рейтинга (1.210) складывает одно и другое.

Лучший рейтинг (Capability API 1.217). Контекстная check может задавать "best": true: проверка навыка, к которой она применена, бросает лучший рейтинг навыка персонажа, если он выше запрошенного. Набор dice-highest может использовать контекстную проверку, которая делает только это; любой другой эффект проверки по-прежнему требует пула костей. Rook's Gambit из Blades – это строка особой способности с "check": {"best": true}, применяемая по имени.

Цены, отмечающие шкалу (Capability API 1.218). Запись контекстной cost может быть {"track": "<id>", "by": N}, а не только {"pool", "amount"}: применение строки или записи отмечает эту обычную текущую шкалу на N, насколько позволяют ее пределы (шкала ран так не отмечается). contextual списка тоже может нести cost. Rook's Gambit из Blades – это строка с "check": {"best": true} и "cost": [{"track": "stress", "by": 2}]. Имена, применяемые через apply=, одинаково читают фигурные и прямые апострофы и кавычки.

Заимствованные каталоги (Capability API 1.220). Каталог может заимствовать каталог другого установленного набора вместо собственного: { "id": "creatures", "label": "Creatures", "holds": "creatures", "from": { "ruleset": "5e-2014", "catalog": "creatures" } }. Набор-источник находится по id, без пространства имен или в пространстве имен сообщества, а его записи читаются относительно заимствующего набора, поэтому запись, называющая то, чего заимствующий набор не объявляет (состояние, ступень угрозы, чувство), пропускается с записью в журнал, а остальные проходят. entries рядом с from добавляются к заимствованным или заменяют запись с тем же id; они проверяются при чтении набора, поэтому заголовок называет все filters, которые они несут (заголовок без них берет фильтры источника). Заимствованное существо, записанное листом, использует id источника; from.sheet говорит, как они читаются в заимствующем наборе: fields сопоставляет поле другому id (или null, чтобы пропустить его), values сопоставляет значения поля, а tiers – уровни владения (у существа, а также те, которые выдает или требует любая запись), как в "sheet": { "fields": { "ac": "ac_typed", "size": null }, "values": { "hp_method": { "by_hand": "manual" } }, "tiers": { "proficient": "trained" } }. Любая заимствованная запись, включая предметы, может принять еще два ключа: refs читает производное значение источника как одно из значений заимствующего набора ("refs": { "prof_martial_weapons": { "field": "martial_weapons" }, "armor_speed_strength": { "abilityScore": "str" } }), а slots переносит слот предмета под имя заимствующего набора ("slots": { "body": "armor" }). Каталог не может заимствовать из собственного набора или из каталога, который сам что-то заимствует. Изображение заимствованного существа сопоставляется как изображение источника (5e-2014/creatures/<id> в наборе изображений существ). Ссылки на заимствованный каталог, например заклинания существа, проверяются при чтении каталога, а не набора.

Более длинные списки развития (Capability API 1.219). sheet.advancement.fields принимает до 64 полей (было 24), поэтому игра, где уровень поднимает много полей, например ячейки для каждого уровня заклинаний и списки владения, может позволить GM поднимать их все. Списку больше чем из 24 полей нужно 1.219.

Двусторонние, владельческие и обменные покупки (Capability API 1.164). "direction": "both" позволяет одному предложению поднимать и опускать свой рейтинг от начального значения (его baseline, если объявлен, должен совпадать с листом): каждый шаг вверх стоит цену кривой, а каждый шаг вниз ниже начала возвращает ее как кредит в пределах creditLimit и ограничений запаса. Учет всегда идет только в одну сторону, поэтому понижение купленного рейтинга возвращает последнюю покупку по той цене, по которой она оплачена, а повышение пониженного возвращает его кредит; покупка и понижение никогда не создают кредит. У такой цели одно предложение во всем конструкторе. ST в GURPS – это { "target": { "ability": "st" }, "direction": "both", "baseline": 10, "min": 7, "max": 14, "cost": { "flat": 10 } }; табличная цена оценивает дробные шаги, например Basic Speed. "direction": "increase" и "decrease" прямо называют одностороннее предложение ("decrease" – это снижение, описанное выше, со своей базовой линией и кредитом).

"effect": "ownership" оценивает предложение по его собственной лестнице, от baseline (или min) вверх, а лист сохраняет большее из собственного значения и купленного уровня: одноочковое знакомство в GURPS оплачивается и указывается, даже если значение по умолчанию уже лучше, а его возврат ничего не стоит листу.

"exchange": { "from": <rating>, "units": 2, "gain": 1, "floor": 9 } превращает предложение в закрытый обмен при создании: каждая покупка снижает from на units и поднимает цель на gain (по умолчанию 1), никогда не опуская from ниже floor и не поднимая цель выше max. Он ничего не стоит запасу, поэтому cost опускается. Обмененные очки никогда не обмениваются дальше: если обмен поднял рейтинг, никакой другой обмен его не снижает, а если обмен снизил рейтинг, никакой другой его не поднимает. Обмены, недоступные классу (when), могут называть те же рейтинги в обратном порядке. Возврат восстанавливает оба рейтинга. Обмен главных требований в OSE – по одному предложению на каждый снижаемый показатель:

{
  "id": "wis_to_int",
  "label": "Lower Wisdom to raise Intelligence",
  "target": { "ability": "int" },
  "exchange": { "from": { "ability": "wis" }, "units": 2, "floor": 9 },
  "min": 3,
  "max": 18
}

Конструктор хранит оплаченные изменения со знаком и их исходные цены под стабильными id шагов и предложений, не больше 1000 строк покупок на предложение. Возврат удаляет последнюю строку и в точности отменяет ее вклад и записанную цену, включая снятие кредита. Он никогда не возвращает свободный рейтинг. Никакие текущие XP, инвентарь, валюта или ресурсы отряда не тратятся.

Смена карьеры, свободных прибавок или источников бюджета сохраняет учет. Недопустимые покупки неактивны; запас показывает исходные траты, отрицательный остаток при перерасходе и предлагаемую новую цену. Общие цели также приостанавливают зависимые покупки в других запасах. Reprice saved purchases (переоценить сохраненные покупки) явно принимает допустимую новую цену для запаса; в остальных случаях верните строки, чтобы исправить его. Ни одна покупка не удаляется и не продается молча. Непотраченные очки носят справочный характер. Back и Next остаются доступными, а All fields сохраняет видимые ручные переопределения в пределах схемы. Описание существующего персонажа и повторное открытие сохраненных выборов никогда не выдают точки заново.

Именованные строки (Capability API 1.154). Шаг rows позволяет игроку при создании добавлять, править и удалять собственные строки в одном из списков листа: слуг, связи, ритуалы и их ингредиенты или что угодно еще, чего нет в каталоге.

{
  "id": "retainers",
  "label": "Retainers",
  "kind": "rows",
  "list": "retainers",
  "columns": ["name", "role", "loyalty"],
  "required": ["name"],
  "min": 1,
  "max": 4,
  "defaults": { "role": "Hireling" }
}

columns – подмножество столбцов списка, которые правит шаг (если опущено – все). required называет столбцы, которые строка должна заполнить, чтобы учитываться. Значок считает целые строки, которых еще не хватает до min (от 0 до 20), плюс каждую строку с пустой обязательной ячейкой, поэтому наполовину записанный ингредиент остается нерешенным. max останавливает Add a row (добавить строку) и никогда не превышает maxItems списка. Новая строка начинается со значений столбцов по умолчанию, затем defaults, которые должны подходить каждому столбцу.

Шаг правит список там, где стоит каждая строка, поэтому два слуги с одним именем остаются двумя строками, а удаление одного сохраняет другого. Строки, записанные выбором из каталога, показываются только для чтения с пометкой "Added by a pick" и появляются и исчезают вместе с выбором. All fields правит каждую строку, как раньше.

Шаг строк может задавать требуемое число строк через countFrom (Capability API 1.799), значение, читаемое из листа персонажа: броски хитов в 5e, по одному на каждый уровень после 1-го. При показе шага конструктор добавляет строки, каждую такую же, какую создает Add a row, пока число собственных строк игрока не достигнет требуемого, никогда не превышая max или maxItems списка; он никогда не убирает строки, а удаленная там строка остается удаленной до следующего показа шага. Персонаж, которого описывают таким, какой он уже есть, не получает строк от просмотра шага. Затем шаг ожидает столько же полностью заполненных строк, как при min, выбирая большее из двух значений, если заданы оба, и показывает тот же счетчик "N of M". Набору правил, использующему этот механизм, нужно Capability API 1.799.

{
  "id": "hit_point_rolls",
  "label": "Hit point rolls",
  "kind": "rows",
  "list": "hp_rolls",
  "required": ["die", "roll"],
  "countFrom": { "derived": "hp_rolls_due" }
}

Условные предложения, пределы из листа и правила создания (Capability API 1.155). Предложение траты может также нести:

Как бюджеты и переопределения, они не могут читать покупаемую цель. Выбор владения с onDuplicate: "replace" может называть replacementFrom – навыки (или спасброски), на которые можно заменить дубликат, вместо всех, что есть в листе; это действует для показываемого, сохраняемого и применяемого.

sheet.builder.constraints вмещает до 40 правил создания. Каждое называет step, на значке которого оно отображается, и label, показываемую там, пока оно не выполняется, необязательный when: Ref и ровно одно из:

{
  "constraints": [
    {
      "id": "disadvantage_cap",
      "label": "Disadvantages give at most 50 points.",
      "step": "traits",
      "rows": { "list": "traits", "filter": { "column": "cost", "below": 0 }, "sum": "cost" },
      "min": -50
    }
  ]
}

Невыполненное правило никогда не блокирует Back, Next или All fields.

Вычисляемые показатели и эффекты, применяемые к одному броску (Capability API 1.156). Характеристика может нести value: Ref[] (от 1 до 8): ее показатель – их сумма, ограниченная ее min и max и показываемая только для чтения. Атрибут Blades – сумма его отмеченных действий; Perception в GURPS – это [{ "abilityScore": "iq" }, { "field": "perception_bought" }], а навыки, бросаемые с ней, следуют купленному. Производные значения, пределы и навыки могут читать вычисляемый показатель, но ни один такой показатель не может читать другой, даже через производное значение. Конструктор никогда его не задает, а все, что для него сохранено, игнорируется.

Список может объявить contextual, чтобы его строки применялись к броску, когда их называет Game Master:

{
  "id": "stunts",
  "label": "Stunts",
  "maxItems": 10,
  "columns": [
    { "id": "name", "label": "Name", "type": "text", "maxLength": 80 },
    { "id": "skill", "label": "Skill", "type": "text", "maxLength": 40 },
    { "id": "bonus", "label": "Bonus", "type": "number", "min": -5, "max": 5, "default": 2 }
  ],
  "contextual": { "name": "name", "skill": "skill", "bonus": "bonus" }
}

name – столбец, по которому Game Master называет строку. skill (необязательно) хранит навык, к которому применяется строка, по id или подписи; пустая ячейка применяется к любой проверке. bonus (числовой столбец) и dice (столбец костей) прибавляются к проверке – в наборе с пулами как кости. to: "saves" применяет строки вместо этого к спасброскам. В наборе с пулами check: { dice?, successes?, double?, explode? } дает каждой примененной строке одинаковый эффект на пул, например специализацию, у которой взрываются десятки.

Запись каталога может нести mechanics.contextual с effects (own-checks-advantage и другие эффекты проверок и спасбросков), modifiers к checks или saves, сужающими skills и saves, эффектом check для пула и cost: [{ "pool": "...", "amount": 1 }], оплачиваемой один раз в броске, к которому она применена. Game Master пишет в проверке apply="Strong Back; Quick Eye" (до четырех имен). Меняют проверку только имена, которые к ней применимы: строка для другого навыка, имя, которое делят две строки, и цена, которую запас не может покрыть, ничего не меняют. Само по себе наличие строки никогда не меняет бросок. Запись перечисляет примененное в from.

Брошенные и прочитанные из листа начальные монеты (Capability API 1.157). Строка монет начального снаряжения может нести roll (кости, например "2d6") или countFrom (Ref, читаемая из листа держателя) вместо count, но не оба, а times (от 1 до 10000) умножает любое из них:

{ "coins": "gold", "roll": "5d4", "times": 10 }

Окно выбора показывает кости ("5d4 gold, rolled when taken"). Бросок происходит один раз, когда группа или держатель берет набор, поэтому повторное открытие окна выбора не бросает его снова. countFrom читает собственный лист держателя, например поле Credit Rating; держатель без листа отклоняется, а количество 0 ничего не добавляет. Строки предметов сохраняют свой фиксированный count.

Начальные значения, задаваемые один раз (Capability API 1.158). Шаг конструктора kind: "initialize" записывает начальные значения, когда игрок их подтверждает, и больше никогда сам этого не делает:

{
  "id": "start",
  "label": "Starting values",
  "kind": "initialize",
  "writes": [
    { "field": "san_start", "value": { "abilityScore": "pow" } },
    { "field": "xp", "remaining": "creation" }
  ]
}

Каждая запись называет поле листа и либо value (фиксированное значение или Ref для числового поля), либо remaining – то, что осталось непотраченным в запасе конструктора. Шаг показывает каждое поле сейчас и то, каким оно станет; его значок ждет, пока игрок их не задаст. Записанные значения сохраняются вместе с конструктором, поэтому повторное открытие, импорт персонажа или последующее изменение POW никогда не записывают их снова. Если лист с тех пор изменился, шаг показывает, что заменило бы повторное задание, и выполняет его только кнопка игрока Set again (задать снова). В персонажа, которого описывают таким, какой он уже есть, ничего не записывается.

Текущий запас может объявить startFrom: Ref, чтобы начинаться со значения, прочитанного из листа, а не полным или пустым, в пределах от 0 до своего максимума, а обычная шкала может объявить startFrom вместо default. Если указать его на поле, записанное шагом initialize, SAN начинается с POW, от которого он был задан, и остается там, где его оставила игра: сохраненное текущее значение всегда важнее начального значения запаса.

Выборы и строки с ценой (Capability API 1.159). Каталожный шаг или шаг строк может называть pool конструктора и cost, чтобы то, что игрок выбирает или пишет, оплачивалось из того же запаса, что и шаги трат. Цена каталожного шага – число или { "filter": "tier" }, собственный числовой фильтр записи. Цена шага строк – число или { "column": "cost" }, читаемое из каждой строки; отрицательная цена – это кредит в пределах creditLimit запаса, поэтому недостаток оплачивает черты. Шаг строк может также называть from – каталог строк, питающий его список: игрок добавляет копию строки записи сколько угодно раз, и каждая копия – его собственная строка, оцениваемая и удаляемая отдельно:

{
  "id": "charms",
  "label": "Charms",
  "kind": "rows",
  "list": "charms",
  "pool": "bonus",
  "cost": { "column": "cost" },
  "from": "charm_book"
}

Выбор, за который запас не может заплатить, не предлагается. Выборы и строки с ценой оплачиваются первыми и никогда не продаются за игрока: когда удаление недостатка приводит к перерасходу запаса, покупки шагов трат перестают применяться, пока игрок это не исправит, а значок каждого шага с ценой учитывает исправление. Сумма, которую столбец не может превышать (уровни Rite), – это правило создания (1.155) с rows.sum и max.

Профили создания и более ранние этапы (Capability API 1.160). sheet.builder.profiles (до 16) позволяет типу персонажа, карьере или пакету приносить собственные шаги и бюджеты:

"profiles": [
  { "id": "dragon", "label": "Dragon-Blooded", "when": { "field": "dragon" },
    "steps": ["aspect_gifts"], "budgets": { "bonus": { "const": 15 } } },
  { "id": "lunar", "label": "Lunar", "when": { "field": "lunar" },
    "steps": ["moon_gifts"], "budgets": { "bonus": { "const": 18 } } }
]

Профиль персонажа – первый, чей when читается больше 0, и конструктор сообщает, какой именно. Шаг, который перечисляет любой профиль, показывается, только пока профилем персонажа является профиль, который его перечисляет; его ответы сохраняются, пока он скрыт, и ничего не дают. budgets профиля заменяют собственные бюджеты этих запасов, поэтому при смене типа бюджет другого типа никогда не сохраняется: покупки, которые он больше не покрывает, перестают применяться, пока игрок их не исправит.

Каталожный шаг или шаг initialize может объявить reads: { "before": "step_id" }. Тогда offeredWhen его записей и его upTo (или значения шага initialize) читают лист таким, каким его делают шаги до указанного шага: все, что более поздние шаги выбрали, выдали или купили, забирается, а то, что игрок ввел сам, сохраняется. Шаг мультикласса читает показатели характеристик до увеличения на этом уровне; снимок Humanity читает добродетели до свободных очков, как бы игрок ни переходил между шагами туда и обратно.

Строки, которые сами являются проверками (Capability API 1.161). Список может объявить до четырех checks, чтобы каждая строка, которую пишет игрок, была проверкой, которую Game Master может назвать по имени:

"checks": [{ "id": "science", "name": "name", "rating": "rating", "ability": "edu" }]

name – текстовый столбец, по которому называют строку, а rating – числовой столбец, который является ее рейтингом; ability (необязательно) прибавляется так же, как характеристика навыка. Science (Physics) и Science (Biology) – это две строки и две проверки, у каждой свой рейтинг. Две проверки в одном списке – это две стойки на одном рейтинге, у каждой своя label, которую Game Master произносит после имени строки: "Fire stew (bold)" и "Fire stew (careful)". Сначала сопоставляются собственные навыки, спасброски и характеристики листа. Имя, которое делят две строки, вообще не является проверкой, пока одну не переименуют, а проверка удаленной строки исчезает вместе с ней. Блок листа для Game Master перечисляет все проверки строк с их числами, а with= работает так же, как у навыка. Шаг строк, оцениваемый по столбцу рейтинга (1.159), покупает рейтинги из запаса создания.

Броски при создании, сохраняемые с костями (Capability API 1.162). Кости создания – это { "count", "sides", "keep"?, "add"?, "multiplier"? }: наибольшие keep граней плюс add, умноженные на multiplier, поэтому (2d6+6) x 5 из CoC – это { "count": 2, "sides": 6, "add": 6, "multiplier": 5 }.

methods.rolls шага характеристик бросает каждый показатель по порядку, каждый костями своей группы, и никогда не позволяет переносить бросок на другой показатель (метод "rolls"):

"rolls": [
  { "abilities": ["str", "con", "dex", "app", "pow"], "dice": { "count": 3, "sides": 6, "multiplier": 5 } },
  { "abilities": ["siz", "int", "edu"], "dice": { "count": 2, "sides": 6, "add": 6, "multiplier": 5 } }
]

Шаг kind: "roll" перечисляет до 12 rolls, каждый из которых записывается в числовое field: удача, хиты, начальные деньги. best (2 или 3) бросает столько раз и сохраняет лучший результат; floor (число или Ref) – наименьшее значение результата, например 1 хит или потенциал не ниже своего показателя; gain превращает его в проверку улучшения, бросаемую против поля и добавляющую gain только при результате выше него, как улучшение EDU в CoC. Каждый бросок сохраняется со своими гранями и показывается с ними. Уже сделанный бросок остается в силе; повторное открытие конструктора никогда не бросает снова, и предлагает это только шаг с retry: true. За описываемого персонажа никогда не бросают.

Подсчитываемые выборы и ограничения при создании (Capability API 1.151). Каждый шаг может нести when: Ref (показывать и применять его, только пока нетекущее значение листа больше нуля) и requiredWhen: Ref (учитывать незавершенные выборы в его значке, только пока значение больше нуля). Скрытые шаги сохраняют свои ответы. Next и Back остаются доступными даже при незавершенных или недопустимых выборах; All fields остается свободной правкой.

Каталожные шаги могут объявить до 12 quotas, каждая из которых использует один из типизированных фильтров каталога:

{
  "id": "ratings",
  "label": "Skill ratings",
  "kind": "catalog",
  "catalog": "ratings",
  "min": 10,
  "max": 10,
  "distinctBy": "skill",
  "quotas": [
    { "filter": "rating", "value": 4, "min": 1, "max": 1 },
    { "filter": "rating", "value": 3, "min": 2, "max": 2 },
    { "filter": "rating", "value": 2, "min": 3, "max": 3 },
    { "filter": "rating", "value": 1, "min": 4, "max": 4 }
  ]
}

Это пирамида в стиле Fate, если каталог предлагает каждый навык на каждом рейтинге. Записи объявляют свои прибавки владения с явными id уровней владения; числовые значения фильтров никогда не придумывают сопоставление с уровнями. У квоты 0 <= min <= max <= максимум шага. Минимумы влияют на значок; максимумы отключают дальнейшие подходящие выборы. distinctBy называет существующий фильтр: выборы не могут иметь одинаковое его значение (или любой общий тег для фильтра тегов), а запись без этого фильтра не учитывается. В остальных случаях различие определяется по id записи. quotaBelow: { "filter": "tier" } требует, чтобы активных выборов на уровне n-1 было строго больше, чем на уровне n, для положительных целых уровней выше 1. Уровень 1 – основание. Удаление поддерживающего выбора делает лишние выборы выше неактивными, забирая их прибавки, но сохраняя ответы для исправления.

Слоты abilities.choose, trained.choose, choose шага владения и entries.choose принимают:

Выборы характеристик дополнительно принимают from, пересекаемый с характеристиками листа и except. Для разных повышений PF2e выбор restricted может предлагать ["str", "dex"], а за ним идет выбор free_boost, исключающий background/restricted. Выборы записей принимают те же quotas, distinctBy и quotaBelow, что и каталожные шаги, ограниченные max или count; они по-прежнему пишут строки, не применяя собственные прибавки выбранных записей.

Выборы владения дополнительно принимают tier (предлагаемый уровень выше необученного, переопределяющий уровень прибавки или конструктора), only: "any" | "trained" | "untrained" и onDuplicate: "replace". Допустимость читает ручное владение и более ранние активные прибавки, исключая собственные предыдущие записи конструктора. Выбранный навык, которым уже владеют из этих источников, открывает отдельный слот замены среди необученных навыков того же вида, сохраняя исходный ответ. Замены соблюдают исключения и уровень выбора. Их сохраненный ключ – ключ исходного слота плюс /replacement. Некарьерные ранги человека могут исключать более ранний выбор карьеры и использовать only: "untrained"; смена карьеры сохраняет недопустимые более поздние ответы.

Условия и новые числа слотов могут читать только значения, измененные более ранними шагами, что исключает самовключающиеся или циклические прибавки. Число слотов не может читать значения листа, если их может изменить более поздний внешний файл каталога; перенесите его шаг-источник раньше или держите этот каталог встроенным. Условие может использовать существующую производную enumTable, чтобы сделать шаг подрасы обязательным только для одного происхождения. requiredWhen влияет только на значки и может читать любое допустимое нетекущее значение. Новые ограниченные выборы остаются нерешенными, если подходящего содержимого нет, с пояснением "not configured". Они никогда молча не снижают требуемое число до доступного содержимого. Ручные правки листа и описанные персонажи сохраняют существующие правила принадлежности конструктора.

Персонаж, созданный без конструктора (лист не пустой и еще не имеет выборов конструктора), открывается described (описанным): выборы записывают то, каким персонаж уже является (увеличения его расы считаются уже вошедшими в показатели), и ничего не меняют в листе, пока игрок не выберет Done: let picks change the sheet (готово: пусть выборы меняют лист). С этого момента изменение выбора забирает то, что дал описанный выбор.

Без tier владение дается на первый уровень выше необученного, который предлагает лист; лист, предлагающий половинный уровень (как навыки в 5e), задает "tier": "proficient".