@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.
@@ -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` | Gender of the character |
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 \| large \| massive` | Relative frame size |
3518
- | `appearance.eye_color` | `string` | Eye color |
3519
- | `appearance.hair_color` | `string` | Hair color |
3520
- | `appearance.skin_color` | `string` | Skin color |
3521
- | `appearance.complexion` | `string` | Complexion |
3522
- | `appearance.extra_features` | `string[]` | Extra features |
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 | Values | Description |
4552
- | ------------------ | --------- | ------------------------------------------ |
4553
- | `templatePriority` | `number` | Template priority, _null_ = not a template |
4554
- | `masteryLevel` | `number` | HM3 mastery level |
4555
- | `parentSkill` | `Address` | Parent skill this skill specializes |
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 | Values | Description |
4719
- | -------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
4720
- | `epoch` | canonical `<year>.<day>` | The canonical day that equals calendar year 1, day 1 |
4721
- | `months` | `{ name, abbreviation?, days }[]` | Ordered months; their days sum to the world's year |
4722
- | `months[].name` | `string`, required | The month's name |
4723
- | `months[].abbreviation` | `string` | Its short form, for a compact date |
4724
- | `months[].days` | `integer`, required | How many days the month holds |
4725
- | `weekdays` | `{ name, abbreviation? }[]` | Ordered week days, indexed from zero; weeks run continuously |
4726
- | `weekdays[].name` | `string`, required | The day's name |
4727
- | `weekdays[].abbreviation` | `string` | Its short form, for a compact date |
4728
- | `seasons` | `{ name, abbreviation?, start }[]` | Seasons starting on one-based days of year |
4729
- | `seasons[].name` | `string`, required | The season's name |
4730
- | `seasons[].abbreviation` | `string` | Its short form, for a compact date |
4731
- | `seasons[].start` | `integer`, required | The one-based day of the year it begins; starts increase down the list |
4732
- | `namedDays` | `{ name, abbreviation?, day }[]` | Names assigned to one-based days of year |
4733
- | `namedDays[].name` | `string`, required | The day's name |
4734
- | `namedDays[].abbreviation` | `string` | Its short form, for a compact date |
4735
- | `namedDays[].day` | `integer`, required | The one-based day of the year it names, distinct within the calendar |
4736
- | `eras` | `{ shortcode, name, abbreviation?, marker?, proclaimedBy?, start, label? }[]` | Year counts; `start` is `null` or an in-calendar year |
4737
- | `eras[].shortcode` | `string`, required | The era's own segment of `<calendar>.<era>`, unique within the calendar |
4738
- | `eras[].name` | `string`, required | The era's name |
4739
- | `eras[].marker` | `string` | Uppercase letters and digits, beginning with a letter, unique across the corpus; an authored date names the era by it |
4740
- | `eras[].abbreviation` | `string` | Its short form, for a compact date |
4741
- | `eras[].proclaimedBy` | `Address` | The body that began the reckoning |
4742
- | `eras[].start` | `null` or `integer`, required | The calendar year the era begins; `null` for the era before year 1 |
4743
- | `eras[].label` | `string` or `{ after?, before? }` | How a date in the era reads, around one `{date}` slot; a string is `after` |
4744
- | `eras[].label.after` | `string` | How a date from the era's start reads, with exactly one `{date}` |
4745
- | `eras[].label.before` | `string` | How a date before the era's start reads, with exactly one `{date}` |
4746
- | `formats` | map of names to Calendaria patterns | Named date formats; `std` is the preferred default |
4747
- | `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 |
4748
- | `form` | `string` | `literature` only: the kind of work in its people's own terms — `epic`, `saga`, `praise-song`, `elegy`. Free text |
4749
- | `subjects` | `Address[]` | `literature` only: the beings, places, gods and other notes the work concerns, and any event, as `note#id` |
4750
- | `language` | `Address` | `literature` only: the tongue it is composed in, naming a skill note with `subType: language` |
4751
- | `events` | event entries — see [Events](#events) | What happened to or at this subject: dated, attributed 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.