@opencharacter/orc-2e 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. package/README.md +69 -12
  2. package/content/classes/alchemist/fields/bomber.yaml +1 -1
  3. package/content/classes/alchemist/fields/chirurgeon.yaml +1 -1
  4. package/content/classes/alchemist/fields/mutagenist.yaml +1 -1
  5. package/content/classes/alchemist/fields/toxicologist.yaml +1 -1
  6. package/content/classes/alchemist.yaml +2 -34
  7. package/content/classes/barbarian/animals/ape.yaml +1 -1
  8. package/content/classes/barbarian/animals/bear.yaml +1 -1
  9. package/content/classes/barbarian/animals/bull.yaml +1 -1
  10. package/content/classes/barbarian/animals/cat.yaml +1 -1
  11. package/content/classes/barbarian/animals/deer.yaml +1 -1
  12. package/content/classes/barbarian/animals/frog.yaml +1 -1
  13. package/content/classes/barbarian/animals/shark.yaml +1 -1
  14. package/content/classes/barbarian/animals/snake.yaml +1 -1
  15. package/content/classes/barbarian/animals/wolf.yaml +1 -1
  16. package/content/classes/barbarian/instincts/animal.yaml +2 -14
  17. package/content/classes/barbarian/instincts/dragon.yaml +1 -2
  18. package/content/classes/barbarian/instincts/fury.yaml +1 -1
  19. package/content/classes/barbarian/instincts/giant.yaml +1 -1
  20. package/content/classes/barbarian/instincts/spirit.yaml +1 -2
  21. package/content/classes/barbarian/instincts/superstition.yaml +1 -1
  22. package/content/classes/barbarian/raging.yaml +3 -1
  23. package/content/classes/barbarian.yaml +2 -36
  24. package/content/classes/bard/muses/enigma.yaml +1 -1
  25. package/content/classes/bard/muses/maestro.yaml +1 -1
  26. package/content/classes/bard/muses/polymath.yaml +1 -1
  27. package/content/classes/bard/muses/warrior.yaml +1 -1
  28. package/content/classes/bard.yaml +2 -34
  29. package/content/classes/champion/causes/desecration.yaml +1 -1
  30. package/content/classes/champion/causes/grandeur.yaml +1 -1
  31. package/content/classes/champion/causes/iniquity.yaml +1 -1
  32. package/content/classes/champion/causes/justice.yaml +1 -1
  33. package/content/classes/champion/causes/liberation.yaml +1 -1
  34. package/content/classes/champion/causes/obedience.yaml +1 -1
  35. package/content/classes/champion/causes/redemption.yaml +1 -1
  36. package/content/classes/champion.yaml +2 -37
  37. package/content/classes/cleric/doctrines/cloistered-cleric.yaml +1 -1
  38. package/content/classes/cleric/doctrines/warpriest.yaml +1 -1
  39. package/content/classes/cleric.yaml +2 -28
  40. package/content/classes/druid/orders/animal.yaml +1 -1
  41. package/content/classes/druid/orders/leaf.yaml +1 -1
  42. package/content/classes/druid/orders/storm.yaml +1 -1
  43. package/content/classes/druid/orders/untamed.yaml +1 -1
  44. package/content/classes/druid.yaml +2 -34
  45. package/content/classes/fighter.yaml +1 -26
  46. package/content/classes/investigator.yaml +1 -26
  47. package/content/classes/monk.yaml +1 -26
  48. package/content/classes/oracle/mysteries/ancestors.yaml +3 -1
  49. package/content/classes/oracle/mysteries/battle.yaml +5 -1
  50. package/content/classes/oracle/mysteries/bones.yaml +3 -1
  51. package/content/classes/oracle/mysteries/cosmos.yaml +3 -1
  52. package/content/classes/oracle/mysteries/flames.yaml +3 -1
  53. package/content/classes/oracle/mysteries/life.yaml +4 -1
  54. package/content/classes/oracle/mysteries/lore.yaml +5 -1
  55. package/content/classes/oracle/mysteries/tempest.yaml +3 -1
  56. package/content/classes/oracle.yaml +2 -38
  57. package/content/classes/ranger/edges/flurry.yaml +1 -1
  58. package/content/classes/ranger/edges/outwit.yaml +1 -1
  59. package/content/classes/ranger/edges/precision.yaml +1 -1
  60. package/content/classes/ranger.yaml +2 -29
  61. package/content/classes/rogue/rackets/mastermind.yaml +1 -1
  62. package/content/classes/rogue/rackets/ruffian.yaml +1 -1
  63. package/content/classes/rogue/rackets/scoundrel.yaml +1 -1
  64. package/content/classes/rogue/rackets/thief.yaml +1 -1
  65. package/content/classes/rogue.yaml +2 -34
  66. package/content/classes/sorcerer/bloodlines/aberrant.yaml +1 -1
  67. package/content/classes/sorcerer/bloodlines/angelic.yaml +1 -1
  68. package/content/classes/sorcerer/bloodlines/demonic.yaml +1 -1
  69. package/content/classes/sorcerer/bloodlines/diabolic.yaml +1 -1
  70. package/content/classes/sorcerer/bloodlines/draconic.yaml +1 -1
  71. package/content/classes/sorcerer/bloodlines/elemental.yaml +1 -1
  72. package/content/classes/sorcerer/bloodlines/fey.yaml +1 -1
  73. package/content/classes/sorcerer/bloodlines/hag.yaml +1 -1
  74. package/content/classes/sorcerer/bloodlines/imperial.yaml +1 -1
  75. package/content/classes/sorcerer/bloodlines/undead.yaml +1 -1
  76. package/content/classes/sorcerer.yaml +2 -40
  77. package/content/classes/swashbuckler.yaml +1 -26
  78. package/content/classes/witch/patrons/faiths-flamekeeper.yaml +1 -1
  79. package/content/classes/witch/patrons/inscribed-one.yaml +1 -1
  80. package/content/classes/witch/patrons/resentment.yaml +1 -1
  81. package/content/classes/witch/patrons/silence-in-snow.yaml +1 -1
  82. package/content/classes/witch/patrons/spinner-of-threads.yaml +1 -1
  83. package/content/classes/witch/patrons/starless-shadow.yaml +1 -1
  84. package/content/classes/witch/patrons/wilding-steward.yaml +1 -1
  85. package/content/classes/witch.yaml +2 -37
  86. package/content/classes/wizard/schools/ars-grammatica.yaml +1 -1
  87. package/content/classes/wizard/schools/battle-magic.yaml +1 -1
  88. package/content/classes/wizard/schools/boundary.yaml +1 -1
  89. package/content/classes/wizard/schools/civic-wizardry.yaml +1 -1
  90. package/content/classes/wizard/schools/mentalism.yaml +1 -1
  91. package/content/classes/wizard/schools/protean-form.yaml +1 -1
  92. package/content/classes/wizard/schools/unified-magical-theory.yaml +1 -1
  93. package/content/classes/wizard/theses/experimental-spellshaping.yaml +1 -1
  94. package/content/classes/wizard/theses/improved-familiar-attunement.yaml +1 -1
  95. package/content/classes/wizard/theses/spell-blending.yaml +1 -1
  96. package/content/classes/wizard/theses/spell-substitution.yaml +1 -1
  97. package/content/classes/wizard/theses/staff-nexus.yaml +1 -1
  98. package/content/classes/wizard.yaml +3 -46
  99. package/content/domains/advanced/air.yaml +7 -0
  100. package/content/domains/advanced/ambition.yaml +7 -0
  101. package/content/domains/advanced/cities.yaml +7 -0
  102. package/content/domains/advanced/confidence.yaml +7 -0
  103. package/content/domains/advanced/creation.yaml +7 -0
  104. package/content/domains/advanced/darkness.yaml +7 -0
  105. package/content/domains/advanced/death.yaml +7 -0
  106. package/content/domains/advanced/destruction.yaml +7 -0
  107. package/content/domains/advanced/dreams.yaml +7 -0
  108. package/content/domains/advanced/earth.yaml +7 -0
  109. package/content/domains/advanced/family.yaml +7 -0
  110. package/content/domains/advanced/fate.yaml +7 -0
  111. package/content/domains/advanced/fire.yaml +7 -0
  112. package/content/domains/advanced/freedom.yaml +7 -0
  113. package/content/domains/advanced/healing.yaml +7 -0
  114. package/content/domains/advanced/indulgence.yaml +7 -0
  115. package/content/domains/advanced/knowledge.yaml +7 -0
  116. package/content/domains/advanced/luck.yaml +7 -0
  117. package/content/domains/advanced/magic.yaml +7 -0
  118. package/content/domains/advanced/might.yaml +7 -0
  119. package/content/domains/advanced/moon.yaml +7 -0
  120. package/content/domains/advanced/nature.yaml +7 -0
  121. package/content/domains/advanced/nightmares.yaml +7 -0
  122. package/content/domains/advanced/pain.yaml +7 -0
  123. package/content/domains/advanced/passion.yaml +7 -0
  124. package/content/domains/advanced/perfection.yaml +7 -0
  125. package/content/domains/advanced/protection.yaml +7 -0
  126. package/content/domains/advanced/secrecy.yaml +7 -0
  127. package/content/domains/advanced/sun.yaml +7 -0
  128. package/content/domains/advanced/travel.yaml +7 -0
  129. package/content/domains/advanced/trickery.yaml +7 -0
  130. package/content/domains/advanced/truth.yaml +7 -0
  131. package/content/domains/advanced/tyranny.yaml +7 -0
  132. package/content/domains/advanced/undeath.yaml +7 -0
  133. package/content/domains/advanced/water.yaml +7 -0
  134. package/content/domains/advanced/wealth.yaml +7 -0
  135. package/content/domains/advanced/zeal.yaml +7 -0
  136. package/content/domains/air.yaml +6 -0
  137. package/content/domains/ambition.yaml +6 -0
  138. package/content/domains/cities.yaml +6 -0
  139. package/content/domains/confidence.yaml +6 -0
  140. package/content/domains/creation.yaml +6 -0
  141. package/content/domains/darkness.yaml +6 -0
  142. package/content/domains/death.yaml +6 -0
  143. package/content/domains/destruction.yaml +6 -0
  144. package/content/domains/dreams.yaml +6 -0
  145. package/content/domains/earth.yaml +6 -0
  146. package/content/domains/family.yaml +6 -0
  147. package/content/domains/fate.yaml +6 -0
  148. package/content/domains/fire.yaml +6 -0
  149. package/content/domains/freedom.yaml +6 -0
  150. package/content/domains/healing.yaml +6 -0
  151. package/content/domains/indulgence.yaml +6 -0
  152. package/content/domains/knowledge.yaml +6 -0
  153. package/content/domains/luck.yaml +6 -0
  154. package/content/domains/magic.yaml +6 -0
  155. package/content/domains/might.yaml +6 -0
  156. package/content/domains/moon.yaml +6 -0
  157. package/content/domains/nature.yaml +6 -0
  158. package/content/domains/nightmares.yaml +6 -0
  159. package/content/domains/pain.yaml +6 -0
  160. package/content/domains/passion.yaml +6 -0
  161. package/content/domains/perfection.yaml +6 -0
  162. package/content/domains/protection.yaml +6 -0
  163. package/content/domains/secrecy.yaml +6 -0
  164. package/content/domains/sun.yaml +6 -0
  165. package/content/domains/travel.yaml +6 -0
  166. package/content/domains/trickery.yaml +6 -0
  167. package/content/domains/truth.yaml +6 -0
  168. package/content/domains/tyranny.yaml +6 -0
  169. package/content/domains/undeath.yaml +6 -0
  170. package/content/domains/water.yaml +6 -0
  171. package/content/domains/wealth.yaml +6 -0
  172. package/content/domains/zeal.yaml +6 -0
  173. package/content/effects/treated-disease.yaml +4 -0
  174. package/content/effects/treated-poison.yaml +4 -0
  175. package/content/feats/ancestry/gnome-obsession.yaml +1 -39
  176. package/content/feats/ancestry/tengu-feather-fan.yaml +3 -3
  177. package/content/feats/archetype/barbarian/barbarian-dedication.yaml +0 -2
  178. package/content/feats/archetype/champion/champions-reaction.yaml +1 -11
  179. package/content/feats/archetype/investigator/skill-mastery.yaml +2 -58
  180. package/content/feats/archetype/rogue/skill-mastery.yaml +2 -58
  181. package/content/feats/champion/deitys-domain.yaml +1 -22
  182. package/content/feats/cleric/advanced-domain.yaml +1 -187
  183. package/content/feats/cleric/domain-initiate.yaml +1 -199
  184. package/content/feats/oracle/domain-acumen.yaml +4 -138
  185. package/content/feats/skill/skill-training.yaml +1 -55
  186. package/content/feats/sorcerer/arcane-evolution.yaml +1 -26
  187. package/content/feats/sorcerer/occult-evolution.yaml +1 -26
  188. package/content/gear/compass-lensatic.yaml +1 -0
  189. package/content/gear/compass.yaml +1 -0
  190. package/content/gear/crowbar-levered.yaml +1 -0
  191. package/content/gear/crowbar.yaml +1 -0
  192. package/content/shields/specific/reflecting-shield.yaml +1 -1
  193. package/content/shields/specific/spellguard-shield.yaml +1 -0
  194. package/content/spells/agile-feet.yaml +1 -0
  195. package/content/spells/appearance-of-wealth.yaml +1 -0
  196. package/content/spells/athletic-rush.yaml +1 -0
  197. package/content/spells/bit-of-luck.yaml +1 -0
  198. package/content/spells/charming-touch.yaml +1 -0
  199. package/content/spells/cloak-of-shadow.yaml +1 -0
  200. package/content/spells/creative-splash.yaml +1 -0
  201. package/content/spells/cry-of-destruction.yaml +1 -0
  202. package/content/spells/dazzling-flash.yaml +1 -0
  203. package/content/spells/deaths-call.yaml +1 -0
  204. package/content/spells/face-in-the-crowd.yaml +1 -0
  205. package/content/spells/fire-ray.yaml +1 -0
  206. package/content/spells/guidance.yaml +2 -0
  207. package/content/spells/healers-blessing.yaml +1 -0
  208. package/content/spells/hurtling-stone.yaml +1 -0
  209. package/content/spells/ignite-ambition.yaml +1 -0
  210. package/content/spells/magics-vessel.yaml +1 -0
  211. package/content/spells/moonbeam.yaml +1 -0
  212. package/content/spells/overstuff.yaml +1 -0
  213. package/content/spells/perfected-mind.yaml +1 -0
  214. package/content/spells/protectors-sacrifice.yaml +1 -0
  215. package/content/spells/pushing-gust.yaml +1 -0
  216. package/content/spells/read-fate.yaml +1 -0
  217. package/content/spells/savor-the-sting.yaml +1 -0
  218. package/content/spells/scholarly-recollection.yaml +1 -0
  219. package/content/spells/soothing-words.yaml +1 -0
  220. package/content/spells/sudden-shift.yaml +1 -0
  221. package/content/spells/sure-strike.yaml +2 -0
  222. package/content/spells/sweet-dream.yaml +1 -0
  223. package/content/spells/tidal-surge.yaml +1 -0
  224. package/content/spells/touch-of-obedience.yaml +1 -0
  225. package/content/spells/touch-of-undeath.yaml +1 -0
  226. package/content/spells/true-target.yaml +2 -0
  227. package/content/spells/unimpeded-stride.yaml +1 -0
  228. package/content/spells/veil-of-confidence.yaml +1 -0
  229. package/content/spells/vibrant-thorns.yaml +1 -0
  230. package/content/spells/waking-nightmare.yaml +1 -0
  231. package/content/spells/weapon-surge.yaml +3 -0
  232. package/content/spells/whispering-quiet.yaml +1 -0
  233. package/content/spells/word-of-truth.yaml +1 -0
  234. package/dist/i18n/en.js +1 -1
  235. package/dist/i18n/en.json +196 -207
  236. package/dist/index.js +1 -1
  237. package/dist/release.json +7103 -3825
  238. package/i18n/en/ancestry-dragonblood.yaml +2 -2
  239. package/i18n/en/archetypes.yaml +6 -6
  240. package/i18n/en/backgrounds.yaml +6 -3
  241. package/i18n/en/battle-forms.yaml +0 -1
  242. package/i18n/en/champion.yaml +1 -1
  243. package/i18n/en/cleric.yaml +151 -149
  244. package/i18n/en/equipment.yaml +4 -1
  245. package/i18n/en/oracle.yaml +0 -38
  246. package/i18n/en/rogue.yaml +3 -3
  247. package/i18n/en/spellcasting.yaml +2 -2
  248. package/i18n/en/type-fields.yaml +2 -0
  249. package/i18n/en.yaml +19 -1
  250. package/pack.yaml +2 -2
  251. package/package.json +2 -2
  252. package/rules/advancement.yaml +1 -0
  253. package/rules/afflictions.yaml +2 -0
  254. package/rules/alchemist.yaml +14 -3
  255. package/rules/ancestry-feats.yaml +55 -13
  256. package/rules/archetypes.yaml +1 -0
  257. package/rules/barbarian.yaml +8 -21
  258. package/rules/bard.yaml +10 -4
  259. package/rules/building.yaml +7 -1
  260. package/rules/champion.yaml +3 -2
  261. package/rules/checks.yaml +1 -1
  262. package/rules/cleric.yaml +13 -3
  263. package/rules/conditions.yaml +1 -0
  264. package/rules/core.yaml +1 -0
  265. package/rules/creation.yaml +18 -0
  266. package/rules/druid.yaml +3 -2
  267. package/rules/equipment.yaml +7 -1
  268. package/rules/heritages.yaml +1 -1
  269. package/rules/investigator.yaml +3 -11
  270. package/rules/layout.yaml +19 -6
  271. package/rules/lores-pc2.yaml +176 -38
  272. package/rules/lores.yaml +226 -50
  273. package/rules/monk.yaml +2 -5
  274. package/rules/oracle.yaml +5 -3
  275. package/rules/ranger.yaml +3 -3
  276. package/rules/rogue.yaml +6 -1
  277. package/rules/skill-actions-athletics.yaml +1 -2
  278. package/rules/skill-actions-stealth.yaml +1 -2
  279. package/rules/skills.yaml +173 -56
  280. package/rules/sorcerer.yaml +16 -4
  281. package/rules/spellcasting.yaml +94 -24
  282. package/rules/spells-high.yaml +3 -3
  283. package/rules/strikes.yaml +3 -1
  284. package/rules/swashbuckler.yaml +4 -17
  285. package/rules/tags.yaml +6 -0
  286. package/rules/witch.yaml +2 -1
  287. package/rules/wizard.yaml +5 -3
  288. package/upgrades/0.2.0-to-0.3.0.yaml +657 -0
