@opencharacter/wwn-srd 0.1.0 → 0.2.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 (42) hide show
  1. package/README.md +41 -3
  2. package/content/classes/mage.yaml +2 -14
  3. package/content/foci/lucky.yaml +3 -2
  4. package/content/foci/traditional-education.yaml +1 -1
  5. package/content/partials/accursed.yaml +1 -0
  6. package/content/partials/bard.yaml +1 -0
  7. package/content/partials/beastmaster.yaml +1 -0
  8. package/content/partials/blood-priest.yaml +1 -0
  9. package/content/partials/duelist.yaml +1 -0
  10. package/content/partials/healer.yaml +1 -0
  11. package/content/partials/mage.yaml +2 -23
  12. package/content/partials/mageslayer.yaml +1 -0
  13. package/content/partials/skinshifter.yaml +1 -0
  14. package/content/partials/thought-noble.yaml +1 -0
  15. package/content/partials/vowed.yaml +1 -0
  16. package/content/partials/wise.yaml +1 -0
  17. package/content/traditions/elementalist.yaml +8 -0
  18. package/content/traditions/high-mage.yaml +8 -0
  19. package/content/traditions/invoker.yaml +9 -0
  20. package/content/traditions/necromancer.yaml +8 -0
  21. package/dist/i18n/en.js +1 -1
  22. package/dist/i18n/en.json +21 -17
  23. package/dist/index.js +1 -1
  24. package/dist/release.json +3461 -2759
  25. package/i18n/en/content.yaml +13 -15
  26. package/i18n/en.yaml +8 -2
  27. package/pack.yaml +2 -2
  28. package/package.json +2 -2
  29. package/rules/advancement.yaml +7 -9
  30. package/rules/backgrounds.yaml +1 -0
  31. package/rules/classes.yaml +1 -0
  32. package/rules/combat.yaml +2 -2
  33. package/rules/creation-steps.yaml +6 -6
  34. package/rules/creation.yaml +30 -95
  35. package/rules/display.yaml +108 -21
  36. package/rules/foci.yaml +1 -0
  37. package/rules/health.yaml +5 -3
  38. package/rules/magic.yaml +46 -59
  39. package/rules/saves.yaml +1 -1
  40. package/rules/skills.yaml +1 -1
  41. package/rules/tags.yaml +7 -0
  42. package/upgrades/0.1.0-to-0.2.0.yaml +61 -0
@@ -32,7 +32,7 @@ arts.accursed.tendrils-of-night.name: 'Tendrils of Night'
32
32
  arts.accursed.unseen-steps.name: 'Unseen Steps'
33
33
  arts.accursed.weeping-wounds.name: 'Weeping Wounds'
34
34
  arts.accursed.weight-of-sin.name: 'Weight of Sin'
35
- arts.bard.a-thousand-tongues.name: 'A Thousand Tongues'
35
+ arts.bard.a-thousand-tongues.name: 'A Thousand Tongues (Bard)'
36
36
  arts.bard.battle-cry.name: 'Battle Cry'
37
37
  arts.bard.cursed-tune.name: 'Cursed Tune'
38
38
  arts.bard.deft-fingers.name: 'Deft Fingers'
@@ -57,7 +57,7 @@ arts.beastmaster.savage-senses.name: 'Savage Senses'
57
57
  arts.beastmaster.shared-vitality.name: 'Shared Vitality'
58
58
  arts.beastmaster.swift-healing.name: 'Swift Healing'
59
59
  arts.beastmaster.tongue-of-the-beasts.name: 'Tongue of the Beasts'
60
- arts.blood-priest.a-thousand-tongues.name: 'A Thousand Tongues'
60
+ arts.blood-priest.a-thousand-tongues.name: 'A Thousand Tongues (Blood Priest)'
61
61
  arts.blood-priest.armor-of-god.name: 'Armor of God'
62
62
  arts.blood-priest.divine-guidance.name: 'Divine Guidance'
63
63
  arts.blood-priest.fear-no-flame.name: 'Fear No Flame'
@@ -226,10 +226,6 @@ classes.adventurer.choices.first.prompt: 'First partial class'
226
226
  classes.adventurer.choices.second.prompt: 'Second partial class'
227
227
  classes.adventurer.name: 'Adventurer'
228
228
  classes.expert.name: 'Expert'
229
- classes.mage.choices.tradition.options.elementalist.name: 'Elementalist'
230
- classes.mage.choices.tradition.options.high-mage.name: 'High Mage'
231
- classes.mage.choices.tradition.options.invoker.name: 'Invoker'
232
- classes.mage.choices.tradition.options.necromancer.name: 'Necromancer'
233
229
  classes.mage.choices.tradition.prompt: 'Magical tradition'
