@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
package/docs/commands.md
CHANGED
|
@@ -2766,3 +2766,186 @@ $ package-build addresses diff --from build/dist/module.zip
|
|
|
2766
2766
|
|
|
2767
2767
|
`package-build package <action> [pack] [entry]`, `package-build deps fetch`,
|
|
2768
2768
|
[Diagnostics](diagnostics.md).
|
|
2769
|
+
|
|
2770
|
+
### `package-build npc new`
|
|
2771
|
+
|
|
2772
|
+
**NAME**
|
|
2773
|
+
|
|
2774
|
+
Write a new NPC being note from a spec, its look drawn from its culture's
|
|
2775
|
+
appearance profile and its name from its culture's language.
|
|
2776
|
+
|
|
2777
|
+
**SYNOPSIS**
|
|
2778
|
+
|
|
2779
|
+
```
|
|
2780
|
+
package-build npc new (--spec <json> | --specfile <path>) [--seed <text>] [--out <path>]
|
|
2781
|
+
```
|
|
2782
|
+
|
|
2783
|
+
**DESCRIPTION**
|
|
2784
|
+
|
|
2785
|
+
Writes one `type: being`, `subType: npc` note: the full `data` block, an
|
|
2786
|
+
`# Appearance {#appearance}` section and a `# Dossier {#dossier}` section, with
|
|
2787
|
+
no system block. The note goes to standard output, or to a new file with
|
|
2788
|
+
`--out`.
|
|
2789
|
+
|
|
2790
|
+
The spec is a possibly incomplete set of frontmatter fields, given as a JSON
|
|
2791
|
+
string with `--spec` or as a `.json`, `.yaml` or `.yml` file with
|
|
2792
|
+
`--specfile`; exactly one of the two is required. `data.culture` and
|
|
2793
|
+
`data.gender` are required in it. Every field the spec gives is written
|
|
2794
|
+
exactly as given, at every depth, and every field it leaves out is generated:
|
|
2795
|
+
|
|
2796
|
+
| Field | Generated value |
|
|
2797
|
+
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
2798
|
+
| `name.full` | Drawn from the culture's language's name lists by one of its patterns for `data.gender`, the given name from the list for that gender. |
|
|
2799
|
+
| `shortcode` | The name transliterated to lowercase letters and digits and cut to twelve characters; a counter replaces its tail where a being holds it. |
|
|
2800
|
+
| `type`, `subType`, `tags` | `being`, `npc`, `[generated, draft]`. |
|
|
2801
|
+
| `data.icon`, `data.species`, `data.packFolder` | The commonest value among the package's npcs of the same culture, else among all its npcs; left out where none states one. |
|
|
2802
|
+
| `data.archetypes` | `[commoner]`, the archetype of a person who fits no more specific one. |
|
|
2803
|
+
| `data.templatePriority`, `data.occupation`, `data.died` | `null`. |
|
|
2804
|
+
| `data.lore`, `data.homes` | `[]`. |
|
|
2805
|
+
| `data.affiliations` | `{}`. |
|
|
2806
|
+
| `data.born` | An adult age of 18 to 60 years before the package's present, as a `<year>.<day>` date; `unknown` where the package states no present. |
|
|
2807
|
+
| `data.frame`, `data.appearance.*` | Weighted draws from the culture's appearance profile; `extra_features` is `[]`. |
|
|
2808
|
+
| `data.height` | From the profile's range for the gender, in feet and inches. |
|
|
2809
|
+
| `data.weight` | From the height and the frame's body-mass band, in pounds. A spec giving height and weight but no frame gets the frame they imply. |
|
|
2810
|
+
|
|
2811
|
+
Generation is seeded from the spec itself, through a canonical serialisation
|
|
2812
|
+
that sorts every map's keys: the same spec always writes the same note, whether
|
|
2813
|
+
or not it states a name, and the order the spec writes its fields in changes
|
|
2814
|
+
nothing. `--seed` adds text to that seed, so the same spec with a different
|
|
2815
|
+
`--seed` writes a different person; two people drawn from a spec that states
|
|
2816
|
+
only the culture and the gender differ only by their seeds.
|
|
2817
|
+
|
|
2818
|
+
`data.culture` resolves as any culture reference does, through this package's
|
|
2819
|
+
content tree and its dependencies, and must name a `lore` note of
|
|
2820
|
+
`subType: culture`. The culture supplies two things, and the command refuses a
|
|
2821
|
+
culture missing either, with an error at the culture note:
|
|
2822
|
+
|
|
2823
|
+
- **Its look**, from `data.appearanceProfile`: the words and ranges every
|
|
2824
|
+
appearance field is drawn from. See
|
|
2825
|
+
[appearance profiles](reference/format-details.md#appearance-profiles).
|
|
2826
|
+
- **Its names**, from the language skill note its `data.language` names, whose
|
|
2827
|
+
`data.names` holds the pattern and the lists. A language with no
|
|
2828
|
+
`data.names` is an error at the language note. See
|
|
2829
|
+
[name lists](reference/format-details.md#name-lists).
|
|
2830
|
+
|
|
2831
|
+
A profile or name lists with problems are refused with a finding at each.
|
|
2832
|
+
|
|
2833
|
+
A spec that states `name.full` keeps it, and the name must fit the language's
|
|
2834
|
+
lists: one of the patterns for `data.gender`, with every placeholder filled by
|
|
2835
|
+
a name of its list, the given name from the list for `data.gender`. A name that does not fit is an
|
|
2836
|
+
error naming the part that fails and the language it was checked against; from
|
|
2837
|
+
a `--specfile`, the error is located at the name in the file. Where the
|
|
2838
|
+
gender has no given list of its own, the given name is drawn from, and
|
|
2839
|
+
checked against, every given list together.
|
|
2840
|
+
|
|
2841
|
+
Two top-level spec keys are section bodies rather than frontmatter.
|
|
2842
|
+
`appearance` is the Appearance section's markdown, written verbatim with its
|
|
2843
|
+
newlines and spacing; without it, the section is a paragraph written from the
|
|
2844
|
+
data. `dossier` is the Dossier section's markdown, likewise verbatim; without
|
|
2845
|
+
it, the section is its heading alone.
|
|
2846
|
+
|
|
2847
|
+
**OPTIONS**
|
|
2848
|
+
|
|
2849
|
+
| Positional | Type | Default | Description |
|
|
2850
|
+
| ---------- | -------------------- | ------- | ---------------------- |
|
|
2851
|
+
| `action` | string, one of `new` | — | The action to perform. |
|
|
2852
|
+
|
|
2853
|
+
| Option | Type | Default | Description |
|
|
2854
|
+
| ------------ | ------ | --------------- | -------------------------------------------------------------------------------- |
|
|
2855
|
+
| `--spec` | string | — | The spec as a JSON string. Exactly one of `--spec` and `--specfile` is required. |
|
|
2856
|
+
| `--specfile` | string | — | The spec as a `.json`, `.yaml` or `.yml` file. |
|
|
2857
|
+
| `--seed` | string | — | Text that seeds generation beside the spec, to draw a different person. |
|
|
2858
|
+
| `--out` | string | standard output | Write the note to this new file. An existing file is never overwritten. |
|
|
2859
|
+
|
|
2860
|
+
**EXIT STATUS**
|
|
2861
|
+
|
|
2862
|
+
1 if neither or both of `--spec` and `--specfile` are given, if the spec
|
|
2863
|
+
cannot be read or lacks `data.culture` or `data.gender`, if `data.culture`
|
|
2864
|
+
names no culture note, if the culture states no appearance profile or no
|
|
2865
|
+
language, if its language states no name lists, if the profile or the lists
|
|
2866
|
+
have problems, if the spec's `name.full` does not fit the lists, if the spec's
|
|
2867
|
+
`shortcode` already names a being, or if `--out` names a file that exists.
|
|
2868
|
+
Otherwise 0.
|
|
2869
|
+
|
|
2870
|
+
**EXAMPLES**
|
|
2871
|
+
|
|
2872
|
+
A spec, `spec.yaml`, stating the culture, the gender, two archetypes, an
|
|
2873
|
+
occupation and the dossier, and no name:
|
|
2874
|
+
|
|
2875
|
+
```yaml
|
|
2876
|
+
data:
|
|
2877
|
+
culture: khelathi
|
|
2878
|
+
gender: male
|
|
2879
|
+
archetypes: [warrior, mariner]
|
|
2880
|
+
occupation: River Fleet Officer
|
|
2881
|
+
dossier: |
|
|
2882
|
+
He holds a commission in the river fleet, and his service is a matter of
|
|
2883
|
+
record rather than of reputation.
|
|
2884
|
+
```
|
|
2885
|
+
|
|
2886
|
+
Run against a package whose world states `present: "720.300"`, whose
|
|
2887
|
+
`khelathi` culture carries the profile in
|
|
2888
|
+
[appearance profiles](reference/format-details.md#appearance-profiles) and
|
|
2889
|
+
names `language: skill-khelathilng`, and whose language carries the lists in
|
|
2890
|
+
[name lists](reference/format-details.md#name-lists):
|
|
2891
|
+
|
|
2892
|
+
```
|
|
2893
|
+
$ package-build npc new --specfile spec.yaml
|
|
2894
|
+
---
|
|
2895
|
+
shortcode: khelemureziq
|
|
2896
|
+
name: {full: Khelemûr ez Iqu}
|
|
2897
|
+
type: being
|
|
2898
|
+
subType: npc
|
|
2899
|
+
tags: [generated, draft]
|
|
2900
|
+
data:
|
|
2901
|
+
templatePriority: null
|
|
2902
|
+
archetypes: [warrior, mariner]
|
|
2903
|
+
occupation: River Fleet Officer
|
|
2904
|
+
lore: []
|
|
2905
|
+
culture: khelathi
|
|
2906
|
+
homes: []
|
|
2907
|
+
affiliations: {}
|
|
2908
|
+
gender: male
|
|
2909
|
+
born: "699.134"
|
|
2910
|
+
died: null
|
|
2911
|
+
height: 5' 11"
|
|
2912
|
+
weight: 167 lbs
|
|
2913
|
+
frame: medium
|
|
2914
|
+
appearance:
|
|
2915
|
+
eye_color: brown
|
|
2916
|
+
hair_color: black
|
|
2917
|
+
skin_color: brown
|
|
2918
|
+
complexion: clear
|
|
2919
|
+
extra_features: []
|
|
2920
|
+
---
|
|
2921
|
+
|
|
2922
|
+
# Appearance {#appearance}
|
|
2923
|
+
|
|
2924
|
+
Khelemûr ez Iqu is a 21-year-old man who stands 5'11" tall with a medium build. He has brown skin, clear complexion, black hair, and brown eyes.
|
|
2925
|
+
|
|
2926
|
+
# Dossier {#dossier}
|
|
2927
|
+
|
|
2928
|
+
He holds a commission in the river fleet, and his service is a matter of
|
|
2929
|
+
record rather than of reputation.
|
|
2930
|
+
```
|
|
2931
|
+
|
|
2932
|
+
A spec file, `bad.yaml`, stating a name whose second part is in no list:
|
|
2933
|
+
|
|
2934
|
+
```
|
|
2935
|
+
$ package-build npc new --specfile bad.yaml
|
|
2936
|
+
bad.yaml:2:9: error: name.full "Aguri ez Lut" does not fit the names of demo-note-skill-khelathilng: "Lut", the {place} part, is not in the place list
|
|
2937
|
+
```
|
|
2938
|
+
|
|
2939
|
+
A spec inline, for a culture that names no language:
|
|
2940
|
+
|
|
2941
|
+
```
|
|
2942
|
+
$ package-build npc new --spec '{"data":{"culture":"plainfolk","gender":"female"}}'
|
|
2943
|
+
assets/content/Cultures/Plainfolk.md:6:1: error: demo-note-lore-plainfolk states no `data.language`, so `npc new` has no name lists to draw from; name the language skill note its people speak
|
|
2944
|
+
```
|
|
2945
|
+
|
|
2946
|
+
**SEE ALSO**
|
|
2947
|
+
|
|
2948
|
+
`package-build lint [root]`,
|
|
2949
|
+
[Appearance profiles](reference/format-details.md#appearance-profiles),
|
|
2950
|
+
[Name lists](reference/format-details.md#name-lists),
|
|
2951
|
+
[A being's look](reference/format-details.md#a-beings-look).
|
package/docs/content-format.md
CHANGED
|
@@ -90,6 +90,12 @@ The [first-note guide](authoring/first-note.md) shows the build commands and how
|
|
|
90
90
|
|
|
91
91
|
Place notes may declare a governing affiliation with `data.government`, or explicit `null` for complete anarchy. Positive population with an omitted government produces an advisory. See [place governments](authoring/frontmatter.md#place-governments).
|
|
92
92
|
|
|
93
|
+
A region may list its settlements in a table under `## Settlements` — name, market, people and holder, one row each — tagged with the holding model it is written in. A row links the settlement's note where one exists, and `package-build lint` holds the two to agreement. See [a region's settlements table](reference/format-details.md#a-regions-settlements-table).
|
|
94
|
+
|
|
95
|
+
A being states its gender, frame and appearance in words from one closed vocabulary: `data.gender`, `data.frame`, and `data.appearance.eye_color`, `hair_color`, `skin_color` and `complexion` each take only the words listed for them, and any other value is an error at the value. `data.appearance.extra_features` stays free text. See [a being's look](reference/format-details.md#a-beings-look).
|
|
96
|
+
|
|
97
|
+
A culture note may state what its people look like in `data.appearanceProfile`: weighted words for frame, eyes, hair, skin and complexion, and height ranges by gender, all from the same vocabulary. A culture names its tongue in `data.language`, and that language skill note may state `data.names`: the patterns its speakers' names are built by and the lists each part is drawn from. `package-build npc new` writes a complete npc note from a spec of a culture and a gender, drawing the name from those lists and everything else the spec leaves out from the profile. See [appearance profiles](reference/format-details.md#appearance-profiles), [name lists](reference/format-details.md#name-lists) and [the command](commands.md#package-build-npc-new).
|
|
98
|
+
|
|
93
99
|
Places, affiliations, lore and beings may name their culture in `data.culture`, and a `doc` of `subType: settingguide` must. A place or affiliation that names none inherits the culture of its parents. See [culture in the index](reference/format-details.md#culture-in-the-index).
|
|
94
100
|
|
|
95
101
|
Blockquote alerts use `[!NOTE]`, `[!TIP]`, `[!IMPORTANT]`, `[!WARNING]`, or `[!]`, with optional attributes after the marker. They replace the former info and warn div fences; secret blocks remain supported. See [alerts](authoring/links-and-markup.md#alerts).
|
package/docs/guides/e2e.md
CHANGED
|
@@ -91,7 +91,14 @@ image made for that build. The first run downloads the release, which needs
|
|
|
91
91
|
`FOUNDRYVTT_CACHE`, or in `container_cache` beneath the data root when that is
|
|
92
92
|
unset. Once the archive is cached and the stage has a licence, later runs
|
|
93
93
|
start without signing in to foundryvtt.com, so its rate limit never stops a
|
|
94
|
-
run.
|
|
94
|
+
run. A key alone does not sign the licence. The image applies
|
|
95
|
+
`FOUNDRYVTT_TEST_LICENSE_KEY` and nothing more; the signature comes from
|
|
96
|
+
accepting the licence agreement in Foundry's own page, once per data root, and
|
|
97
|
+
then persists in `Config/license.json` there. On a fresh data root, start the
|
|
98
|
+
stage with no world (`package-build container test start`), open it in a
|
|
99
|
+
browser and accept the agreement. A run against an unsigned licence fails at
|
|
100
|
+
once saying so, naming the data root, instead of waiting for a world that never
|
|
101
|
+
activates. Under rootless Docker, set
|
|
95
102
|
`FOUNDRYVTT_CONTAINER_USER=0:0`: container root is then the host user, so every
|
|
96
103
|
file under the data root belongs to them, where the image would otherwise run
|
|
97
104
|
Foundry as user 1000. With the local settings in place, seed the world:
|