package/README.md CHANGED
@@ -14,6 +14,9 @@ planes and characters) is left out.
14
14
  pnpm add @opencharacter/engine @opencharacter/orc-2e
15
15
  ```
16
16
 
17
+ This release needs spec 0.3: `@opencharacter/engine` 0.3.0 or later. An engine for an older
18
+ spec refuses it (`spec-version-unsupported`).
19
+
17
20
  The package's default export is the built pack (a `PackRelease`), and `i18n/en` its English
18
21
  text:
19
22
 
@@ -28,9 +31,9 @@ const { ruleset } = loaded;
28
31
 
29
32
  // A new character, made by the random creation start: every pick is drawn, so it finishes.
30
33
  const blank = {
31
- specVersion: '0.2.0',
34
+ specVersion: '0.3.0',
32
35
  id: 'new-character',
33
- packs: [{ id: 'orc-2e', version: '0.2.0' }],
36
+ packs: [{ id: 'orc-2e', version: '0.3.0' }],
34
37
  creating: true,
35
38
  };
36
39
  const created = startAction(ruleset, blank, {
@@ -75,6 +78,54 @@ reading is listed under [Rule readings](#rule-readings).
75
78
  GM Core's relics and vehicles, the setting's proper nouns, and anything from the pre-Remaster
76
79
  (OGL) books, such as Ancestry Paragon and dual-class characters; GM Core's level 0 characters.
77
80
 
81
+ ## Add-on packs
82
+
83
+ A pack that depends on `orc-2e` can add to what it offers:
84
+
85
+ - **Subclasses:** a feature whose `classOption` names a class's choice (`barbarian.instinct`,
86
+ `bard.muse`, `cleric.doctrine`, `wizard.school`, …) joins that choice, and Champion's Reaction
87
+ for causes.
88
+ - **Domains:** a `domain` item joins Domain Initiate and Domain Acumen (an advanced one, with
89
+ `advanced: true`, Advanced Domain); an initial domain spell names its domain in its `domain`
90
+ field for Deity's Domain; a mystery grants its domains into `oracle.domains`.
91
+ - **Gear:** tags, not IDs, mark Force Open's crowbar (`tool.crowbar`), Sense Direction's compass
92
+ (`tool.compass`) and shields against spells (`shield.against-spells`).
93
+ - **Archetypes:** a new archetype declares its own `archetypes.<name>.feats` field tagged
94
+ `archetype-feats`; a feat for an existing archetype adds 1 to that archetype's field.
95
+ - **Open enums** (`extendEnums`): the identity fields (`barbarian.instinct`, `bard.muse`,
96
+ `champion.cause`, `cleric.doctrine`, `druid.order`, `investigator.methodology`,
97
+ `oracle.mystery`, `ranger.edge`, `rogue.racket`, `sorcerer.bloodline`, `swashbuckler.style`,
98
+ `wizard.school`, `wizard.thesis`, `witch.patron`, `alchemist.field`, `stance.current`), which
99
+ a new subclass feature sets with its own effect (`{ target: barbarian.instinct, op: set,
100
+ value: "'thunder'" }`), as the core's do; weapon `group` and `damageType`, armor `group`,
101
+ consumable `category`, `damageType` and `persistentType`, spell damage types (`damageType`,
102
+ `damage2Type`, `persistentType` and the cast's `damageType` state), affliction and persistent
103
+ damage condition damage types, feat `category`, and the damage type parameters of `cast-spell`
104
+ (`damageType`) and `bomb-strike` (`damageType`, `persistentType`), so an added bomb or spell
105
+ deals its type (`orc-2e:actions.bomb-strike.params.damageType`). A new damage type or group also needs its
106
+ tag (`damage.sonic`, `group.firearm`), declared and named in the add-on.
107
+ - **Choices** (`extendChoices`): written value and inline option choices take additions: the
108
+ dedications' identity picks (Barbarian Dedication's `instinct`), the follow-up feats' inline
109
+ options (Order Explorer's `order`, Additional Lore's `lore`), and the 15- and 16-skill lists.
110
+ - **Naming what an add-on adds:** it names each added value, option or key in its own text,
111
+ under the key this pack would use, and `createText` finds it there when the app passes the
112
+ ruleset's `enumOrigins`, `optionOrigins` and `familyOrigins`. For example,
113
+ `sonic` added to `orc-2e:types.weapon.fields.damageType` is
114
+ `types.weapon.fields.damageType.values.sonic.name: Sonic` (through `enumOrigins`), and an
115
+ Order Explorer option `stone` is
116
+ `feats.druid.order-explorer.choices.order.options.stone.name: Stone` (through
117
+ `optionOrigins`).
118
+ - **Skills and Lores:** a choice of any skill reads `skills.offered` and one of any Lore
119
+ `skills.lores`; an add-on's Lore declares its fields (`skills.lore.<name>.rank`, `.mod`, …,
120
+ as `rules/lores.yaml` does) and grants its tag into both with a rules effect.
121
+ - **Step tags** for rules-level `option` and `changes` effects: `creation.ancestry`,
122
+ `creation.heritage`, `creation.background`, `creation.class` and `creation.finish` (guided and
123
+ random creation), `level-up.gain`, and the actions' own (`strike.hit`, …).
124
+
125
+ Still closed: attributes, proficiency ranks, saves, spell traditions (and a staff's
126
+ `tradition`), weapon and armor categories, and physical damage types for `versatile` and
127
+ `modular`, the game's fixed sets.
128
+
78
129
  ## License
79
130
 
80
131
  - **License:** the ORC License. Its four notices (Article III) are in the manifest, which apps
@@ -307,8 +358,8 @@ reading is listed under [Rule readings](#rule-readings).
307
358
  trained. Demoralize frightens, Trip knocks prone (1d6 bludgeoning on a critical success),
308
359
  Grapple grabs or restrains, Escape frees; Treat Wounds (any DC your rank allows, an hour
309
360
  doubling it) and Battle Medicine heal, Treat Poison and Treat Disease give the next save a
310
- circumstance modifier (an applied effect), Administer First Aid stabilizes; Feint makes the
311
- target off-guard to your melee Strikes (`feint.target`, which the Strike reads); a critical
361
+ circumstance modifier (an applied effect that save removes), Administer First Aid stabilizes;
362
+ Feint makes the target off-guard to your melee Strikes (`feint.target`, which the Strike reads); a critical
312
363
  failure to Trip or Shove is prone, to Disarm off-guard; Subsist's failure is fatigued. Attack-
313
364
  trait actions take and count the multiple attack penalty. Actions against several creatures
314
365
  (Hide, Sneak, Lie, Coerce, Make an Impression, Seek, …) roll once and give each one's degree
@@ -648,16 +699,19 @@ reading is listed under [Rule readings](#rule-readings).
648
699
  - **Hero Points**: an input, 1 to start, at most 3; spending them is the app's.
649
700
  - **Creation**: a guided start, `standard`, and a random one,
650
701
  `random`. Guided: an ancestry and its heritage, a background and a class, then what each brings in the book's order: the ancestry's
651
- boosts and the heritage's choices, the background's boosts (and a scholar's skill), the class's
652
- key attribute, its skill, its trained skills (3 + Intelligence, each one not trained yet) and
653
- its feat; then the rest (four free boosts, the ancestry feat, languages, a training freed by a
654
- skill trained twice), and full Hit Points. While being created the character needs an
702
+ boosts and the heritage's choices, the background's boosts (and a scholar's skill), the four
703
+ free boosts, the class's key attribute, its skill, its trained skills (3 + Intelligence, each
704
+ one not trained yet, counted with the free boosts in) and its feat; then the rest (the ancestry
705
+ feat, languages, a training freed by a skill trained twice), and full Hit Points. While being created the character needs an
655
706
  ancestry, a background and a class (`creation-ancestry-background-class`); it never has more
656
707
  than one of each (the content types' `copies: { max: 1 }`), created or not.
657
708
  - **Random** (`random-character`): the rules have players choose, so the odds are the pack's. The same picks in the same order, each drawn by the engine uniformly among the
658
709
  options eligible then (`random`): the ancestry, its heritage, the background
659
710
  and the class, then every pick they bring (heritage feats, the key attribute, trained
660
- skills, feats, languages, a freed training). Boosts follow a priority instead. An ancestry
711
+ skills, feats, languages, a freed training). One difference: the four free boosts come
712
+ after the class's picks, so a choice that sets the key attribute (a rogue's racket) is made
713
+ before they're placed; a trained skill the final Intelligence adds is drawn with the rest.
714
+ Boosts follow a priority instead. An ancestry
661
715
  takes its standard boosts (the book's default). The key attribute is planned with the
662
716
  class: the class's own (a barbarian's Strength), else Strength or Dexterity, a d2 deciding;
663
717
  the class's key attribute pick takes the planned one when it is offered (a rogue other than
@@ -744,7 +798,8 @@ Where the books leave a rule open, or the format needs a choice the books don't
744
798
  reads it as below. These are the pack's provisional calls; a table may rule otherwise.
745
799
 
746
800
  - **Random start:** the books have players choose, so the odds are the pack's. Each pick is
747
- drawn uniformly among the options eligible then, in the guided start's order. Boosts follow a
801
+ drawn uniformly among the options eligible then, in the guided start's order, except that
802
+ the free boosts follow the class's picks, once the key attribute is known. Boosts follow a
748
803
  priority instead: an ancestry takes its standard boosts; the key attribute is planned with the
749
804
  class (its own, else Strength or Dexterity on a d2); every boost goes to the first offered of
750
805
  the key attribute, Constitution, Dexterity, Wisdom, Strength, Intelligence and Charisma.
@@ -807,8 +862,10 @@ reads it as below. These are the pack's provisional calls; a table may rule othe
807
862
  flanked or in cover (situational choices), when a condition is gained (`applyEffect`), daily
808
863
  preparations (the pack's `daily-preparations` and `prepare-spells` say what happens), rests; a
809
864
  spell's duration, sustaining and dismissing it, its area and who is in it (an applied spell
810
- stays until the app removes it; a spell on "you and your allies" takes the caster as an ally
811
- too); summoned creatures; onset, intervals and virulence of afflictions.
865
+ stays until the app removes it, but one for the next roll, such as guidance, sure strike,
866
+ true target or weapon surge, ends on the roll it changes; a spell on "you and your allies"
867
+ takes the caster as an ally too); summoned creatures; onset, intervals and virulence of
868
+ afflictions.
812
869
  - **Text only:** critical specialization, armor specialization, the skill feats that change
813
870
  time, other creatures or what the GM tells you (58 of 106), the skill actions' movement,
814
871
  attitudes and detection toward one observer, innate spells from heritages, Lunge; the rogue's,
@@ -1,6 +1,6 @@
1
1
  id: classes.alchemist.fields.bomber
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: alchemist.research-field }
4
4
  effects:
5
5
  - { target: alchemist.field, op: set, value: "'bomber'" }
6
6
  choices:
@@ -1,6 +1,6 @@
1
1
  id: classes.alchemist.fields.chirurgeon
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: alchemist.research-field }
4
4
  # Medicine checks use Crafting's modifier through an `atLeast` on Medicine's.
5
5
  effects:
6
6
  - { target: alchemist.field, op: set, value: "'chirurgeon'" }
@@ -1,6 +1,6 @@
1
1
  id: classes.alchemist.fields.mutagenist
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: alchemist.research-field }
4
4
  effects:
5
5
  - { target: alchemist.field, op: set, value: "'mutagenist'" }
6
6
  - target: { steps: [consumable.drink] }
@@ -1,6 +1,6 @@
1
1
  id: classes.alchemist.fields.toxicologist
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: alchemist.research-field }
4
4
  effects:
5
5
  - { target: alchemist.field, op: set, value: "'toxicologist'" }
6
6
  - target: { incoming: { fields: [hp.current], tags: [damage.poison] } }
@@ -45,44 +45,12 @@ grants:
45
45
  - { item: features.alchemist.medium-armor-mastery, when: level >= 19 }
46
46
  choices:
47
47
  - id: research-field
48
- from:
49
- items:
50
- [
51
- classes.alchemist.fields.bomber,
52
- classes.alchemist.fields.chirurgeon,
53
- classes.alchemist.fields.mutagenist,
54
- classes.alchemist.fields.toxicologist,
55
- ]
48
+ from: { type: feature, where: "item.classOption == 'alchemist.research-field'" }
56
49
  - id: skills
57
50
  unique: skill-training
58
51
  pick: 3 + max(0, attributes.int.mod)
59
52
  from:
60
- values:
61
- [
62
- skill.acrobatics,
63
- skill.arcana,
64
- skill.athletics,
65
- skill.crafting,
66
- skill.deception,
67
- skill.diplomacy,
68
- skill.intimidation,
69
- skill.medicine,
70
- skill.nature,
71
- skill.occultism,
72
- skill.performance,
73
- skill.religion,
74
- skill.society,
75
- skill.stealth,
76
- skill.survival,
77
- skill.thievery,
78
- skill.lore.academia,
79
- skill.lore.circus,
80
- skill.lore.farming,
81
- skill.lore.legal,
82
- skill.lore.scribing,
83
- skill.lore.underworld,
84
- skill.lore.warfare,
85
- ]
53
+ values: { formula: skills.offered }
86
54
  where: '!(value in skills.trained) && !(value in skills.chosen) || value in choice.picks'
87
55
  effects:
88
56
  - { target: skills.chosen, op: grant, value: { formula: pick.value } }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.animals.ape
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.animal }
4
4
  # The animal's unarmed attacks are standard copies while you have it; Rage equips them.
5
5
  standardCopies:
6
6
  - { type: weapon, where: "'animal.ape' in item.tags" }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.animals.bear
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.animal }
4
4
  # The animal's unarmed attacks are standard copies while you have it; Rage equips them.
5
5
  standardCopies:
6
6
  - { type: weapon, where: "'animal.bear' in item.tags" }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.animals.bull
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.animal }
4
4
  # The animal's unarmed attacks are standard copies while you have it; Rage equips them.
5
5
  standardCopies:
6
6
  - { type: weapon, where: "'animal.bull' in item.tags" }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.animals.cat
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.animal }
4
4
  # The animal's unarmed attacks are standard copies while you have it; Rage equips them.
5
5
  standardCopies:
6
6
  - { type: weapon, where: "'animal.cat' in item.tags" }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.animals.deer
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.animal }
4
4
  # The animal's unarmed attacks are standard copies while you have it; Rage equips them.
5
5
  standardCopies:
6
6
  - { type: weapon, where: "'animal.deer' in item.tags" }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.animals.frog
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.animal }
4
4
  # The animal's unarmed attacks are standard copies while you have it; Rage equips them.
5
5
  standardCopies:
6
6
  - { type: weapon, where: "'animal.frog' in item.tags" }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.animals.shark
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.animal }
4
4
  # The animal's unarmed attacks are standard copies while you have it; Rage equips them.
5
5
  standardCopies:
6
6
  - { type: weapon, where: "'animal.shark' in item.tags" }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.animals.snake
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.animal }
4
4
  # The animal's unarmed attacks are standard copies while you have it; Rage equips them.
5
5
  standardCopies:
6
6
  - { type: weapon, where: "'animal.snake' in item.tags" }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.animals.wolf
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.animal }
4
4
  # The animal's unarmed attacks are standard copies while you have it; Rage equips them.
5
5
  standardCopies:
6
6
  - { type: weapon, where: "'animal.wolf' in item.tags" }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.instincts.animal
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.instinct }
4
4
  effects:
5
5
  - { target: barbarian.instinct, op: set, value: "'animal'" }
6
6
  - { target: rage.animalDamage, op: set, value: 'level >= 15 ? 12 : level >= 7 ? 5 : 2' }
@@ -8,16 +8,4 @@ effects:
8
8
  - { target: rage.resists, op: grant, value: { tag: damage.slashing }, when: level >= 9 }
9
9
  choices:
10
10
  - id: animal
11
- from:
12
- items:
13
- [
14
- classes.barbarian.animals.ape,
15
- classes.barbarian.animals.bear,
16
- classes.barbarian.animals.bull,
17
- classes.barbarian.animals.cat,
18
- classes.barbarian.animals.deer,
19
- classes.barbarian.animals.frog,
20
- classes.barbarian.animals.shark,
21
- classes.barbarian.animals.snake,
22
- classes.barbarian.animals.wolf,
23
- ]
11
+ from: { type: feature, where: "item.classOption == 'barbarian.animal'" }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.instincts.dragon
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.instinct }
4
4
  effects:
5
5
  - { target: barbarian.instinct, op: set, value: "'dragon'" }
6
6
  - { target: rage.altDamage, op: set, value: 'level >= 15 ? 16 : level >= 7 ? 8 : 4' }
@@ -9,7 +9,6 @@ choices:
9
9
  - id: breath
10
10
  from: { values: [bludgeoning, fire, force, mental, poison, spirit] }
11
11
  effects:
12
- - { target: rage.altType, op: set, value: pick.value }
13
12
  - target: rage.resists
14
13
  op: grant
15
14
  value: { formula: "'damage.' + pick.value" }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.instincts.fury
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.instinct }
4
4
  effects:
5
5
  - { target: barbarian.instinct, op: set, value: "'fury'" }
6
6
  - { target: rage.damage, op: set, value: 'level >= 15 ? 13 : level >= 7 ? 7 : 3' }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.instincts.giant
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.instinct }
4
4
  # The player sets `rage.largerWeapon` while wielding a larger weapon, since weapon size isn't
5
5
  # modeled.
6
6
  effects:
@@ -1,8 +1,7 @@
1
1
  id: classes.barbarian.instincts.spirit
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.instinct }
4
4
  effects:
5
5
  - { target: barbarian.instinct, op: set, value: "'spirit'" }
6
6
  - { target: rage.altDamage, op: set, value: 'level >= 15 ? 13 : level >= 7 ? 7 : 3' }
7
- - { target: rage.altType, op: set, value: "'spirit'" }
8
7
  - { target: rage.resists, op: grant, value: { tag: damage.void }, when: level >= 9 }
@@ -1,6 +1,6 @@
1
1
  id: classes.barbarian.instincts.superstition
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: barbarian.instinct }
4
4
  effects:
5
5
  - { target: barbarian.instinct, op: set, value: "'superstition'" }
6
6
  - { target: rage.damage, op: set, value: 'level >= 15 ? 13 : level >= 7 ? 7 : 3' }
@@ -14,7 +14,9 @@ effects:
14
14
  / ('trait.agile' in roll.item.tags ? 2 : 1))
15
15
  tags:
16
16
  - formula: >-
17
- self.alternate && rage.altDamage > 0 ? 'damage.' + rage.altType
17
+ self.alternate && barbarian.instinct == 'spirit' ? 'damage.spirit'
18
+ : self.alternate && size(picksOf('classes.barbarian.instincts.dragon', 'breath')) > 0
19
+ ? 'damage.' + picksOf('classes.barbarian.instincts.dragon', 'breath')[0]
18
20
  : 'damage.' + roll.item.damageType
19
21
  when: >-
20
22
  roll.item.range == 0 && (!(has(flags.thrown) && flags.thrown) || rage.thrown)
@@ -46,46 +46,12 @@ grants:
46
46
  - { item: classes.barbarian.devastator, when: level >= 19 }
47
47
  choices:
48
48
  - id: instinct
49
- from:
50
- items:
51
- [
52
- classes.barbarian.instincts.animal,
53
- classes.barbarian.instincts.dragon,
54
- classes.barbarian.instincts.fury,
55
- classes.barbarian.instincts.giant,
56
- classes.barbarian.instincts.spirit,
57
- classes.barbarian.instincts.superstition,
58
- ]
49
+ from: { type: feature, where: "item.classOption == 'barbarian.instinct'" }
59
50
  - id: skills
60
51
  unique: skill-training
61
52
  pick: 3 + max(0, attributes.int.mod)
62
53
  from:
63
- values:
64
- [
65
- skill.acrobatics,
66
- skill.arcana,
67
- skill.athletics,
68
- skill.crafting,
69
- skill.deception,
70
- skill.diplomacy,
71
- skill.intimidation,
72
- skill.medicine,
73
- skill.nature,
74
- skill.occultism,
75
- skill.performance,
76
- skill.religion,
77
- skill.society,
78
- skill.stealth,
79
- skill.survival,
80
- skill.thievery,
81
- skill.lore.academia,
82
- skill.lore.circus,
83
- skill.lore.farming,
84
- skill.lore.legal,
85
- skill.lore.scribing,
86
- skill.lore.underworld,
87
- skill.lore.warfare,
88
- ]
54
+ values: { formula: skills.offered }
89
55
  where: '!(value in skills.trained) && !(value in skills.chosen) || value in choice.picks'
90
56
  effects:
91
57
  - { target: skills.chosen, op: grant, value: { formula: pick.value } }
@@ -1,6 +1,6 @@
1
1
  id: classes.bard.muses.enigma
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: bard.muse }
4
4
  effects:
5
5
  - { target: bard.muse, op: set, value: "'enigma'" }
6
6
  - { target: bard.muses, op: grant, value: { tag: muse.enigma } }
@@ -1,6 +1,6 @@
1
1
  id: classes.bard.muses.maestro
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: bard.muse }
4
4
  effects:
5
5
  - { target: bard.muse, op: set, value: "'maestro'" }
6
6
  - { target: bard.muses, op: grant, value: { tag: muse.maestro } }
@@ -1,6 +1,6 @@
1
1
  id: classes.bard.muses.polymath
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: bard.muse }
4
4
  effects:
5
5
  - { target: bard.muse, op: set, value: "'polymath'" }
6
6
  - { target: bard.muses, op: grant, value: { tag: muse.polymath } }
@@ -1,6 +1,6 @@
1
1
  id: classes.bard.muses.warrior
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: bard.muse }
4
4
  effects:
5
5
  - { target: bard.muse, op: set, value: "'warrior'" }
6
6
  - { target: bard.muses, op: grant, value: { tag: muse.warrior } }
@@ -56,44 +56,12 @@ grants:
56
56
  choices:
57
57
  # The muse is asked first, so the repertoire's picks follow it.
58
58
  - id: muse
59
- from:
60
- items:
61
- [
62
- classes.bard.muses.enigma,
63
- classes.bard.muses.maestro,
64
- classes.bard.muses.polymath,
65
- classes.bard.muses.warrior,
66
- ]
59
+ from: { type: feature, where: "item.classOption == 'bard.muse'" }
67
60
  - id: skills
68
61
  unique: skill-training
69
62
  pick: 4 + max(0, attributes.int.mod)
70
63
  from:
71
- values:
72
- [
73
- skill.acrobatics,
74
- skill.arcana,
75
- skill.athletics,
76
- skill.crafting,
77
- skill.deception,
78
- skill.diplomacy,
79
- skill.intimidation,
80
- skill.medicine,
81
- skill.nature,
82
- skill.occultism,
83
- skill.performance,
84
- skill.religion,
85
- skill.society,
86
- skill.stealth,
87
- skill.survival,
88
- skill.thievery,
89
- skill.lore.academia,
90
- skill.lore.circus,
91
- skill.lore.farming,
92
- skill.lore.legal,
93
- skill.lore.scribing,
94
- skill.lore.underworld,
95
- skill.lore.warfare,
96
- ]
64
+ values: { formula: skills.offered }
97
65
  where: '!(value in skills.trained) && !(value in skills.chosen) || value in choice.picks'
98
66
  effects:
99
67
  - { target: skills.chosen, op: grant, value: { formula: pick.value } }
@@ -1,7 +1,7 @@
1
1
  id: classes.champion.causes.desecration
2
2
  type: feature
3
3
  tags: [trait.uncommon]
4
- fields: { level: 1 }
4
+ fields: { level: 1, classOption: champion.cause }
5
5
  prerequisites:
6
6
  - { id: sanctification, when: "champion.sanctification == 'unholy'" }
7
7
  effects:
@@ -1,6 +1,6 @@
1
1
  id: classes.champion.causes.grandeur
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: champion.cause }
4
4
  prerequisites:
5
5
  - { id: sanctification, when: "champion.sanctification == 'holy'" }
6
6
  effects:
@@ -1,7 +1,7 @@
1
1
  id: classes.champion.causes.iniquity
2
2
  type: feature
3
3
  tags: [trait.uncommon]
4
- fields: { level: 1 }
4
+ fields: { level: 1, classOption: champion.cause }
5
5
  prerequisites:
6
6
  - { id: sanctification, when: "champion.sanctification == 'unholy'" }
7
7
  effects:
@@ -1,6 +1,6 @@
1
1
  id: classes.champion.causes.justice
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: champion.cause }
4
4
  effects:
5
5
  - { target: champion.cause, op: set, value: "'justice'", when: class.has.champion }
6
6
  actions:
@@ -1,6 +1,6 @@
1
1
  id: classes.champion.causes.liberation
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: champion.cause }
4
4
  effects:
5
5
  - { target: champion.cause, op: set, value: "'liberation'", when: class.has.champion }
6
6
  actions:
@@ -1,6 +1,6 @@
1
1
  id: classes.champion.causes.obedience
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: champion.cause }
4
4
  effects:
5
5
  - { target: champion.cause, op: set, value: "'obedience'", when: class.has.champion }
6
6
  actions:
@@ -1,6 +1,6 @@
1
1
  id: classes.champion.causes.redemption
2
2
  type: feature
3
- fields: { level: 1 }
3
+ fields: { level: 1, classOption: champion.cause }
4
4
  prerequisites:
5
5
  - { id: sanctification, when: "champion.sanctification == 'holy'" }
6
6
  effects:
@@ -140,17 +140,7 @@ choices:
140
140
  effects:
141
141
  - { target: attacks.favoredWeapons, op: grant, value: { formula: pick.id } }
142
142
  - id: cause
143
- from:
144
- items:
145
- [
146
- classes.champion.causes.desecration,
147
- classes.champion.causes.grandeur,
148
- classes.champion.causes.iniquity,
149
- classes.champion.causes.justice,
150
- classes.champion.causes.liberation,
151
- classes.champion.causes.obedience,
152
- classes.champion.causes.redemption,
153
- ]
143
+ from: { type: feature, where: "item.classOption == 'champion.cause'" }
154
144
  - id: devotion-spell
155
145
  from:
156
146
  options:
@@ -171,32 +161,7 @@ choices:
171
161
  unique: skill-training
172
162
  pick: 2 + max(0, attributes.int.mod)
173
163
  from:
174
- values:
175
- [
176
- skill.acrobatics,
177
- skill.arcana,
178
- skill.athletics,
179
- skill.crafting,
180
- skill.deception,
181
- skill.diplomacy,
182
- skill.intimidation,
183
- skill.medicine,
184
- skill.nature,
185
- skill.occultism,
186
- skill.performance,
187
- skill.religion,
188
- skill.society,
189
- skill.stealth,
190
- skill.survival,
191
- skill.thievery,
192
- skill.lore.academia,
193
- skill.lore.circus,
194
- skill.lore.farming,
195
- skill.lore.legal,
196
- skill.lore.scribing,
197
- skill.lore.underworld,
198
- skill.lore.warfare,
199
- ]
164
+ values: { formula: skills.offered }
200
165
  where: '!(value in skills.trained) && !(value in skills.chosen) || value in choice.picks'
201
166
  effects:
202
167
  - { target: skills.chosen, op: grant, value: { formula: pick.value } }