234
230
  classes.mage.name: 'Mage'
235
231
  classes.warrior.name: 'Warrior'
@@ -255,7 +251,7 @@ foci.henchkeeper.name: 'Henchkeeper'
255
251
  foci.impervious-defense.name: 'Impervious Defense'
256
252
  foci.impostor.name: 'Impostor'
257
253
  foci.lucky.name: 'Lucky'
258
- foci.lucky.prerequisites.low-attribute: 'An attribute modifier of -1 or less'
254
+ foci.lucky.prerequisites.low-attribute: 'An attribute score of 7 or less (a modifier of -1 or worse)'
259
255
  foci.nullifier.name: 'Nullifier'
260
256
  foci.nullifier.prerequisites.non-mage: 'Not a Mage or partial Mage'
261
257
  foci.poisoner.name: 'Poisoner'
@@ -337,14 +333,6 @@ partials.blood-priest.name: 'Blood Priest'
337
333
  partials.duelist.name: 'Duelist'
338
334
  partials.expert.name: 'Partial Expert'
339
335
  partials.healer.name: 'Healer'
340
- partials.mage.choices.tradition.options.elementalist.name: 'Elementalist'
341
- partials.mage.choices.tradition.options.elementalist.prerequisites.no-invoker: 'No partial Invoker'
342
- partials.mage.choices.tradition.options.high-mage.name: 'High Mage'
343
- partials.mage.choices.tradition.options.high-mage.prerequisites.no-invoker: 'No partial Invoker'
344
- partials.mage.choices.tradition.options.invoker.name: 'Invoker'
345
- partials.mage.choices.tradition.options.invoker.prerequisites.no-other-caster: 'No other partial spellcasting class'
346
- partials.mage.choices.tradition.options.necromancer.name: 'Necromancer'
347
- partials.mage.choices.tradition.options.necromancer.prerequisites.no-invoker: 'No partial Invoker'
348
336
  partials.mage.choices.tradition.prompt: 'Magical tradition'
349
337
  partials.mage.name: 'Partial Mage'
350
338
  partials.mageslayer.name: 'Mageslayer'
@@ -472,3 +460,13 @@ weapons.throwing-blade.name: 'Throwing blade'
472
460
  weapons.unarmed.name: 'Unarmed attack'
473
461
  weapons.war-axe.name: 'War axe'
474
462
  weapons.war-hammer.name: 'War hammer'
463
+ types.tradition.name: 'Magical tradition'
464
+ types.tradition.fields.key.name: 'Tradition key'
465
+ traditions.elementalist.name: 'Elementalist'
466
+ traditions.high-mage.name: 'High Mage'
467
+ traditions.invoker.name: 'Invoker'
468
+ traditions.necromancer.name: 'Necromancer'
469
+ traditions.elementalist.prerequisites.no-invoker: 'No partial Invoker'
470
+ traditions.high-mage.prerequisites.no-invoker: 'No partial Invoker'
471
+ traditions.invoker.prerequisites.no-other-caster: 'No other partial spellcasting class'
472
+ traditions.necromancer.prerequisites.no-invoker: 'No partial Invoker'
package/i18n/en.yaml CHANGED
@@ -415,11 +415,11 @@ fields.xp.nextLevel.name: 'Next level at'
415
415
  fields.xp.pace.name: 'Leveling pace'
416
416
  fields.xp.pace.values.fast.name: 'Fast'
417
417
  fields.xp.pace.values.slow.name: 'Slow'
418
- groups.advancement-actions.label: 'Advancement'
418
+ groups.advancement-actions.label: 'Level up'
419
419
  groups.advancement.label: 'Advancement'
420
420
  groups.armor.label: 'Armor'
421
421
  groups.arts.label: 'Arts'
422
- groups.attacks.label: 'Combat'
422
+ groups.attacks.label: 'Attacks'
423
423
  groups.attributes.label: 'Attributes'
424
424
  groups.background.label: 'Background'
425
425
  groups.checks.label: 'Checks and saves'
@@ -449,6 +449,7 @@ headline: 'Level {field_level} {type_background} {type_class}'
449
449
  pack.name: 'Worlds Without Number (SRD)'
450
450
  situational.nullified.name: 'Near a Nullifier (+2 against magic)'
451
451
  tags.advancement.name: 'Advancement'
452
+ tags.advancement.level.name: 'New level'
452
453
  tags.armor-piercing.name: 'Armor Piercing'
