@heroiclands/package-build 23.2.2 → 23.3.1
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.
- package/CHANGELOG.md +29 -0
- package/bin/content-commands.mjs +293 -2
- package/ci/content-format-reference.mjs +28 -5
- package/docs/api.md +37 -23
- package/docs/authoring/frontmatter.md +2 -0
- package/docs/commands.md +183 -0
- package/docs/content-format.md +6 -0
- package/docs/guides/e2e.md +8 -1
- package/docs/reference/format-details.md +471 -46
- package/docs/reference/note-types.md +124 -107
- package/e2e.mjs +37 -10
- package/engine/appearance-profile.mjs +330 -0
- package/engine/content-format.yaml +8 -0
- package/engine/data-keys.mjs +26 -6
- package/engine/index.mjs +3 -0
- package/engine/infobox.mjs +1 -1
- package/engine/language-names.mjs +634 -0
- package/engine/literature-notes.mjs +62 -27
- package/engine/note-vocabulary.mjs +370 -19
- package/engine/npc-generate.mjs +633 -0
- package/engine/settlement-tables.mjs +777 -0
- package/package.json +1 -1
- package/types/e2e.d.mts +5 -1
- package/types/engine/appearance-profile.d.mts +94 -0
- package/types/engine/data-keys.d.mts +2 -2
- package/types/engine/index.d.mts +1 -0
- package/types/engine/infobox.d.mts +1 -1
- package/types/engine/language-names.d.mts +140 -0
- package/types/engine/literature-notes.d.mts +14 -3
- package/types/engine/note-vocabulary.d.mts +31 -0
- package/types/engine/npc-generate.d.mts +124 -0
- package/types/engine/settlement-tables.d.mts +164 -0
|
@@ -3505,7 +3505,7 @@ See [a being's subtype describes the subject](#a-beings-subtype-describes-the-su
|
|
|
3505
3505
|
| `affiliations.<Address>.office` | `string` | A post that body names in its `governance.offices`, where the being holds one |
|
|
3506
3506
|
| `affiliations.<Address>.societies` | `string[]` | The societies the membership is held in, by name; SoHL carries the first as `system.society` |
|
|
3507
3507
|
| `socialTies` | `Map<Address, Tie>` | Defining support and opposition, directed from this being to others |
|
|
3508
|
-
| `gender` | `male \| female \| other`
|
|
3508
|
+
| `gender` | `male \| female \| nonbinary \| none \| other` | Gender of the being — see [a being's look](#a-beings-look) |
|
|
3509
3509
|
| `species` | `Address` | Being's species (lore) |
|
|
3510
3510
|
| `born` | `date \| unknown` | When the being was born; absent, it was never born |
|
|
3511
3511
|
| `calendar` | `Address` | Calendar note that prints the being's dates |
|
|
@@ -3514,12 +3514,12 @@ See [a being's subtype describes the subject](#a-beings-subtype-describes-the-su
|
|
|
3514
3514
|
| `ageYears` | `number` | Written by the compiler beside an `age` estimate — the `~` stripped; a note never authors this |
|
|
3515
3515
|
| `height` | `1.91m \| 6' 3"` | Height in metres or feet and inches |
|
|
3516
3516
|
| `weight` | `85kg \| 187 lbs` | Body weight in kilograms or pounds |
|
|
3517
|
-
| `frame` | `scant \| light \| medium \|
|
|
3518
|
-
| `appearance.eye_color` |
|
|
3519
|
-
| `appearance.hair_color` |
|
|
3520
|
-
| `appearance.skin_color` |
|
|
3521
|
-
| `appearance.complexion` | `
|
|
3522
|
-
| `appearance.extra_features` | `string[]` |
|
|
3517
|
+
| `frame` | `scant \| light \| medium \| heavy \| massive` | Relative frame — see [a being's look](#a-beings-look) |
|
|
3518
|
+
| `appearance.eye_color` | a word | Eye colour — see [a being's look](#a-beings-look) |
|
|
3519
|
+
| `appearance.hair_color` | a word | Hair colour — see [a being's look](#a-beings-look) |
|
|
3520
|
+
| `appearance.skin_color` | a word | Skin colour — see [a being's look](#a-beings-look) |
|
|
3521
|
+
| `appearance.complexion` | `word \| word[]` | The skin's condition, one word or several — see [a being's look](#a-beings-look) |
|
|
3522
|
+
| `appearance.extra_features` | `string[]` | Anything else a stranger would notice, in free text |
|
|
3523
3523
|
|
|
3524
3524
|
Author `data.height` as a string of decimal metres (`1.91m` or `1.91 m`) or
|
|
3525
3525
|
whole feet with optional inches (`6'`, `6'3"`, or `6' 3"`). Inches must be
|
|
@@ -3543,6 +3543,300 @@ data:
|
|
|
3543
3543
|
lore: [lore-marchlaw]
|
|
3544
3544
|
```
|
|
3545
3545
|
|
|
3546
|
+
#### A being's look
|
|
3547
|
+
|
|
3548
|
+
**A being's gender, frame and appearance are stated in words from one closed
|
|
3549
|
+
vocabulary**, so every package describes a face in the same terms and a
|
|
3550
|
+
misspelt or invented word is caught. `data.gender`, `data.frame`,
|
|
3551
|
+
`data.appearance.eye_color`, `data.appearance.hair_color` and
|
|
3552
|
+
`data.appearance.skin_color` each take one word from their own list.
|
|
3553
|
+
`data.appearance.complexion` takes one word or a list of them, since a face
|
|
3554
|
+
carries more than one condition at once; a single word means a list of one.
|
|
3555
|
+
Any other value — a word from another field's list, a variant spelling such as
|
|
3556
|
+
`gray` for `grey`, or an empty string — is an error at the value, naming the
|
|
3557
|
+
words the field takes. Leave a field out when the fact is unrecorded.
|
|
3558
|
+
|
|
3559
|
+
`data.appearance.extra_features` is not closed. It is a list of free-text
|
|
3560
|
+
marks — a scar and where it came from, a missing finger, a limp — for what no
|
|
3561
|
+
word in the vocabulary covers.
|
|
3562
|
+
|
|
3563
|
+
```yaml
|
|
3564
|
+
data:
|
|
3565
|
+
gender: female
|
|
3566
|
+
frame: light
|
|
3567
|
+
appearance:
|
|
3568
|
+
eye_color: dark_brown
|
|
3569
|
+
hair_color: greying_black
|
|
3570
|
+
skin_color: olive
|
|
3571
|
+
complexion: [weathered, freckled]
|
|
3572
|
+
extra_features:
|
|
3573
|
+
- a burn scar across the back of the left hand
|
|
3574
|
+
```
|
|
3575
|
+
|
|
3576
|
+
The words, and what each means:
|
|
3577
|
+
|
|
3578
|
+
<!-- being-look:start -->
|
|
3579
|
+
|
|
3580
|
+
**`data.gender`**
|
|
3581
|
+
|
|
3582
|
+
| Word | Label | Meaning |
|
|
3583
|
+
| ----------- | --------- | ------------------------------------------------------------------ |
|
|
3584
|
+
| `female` | Female | Female. |
|
|
3585
|
+
| `male` | Male | Male. |
|
|
3586
|
+
| `nonbinary` | Nonbinary | Neither male nor female. |
|
|
3587
|
+
| `none` | None | The being has no gender, as against one that is simply unrecorded. |
|
|
3588
|
+
| `other` | Other | A gender none of these words fits. |
|
|
3589
|
+
|
|
3590
|
+
**`data.frame`**
|
|
3591
|
+
|
|
3592
|
+
| Word | Label | Meaning |
|
|
3593
|
+
| --------- | ------- | --------------------------------------------- |
|
|
3594
|
+
| `scant` | Scant | Very thin, with little flesh over the bone. |
|
|
3595
|
+
| `light` | Light | Slender, narrow through shoulder and hip. |
|
|
3596
|
+
| `medium` | Medium | The ordinary build, neither slight nor heavy. |
|
|
3597
|
+
| `heavy` | Heavy | Broad and solid, in muscle or in flesh. |
|
|
3598
|
+
| `massive` | Massive | Exceptionally large in frame. |
|
|
3599
|
+
|
|
3600
|
+
**`data.appearance.eye_color`**
|
|
3601
|
+
|
|
3602
|
+
| Word | Label | Meaning |
|
|
3603
|
+
| ------------ | ---------- | ---------------------------------------------------------------------------------- |
|
|
3604
|
+
| `amber` | Amber | Golden or coppery, with no grey or green in it; the honey-toned eye. |
|
|
3605
|
+
| `black` | Black | An iris that cannot be told from the pupil in any light, darker than `dark_brown`. |
|
|
3606
|
+
| `blue` | Blue | Unmixed blue, from pale ice to deep sea. |
|
|
3607
|
+
| `brown` | Brown | Mid-brown, the iris pattern still legible in ordinary light. |
|
|
3608
|
+
| `dark_brown` | Dark Brown | Brown so deep the iris barely separates from the pupil. |
|
|
3609
|
+
| `grey` | Grey | Grey or grey-blue, cool and without green. |
|
|
3610
|
+
| `green` | Green | Green dominant, with no brown ring worth naming. |
|
|
3611
|
+
| `hazel` | Hazel | Brown and green together, often shifting with the light; the commonest mixed eye. |
|
|
3612
|
+
| `violet` | Violet | The pink-violet of an iris carrying no pigment. |
|
|
3613
|
+
|
|
3614
|
+
**`data.appearance.hair_color`**
|
|
3615
|
+
|
|
3616
|
+
| Word | Label | Meaning |
|
|
3617
|
+
| ------------------ | ---------------- | ------------------------------------------------------------------------- |
|
|
3618
|
+
| `auburn` | Auburn | Red-brown with the red dominant. |
|
|
3619
|
+
| `black` | Black | True black, with no brown cast in sunlight. |
|
|
3620
|
+
| `blonde` | Blonde | Light yellow, from near-white to wheat. |
|
|
3621
|
+
| `brown` | Brown | Mid-brown, neither dark nor reddish. |
|
|
3622
|
+
| `chestnut` | Chestnut | Mid-brown with a red cast, the brown dominant — between brown and auburn. |
|
|
3623
|
+
| `dark_blonde` | Dark Blonde | Blonde darkened towards light brown. |
|
|
3624
|
+
| `dark_brown` | Dark Brown | Brown approaching black, still brown in sunlight. |
|
|
3625
|
+
| `grey` | Grey | Grey throughout, with nothing of the original colour left to read. |
|
|
3626
|
+
| `greying_black` | Greying Black | Black still dominant, grey coming in. |
|
|
3627
|
+
| `greying_brown` | Greying Brown | Brown still dominant, grey coming in. |
|
|
3628
|
+
| `red` | Red | Ginger or copper, the red unmixed with brown. |
|
|
3629
|
+
| `silver` | Silver | Grey with a bright metallic sheen rather than a dull cast. |
|
|
3630
|
+
| `strawberry_blond` | Strawberry Blond | Pale red-gold: blonde with a red cast, lighter than red. |
|
|
3631
|
+
| `white` | White | Wholly white, whether from age or from carrying no pigment. |
|
|
3632
|
+
|
|
3633
|
+
**`data.appearance.skin_color`**
|
|
3634
|
+
|
|
3635
|
+
| Word | Label | Meaning |
|
|
3636
|
+
| ------------ | ---------- | ------------------------------------------------------------------------------------------- |
|
|
3637
|
+
| `pale` | Pale | The lightest skin, which burns rather than browns; also skin carrying no pigment. |
|
|
3638
|
+
| `fair` | Fair | Light with a pink cast, burning before it browns. |
|
|
3639
|
+
| `light` | Light | Light and neutral, browning without burning readily. |
|
|
3640
|
+
| `medium` | Medium | Neither light nor dark, with no strong cast either way. |
|
|
3641
|
+
| `olive` | Olive | Medium with a green-grey cast. |
|
|
3642
|
+
| `tawny` | Tawny | Light brown, warm rather than olive. |
|
|
3643
|
+
| `golden` | Golden | Light to medium with a yellow cast. |
|
|
3644
|
+
| `tanned` | Tanned | Medium, darkened by sun rather than by birth. |
|
|
3645
|
+
| `swarthy` | Swarthy | Dark with an olive or sallow cast, between olive and brown. |
|
|
3646
|
+
| `brown` | Brown | Mid-brown. |
|
|
3647
|
+
| `dark` | Dark | Darker than brown with no particular cast; the general word where no finer shade is stated. |
|
|
3648
|
+
| `dark_brown` | Dark Brown | Deep brown. |
|
|
3649
|
+
| `ebony` | Ebony | The darkest skin, near-black. |
|
|
3650
|
+
|
|
3651
|
+
**`data.appearance.complexion`**
|
|
3652
|
+
|
|
3653
|
+
| Word | Label | Meaning |
|
|
3654
|
+
| ------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
3655
|
+
| `ashen` | Ashen | Grey and drained; the skin of serious illness, shock or terror. |
|
|
3656
|
+
| `blotchy` | Blotchy | Uneven in colour, patched red or pale. |
|
|
3657
|
+
| `chapped` | Chapped | Reddened and cracked by cold and wind. |
|
|
3658
|
+
| `clear` | Clear | Free of blemish, mark or broken vessel. |
|
|
3659
|
+
| `freckled` | Freckled | Freckled, in patches or across the whole face. |
|
|
3660
|
+
| `jaundiced` | Jaundiced | Yellowed, the colour a failing liver gives. |
|
|
3661
|
+
| `leathery` | Leathery | Thickened and toughened by years of exposure. |
|
|
3662
|
+
| `oily` | Oily | Carrying a greasy sheen. |
|
|
3663
|
+
| `pasty` | Pasty | Pale and doughy; the skin of indoor work and poor feeding. |
|
|
3664
|
+
| `pimpled` | Pimpled | Presently broken out, with pimples at brow, cheek or jaw. |
|
|
3665
|
+
| `pockmarked` | Pockmarked | Pitted by pox, or by deep pimples long since healed. |
|
|
3666
|
+
| `rough` | Rough | Coarse in texture, without the wear of outdoor work. |
|
|
3667
|
+
| `ruddy` | Ruddy | High colour at cheek and nose, from weather, drink or constitution. |
|
|
3668
|
+
| `sallow` | Sallow | Yellowish and bloodless. |
|
|
3669
|
+
| `scabrous` | Scabrous | Rough and scaling, the skin of a lasting complaint such as eczema. |
|
|
3670
|
+
| `scarred` | Scarred | Marked by healed wounds. `extra_features` says where and from what. |
|
|
3671
|
+
| `smooth` | Smooth | Even in texture, whatever marks it carries. |
|
|
3672
|
+
| `sun_kissed` | Sun-Kissed | Browned by sun on skin not naturally that dark. |
|
|
3673
|
+
| `sunburnt` | Sunburnt | Presently burned, red and peeling. |
|
|
3674
|
+
| `translucent` | Translucent | So pale the vessels show through. |
|
|
3675
|
+
| `vitiligo` | Vitiligo | Patched with white where the skin has lost its colour, most often at face, hands and mouth. The tone it has lost is still what `skin_color` states. |
|
|
3676
|
+
| `wan` | Wan | Pale and drained; the skin of exhaustion or convalescence. |
|
|
3677
|
+
| `weathered` | Weathered | Worn and lined by sun and wind; the skin of outdoor work. |
|
|
3678
|
+
| `wrinkled` | Wrinkled | Deeply lined by age. |
|
|
3679
|
+
|
|
3680
|
+
<!-- being-look:end -->
|
|
3681
|
+
|
|
3682
|
+
#### Appearance profiles
|
|
3683
|
+
|
|
3684
|
+
**A culture states what its people look like in `data.appearanceProfile`**, and
|
|
3685
|
+
`package-build npc new` draws a person of that culture from it — see
|
|
3686
|
+
[the command](../commands.md#package-build-npc-new). Only a `lore` note of
|
|
3687
|
+
`subType: culture` takes the key; on any other note it is an error at the key.
|
|
3688
|
+
|
|
3689
|
+
The profile has six keys, all required:
|
|
3690
|
+
|
|
3691
|
+
- `frame`, `eye_color`, `hair_color`, `skin_color` and `complexion` each map
|
|
3692
|
+
words of that field's [vocabulary](#a-beings-look) to positive weights. A
|
|
3693
|
+
word's chance of being drawn is its weight over the sum of the weights in its
|
|
3694
|
+
map; a word left out is never drawn.
|
|
3695
|
+
- `height` maps a `gender` word to a range, `{min, max}`, each a height in
|
|
3696
|
+
metres or feet and inches as `data.height` takes it. `female` and `male` are
|
|
3697
|
+
required. A gender with no range of its own draws from the span of every
|
|
3698
|
+
range the profile states.
|
|
3699
|
+
|
|
3700
|
+
Weight is not in the profile. It follows from the height and frame drawn: each
|
|
3701
|
+
frame word means a band of body-mass index, so a heavy frame always weighs more
|
|
3702
|
+
than a light one of the same height.
|
|
3703
|
+
|
|
3704
|
+
| Frame | Body-mass index (kg/m²) |
|
|
3705
|
+
| --------- | ----------------------- |
|
|
3706
|
+
| `scant` | 16.5 to 19 |
|
|
3707
|
+
| `light` | 19 to 21.5 |
|
|
3708
|
+
| `medium` | 21.5 to 24.5 |
|
|
3709
|
+
| `heavy` | 24.5 to 28 |
|
|
3710
|
+
| `massive` | 28 to 33 |
|
|
3711
|
+
|
|
3712
|
+
```yaml
|
|
3713
|
+
shortcode: khelathi
|
|
3714
|
+
name: { full: The Khelâthi }
|
|
3715
|
+
type: lore
|
|
3716
|
+
subType: culture
|
|
3717
|
+
data:
|
|
3718
|
+
appearanceProfile:
|
|
3719
|
+
frame: { light: 2, medium: 5, heavy: 2 }
|
|
3720
|
+
eye_color: { brown: 6, dark_brown: 3, hazel: 1 }
|
|
3721
|
+
hair_color: { black: 6, dark_brown: 3 }
|
|
3722
|
+
skin_color: { tawny: 5, olive: 3, brown: 2 }
|
|
3723
|
+
complexion: { clear: 3, weathered: 2, smooth: 2 }
|
|
3724
|
+
height:
|
|
3725
|
+
female:
|
|
3726
|
+
min: 4' 11"
|
|
3727
|
+
max: 5' 8"
|
|
3728
|
+
male:
|
|
3729
|
+
min: 5' 4"
|
|
3730
|
+
max: 6' 3"
|
|
3731
|
+
```
|
|
3732
|
+
|
|
3733
|
+
`package-build lint` checks the profile, with a finding at the word, weight or
|
|
3734
|
+
key at fault: a word outside its field's vocabulary or from another field's
|
|
3735
|
+
list, a weight that is not a positive number, a word map with no words, a
|
|
3736
|
+
missing key, a missing `female` or `male` range, a height that does not read,
|
|
3737
|
+
a range whose `min` is above its `max`, and a `height` key that is not a
|
|
3738
|
+
gender.
|
|
3739
|
+
|
|
3740
|
+
`package-build npc new` refuses a culture that states no profile, naming the
|
|
3741
|
+
culture note.
|
|
3742
|
+
|
|
3743
|
+
#### Name lists
|
|
3744
|
+
|
|
3745
|
+
**A language states how its speakers are named in `data.names`**, and
|
|
3746
|
+
`package-build npc new` draws a person's name from it, or checks a name it is
|
|
3747
|
+
given against it — see [the command](../commands.md#package-build-npc-new).
|
|
3748
|
+
Only a `skill` note of `subType: language` takes the key; on any other skill it
|
|
3749
|
+
is an error at the key. A culture reaches the lists through `data.language`,
|
|
3750
|
+
which names the language skill note its people speak, so cultures sharing a
|
|
3751
|
+
tongue share its lists.
|
|
3752
|
+
|
|
3753
|
+
The lists have two required keys, and any number of lists named by the
|
|
3754
|
+
language:
|
|
3755
|
+
|
|
3756
|
+
- `pattern` is the name's shape: placeholders such as `{given}` and `{clan}`,
|
|
3757
|
+
each naming a list, with the text around them written as it stands. Text may
|
|
3758
|
+
sit directly against a placeholder, as `sen` does in `"{given.male}sen"`.
|
|
3759
|
+
`"{given} {clan}"` puts the given name first, `"{family} {given}"` puts the
|
|
3760
|
+
family name first, and `"{given} yra {clan}"` joins the two with a particle.
|
|
3761
|
+
A pattern takes one of three forms:
|
|
3762
|
+
- **one pattern**, which every name takes;
|
|
3763
|
+
- **a list of patterns**, for a tongue whose people are named in several
|
|
3764
|
+
forms — by standing, by place, or by given name alone. A name may take any
|
|
3765
|
+
of them, and a drawn name takes one of them;
|
|
3766
|
+
- **a map of `gender` words** to a pattern or a list of them, for a tongue
|
|
3767
|
+
whose forms differ by gender. A gender with no pattern of its own takes
|
|
3768
|
+
every pattern stated.
|
|
3769
|
+
- `given` maps a `gender` word to a list of given names. `female` and `male`
|
|
3770
|
+
are required. `{given}` draws from the list for the person's gender, or from
|
|
3771
|
+
every given list together where that gender has none. `{given.<gender>}`
|
|
3772
|
+
draws from that gender's list whatever the person's gender, as a patronymic
|
|
3773
|
+
draws a father's name.
|
|
3774
|
+
- Every other key is a list of names that the placeholder of the same name
|
|
3775
|
+
draws from. A list name is letters, digits and underscores, beginning with a
|
|
3776
|
+
letter.
|
|
3777
|
+
|
|
3778
|
+
Each placeholder draws one name from its list, each name as likely as any
|
|
3779
|
+
other, and a drawn name takes one of its gender's patterns, each as likely as
|
|
3780
|
+
any other.
|
|
3781
|
+
|
|
3782
|
+
A tongue whose people are named by standing states each form in a list:
|
|
3783
|
+
|
|
3784
|
+
```yaml
|
|
3785
|
+
shortcode: khelathilng
|
|
3786
|
+
name: { full: Khelâthi Language }
|
|
3787
|
+
type: skill
|
|
3788
|
+
subType: language
|
|
3789
|
+
data:
|
|
3790
|
+
names:
|
|
3791
|
+
pattern: ["{given} {house}", "{given} ez {place}", "{given}"]
|
|
3792
|
+
given:
|
|
3793
|
+
female: [Rethutê, Agosi, Ahmuzê]
|
|
3794
|
+
male: [Aguri, Khelemûr, Gezebari]
|
|
3795
|
+
house: [Reth'el'Lêru, Uqa'el'Lêru]
|
|
3796
|
+
place: [Zileti, Iqu, Lut-Psaqa]
|
|
3797
|
+
```
|
|
3798
|
+
|
|
3799
|
+
A Khelâthi culture names its tongue with `language: skill-khelathilng`. A
|
|
3800
|
+
person drawn from these lists is called something like _Rethutê Reth'el'Lêru_,
|
|
3801
|
+
_Khelemûr ez Iqu_ or _Ahmuzê_, and a name an author gives in any of the three
|
|
3802
|
+
forms fits. A name fits when it takes one of the gender's patterns with every
|
|
3803
|
+
placeholder filled by a name of its list, the given name from the list for the
|
|
3804
|
+
person's gender: _Agosi ez Zileti_ fits a woman and not a man, and _Aguri ez
|
|
3805
|
+
Lut_ fits nobody, because _Lut_ is not in `place`. Names compare in Unicode
|
|
3806
|
+
NFC, so a precomposed and a decomposed accent are the same letter.
|
|
3807
|
+
|
|
3808
|
+
A tongue whose people carry a parent's name, with an ending that depends on
|
|
3809
|
+
their own gender, keys its patterns by gender:
|
|
3810
|
+
|
|
3811
|
+
```yaml
|
|
3812
|
+
shortcode: northlng
|
|
3813
|
+
name: { full: Northern Language }
|
|
3814
|
+
type: skill
|
|
3815
|
+
subType: language
|
|
3816
|
+
data:
|
|
3817
|
+
names:
|
|
3818
|
+
pattern:
|
|
3819
|
+
male: "{given} {given.male}sen"
|
|
3820
|
+
female: "{given} {given.male}dóttir"
|
|
3821
|
+
given:
|
|
3822
|
+
female: [Sigrid, Astrid, Ragna]
|
|
3823
|
+
male: [Ulf, Harald, Torvald]
|
|
3824
|
+
```
|
|
3825
|
+
|
|
3826
|
+
A man drawn from these lists is called something like _Ulf Torvaldsen_ and a
|
|
3827
|
+
woman _Astrid Ulfdóttir_: the second name is a man's given name either way,
|
|
3828
|
+
with the ending the pattern for the person's gender gives it. _Ulf
|
|
3829
|
+
Haralddóttir_ does not fit a man, because it has the form of the women's
|
|
3830
|
+
pattern.
|
|
3831
|
+
|
|
3832
|
+
`package-build lint` checks the lists, with a finding at the pattern, list,
|
|
3833
|
+
name or key at fault: a pattern with an unmatched brace or no placeholder, a
|
|
3834
|
+
placeholder that names no list, a `{given.<gender>}` whose gender has no given
|
|
3835
|
+
list, a dotted placeholder on a list other than `given`, a list that no pattern
|
|
3836
|
+
names, a list name a placeholder cannot spell, an empty list of patterns or of
|
|
3837
|
+
names, an empty name, a missing `pattern` or `given`, a missing `female` or
|
|
3838
|
+
`male` list, and a `pattern` or `given` key that is not a gender.
|
|
3839
|
+
|
|
3546
3840
|
#### The bodies a being belongs to, and its standing in each
|
|
3547
3841
|
|
|
3548
3842
|
**Membership**: `{rank: number, office: string, societies: string[]}` — `rank`
|
|
@@ -4548,11 +4842,16 @@ SoHL sets `system.quantity` to `1` for each compendium item.
|
|
|
4548
4842
|
- combat
|
|
4549
4843
|
- combattechnique
|
|
4550
4844
|
|
|
4551
|
-
| `data` property
|
|
4552
|
-
|
|
|
4553
|
-
| `templatePriority`
|
|
4554
|
-
| `masteryLevel`
|
|
4555
|
-
| `parentSkill`
|
|
4845
|
+
| `data` property | Values | Description |
|
|
4846
|
+
| -------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
4847
|
+
| `templatePriority` | `number` | Template priority, _null_ = not a template |
|
|
4848
|
+
| `masteryLevel` | `number` | HM3 mastery level |
|
|
4849
|
+
| `parentSkill` | `Address` | Parent skill this skill specializes |
|
|
4850
|
+
| `names` | `{ pattern, given, <name>... }` | `language` only: how its speakers are named, for `package-build npc new` — see [name lists](#name-lists) |
|
|
4851
|
+
| `names.pattern` | `string`, `string[]` or map of `gender` words to either, required | Placeholders such as `{given}`, `{given.male}` and `{clan}`, each naming a list, with literal text around them; a list states several forms, a map each gender's forms |
|
|
4852
|
+
| `names.given` | map of `gender` words to lists of names, required | Given names by gender; `female` and `male` are required |
|
|
4853
|
+
| `names.given.<name>` | `string[]` | The given names of one gender |
|
|
4854
|
+
| `names.<name>` | `string[]` | A list the placeholder of the same name draws from |
|
|
4556
4855
|
|
|
4557
4856
|
if a `sohl` property is present, a SoHL item of type "skill" is created.
|
|
4558
4857
|
|
|
@@ -4715,40 +5014,49 @@ naming any other note is an error at the value. A `lore` note that states no cul
|
|
|
4715
5014
|
none, since a `lore` note has no `data.parents` to inherit through; a culture note reads as
|
|
4716
5015
|
its own Address in the index. See [Culture in the index](#culture-in-the-index).
|
|
4717
5016
|
|
|
4718
|
-
| `data` property
|
|
4719
|
-
|
|
|
4720
|
-
| `epoch`
|
|
4721
|
-
| `months`
|
|
4722
|
-
| `months[].name`
|
|
4723
|
-
| `months[].abbreviation`
|
|
4724
|
-
| `months[].days`
|
|
4725
|
-
| `weekdays`
|
|
4726
|
-
| `weekdays[].name`
|
|
4727
|
-
| `weekdays[].abbreviation`
|
|
4728
|
-
| `seasons`
|
|
4729
|
-
| `seasons[].name`
|
|
4730
|
-
| `seasons[].abbreviation`
|
|
4731
|
-
| `seasons[].start`
|
|
4732
|
-
| `namedDays`
|
|
4733
|
-
| `namedDays[].name`
|
|
4734
|
-
| `namedDays[].abbreviation`
|
|
4735
|
-
| `namedDays[].day`
|
|
4736
|
-
| `eras`
|
|
4737
|
-
| `eras[].shortcode`
|
|
4738
|
-
| `eras[].name`
|
|
4739
|
-
| `eras[].marker`
|
|
4740
|
-
| `eras[].abbreviation`
|
|
4741
|
-
| `eras[].proclaimedBy`
|
|
4742
|
-
| `eras[].start`
|
|
4743
|
-
| `eras[].label`
|
|
4744
|
-
| `eras[].label.after`
|
|
4745
|
-
| `eras[].label.before`
|
|
4746
|
-
| `formats`
|
|
4747
|
-
| `culture`
|
|
4748
|
-
| `form`
|
|
4749
|
-
| `subjects`
|
|
4750
|
-
| `language`
|
|
4751
|
-
| `events`
|
|
5017
|
+
| `data` property | Values | Description |
|
|
5018
|
+
| ------------------------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
5019
|
+
| `epoch` | canonical `<year>.<day>` | The canonical day that equals calendar year 1, day 1 |
|
|
5020
|
+
| `months` | `{ name, abbreviation?, days }[]` | Ordered months; their days sum to the world's year |
|
|
5021
|
+
| `months[].name` | `string`, required | The month's name |
|
|
5022
|
+
| `months[].abbreviation` | `string` | Its short form, for a compact date |
|
|
5023
|
+
| `months[].days` | `integer`, required | How many days the month holds |
|
|
5024
|
+
| `weekdays` | `{ name, abbreviation? }[]` | Ordered week days, indexed from zero; weeks run continuously |
|
|
5025
|
+
| `weekdays[].name` | `string`, required | The day's name |
|
|
5026
|
+
| `weekdays[].abbreviation` | `string` | Its short form, for a compact date |
|
|
5027
|
+
| `seasons` | `{ name, abbreviation?, start }[]` | Seasons starting on one-based days of year |
|
|
5028
|
+
| `seasons[].name` | `string`, required | The season's name |
|
|
5029
|
+
| `seasons[].abbreviation` | `string` | Its short form, for a compact date |
|
|
5030
|
+
| `seasons[].start` | `integer`, required | The one-based day of the year it begins; starts increase down the list |
|
|
5031
|
+
| `namedDays` | `{ name, abbreviation?, day }[]` | Names assigned to one-based days of year |
|
|
5032
|
+
| `namedDays[].name` | `string`, required | The day's name |
|
|
5033
|
+
| `namedDays[].abbreviation` | `string` | Its short form, for a compact date |
|
|
5034
|
+
| `namedDays[].day` | `integer`, required | The one-based day of the year it names, distinct within the calendar |
|
|
5035
|
+
| `eras` | `{ shortcode, name, abbreviation?, marker?, proclaimedBy?, start, label? }[]` | Year counts; `start` is `null` or an in-calendar year |
|
|
5036
|
+
| `eras[].shortcode` | `string`, required | The era's own segment of `<calendar>.<era>`, unique within the calendar |
|
|
5037
|
+
| `eras[].name` | `string`, required | The era's name |
|
|
5038
|
+
| `eras[].marker` | `string` | Uppercase letters and digits, beginning with a letter, unique across the corpus; an authored date names the era by it |
|
|
5039
|
+
| `eras[].abbreviation` | `string` | Its short form, for a compact date |
|
|
5040
|
+
| `eras[].proclaimedBy` | `Address` | The body that began the reckoning |
|
|
5041
|
+
| `eras[].start` | `null` or `integer`, required | The calendar year the era begins; `null` for the era before year 1 |
|
|
5042
|
+
| `eras[].label` | `string` or `{ after?, before? }` | How a date in the era reads, around one `{date}` slot; a string is `after` |
|
|
5043
|
+
| `eras[].label.after` | `string` | How a date from the era's start reads, with exactly one `{date}` |
|
|
5044
|
+
| `eras[].label.before` | `string` | How a date before the era's start reads, with exactly one `{date}` |
|
|
5045
|
+
| `formats` | map of names to Calendaria patterns | Named date formats; `std` is the preferred default |
|
|
5046
|
+
| `culture` | `Address` | The people this lore belongs to — for a `literature` note, the people whose work it is — naming a lore note with `subType: culture`; not on a `culture` note |
|
|
5047
|
+
| `form` | `string` | `literature` only: the kind of work in its people's own terms — `epic`, `saga`, `praise-song`, `elegy`. Free text |
|
|
5048
|
+
| `subjects` | `Address[]` | `literature` only: the beings, places, gods and other notes the work concerns, and any event, as `note#id` |
|
|
5049
|
+
| `language` | `Address` | `literature` and `culture` only: the tongue a work is composed in, or a culture's people speak, naming a skill note with `subType: language`; `package-build npc new` draws a culture's names from that language's [name lists](#name-lists) |
|
|
5050
|
+
| `events` | event entries — see [Events](#events) | What happened to or at this subject: dated, attributed events |
|
|
5051
|
+
| `appearanceProfile` | `{ frame, eye_color, hair_color, skin_color, complexion, height }` | `culture` only: what its people look like, for `package-build npc new` — see [appearance profiles](#appearance-profiles) |
|
|
5052
|
+
| `appearanceProfile.frame` | map of `frame` words to positive weights, required | How often each frame is drawn |
|
|
5053
|
+
| `appearanceProfile.eye_color` | map of `eye_color` words to positive weights, required | How often each eye colour is drawn |
|
|
5054
|
+
| `appearanceProfile.hair_color` | map of `hair_color` words to positive weights, required | How often each hair colour is drawn |
|
|
5055
|
+
| `appearanceProfile.skin_color` | map of `skin_color` words to positive weights, required | How often each skin colour is drawn |
|
|
5056
|
+
| `appearanceProfile.complexion` | map of `complexion` words to positive weights, required | How often each complexion is drawn |
|
|
5057
|
+
| `appearanceProfile.height` | map of `gender` words to `{ min, max }`, required | Height ranges by gender; `female` and `male` are required |
|
|
5058
|
+
| `appearanceProfile.height.<name>.min` | height in metres or feet and inches, required | The shortest height drawn for that gender |
|
|
5059
|
+
| `appearanceProfile.height.<name>.max` | height in metres or feet and inches, required | The tallest height drawn for that gender |
|
|
4752
5060
|
|
|
4753
5061
|
`data.events` is available on every `lore` subType, and is described in full under [Events](#events).
|
|
4754
5062
|
|
|
@@ -5294,6 +5602,123 @@ The place's `lore` links cover its peoples, calendar, law and history. Political
|
|
|
5294
5602
|
languages belong to a polity's `sohl.system.commonSkills`, while the note's
|
|
5295
5603
|
`description` provides its page summary.
|
|
5296
5604
|
|
|
5605
|
+
#### A region's settlements table
|
|
5606
|
+
|
|
5607
|
+
A region lists its settlements in a table on its own note: one row for each
|
|
5608
|
+
settlement, stating what its market is, how many people it holds and who holds
|
|
5609
|
+
it. **A row is the whole record of a settlement that has no note.** Where a
|
|
5610
|
+
note exists the row links it, and the two must agree. A package that writes no
|
|
5611
|
+
such table is not affected by anything in this section.
|
|
5612
|
+
|
|
5613
|
+
The table is a markdown table under a level-two `## Settlements` heading on the
|
|
5614
|
+
region's `place` note. Its header is exactly these columns, in this order. `For`
|
|
5615
|
+
may be left out; the header carries no other column:
|
|
5616
|
+
|
|
5617
|
+
| Name | Market | People | Held by | For |
|
|
5618
|
+
| ---- | ------ | ------ | ------- | --- |
|
|
5619
|
+
|
|
5620
|
+
- **Name** — the settlement. Where it has a note, a link to it with the pipe
|
|
5621
|
+
escaped for the table, `[[place-ashford\|Ashford]]`; otherwise plain text.
|
|
5622
|
+
- **Market** — the market class as its number and its name, lower case:
|
|
5623
|
+
`1 hamlet`, `2 village`, `3 town`, `4 market town`, `5 city`, `6 great city`.
|
|
5624
|
+
The scale is the one [`data.market`](#what-a-settlements-market-supports)
|
|
5625
|
+
states.
|
|
5626
|
+
- **People** — the population, a whole number, grouped with commas or not:
|
|
5627
|
+
`60`, `420`, `3,400`.
|
|
5628
|
+
- **Held by** — who holds it, written in the region's holding model. Link the
|
|
5629
|
+
holder where it has a note.
|
|
5630
|
+
- **For** — a short phrase saying why the place is there: the ford, the mine,
|
|
5631
|
+
the shrine.
|
|
5632
|
+
|
|
5633
|
+
At least one sentence of prose follows the table, before the next heading,
|
|
5634
|
+
saying what the table leaves out. A section filled by an `sql` fence is
|
|
5635
|
+
generated from the notes and is not read as a settlements table.
|
|
5636
|
+
|
|
5637
|
+
**The region names its holding model as a tag.** A note carrying a settlements
|
|
5638
|
+
table carries at least one of these tags; a region whose countryside is held
|
|
5639
|
+
two ways carries both. Tags stay open, so a misspelled model is not reported as
|
|
5640
|
+
such: the table's note is reported for naming no model.
|
|
5641
|
+
|
|
5642
|
+
| `holdingModel` value | the Held by cell names |
|
|
5643
|
+
| -------------------- | ---------------------- |
|
|
5644
|
+
| `held` | a person or a house |
|
|
5645
|
+
| `endowed` | an institution |
|
|
5646
|
+
| `registered` | an office |
|
|
5647
|
+
| `kin` | a kindred |
|
|
5648
|
+
| `polis` | the city |
|
|
5649
|
+
|
|
5650
|
+
A linked holder is an `affiliation` or a `being`, and a `being` is a person: it
|
|
5651
|
+
may hold land only in a region tagged `held`.
|
|
5652
|
+
|
|
5653
|
+
**A settlement belongs to one table** — that of the nearest place above it, by
|
|
5654
|
+
`parents`, that carries a settlements table. Every `settlement` note that table
|
|
5655
|
+
covers has a row there and nowhere else.
|
|
5656
|
+
|
|
5657
|
+
A worked example. `Vale.md`:
|
|
5658
|
+
|
|
5659
|
+
```markdown
|
|
5660
|
+
---
|
|
5661
|
+
shortcode: vale
|
|
5662
|
+
name: { full: The Vale }
|
|
5663
|
+
type: place
|
|
5664
|
+
subType: region
|
|
5665
|
+
tags: [region, held]
|
|
5666
|
+
data:
|
|
5667
|
+
population: 100000
|
|
5668
|
+
government: crown
|
|
5669
|
+
---
|
|
5670
|
+
|
|
5671
|
+
## Settlements
|
|
5672
|
+
|
|
5673
|
+
| Name | Market | People | Held by | For |
|
|
5674
|
+
| -------------------------- | ------------- | -----: | ---------------------------------------- | -------------------------- |
|
|
5675
|
+
| [[place-ashford\|Ashford]] | 4 market town | 3,400 | [[affiliation-crown\|the Crown]] | the ford on the drove road |
|
|
5676
|
+
| Weyshott | 2 village | 420 | [[being-aldwyn\|Sir Aldwyn of Brynwold]] | the manor's mill |
|
|
5677
|
+
| Cold Hatch | 1 hamlet | 60 | Sir Aldwyn of Brynwold | the sheepwalk |
|
|
5678
|
+
|
|
5679
|
+
Some four hundred further villages lie in the vale, none of them named here.
|
|
5680
|
+
```
|
|
5681
|
+
|
|
5682
|
+
`Ashford.md` states `parents: [vale]`, `population: 3400` and `market: 4`, so its
|
|
5683
|
+
row agrees with it. Weyshott and Cold Hatch have no notes; their rows are their
|
|
5684
|
+
whole record. Change Ashford's row to `3,000` and `package-build lint` reports:
|
|
5685
|
+
|
|
5686
|
+
```text
|
|
5687
|
+
assets/content/Vale.md:16:49: error: figure disagrees: Ashford is carried at 3,000 here and 3,400 on its own note
|
|
5688
|
+
```
|
|
5689
|
+
|
|
5690
|
+
`package-build lint` reports each of these as an error, each named by the
|
|
5691
|
+
phrase its message begins with:
|
|
5692
|
+
|
|
5693
|
+
- **`settlements columns`** — the header is not the declared columns in
|
|
5694
|
+
order. The table's rows are not read until it is.
|
|
5695
|
+
- **`no holding model`** — the note carries a settlements table and none of
|
|
5696
|
+
the holding-model tags. Reported at its `tags`.
|
|
5697
|
+
- **`market class`** — a Market cell is not a class written as its number and
|
|
5698
|
+
its name.
|
|
5699
|
+
- **`people figure`** — a People cell is not a positive whole number.
|
|
5700
|
+
- **`no holder`** — a Held by cell is empty.
|
|
5701
|
+
- **`not a holder`** — a Held by link names a note that is neither an
|
|
5702
|
+
affiliation nor a being.
|
|
5703
|
+
- **`holder out of model`** — a Held by link names a being in a region not
|
|
5704
|
+
tagged `held`.
|
|
5705
|
+
- **`not a settlement`** — a Name link names a note that is not a place.
|
|
5706
|
+
- **`figure disagrees`** — a linked row's People differs from its note's
|
|
5707
|
+
`data.population`, or the note states none.
|
|
5708
|
+
- **`market disagrees`** — a linked row's Market differs from its note's
|
|
5709
|
+
`data.market`, or the note states none.
|
|
5710
|
+
- **`unlinked settlement`** — an unlinked Name is the name or an alias of a
|
|
5711
|
+
settlement note the table covers. The finding gives the link to write.
|
|
5712
|
+
- **`missing row`** — a settlement note the table covers has no row. Reported
|
|
5713
|
+
at the table's header.
|
|
5714
|
+
- **`duplicate settlement`** — a settlement has a second row in one table, or
|
|
5715
|
+
a row in a table other than the one covering it.
|
|
5716
|
+
- **`no tail`** — no sentence follows the table before the next heading.
|
|
5717
|
+
Reported at the table's last row.
|
|
5718
|
+
|
|
5719
|
+
A cell's finding is located at the cell. A link in a cell that resolves to no
|
|
5720
|
+
note is reported by the link check, once, and not again here.
|
|
5721
|
+
|
|
5297
5722
|
### type: scenario
|
|
5298
5723
|
|
|
5299
5724
|
Content prepared to be played — a situation with its cast, places, and possible outcomes.
|