453
454
  tags.art.name: 'Art'
454
455
  tags.attack.melee.name: 'Melee attack'
@@ -469,6 +470,8 @@ tags.beast.name: 'Beast'
469
470
  tags.check.name: 'Skill check'
470
471
  tags.combat.name: 'Combat'
471
472
  tags.creation.name: 'Creation'
473
+ tags.creation.finish.name: 'Creation finish'
474
+ tags.creation.purse.name: 'Starting silver'
472
475
  tags.curse-blessing.name: 'Curse or blessing'
473
476
  tags.damage.melee.name: 'Melee damage'
474
477
  tags.damage.name: 'Damage'
@@ -487,6 +490,7 @@ tags.initiative.name: 'Initiative'
487
490
  tags.less-lethal.name: 'Less Lethal'
488
491
  tags.long.name: 'Long'
489
492
  tags.mage-class.name: 'Mage class'
493
+ tags.full-mage.name: 'Full Mage class'
490
494
  tags.mod-bonus.name: 'Modifier bonus'
491
495
  tags.mod-cap.name: 'Modifier cap'
492
496
  tags.noncombat.name: 'Non-combat'
@@ -495,6 +499,8 @@ tags.precise.name: 'Precisely Murderous'
495
499
  tags.reload.name: 'Reload'
496
500
  tags.repeatable.name: 'Taken more than once'
497
501
  tags.rest.name: 'Rest'
502
+ tags.rest.night.name: "Night's rest"
503
+ tags.rest.scene.name: 'Scene end'
498
504
  tags.save.evasion.name: 'Evasion save'
499
505
  tags.save.luck.name: 'Luck save'
500
506
  tags.save.mental.name: 'Mental save'
package/pack.yaml CHANGED
@@ -1,6 +1,6 @@
1
1
  id: wwn-srd
2
- version: 0.1.0
3
- specVersion: 0.2.0
2
+ version: 0.2.0
3
+ specVersion: 0.3.0
4
4
  license: CC0-1.0
5
5
  notices:
6
6
  not-affiliated: >-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencharacter/wwn-srd",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Open Character Format pack for the character rules of the Worlds Without Number SRD (CC0). Unofficial.",
5
5
  "keywords": [
6
6
  "character-sheet",
@@ -52,7 +52,7 @@
52
52
  "access": "public"
53
53
  },
54
54
  "devDependencies": {
55
- "@opencharacter/engine": "0.2.0"
55
+ "@opencharacter/engine": "0.3.0"
56
56
  },
57
57
  "engines": {
58
58
  "node": ">=22"
@@ -21,7 +21,7 @@ actions:
21
21
  # spells. Saves and attack bonus follow the level.
22
22
  - id: level-up
23
23
  tags: [advancement]
24
- available: '!character.creating && level < 10'
24
+ available: '!character.creating && level < 10 && xp.levelUp'
25
25
  params:
26
26
  random: { type: boolean, default: false }
27
27
  results: [advanced]
@@ -32,6 +32,7 @@ actions:
32
32
  - when: true
33
33
  flags: { oldMax: hp.max, oldRolled: hp.rolled }
34
34
  - id: gain
35
+ tags: [advancement.level]
35
36
  kind: changes
36
37
  changes:
37
38
  - { type: adjust, field: level, by: 1 }
@@ -77,7 +78,7 @@ actions:
77
78
  sheet: proposed
78
79
  random: params.random
79
80
  options:
80
- values: [highmage, elementalist, necromancer, invoker]
81
+ values: { formula: "keysOf('spellTrad') + ['invoker']" }
81
82
  where: "fieldOf('tradition.{trad}.tier', value) > 0"
82
83
  recommend: options[0]
83
84
  - id: newSpells
@@ -97,11 +98,8 @@ actions:
97
98
  type: spell
98
99
  where: >-
99
100
  item.level <= spells.maxLevel && countCopies(copy.item == item.id) == 0
100
- && (item.list == 'high'
101
- || (item.list == 'elementalist' && (steps.spellTradition.picked == 'elementalist'
102
- || (steps.spellTradition.picked == 'invoker' && invoker.education == 'elementalist')))
103
- || (item.list == 'necromancer' && (steps.spellTradition.picked == 'necromancer'
104
- || (steps.spellTradition.picked == 'invoker' && invoker.education == 'necromancer'))))
101
+ && (item.list == 'high' || item.list == steps.spellTradition.picked
102
+ || (steps.spellTradition.picked == 'invoker' && invoker.education == item.list))
105
103
  recommend: options[0]
106
104
  changes:
107
105
  - type: addItem
@@ -172,11 +170,11 @@ actions:
172
170
  - { type: adjust, when: flags.attribute, field: attributes.boosts, by: 1 }
173
171
  - type: adjust
174
172
  when: '!flags.attribute'
175
- field: { formula: "'skills.' + steps.pick.picked" }
173
+ field: { formula: "fieldId('skills.{skill}', steps.pick.picked)" }
176
174
  by: 1
177
175
  - type: set
178
176
  when: '!flags.attribute'
179
- field: { formula: "'skillCredit.' + steps.pick.picked" }
177
+ field: { formula: "fieldId('skillCredit.{skill}', steps.pick.picked)" }
180
178
  value: 0
181
179
  - { type: adjust, when: flags.expert > 0, field: skillPoints.expert, by: -flags.expert }
182
180
  - type: adjust
@@ -27,6 +27,7 @@ contentTypes:
27
27
  fields:
28
28
  '{backgroundEntry}':
29
29
  type: enum
30
+ open: true
30
31
  values:
31
32
  [
32
33
  administer,
@@ -58,6 +58,7 @@ contentTypes:
58
58
  copies: { max: 1 }
59
59
  # An Adventurer's two halves.
60
60
  partial:
61
+ grantOnly: true
61
62
  copies: { max: 0 }
62
63
 
63
64
  constraints:
package/rules/combat.yaml CHANGED
@@ -71,7 +71,7 @@ contentTypes:
71
71
  shock: { type: integer, default: 0, min: 0 }
72
72
  shockAc: { type: integer, default: 0, min: 0 }
73
73
  attribute: { type: enum, values: [str, dex, str-dex], required: true }
74
- skill: { type: enum, values: [stab, shoot, punch], required: true }
74
+ skill: { type: enum, values: [stab, shoot, punch], required: true, open: true }
75
75
  rangeShort: { type: integer, min: 0 }
76
76
  rangeLong: { type: integer, min: 0 }
77
77
  cost: { type: integer, min: 0 }
@@ -114,7 +114,7 @@ resultBands:
114
114
  - { id: hit, when: 'roll.kept[0] == 20' }
115
115
  - { id: miss, when: 'roll.kept[0] == 1' }
116
116
  - { id: rolled, when: flags.ac < 0 }
117
- - { id: hit, when: roll.total >= flags.ac }
117
+ - { id: hit, when: roll.total >= flags.ac, success: true }
118
118
  - { id: miss, when: true }
119
119
 
120
120
  actions:
@@ -101,15 +101,15 @@ actions:
101
101
  changes:
102
102
  - type: adjust
103
103
  when: params.points == 0
104
- field: { formula: "'skills.' + flags.target" }
104
+ field: { formula: "fieldId('skills.{skill}', flags.target)" }
105
105
  by: 1
106
106
  - type: adjust
107
107
  when: params.points > 0 && flags.first + flags.second > 0
108
- field: { formula: "'skills.' + flags.target" }
108
+ field: { formula: "fieldId('skills.{skill}', flags.target)" }
109
109
  by: flags.first + flags.second
110
110
  - type: set
111
111
  when: params.points > 0
112
- field: { formula: "'skillCredit.' + flags.target" }
112
+ field: { formula: "fieldId('skillCredit.{skill}', flags.target)" }
113
113
  value: >-
114
114
  flags.second > 0 ? flags.left - flags.from - flags.first - 2 : flags.left
115
115
  - id: result
@@ -181,9 +181,9 @@ actions:
181
181
  || (item.requires == 'non-mage' && class.mage == 0)
182
182
  || (item.requires == 'expert' && class.expert > 0)
183
183
  || (item.requires == 'invoker' && tradition.invoker.tier > 0)
184
- || (item.requires == 'low-attribute' && min(attributes.str.mod,
185
- attributes.dex.mod, attributes.con.mod, attributes.int.mod,
186
- attributes.wis.mod, attributes.cha.mod) <= -1))
184
+ || (item.requires == 'low-attribute' && min(attributes.str.score,
185
+ attributes.dex.score, attributes.con.score, attributes.int.score,
186
+ attributes.wis.score, attributes.cha.score) <= 7))
187
187
  recommend: options[0]
188
188
  - id: held
189
189
  kind: branch
@@ -224,97 +224,29 @@ actions:
224
224
  use: gain-skill
225
225
  params: { skill: "'any'", random: params.random }
226
226
 
227
- # Each tradition's bonus skill: Magic for most Mages, the class's own skill for the rest.
228
- - id: highmageSkill
229
- kind: action
230
- sheet: proposed
231
- when: tradition.highmage.tier > 0
232
- use: gain-skill
233
- params: { skill: "'magic'", random: params.random }
234
- - id: elementalistSkill
235
- kind: action
236
- sheet: proposed
237
- when: tradition.elementalist.tier > 0
238
- use: gain-skill
239
- params: { skill: "'magic'", random: params.random }
240
- - id: necromancerSkill
241
- kind: action
242
- sheet: proposed
243
- when: tradition.necromancer.tier > 0
244
- use: gain-skill
245
- params: { skill: "'magic'", random: params.random }
246
- - id: invokerSkill
247
- kind: action
248
- sheet: proposed
249
- when: tradition.invoker.tier > 0
250
- use: gain-skill
251
- params: { skill: "'magic'", random: params.random }
252
- - id: healerSkill
253
- kind: action
254
- sheet: proposed
255
- when: tradition.healer.tier > 0
256
- use: gain-skill
257
- params: { skill: "'heal'", random: params.random }
258
- - id: vowedSkill
259
- kind: action
260
- sheet: proposed
261
- when: tradition.vowed.tier > 0 && vowed.skill != ''
262
- use: gain-skill
263
- params: { skill: vowed.skill, random: params.random }
264
- - id: accursedSkill
265
- kind: action
266
- sheet: proposed
267
- when: tradition.accursed.tier > 0
268
- use: gain-skill
269
- params: { skill: "'magic'", random: params.random }
270
- - id: bardSkill
271
- kind: action
272
- sheet: proposed
273
- when: tradition.bard.tier > 0
274
- use: gain-skill
275
- params: { skill: "'perform'", random: params.random }
276
- - id: beastmasterSkill
277
- kind: action
278
- sheet: proposed
279
- when: tradition.beastmaster.tier > 0
280
- use: gain-skill
281
- params: { skill: "'survive'", random: params.random }
282
- - id: bloodpriestSkill
283
- kind: action
284
- sheet: proposed
285
- when: tradition.bloodpriest.tier > 0
286
- use: gain-skill
287
- params: { skill: "'pray'", random: params.random }
288
- - id: duelistSkill
289
- kind: action
290
- sheet: proposed
291
- when: tradition.duelist.tier > 0
292
- use: gain-skill
293
- params: { skill: "'stab'", random: params.random }
294
- - id: mageslayerSkill
295
- kind: action
296
- sheet: proposed
297
- when: tradition.mageslayer.tier > 0
298
- use: gain-skill
299
- params: { skill: "'magic'", random: params.random }
300
- - id: skinshifterSkill
301
- kind: action
302
- sheet: proposed
303
- when: tradition.skinshifter.tier > 0
304
- use: gain-skill
305
- params: { skill: "'survive'", random: params.random }
306
- - id: thoughtnobleSkill
307
- kind: action
308
- sheet: proposed
309
- when: tradition.thoughtnoble.tier > 0
310
- use: gain-skill
311
- params: { skill: "'notice'", random: params.random }
312
- - id: wiseSkill
313
- kind: action
227
+ # Each tradition's bonus skill (`tradition.<key>.skill`): Magic for most Mages, the class's
228
+ # own skill for the rest, in tradition order.
229
+ - id: traditionSkills
230
+ kind: branch
314
231
  sheet: proposed
315
- when: tradition.wise.tier > 0 && wise.skill != ''
316
- use: gain-skill
317
- params: { skill: wise.skill, random: params.random }
232
+ cases:
233
+ - when: true
234
+ flags:
235
+ traditionSkills: >-
236
+ mapList(filterList(keysOf('trad'), fieldOf('tradition.{trad}.tier', x) > 0
237
+ && fieldOf('tradition.{trad}.skill', x) != ''), fieldOf('tradition.{trad}.skill', x))
238
+ - id: traditionSkill
239
+ kind: group
240
+ when: size(flags.traditionSkills) > 0
241
+ repeat: { while: size(steps.traditionSkill) < size(flags.traditionSkills), max: 15 }
242
+ steps:
243
+ - id: gain
244
+ kind: action
245
+ sheet: proposed
246
+ use: gain-skill
247
+ params:
248
+ skill: flags.traditionSkills[size(steps.traditionSkill)]
249
+ random: params.random
318
250
 
319
251
  # The arts each tradition lets a new mage pick, and the first-level spells they know.
320
252
  - id: arts
@@ -332,10 +264,9 @@ actions:
332
264
  type: spell
333
265
  where: >-
334
266
  item.level == 1 && countCopies(copy.item == item.id) == 0
335
- && (item.list == 'high' || (item.list == 'elementalist'
336
- && (tradition.elementalist.tier > 0 || invoker.education == 'elementalist'))
337
- || (item.list == 'necromancer' && (tradition.necromancer.tier > 0
338
- || invoker.education == 'necromancer')))
267
+ && (item.list == 'high' || (item.list in keysOf('trad')
268
+ && (fieldOf('tradition.{trad}.tier', item.list) > 0
269
+ || invoker.education == item.list)))
339
270
  recommend: options[0]
340
271
  changes:
341
272
  - type: addItem
@@ -361,6 +292,7 @@ actions:
361
292
  # afford; spellcasters and the Vowed skip armor, which hinders their magic.
362
293
  - { id: silverRoll, kind: roll, tags: [creation], parts: [{ dice: 3d6 }] }
363
294
  - id: purse
295
+ tags: [creation.purse]
364
296
  kind: changes
365
297
  changes:
366
298
  - { type: adjust, field: coins.silver, by: steps.silverRoll.total * 10 }
@@ -416,7 +348,7 @@ actions:
416
348
  - { type: addItem, entry: { item: picked.id, equipped: true } }
417
349
  - *pay
418
350
  - *change
419
- # Up to six pieces of gear, one of each.
351
+ # Up to six pieces of gear, one of each, no more than the character can carry.
420
352
  - id: gear
421
353
  kind: choice
422
354
  sheet: proposed
@@ -428,6 +360,8 @@ actions:
428
360
  where: >-
429
361
  picks == 0
430
362
  && (item.costUnit == 'cp' ? ceil(item.cost / 10) : item.cost) <= coins.silver
363
+ && (item.id == @gear.backpack ? enc.readied + item.enc <= enc.readiedLimit + 4
364
+ : enc.stowed + item.enc <= enc.stowedLimit + 8)
431
365
  recommend: >-
432
366
  filterList([@gear.backpack, @gear.rations, @gear.waterskin, @gear.tinder-box,
433
367
  @gear.torch, @gear.rope, options[0]], x in options)[0]
@@ -438,6 +372,7 @@ actions:
438
372
  - *change
439
373
 
440
374
  - id: finish
375
+ tags: [creation.finish]
441
376
  kind: changes
442
377
  sheet: proposed
443
378
  changes:
@@ -241,71 +241,158 @@ display:
241
241
  attributes.cha.modCap: { hidden: true }
242
242
  skills.administer:
243
243
  rolls: [{ action: skill-check, params: { skill: skills.administer, attribute: int } }]
244
- skillCredit.administer: { visibility: background, showWhen: skillCredit.administer > 0 }
244
+ skillCredit.administer:
245
+ {
246
+ groups: [advancement],
247
+ priority: 7,
248
+ visibility: background,
249
+ showWhen: skillCredit.administer > 0,
250
+ }
245
251
  skills.connect:
246
252
  rolls: [{ action: skill-check, params: { skill: skills.connect, attribute: cha } }]
247
- skillCredit.connect: { visibility: background, showWhen: skillCredit.connect > 0 }
253
+ skillCredit.connect:
254
+ {
255
+ groups: [advancement],
256
+ priority: 7,
257
+ visibility: background,
258
+ showWhen: skillCredit.connect > 0,
259
+ }
248
260
  skills.convince:
249
261
  rolls: [{ action: skill-check, params: { skill: skills.convince, attribute: cha } }]
250
- skillCredit.convince: { visibility: background, showWhen: skillCredit.convince > 0 }
262
+ skillCredit.convince:
263
+ {
264
+ groups: [advancement],
265
+ priority: 7,
266
+ visibility: background,
267
+ showWhen: skillCredit.convince > 0,
268
+ }
251
269
  skills.craft:
252
270
  rolls: [{ action: skill-check, params: { skill: skills.craft, attribute: int } }]
253
- skillCredit.craft: { visibility: background, showWhen: skillCredit.craft > 0 }
271
+ skillCredit.craft:
272
+ {
273
+ groups: [advancement],
274
+ priority: 7,
275
+ visibility: background,
276
+ showWhen: skillCredit.craft > 0,
277
+ }
254
278
  skills.exert:
255
279
  rolls: [{ action: skill-check, params: { skill: skills.exert, attribute: str } }]
256
- skillCredit.exert: { visibility: background, showWhen: skillCredit.exert > 0 }
280
+ skillCredit.exert:
281
+ {
282
+ groups: [advancement],
283
+ priority: 7,
284
+ visibility: background,
285
+ showWhen: skillCredit.exert > 0,
286
+ }
257
287
  skills.heal:
258
288
  rolls: [{ action: skill-check, params: { skill: skills.heal, attribute: int } }]
259
- skillCredit.heal: { visibility: background, showWhen: skillCredit.heal > 0 }
289
+ skillCredit.heal:
290
+ { groups: [advancement], priority: 7, visibility: background, showWhen: skillCredit.heal > 0 }
260
291
  skills.know:
261
292
  rolls: [{ action: skill-check, params: { skill: skills.know, attribute: int } }]
262
- skillCredit.know: { visibility: background, showWhen: skillCredit.know > 0 }
293
+ skillCredit.know:
294
+ { groups: [advancement], priority: 7, visibility: background, showWhen: skillCredit.know > 0 }
263
295
  skills.lead:
264
296
  rolls: [{ action: skill-check, params: { skill: skills.lead, attribute: cha } }]
265
- skillCredit.lead: { visibility: background, showWhen: skillCredit.lead > 0 }
297
+ skillCredit.lead:
298
+ { groups: [advancement], priority: 7, visibility: background, showWhen: skillCredit.lead > 0 }
266
299
  skills.magic:
267
300
  rolls: [{ action: skill-check, params: { skill: skills.magic, attribute: int } }]
268
- skillCredit.magic: { visibility: background, showWhen: skillCredit.magic > 0 }
301
+ skillCredit.magic:
302
+ {
303
+ groups: [advancement],
304
+ priority: 7,
305
+ visibility: background,
306
+ showWhen: skillCredit.magic > 0,
307
+ }
269
308
  skills.notice:
270
309
  rolls: [{ action: skill-check, params: { skill: skills.notice, attribute: wis } }]
271
- skillCredit.notice: { visibility: background, showWhen: skillCredit.notice > 0 }
310
+ skillCredit.notice:
311
+ {
312
+ groups: [advancement],
313
+ priority: 7,
314
+ visibility: background,
315
+ showWhen: skillCredit.notice > 0,
316
+ }
272
317
  skills.perform:
273
318
  rolls: [{ action: skill-check, params: { skill: skills.perform, attribute: cha } }]
274
- skillCredit.perform: { visibility: background, showWhen: skillCredit.perform > 0 }
319
+ skillCredit.perform:
320
+ {
321
+ groups: [advancement],
322
+ priority: 7,
323
+ visibility: background,
324
+ showWhen: skillCredit.perform > 0,
325
+ }
275
326
  skills.pray:
276
327
  rolls: [{ action: skill-check, params: { skill: skills.pray, attribute: wis } }]
277
- skillCredit.pray: { visibility: background, showWhen: skillCredit.pray > 0 }
328
+ skillCredit.pray:
329
+ { groups: [advancement], priority: 7, visibility: background, showWhen: skillCredit.pray > 0 }
278
330
  skills.punch:
279
331
  rolls: [{ action: skill-check, params: { skill: skills.punch, attribute: str } }]
280
- skillCredit.punch: { visibility: background, showWhen: skillCredit.punch > 0 }
332
+ skillCredit.punch:
333
+ {
334
+ groups: [advancement],
335
+ priority: 7,
336
+ visibility: background,
337
+ showWhen: skillCredit.punch > 0,
338
+ }
281
339
  skills.ride:
282
340
  rolls: [{ action: skill-check, params: { skill: skills.ride, attribute: dex } }]
283
- skillCredit.ride: { visibility: background, showWhen: skillCredit.ride > 0 }
341
+ skillCredit.ride:
342
+ { groups: [advancement], priority: 7, visibility: background, showWhen: skillCredit.ride > 0 }
284
343
  skills.sail:
285
344
  rolls: [{ action: skill-check, params: { skill: skills.sail, attribute: dex } }]
286
- skillCredit.sail: { visibility: background, showWhen: skillCredit.sail > 0 }
345
+ skillCredit.sail:
346
+ { groups: [advancement], priority: 7, visibility: background, showWhen: skillCredit.sail > 0 }
287
347
  skills.shoot:
288
348
  rolls: [{ action: skill-check, params: { skill: skills.shoot, attribute: dex } }]
289
- skillCredit.shoot: { visibility: background, showWhen: skillCredit.shoot > 0 }
349
+ skillCredit.shoot:
350
+ {
351
+ groups: [advancement],
352
+ priority: 7,
353
+ visibility: background,
354
+ showWhen: skillCredit.shoot > 0,
355
+ }
290
356
  skills.sneak:
291
357
  rolls: [{ action: skill-check, params: { skill: skills.sneak, attribute: dex } }]
292
- skillCredit.sneak: { visibility: background, showWhen: skillCredit.sneak > 0 }
358
+ skillCredit.sneak:
359
+ {
360
+ groups: [advancement],
361
+ priority: 7,
362
+ visibility: background,
363
+ showWhen: skillCredit.sneak > 0,
364
+ }
293
365
  skills.stab:
294
366
  rolls: [{ action: skill-check, params: { skill: skills.stab, attribute: str } }]
295
- skillCredit.stab: { visibility: background, showWhen: skillCredit.stab > 0 }
367
+ skillCredit.stab:
368
+ { groups: [advancement], priority: 7, visibility: background, showWhen: skillCredit.stab > 0 }
296
369
  skills.survive:
297
370
  rolls: [{ action: skill-check, params: { skill: skills.survive, attribute: wis } }]
298
- skillCredit.survive: { visibility: background, showWhen: skillCredit.survive > 0 }
371
+ skillCredit.survive:
372
+ {
373
+ groups: [advancement],
374
+ priority: 7,
375
+ visibility: background,
376
+ showWhen: skillCredit.survive > 0,
377
+ }
299
378
  skills.trade:
300
379
  rolls: [{ action: skill-check, params: { skill: skills.trade, attribute: cha } }]
301
- skillCredit.trade: { visibility: background, showWhen: skillCredit.trade > 0 }
380
+ skillCredit.trade:
381
+ {
382
+ groups: [advancement],
383
+ priority: 7,
384
+ visibility: background,
385
+ showWhen: skillCredit.trade > 0,
386
+ }
302
387
  skills.work:
303
388
  rolls: [{ action: skill-check, params: { skill: skills.work, attribute: int } }]
304
- skillCredit.work: { visibility: background, showWhen: skillCredit.work > 0 }
389
+ skillCredit.work:
390
+ { groups: [advancement], priority: 7, visibility: background, showWhen: skillCredit.work > 0 }
305
391
  saves.physical: { rolls: [{ action: saving-throw, params: { save: saves.physical } }] }
306
392
  saves.evasion: { rolls: [{ action: saving-throw, params: { save: saves.evasion } }] }
307
393
  saves.mental: { rolls: [{ action: saving-throw, params: { save: saves.mental } }] }
308
394
  saves.luck: { rolls: [{ action: saving-throw, params: { save: saves.luck } }] }
395
+ 'tradition.{trad}.skill': { hidden: true }
309
396
  tradition.highmage.tier: { hidden: true }
310
397
  tradition.elementalist.tier: { hidden: true }
311
398
  tradition.necromancer.tier: { hidden: true }
package/rules/foci.yaml CHANGED
@@ -7,6 +7,7 @@ contentTypes:
7
7
  # the combat skills) or `none`.
8
8
  bonusSkill:
9
9
  type: enum
10
+ open: true
10
11
  values:
11
12
  [
12
13
  none,
package/rules/health.yaml CHANGED
@@ -131,6 +131,7 @@ actions:
131
131
  results: [rested]
132
132
  steps:
133
133
  - id: recover
134
+ tags: [rest.night]
134
135
  kind: changes
135
136
  changes:
136
137
  - {
@@ -150,11 +151,11 @@ actions:
150
151
  - { type: set, field: spells.pointsUsed, value: 0 }
151
152
  - type: set
152
153
  forEach: keysOf('effortTrad')
153
- field: { formula: "'effort.' + x + '.day'" }
154
+ field: { formula: "fieldId('effort.{effortTrad}.day', x)" }
154
155
  value: 0
155
156
  - type: set
156
157
  forEach: keysOf('effortTrad')
157
- field: { formula: "'effort.' + x + '.scene'" }
158
+ field: { formula: "fieldId('effort.{effortTrad}.scene', x)" }
158
159
  value: 0
159
160
  - id: result
160
161
  kind: outcome
@@ -165,11 +166,12 @@ actions:
165
166
  results: [ended]
166
167
  steps:
167
168
  - id: reclaim
169
+ tags: [rest.scene]
168
170
  kind: changes
169
171
  changes:
170
172
  - type: set
171
173
  forEach: keysOf('effortTrad')
172
- field: { formula: "'effort.' + x + '.scene'" }
174
+ field: { formula: "fieldId('effort.{effortTrad}.scene', x)" }
173
175
  value: 0
174
176
  - id: result
175
177
  kind: outcome