@heroiclands/package-build 22.14.2 → 22.14.4
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 +26 -0
- package/bin/content-build.mjs +6 -6
- package/bin/package-build.mjs +10 -0
- package/config.mjs +18 -1
- package/content-config.mjs +2 -2
- package/docs/api.md +66 -37
- package/docs/configuration.md +16 -7
- package/docs/content-format.md +172 -200
- package/docs/getting-started.md +46 -14
- package/docs/project-setup.md +5 -6
- package/engine/address.mjs +3 -5
- package/engine/asset-bindings.mjs +66 -0
- package/engine/calendar-notes.mjs +74 -0
- package/engine/changelog-lint.mjs +2 -2
- package/engine/content-images.mjs +20 -10
- package/engine/content-index.mjs +63 -36
- package/engine/content-lint.mjs +1 -2
- package/engine/content-package.mjs +2 -2
- package/engine/content-tables.mjs +4 -8
- package/engine/folder-notes.mjs +1 -2
- package/engine/foundry-entries.mjs +21 -6
- package/engine/frontmatter-lint.mjs +3 -4
- package/engine/frontmatter.mjs +5 -8
- package/engine/helpers.mjs +3 -4
- package/engine/index.mjs +3 -0
- package/engine/infobox.mjs +66 -2
- package/engine/item-registry.mjs +2 -2
- package/engine/note-vocabulary.mjs +83 -5
- package/engine/pack-config.mjs +2 -2
- package/engine/pack-router.mjs +2 -2
- package/engine/pdf-render.mjs +31 -8
- package/engine/pdf-toc.mjs +3 -3
- package/engine/retired-fields.mjs +1 -1
- package/engine/scene-levels.mjs +4 -4
- package/engine/schema-check.mjs +1 -1
- package/engine/site-build.mjs +134 -121
- package/engine/site-preview.mjs +293 -0
- package/engine/site-root.mjs +20 -2
- package/engine/social-tie-terms.mjs +11 -0
- package/engine/social-ties.mjs +84 -0
- package/engine/sql-tables.mjs +4 -9
- package/hm3/actors.mjs +1 -1
- package/package.json +3 -3
- package/sohl/item-fields.mjs +2 -2
- package/types/config.d.mts +8 -0
- package/types/content-config.d.mts +1 -1
- package/types/engine/address.d.mts +3 -5
- package/types/engine/asset-bindings.d.mts +6 -0
- package/types/engine/calendar-notes.d.mts +12 -0
- package/types/engine/content-images.d.mts +7 -4
- package/types/engine/content-index.d.mts +11 -0
- package/types/engine/content-package.d.mts +2 -2
- package/types/engine/folder-notes.d.mts +1 -2
- package/types/engine/frontmatter-lint.d.mts +1 -2
- package/types/engine/frontmatter.d.mts +2 -4
- package/types/engine/helpers.d.mts +3 -4
- package/types/engine/index.d.mts +1 -0
- package/types/engine/item-registry.d.mts +2 -2
- package/types/engine/note-vocabulary.d.mts +5 -6
- package/types/engine/pack-config.d.mts +1 -1
- package/types/engine/pack-router.d.mts +1 -1
- package/types/engine/pdf-render.d.mts +10 -1
- package/types/engine/pdf-toc.d.mts +1 -1
- package/types/engine/site-build.d.mts +36 -3
- package/types/engine/site-preview.d.mts +34 -0
- package/types/engine/social-tie-terms.d.mts +5 -0
- package/types/engine/social-ties.d.mts +10 -0
package/docs/content-format.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
### Documentation
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Markdown generates a JournalEntry: content before the first H1 becomes its "Introduction" page, and each H1 begins another page. The document Address is `<package>-note-<note_type>-<shortcode>`.
|
|
6
6
|
|
|
7
7
|
An **infobox** is prepended to the entry's first page, before the prose. It is
|
|
8
8
|
not a page of its own: a page is what a Foundry UUID addresses, and a summary a
|
|
@@ -51,7 +51,7 @@ system makes the page checkable — _every page carries exactly the boxes its ty
|
|
|
51
51
|
maps to_ is an assertion the build can make, so a missing infobox is a failure
|
|
52
52
|
rather than something nobody notices.
|
|
53
53
|
|
|
54
|
-
For
|
|
54
|
+
For web pages, the full Markdown body renders as HTML with its infoboxes.
|
|
55
55
|
|
|
56
56
|
### The infobox
|
|
57
57
|
|
|
@@ -154,7 +154,7 @@ a reader reassemble one fact from two cells, and reads worst in the book, whose
|
|
|
154
154
|
label column is a narrow small-caps rule. A medium cannot supply it either —
|
|
155
155
|
appending `d` to a price means knowing which row is the price, which is the one
|
|
156
156
|
thing a generic renderer must never know. A row carrying a unit is `text`,
|
|
157
|
-
because a number with a unit
|
|
157
|
+
because a number with a unit is text for presentation.
|
|
158
158
|
|
|
159
159
|
**What a field is called** is a **presentation overlay** on that same
|
|
160
160
|
declaration, per system. It carries two things a compiler's field list cannot,
|
|
@@ -346,14 +346,14 @@ index, silently, and the index still renders. That is the same failure a
|
|
|
346
346
|
misspelled `data:` key is, and it gets the same answer — the vocabulary
|
|
347
347
|
is declared, so a near miss is a finding that names what you probably meant.
|
|
348
348
|
|
|
349
|
-
| group | applies to | tags
|
|
350
|
-
| ------------------- | ---------------------- |
|
|
351
|
-
| **place kind** | `place` / `settlement` | `city`, `city-state`, `town`, `village`, `settlement`, `port`, `fortress`, `citadel`, `castle`, `stronghold`, `garrison`, `camp`, `oasis`, `waypoint`, `post`, `precinct`, `district`, `necropolis`, `hall`, `capital`
|
|
352
|
-
| **place character** | `place` | `fortified`, `temple`, `market`, `trading`, `merchant`, `mining`, `fishing`, `naval`, `military`, `imperial`, `provincial`, `coastal`, `river`, `lakeside`, `hill`, `mountain`, `valley`, `forest`, `woodland`, `inland`, `island`, `frontier`, `border`, `craft`, `caravan`, `pilgrimage`, `holy`, `sacred`, `free` |
|
|
353
|
-
| **place scale** | `place` / `region` | `continent`
|
|
354
|
-
| **being station** | `being` | `tradesfolk`, `common-folk`, `soldiery`, `administration`, `clergy`, `mages`, `underworld`, `dependents`, `guilded`, `unguilded`
|
|
355
|
-
| **being kind** | `being` | `character`, `creature`
|
|
356
|
-
| **state** | any | `draft`
|
|
349
|
+
| group | applies to | tags |
|
|
350
|
+
| ------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
351
|
+
| **place kind** | `place` / `settlement` | `city`, `city-state`, `town`, `village`, `settlement`, `port`, `fortress`, `citadel`, `castle`, `stronghold`, `garrison`, `camp`, `oasis`, `waypoint`, `post`, `precinct`, `district`, `necropolis`, `hall`, `capital` |
|
|
352
|
+
| **place character** | `place` | `fortified`, `temple`, `market`, `trading`, `merchant`, `mining`, `fishing`, `naval`, `military`, `imperial`, `provincial`, `coastal`, `river`, `lakeside`, `hill`, `mountain`, `valley`, `forest`, `woodland`, `inland`, `island`, `frontier`, `border`, `craft`, `caravan`, `pilgrimage`, `holy`, `sacred`, `free`, `ford`, `portage`, `pass`, `well` |
|
|
353
|
+
| **place scale** | `place` / `region` | `continent` |
|
|
354
|
+
| **being station** | `being` | `tradesfolk`, `common-folk`, `soldiery`, `administration`, `clergy`, `mages`, `underworld`, `dependents`, `guilded`, `unguilded` |
|
|
355
|
+
| **being kind** | `being` | `character`, `creature` |
|
|
356
|
+
| **state** | any | `draft` |
|
|
357
357
|
|
|
358
358
|
**`draft` is the one tag either build reads.** It does two things and nothing
|
|
359
359
|
else: a link _into_ a draft note renders marked, and the note itself states that
|
|
@@ -739,9 +739,7 @@ moved one and not the other.
|
|
|
739
739
|
|
|
740
740
|
**No image key is one of those.** A top-level `img:` is not authored at all:
|
|
741
741
|
`data.icon` is a different key holding a different kind of value, and a note
|
|
742
|
-
writing `img:` is naming a file where an address belongs. `portrait:` is not
|
|
743
|
-
relocated either, at any level — a portrait is an embed in the body, and the
|
|
744
|
-
key that used to declare one is not a key.
|
|
742
|
+
writing `img:` is naming a file where an address belongs. `portrait:` is not authorable at any level; a portrait is an embed in the body.
|
|
745
743
|
|
|
746
744
|
**Two of the eight are Item-only in SoHL.** `actionDefs` and `notes` are declared
|
|
747
745
|
on every SoHL Item subtype and on no SoHL Actor, so on a `being` or a `vehicle`
|
|
@@ -822,6 +820,14 @@ does not know still resolves on the website and in the book — those need only
|
|
|
822
820
|
the name and the suffix — and has no Foundry address, which is refused rather
|
|
823
821
|
than guessed.
|
|
824
822
|
|
|
823
|
+
An art package that replaces another package's images can declare
|
|
824
|
+
`packageBuild.assets[].bindsTo` on the relevant asset copy. Each file's basename
|
|
825
|
+
then acts as a shortcode for the declared package and type. The related
|
|
826
|
+
`relationships.requires[].contentIndex` supplies the address index; with that
|
|
827
|
+
index enabled, an asset with no matching note is a located build error. See
|
|
828
|
+
[asset bindings](configuration.md#packagebuildstagedir-and-packagebuildassets)
|
|
829
|
+
for the configuration and cache requirements.
|
|
830
|
+
|
|
825
831
|
**The host is configuration.** `site.assets` in `package-build.config.yaml` is
|
|
826
832
|
the root the web form is joined onto, and a package-owned image on a page with
|
|
827
833
|
none set is an error naming that key.
|
|
@@ -885,7 +891,7 @@ data:
|
|
|
885
891
|
|
|
886
892
|
It is deliberately close to the retired `package:` and deliberately not the same
|
|
887
893
|
word: `package:` said which _distribution_ owned a note — now the repository's
|
|
888
|
-
`contentPackage`, and
|
|
894
|
+
`contentPackage`, and not authorable — while `pack:` says which
|
|
889
895
|
_compendium_ receives its document.
|
|
890
896
|
|
|
891
897
|
**It names the pack for the note's _own_ document.** A document derived from it
|
|
@@ -1002,9 +1008,8 @@ real priority** — the one SoHL's own templates ship at — not an absence.
|
|
|
1002
1008
|
**Where it lands differs by system, because HM3's data model has no field for
|
|
1003
1009
|
it.** SoHL records it in `system`; HM3 keeps it under its own flag scope,
|
|
1004
1010
|
`flags.hm3`, and a note that is not a template writes nothing there rather than a
|
|
1005
|
-
`null` nothing reads. Both
|
|
1006
|
-
|
|
1007
|
-
SoHL and stop at HM3, with nothing said on either side.
|
|
1011
|
+
`null` nothing reads. Both HM3 Item and Actor passes write their own flag when
|
|
1012
|
+
the note declares a priority.
|
|
1008
1013
|
|
|
1009
1014
|
**How a winner is chosen.** Opening a Create dialog gathers every candidate
|
|
1010
1015
|
across the world and every matching compendium, _including other modules'_. Those
|
|
@@ -1067,16 +1072,10 @@ correctly and is wrong for a folder, and wrong in a way nothing outside the
|
|
|
1067
1072
|
build can detect: the result is a plausible 16-character id that resolves to
|
|
1068
1073
|
nothing.
|
|
1069
1074
|
|
|
1070
|
-
**
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
every pack of a document type, which is exactly the scope a primary document's
|
|
1075
|
-
id must be unique within, and it said nothing at all about a duplicate `id`. So
|
|
1076
|
-
the derived id inherits a guard that already exists, where the authored one had
|
|
1077
|
-
none. It is the same principle that turned `folder: ONXsqZAIZr2qzxTb` into
|
|
1078
|
-
`packFolder: <address>` above: an opaque derived identity does not belong in
|
|
1079
|
-
authored content.
|
|
1075
|
+
**The Address determines the default id.** `content-lint` refuses a duplicate
|
|
1076
|
+
Address across the packs of a document type, so the derived id shares that
|
|
1077
|
+
uniqueness scope. An author pins a document's identity with `data.id` when it
|
|
1078
|
+
must remain stable across an Address change.
|
|
1080
1079
|
|
|
1081
1080
|
**An authored `data.id` wins**, and that is how a document's identity is
|
|
1082
1081
|
**pinned**:
|
|
@@ -1139,27 +1138,9 @@ it — so a documentation journal is filed beside the item it describes without
|
|
|
1139
1138
|
the journals pack having to declare anything. A folder nothing references
|
|
1140
1139
|
materialises nowhere.
|
|
1141
1140
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
and `sohl-kethira-basic` had no journal folder file at all, so both emitted
|
|
1146
|
-
documentation journals into folders their own pack never declared — silently.
|
|
1147
|
-
With one folder note and one address there is no second file to disagree with
|
|
1148
|
-
the first.
|
|
1149
|
-
|
|
1150
|
-
> **`packFolder` was a path** for one release (`Possessions/Misc_Gear/Cooking`).
|
|
1151
|
-
> A path encoded the hierarchy in the value, so reparenting a folder made every
|
|
1152
|
-
> note naming it wrong — a structural edit became a corpus-wide rewrite. The
|
|
1153
|
-
> path form is **removed**, not deprecated: nothing authored it yet, which is
|
|
1154
|
-
> the whole reason the change was cheap enough to make.
|
|
1155
|
-
|
|
1156
|
-
> **`folder:` was a Foundry id**, resolved against a per-pack
|
|
1157
|
-
> `*-folders.yaml` — five files per tree. Both halves are **retired** together
|
|
1158
|
-
> : the id spelling has nothing left to resolve against once the YAML is
|
|
1159
|
-
> gone, and the YAML has no reader once the spelling is refused. A note that
|
|
1160
|
-
> still writes `folder:` fails the build, naming `packFolder` and the line to
|
|
1161
|
-
> rewrite, rather than being ignored — a retired field left ignored reads to
|
|
1162
|
-
> its author as though it still works.
|
|
1141
|
+
One folder note and one Address supply every pack that references it.
|
|
1142
|
+
`data.packFolder` names a folder by Address. A top-level `folder:` key is
|
|
1143
|
+
refused with a finding that names `data.packFolder` and the authored line.
|
|
1163
1144
|
|
|
1164
1145
|
#### The knowledgebase category
|
|
1165
1146
|
|
|
@@ -1343,21 +1324,11 @@ hyphenated value is reported where it wrote it:
|
|
|
1343
1324
|
Trauma/Blood_Loss.md:3:1: error: `subType` "blood-loss" is not a well-formed subType — a subType is lowercase letters and digits only (^[a-z0-9]+$), the same charset a type, a shortcode and a contentPackage are held to. It is a vocabulary term the whole toolchain keys on, and one closed set away from being an address segment again, so a charset that held for every term but this one would be a rule nobody could state in a sentence
|
|
1344
1325
|
```
|
|
1345
1326
|
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
charset check — it contains a hyphen, which is the reason that always applied.
|
|
1352
|
-
No retirement-specific code outlived the sweep.
|
|
1353
|
-
|
|
1354
|
-
That is a guarantee rather than an observation, and it holds: of **4,456 distinct
|
|
1355
|
-
shortcodes** across the four content trees, not one contains a character outside
|
|
1356
|
-
`[a-z0-9]`. It is load-bearing, so relaxing the charset later would break
|
|
1357
|
-
resolution with nothing to say so.
|
|
1358
|
-
|
|
1359
|
-
`type/shortcode` with a slash is the legacy form, still resolved so links written
|
|
1360
|
-
before the vault migrated do not silently die. A slash is _unconditionally_ an
|
|
1327
|
+
The `doc` subType is **`userguide`**. A hyphenated `user-guide` is refused by
|
|
1328
|
+
the shared charset check. Shortcodes likewise contain only lowercase letters
|
|
1329
|
+
and digits, preserving one unambiguous Address grammar.
|
|
1330
|
+
|
|
1331
|
+
`type/shortcode` with a slash is accepted. A slash is _unconditionally_ an
|
|
1361
1332
|
address separator — pipe or no pipe — so an unknown type before one is an error
|
|
1362
1333
|
rather than something to guess at.
|
|
1363
1334
|
|
|
@@ -1403,13 +1374,9 @@ Which of the two a field holds is the field's own declaration, stated in the
|
|
|
1403
1374
|
An address that names no note **fails the build** — in the link checker,
|
|
1404
1375
|
in the pack compilers and in the site build alike.
|
|
1405
1376
|
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
property of the **bare** form, which is retired, and the intent behind it has a
|
|
1410
|
-
real spelling now: a note tagged `draft` exists, resolves, compiles and
|
|
1411
|
-
publishes, and a link to it renders visibly marked. So an address landing
|
|
1412
|
-
nowhere is a typo or an omission, and both want fixing.
|
|
1377
|
+
A `draft` note exists, resolves, compiles and publishes; a link to it renders
|
|
1378
|
+
visibly marked. An Address landing nowhere is a typo or an omission and earns
|
|
1379
|
+
an error.
|
|
1413
1380
|
|
|
1414
1381
|
There are six ways a link can fail, and each is one **error** with one message
|
|
1415
1382
|
wherever it is met:
|
|
@@ -1424,11 +1391,9 @@ wherever it is met:
|
|
|
1424
1391
|
| `ambiguous` | _unreachable; kept for the manifest_ | — |
|
|
1425
1392
|
| `unknown-anchor` | the address resolves; the `#section` does not | correct the anchor |
|
|
1426
1393
|
|
|
1427
|
-
`ambiguous`
|
|
1428
|
-
so
|
|
1429
|
-
|
|
1430
|
-
reason is retained so a consumer switching on it does not break, and because a
|
|
1431
|
-
vendored manifest built by an older toolchain may still carry the finding.
|
|
1394
|
+
`ambiguous` is a reserved reason in the result vocabulary. An omitted segment
|
|
1395
|
+
defaults rather than wildcarding, so each written target expands to one
|
|
1396
|
+
canonical Address and a lookup returns one entry or none.
|
|
1432
1397
|
|
|
1433
1398
|
The vocabulary and the messages live in one module (`engine/wikilink-syntax.mjs`)
|
|
1434
1399
|
precisely because an author meets whichever build ran first. Three resolvers read
|
|
@@ -1565,19 +1530,9 @@ There is one namespace, and the pipe is required:
|
|
|
1565
1530
|
**A link written without a label addresses nothing**, and the correction
|
|
1566
1531
|
is always the same: write `[[type-shortcode|Text]]`.
|
|
1567
1532
|
|
|
1568
|
-
The bare form does not
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
across 8,305 wikilinks in three content trees, **not one** bare link resolved to
|
|
1572
|
-
a note. What the index behind it did do was fold every note's `name.full` into
|
|
1573
|
-
itself, so two notes of one type could not share a display name — a rules page
|
|
1574
|
-
and a user guide page both called "Gear" were a build failure whose every
|
|
1575
|
-
available fix moved a published URL.
|
|
1576
|
-
|
|
1577
|
-
The top-level `aliases:` that fed it is **retired** and refused. The nested
|
|
1578
|
-
`name.aliases:` is **not**: it is reserved for a use that does not exist yet, so
|
|
1579
|
-
it is permitted and read by nothing — no index, no resolver, no lint rule, no
|
|
1580
|
-
derived address. A note carrying one behaves exactly as one without it.
|
|
1533
|
+
The bare form does not resolve by display name or alias. `name.aliases` is
|
|
1534
|
+
indexed for search and completion, while an authored link names an Address.
|
|
1535
|
+
A top-level `aliases:` key is refused.
|
|
1581
1536
|
|
|
1582
1537
|
Requiring the label is also what makes positional parsing safe. Note names
|
|
1583
1538
|
contain hyphens — `Grukar-ahk` is a name, not a `Grukar` of type `ahk` — so a
|
|
@@ -2111,10 +2066,10 @@ place for those words and this is it.
|
|
|
2111
2066
|
|
|
2112
2067
|
##### Width is a class, and the ordinary width carries no marker
|
|
2113
2068
|
|
|
2114
|
-
| `class` value | book
|
|
2115
|
-
| ------------- |
|
|
2116
|
-
| _(none)_ |
|
|
2117
|
-
| `.full-width` |
|
|
2069
|
+
| `class` value | book | website | Foundry journal |
|
|
2070
|
+
| ------------- | ----------------------------- | ------------------ | --------------- |
|
|
2071
|
+
| _(none)_ | natural width within a column | natural width | natural width |
|
|
2072
|
+
| `.full-width` | page measure | full content width | full page width |
|
|
2118
2073
|
|
|
2119
2074
|
The simple case needs no spelling, which is why the ordinary width has no name.
|
|
2120
2075
|
|
|
@@ -2125,21 +2080,24 @@ refused.
|
|
|
2125
2080
|
|
|
2126
2081
|
##### Named size is `size:`
|
|
2127
2082
|
|
|
2128
|
-
| `size` value |
|
|
2129
|
-
| ------------ |
|
|
2130
|
-
| `auto` |
|
|
2131
|
-
| `small` |
|
|
2132
|
-
| `medium` |
|
|
2133
|
-
| `large` |
|
|
2134
|
-
| `xlarge` |
|
|
2135
|
-
| `full-width` |
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2083
|
+
| `size` value | website and Foundry | book |
|
|
2084
|
+
| ------------ | ------------------- | ------------ |
|
|
2085
|
+
| `auto` | natural size | natural size |
|
|
2086
|
+
| `small` | 64 CSS pixels | 1.6 cm |
|
|
2087
|
+
| `medium` | 128 CSS pixels | 3.2 cm |
|
|
2088
|
+
| `large` | 256 CSS pixels | 5.6 cm |
|
|
2089
|
+
| `xlarge` | 512 CSS pixels | 8 cm |
|
|
2090
|
+
| `full-width` | content measure | page measure |
|
|
2091
|
+
|
|
2092
|
+
These are maximum display widths for Markdown images and embedded assets;
|
|
2093
|
+
height follows the file's aspect ratio. The available column, page, or browser
|
|
2094
|
+
measure caps every size, and print also caps image height within the page.
|
|
2095
|
+
Omitting `size:` means `auto`, which uses the file's natural dimensions within
|
|
2096
|
+
those bounds. `full-width` spans the book's page rather than one column. The
|
|
2097
|
+
`.full-width` class also grants page scope in print; when it accompanies a
|
|
2098
|
+
bounded `size:`, the image keeps that bounded width inside the page figure.
|
|
2099
|
+
A `size:` may sit before or after `float:` in the same directive, and neither
|
|
2100
|
+
changes the other's behavior.
|
|
2143
2101
|
|
|
2144
2102
|
##### Position is `float:`
|
|
2145
2103
|
|
|
@@ -2422,7 +2380,7 @@ For JournalEntries, the following rules apply:
|
|
|
2422
2380
|
|
|
2423
2381
|
- `# ... {#spoilers}`: The contents of this header go into a page which is viewable only by the GM (`CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE`).
|
|
2424
2382
|
|
|
2425
|
-
**
|
|
2383
|
+
**Archetypes** describe characters in broad terms and help match them to an adventure. The list is:
|
|
2426
2384
|
|
|
2427
2385
|
- warrior: Can hold a line and win a fight.
|
|
2428
2386
|
- skirmisher: Fights light — ambush, missile, mobility.
|
|
@@ -2462,10 +2420,11 @@ Generates a living (or undead, or spirit) being.
|
|
|
2462
2420
|
| `lore` | `Address[]` | Lore concerning this being — the people it is of, the standing it holds, the law it lives under |
|
|
2463
2421
|
| `homes` | `Address[]` | Place the being calls home |
|
|
2464
2422
|
| `affiliations` | `Address[]` | Affilliations (e.g., arcane/divine traditions, polities, etc) |
|
|
2423
|
+
| `socialTies` | `Map<Address, Tie>` | Defining support and opposition, directed from this being to others |
|
|
2465
2424
|
| `gender` | `male \| female \| other` | Gender of the character |
|
|
2466
2425
|
| `species` | `Address` | Being's species (lore) |
|
|
2467
|
-
| `born` | `
|
|
2468
|
-
| `died` | `
|
|
2426
|
+
| `born` | `date \| unknown` | When the being was born; absent, it was never born |
|
|
2427
|
+
| `died` | `date \| unknown` | When the being died; absent, it is alive |
|
|
2469
2428
|
| `age` | `34 \| ~34` | Age in years, stated only to override what `born` says; `~` marks an estimate |
|
|
2470
2429
|
| `ageYears` | `number` | Written by the compiler beside an `age` estimate — the `~` stripped; a note never authors this |
|
|
2471
2430
|
| `height` | `number` | Height in meters |
|
|
@@ -2477,6 +2436,29 @@ Generates a living (or undead, or spirit) being.
|
|
|
2477
2436
|
| `appearance.complexion` | `string` | Complexion |
|
|
2478
2437
|
| `appearance.extra_features` | `string[]` | Extra features |
|
|
2479
2438
|
|
|
2439
|
+
#### The people who matter to a being
|
|
2440
|
+
|
|
2441
|
+
`data.socialTies` records relationships that define the subject's dossier, not
|
|
2442
|
+
everyone the subject knows. An absent entry says nothing about that relationship.
|
|
2443
|
+
An acquaintance belongs here when, for example, a guard will recognize the
|
|
2444
|
+
subject at a gate. A father and an independent adult son can have no tie in
|
|
2445
|
+
either note; a daughter who relies on her father may be his `dependent`.
|
|
2446
|
+
|
|
2447
|
+
The keys are bare Addresses with an explicit `being` or `affiliation` type.
|
|
2448
|
+
Values are `patron`, `friend`, `dependent`, `acquaintance`, `rival`, or
|
|
2449
|
+
`nemesis`. A patron supports the subject from greater power or status; a
|
|
2450
|
+
friend supports them from goodwill; a dependent relies on their protection;
|
|
2451
|
+
an acquaintance knows them without a strong disposition; a rival opposes them
|
|
2452
|
+
without implacable hostility; a nemesis opposes them personally and
|
|
2453
|
+
implacably. The infobox groups targets by term and links to their notes.
|
|
2454
|
+
|
|
2455
|
+
Each tie is one-sided. The target need not name the subject back, even when
|
|
2456
|
+
`patron` and `dependent` would describe opposite ends of the same support.
|
|
2457
|
+
Kinship, household membership, organizational membership, rank, and office are
|
|
2458
|
+
distinct facts. Their relevant effects may appear as ties, while their details
|
|
2459
|
+
belong in prose, `data.affiliations`, or governance fields. A tie has no
|
|
2460
|
+
mechanical modifier.
|
|
2461
|
+
|
|
2480
2462
|
#### When a being was born, when it died, and how old it is
|
|
2481
2463
|
|
|
2482
2464
|
**Absence asserts a fact rather than recording a gap**, and that is what these
|
|
@@ -2694,11 +2676,9 @@ unanchored page is keyed on its heading, so inserting a heading leaves every
|
|
|
2694
2676
|
other page's id where it was. Two sibling pages sharing a heading is likewise a
|
|
2695
2677
|
build error, matching the `MD024` lint rule that already refuses it.
|
|
2696
2678
|
|
|
2697
|
-
|
|
2679
|
+
A `sohl` block produces a SoHL actor of type `being`. An `hm3` block produces an HM3 actor. Its document type is **not** derived: `hm3.type` states it, and must be `character` or `creature`. A note that omits it is an error naming the note — see _The note vocabulary, and how it maps_.
|
|
2698
2680
|
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
A SoHL "being" document will be created, as will an "HM3" document.
|
|
2681
|
+
A SoHL "being" document is created, as will an "HM3" document.
|
|
2702
2682
|
|
|
2703
2683
|
| shared source | → sohl | → hm3 |
|
|
2704
2684
|
| ----------------- | ------ | ------------------- |
|
|
@@ -2829,8 +2809,7 @@ Definition of a level within the organization (e.g., Priest, Layperson, Member,
|
|
|
2829
2809
|
owned outright, with no standing at law except through an owner. The title is
|
|
2830
2810
|
what this body calls it and the description is how this body puts it, but the
|
|
2831
2811
|
obligations and rights belong to the standing itself, so they are written once
|
|
2832
|
-
and cited by every ladder that confers it.
|
|
2833
|
-
titles across 2,602 rank entries resolve onto 43 standings.
|
|
2812
|
+
and cited by every ladder that confers it.
|
|
2834
2813
|
|
|
2835
2814
|
That is also what makes a rank answerable across bodies. Without it, asking what
|
|
2836
2815
|
a `Naukrátissa` may do means reading the Bethûan fleet's ladder; with it, the
|
|
@@ -3063,9 +3042,9 @@ Note: `data.quantity` may not be specified. Quantity is always 1.
|
|
|
3063
3042
|
| `quality` | `number` | Gear quality |
|
|
3064
3043
|
| `durability` | `number` | Gear durability |
|
|
3065
3044
|
|
|
3066
|
-
If a `sohl` property is present, a SoHL item of type "armorgear"
|
|
3045
|
+
If a `sohl` property is present, a SoHL item of type "armorgear" is created.
|
|
3067
3046
|
|
|
3068
|
-
The note type is `armorgear` in both
|
|
3047
|
+
The note type is `armorgear` in both systems.
|
|
3069
3048
|
|
|
3070
3049
|
| shared source | → sohl | → hm3 |
|
|
3071
3050
|
| ----------------- | ----------------------- | --------------- |
|
|
@@ -3080,7 +3059,7 @@ The note type is `armorgear` in both cases. The `gear` suffix was briefly rename
|
|
|
3080
3059
|
| ------------------ | -------- | ------------------------------------------ |
|
|
3081
3060
|
| `templatePriority` | `number` | Template priority, _null_ = not a template |
|
|
3082
3061
|
|
|
3083
|
-
if a `hm3` property is present, an HM3 item of type "armorlocation"
|
|
3062
|
+
if a `hm3` property is present, an HM3 item of type "armorlocation" is created.
|
|
3084
3063
|
|
|
3085
3064
|
| shared source | → sohl | → hm3 |
|
|
3086
3065
|
| ------------- | ------ | ----- |
|
|
@@ -3092,7 +3071,7 @@ if a `hm3` property is present, an HM3 item of type "armorlocation" will be crea
|
|
|
3092
3071
|
| ------------------ | -------- | ------------------------------------------ |
|
|
3093
3072
|
| `templatePriority` | `number` | Template priority, _null_ = not a template |
|
|
3094
3073
|
|
|
3095
|
-
if a `sohl` property is present, a SoHL item of type "attribute"
|
|
3074
|
+
if a `sohl` property is present, a SoHL item of type "attribute" is created.
|
|
3096
3075
|
|
|
3097
3076
|
| shared source | → sohl | → hm3 |
|
|
3098
3077
|
| ------------- | ------ | ----- |
|
|
@@ -3116,7 +3095,7 @@ if a `sohl` property is present, a SoHL item of type "attribute" will be created
|
|
|
3116
3095
|
| `potency` | `na \| mild \| strong \| great` | Concoction Potency (mundane/exotic concoctions) |
|
|
3117
3096
|
| `strength` | `number` | Strength: higher the number, greater the strength |
|
|
3118
3097
|
|
|
3119
|
-
if a `sohl` property is present, a SoHL item of type "concoctiongear"
|
|
3098
|
+
if a `sohl` property is present, a SoHL item of type "concoctiongear" is created.
|
|
3120
3099
|
|
|
3121
3100
|
| shared source | → sohl | → hm3 |
|
|
3122
3101
|
| ----------------- | ----------------------- | ----- |
|
|
@@ -3142,9 +3121,9 @@ Note: `data.quantity` may not be specified; quantity is always set to 1.
|
|
|
3142
3121
|
| `durability` | `number` | Gear durability |
|
|
3143
3122
|
| `capacity` | `number` | HM3 container capacity (in lbs) |
|
|
3144
3123
|
|
|
3145
|
-
if a `sohl` property is present, a SoHL item of type "containergear"
|
|
3124
|
+
if a `sohl` property is present, a SoHL item of type "containergear" is created.
|
|
3146
3125
|
|
|
3147
|
-
if a `hm3` property is present, an HM3 item of type "containergear"
|
|
3126
|
+
if a `hm3` property is present, an HM3 item of type "containergear" is created.
|
|
3148
3127
|
|
|
3149
3128
|
| shared source | → sohl | → hm3 |
|
|
3150
3129
|
| ----------------- | ----------------------- | --------------------- |
|
|
@@ -3167,9 +3146,9 @@ SoHL reads a container’s capacity in pounds from `sohl.maxCapacity`.
|
|
|
3167
3146
|
| `durability` | `number` | Gear durability |
|
|
3168
3147
|
| `quantity` | `number` | HM3 gear quantity (default: 1) |
|
|
3169
3148
|
|
|
3170
|
-
if a `sohl` property is present, a SoHL item of type "miscgear"
|
|
3149
|
+
if a `sohl` property is present, a SoHL item of type "miscgear" is created.
|
|
3171
3150
|
|
|
3172
|
-
if a `hm3` property is present, an HM3 item of type "miscgear"
|
|
3151
|
+
if a `hm3` property is present, an HM3 item of type "miscgear" is created.
|
|
3173
3152
|
|
|
3174
3153
|
| shared source | → sohl | → hm3 |
|
|
3175
3154
|
| ----------------- | ----------------------- | ----------------- |
|
|
@@ -3205,7 +3184,7 @@ SoHL sets `system.quantity` to `1` for each compendium item.
|
|
|
3205
3184
|
| `charges.value` | `number` | Current number of charges available, _null_ = charges not used |
|
|
3206
3185
|
| `charges.max` | `number` | Maximum number of charges, _null_ = no maximum |
|
|
3207
3186
|
|
|
3208
|
-
if a `sohl` property is present, a SoHL item of type "mystery"
|
|
3187
|
+
if a `sohl` property is present, a SoHL item of type "mystery" is created.
|
|
3209
3188
|
|
|
3210
3189
|
`system.assocSkillCode` and `system.assocAffiliationCode` are authored under
|
|
3211
3190
|
`sohl.system` as shortcodes and have no shared source; `data.assocSkill` and
|
|
@@ -3246,7 +3225,7 @@ if a `sohl` property is present, a SoHL item of type "mystery" will be created.
|
|
|
3246
3225
|
| `charges.value` | `number` | Current number of charges available, _null_ = charges not used |
|
|
3247
3226
|
| `charges.max` | `number` | Maximum number of charges, _null_ = no maximum |
|
|
3248
3227
|
|
|
3249
|
-
if a `sohl` property is present, a SoHL item of type "mysticalability"
|
|
3228
|
+
if a `sohl` property is present, a SoHL item of type "mysticalability" is created.
|
|
3250
3229
|
|
|
3251
3230
|
If an `hm3` property is present, an HM3 item is created, and `hm3.type` states which — `psionic`, `spell` or `invocation`. It is **authored, not derived from `subType`**: the ten mystical-ability subtypes do not partition onto HM3's three documents (a `spiritrite`, an `alchemy` and a `divination` each answer to none of them), so a derivation would be a guess with a plausible shape. A note that omits it is an error naming the note.
|
|
3252
3231
|
|
|
@@ -3284,9 +3263,9 @@ the item’s base mastery and level from `sohl.masteryLevelBase` and
|
|
|
3284
3263
|
| `durability` | `number` | Gear durability |
|
|
3285
3264
|
| `quantity` | `number` | HM3 gear quantity (default: 1) |
|
|
3286
3265
|
|
|
3287
|
-
if a `sohl` property is present, a SoHL item of type "projectilegear"
|
|
3266
|
+
if a `sohl` property is present, a SoHL item of type "projectilegear" is created.
|
|
3288
3267
|
|
|
3289
|
-
If an `hm3` property is present,
|
|
3268
|
+
If an `hm3` property is present, an HM3 item of type "missilegear" is created.
|
|
3290
3269
|
|
|
3291
3270
|
Note that `weapon` can also produce an HM3 `missilegear`. Since `(type, shortcode)` is a
|
|
3292
3271
|
flat namespace, a `projectilegear` and a `weapon` sharing a shortcode would collide on the
|
|
@@ -3324,9 +3303,9 @@ SoHL sets `system.quantity` to `1` for each compendium item.
|
|
|
3324
3303
|
| `masteryLevel` | `number` | HM3 mastery level |
|
|
3325
3304
|
| `parentSkill` | `Address` | Parent skill this skill specializes |
|
|
3326
3305
|
|
|
3327
|
-
if a `sohl` property is present, a SoHL item of type "skill"
|
|
3306
|
+
if a `sohl` property is present, a SoHL item of type "skill" is created.
|
|
3328
3307
|
|
|
3329
|
-
If an `hm3` property is present,
|
|
3308
|
+
If an `hm3` property is present, an HM3 item of type "skill" is created.
|
|
3330
3309
|
|
|
3331
3310
|
Note: `hm3.system.type` (skill types) use the values "Craft", "Physical", "Communication", "Combat", "Magic", and "Ritual". These do not cleanly map to the `subType` values. Because of this, the `hm3.system.type` value must be specified with the appropriate value when defining HM3 skills.
|
|
3332
3311
|
|
|
@@ -3367,7 +3346,7 @@ SoHL reads a skill’s base mastery from `sohl.masteryLevelBase`.
|
|
|
3367
3346
|
| `courseDurationFormula` | `RollFormula` | Formula for the interval between course tests — shock, coma, infection |
|
|
3368
3347
|
| `courseDurationBase` | `number` | That interval in seconds, stated outright instead of rolled |
|
|
3369
3348
|
|
|
3370
|
-
if a `sohl` property is present, a SoHL item of type "trauma"
|
|
3349
|
+
if a `sohl` property is present, a SoHL item of type "trauma" is created.
|
|
3371
3350
|
|
|
3372
3351
|
If an `hm3` property is present, an HM3 item is created. `hm3.type` must be specified as either `injury` or `trait`.
|
|
3373
3352
|
|
|
@@ -3406,7 +3385,7 @@ Note: `data.quantity` may not be specified. Quantity is always 1.
|
|
|
3406
3385
|
| `quality` | `number` | Gear quality |
|
|
3407
3386
|
| `durability` | `number` | Gear durability |
|
|
3408
3387
|
|
|
3409
|
-
if a `sohl` property is present, a SoHL item of type "weapongear"
|
|
3388
|
+
if a `sohl` property is present, a SoHL item of type "weapongear" is created,
|
|
3410
3389
|
carrying every strike mode the weapon has — melee and missile alike — on
|
|
3411
3390
|
`system.strikeModes`.
|
|
3412
3391
|
|
|
@@ -3453,6 +3432,7 @@ In-world information about people, places, or concepts.
|
|
|
3453
3432
|
| `weekdays` | `{ name, abbreviation? }[]` | The days of the week it names, in order; a calendar with no week writes none |
|
|
3454
3433
|
| `seasons` | `{ name, abbreviation?, monthStart?, monthEnd?, dayStart?, dayEnd? }[]` | The seasons it marks, bounded by month or by day of year |
|
|
3455
3434
|
| `eras` | `{ shortcode, name, abbreviation?, proclaimedBy?, start, end? }[]` | The year-counts kept in it, each addressed `<calendar shortcode>.<era shortcode>` |
|
|
3435
|
+
| `dateFormats` | `Map<slot, format>` | Calendaria display formats for this calendar |
|
|
3456
3436
|
| `event` | `Map<field, value>` | A dated occurrence, with its sources, locations, reach, and relationships |
|
|
3457
3437
|
|
|
3458
3438
|
`data.event` is available on every `lore` subType. It holds structured
|
|
@@ -3463,7 +3443,7 @@ chronology tools and does not appear as an infobox row.
|
|
|
3463
3443
|
|
|
3464
3444
|
#### What a calendar note declares
|
|
3465
3445
|
|
|
3466
|
-
**
|
|
3446
|
+
**The calendar keys belong to `subType: calendar` and to no other genre of
|
|
3467
3447
|
`lore`.** A note carrying one under any other subType is refused, and a calendar
|
|
3468
3448
|
note that states no `months` and no `epoch` is refused too: a calendar divides
|
|
3469
3449
|
the year and says where the count begins, and one that does neither is prose
|
|
@@ -3489,8 +3469,16 @@ data:
|
|
|
3489
3469
|
abbreviation: AF
|
|
3490
3470
|
proclaimedBy: vylarinmpr
|
|
3491
3471
|
start: 1
|
|
3472
|
+
dateFormats: { full: "D MMMM, YYYY", yearLabel: "[Year] YYYY" }
|
|
3492
3473
|
```
|
|
3493
3474
|
|
|
3475
|
+
`dateFormats` accepts `short`, `long`, `full`, `time`, `weekHeader`,
|
|
3476
|
+
`yearHeader`, `yearLabel`, and `crossCalendar`. Each value is a Calendaria
|
|
3477
|
+
format string. Its date tokens may appear bare; ordinary words belong in
|
|
3478
|
+
`[brackets]` or `{braces}` so they print literally. A bare letter run that is
|
|
3479
|
+
not a Calendaria token is an error. The `time12` slot is outside this
|
|
3480
|
+
vocabulary.
|
|
3481
|
+
|
|
3494
3482
|
**Position in the list is position in the year.** Days that belong to no month
|
|
3495
3483
|
are a short month like any other: a five-day festival is one entry, and where it
|
|
3496
3484
|
sits in the list is where it falls in the year. There is no intercalary
|
|
@@ -3545,12 +3533,6 @@ depicts what it depicts. A place's maps are therefore derived — every map whos
|
|
|
3545
3533
|
The three differ only in the canvas defaults derived for them, which is why they
|
|
3546
3534
|
are subTypes of one type rather than three types.
|
|
3547
3535
|
|
|
3548
|
-
> The three are also readable as **types**, which is the shape notes in the
|
|
3549
|
-
> wild still carry: a note writing `type: battlemap` is reported and told what
|
|
3550
|
-
> to write instead, exactly as a note writing `type: character` is. A
|
|
3551
|
-
> consumer's `sections` config keys off the type, so it takes one `map` entry
|
|
3552
|
-
> rather than three.
|
|
3553
|
-
|
|
3554
3536
|
**NoteLocation** is `[GridLocation, anchor]` where the `anchor` is an anchor identified in the body of the note, and `GridLocation` represents a particular grid location on the document.
|
|
3555
3537
|
|
|
3556
3538
|
The `data:` fields, of which three are required:
|
|
@@ -3619,39 +3601,17 @@ address, not filling in a Foundry field.
|
|
|
3619
3601
|
|
|
3620
3602
|
**Two unit conventions, deliberately.** Geometry — walls, doors, lights, tiles,
|
|
3621
3603
|
sounds, region shapes — is authored in **pixels**, Foundry's native storage,
|
|
3622
|
-
because
|
|
3623
|
-
|
|
3604
|
+
because traced walls often fall between grid intersections. Map pins are
|
|
3605
|
+
authored in **grid squares**, commonly
|
|
3624
3606
|
half-integers, because that is how a person reads a position off a map. The two
|
|
3625
3607
|
are told apart by their key: `position:` and segment or shape coordinates are
|
|
3626
3608
|
pixels, `at:` is grid squares. Mixing them fails silently and visually in
|
|
3627
3609
|
Foundry, so the build refuses rather than resolving.
|
|
3628
3610
|
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
> SoHL infobox implying a specificity it does not have. It is the same class of
|
|
3634
|
-
> mistake as storing the template priority in flags: the data went where the only
|
|
3635
|
-
> available container was, rather than where it belongs. Three notes carry it today.
|
|
3636
|
-
|
|
3637
|
-
**A map is always a leaf.** Its frontmatter references nothing outside itself.
|
|
3638
|
-
`notes:` is a list of `[anchor, GridLocation]`, and each anchor names a heading in
|
|
3639
|
-
**this map note's own body** — never an external note. A pin therefore opens the
|
|
3640
|
-
map's own journal page, so the prose describing a spot on the map lives with the
|
|
3641
|
-
map that shows it.
|
|
3642
|
-
|
|
3643
|
-
That constraint is the point, not an accident of the format. A map that names no
|
|
3644
|
-
other note can be reused by any place, any scenario and any package, and can be
|
|
3645
|
-
moved between them without dragging references along. It also cannot carry a
|
|
3646
|
-
dangling reference: only things pointing _at_ a map can break, which is the safe
|
|
3647
|
-
direction for the failure to run.
|
|
3648
|
-
|
|
3649
|
-
**So the reference runs from the place.** A `place` names its maps through
|
|
3650
|
-
`data.maps`; the map says nothing about which places it depicts. That is the
|
|
3651
|
-
opposite of how the pins run, and deliberately so — the pins point inward to keep
|
|
3652
|
-
the map self-contained, and the place points outward because it is the thing that
|
|
3653
|
-
knows which maps belong to it. A keep with three floor plans is a place naming
|
|
3654
|
-
three maps, and none of those maps needs to know it is a keep.
|
|
3611
|
+
**Map pins stay within the map.** `notes:` names anchors in this map note's own
|
|
3612
|
+
body, so a pin opens the journal page describing that spot. `data.place` names
|
|
3613
|
+
the place depicted by the map when one exists. A place's map listing is derived
|
|
3614
|
+
from those map notes, so each map states the relationship once.
|
|
3655
3615
|
|
|
3656
3616
|
### type: place
|
|
3657
3617
|
|
|
@@ -3668,6 +3628,7 @@ three maps, and none of those maps needs to know it is a keep.
|
|
|
3668
3628
|
| `data` property | Values | Description |
|
|
3669
3629
|
| --------------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
3670
3630
|
| `demonym` | `string` | What a person from this place is called — a Vylarian |
|
|
3631
|
+
| `purpose` | `placeCharacter` tag | The reason a settlement, site, or structure exists |
|
|
3671
3632
|
| `lore` | `Address[]` | Lore concerning this place — its peoples, its law, its calendar, its history |
|
|
3672
3633
|
| `parents` | `Address[]` | Enclosing places within which this place is located |
|
|
3673
3634
|
| `population` | `number` | Approximate population (precision 2 significant digits) |
|
|
@@ -3690,6 +3651,17 @@ three maps, and none of those maps needs to know it is a keep.
|
|
|
3690
3651
|
| `moon.newOn` | `date` | A day it was new, written in the reference calendar |
|
|
3691
3652
|
| `moon.eclipses` | `string` | `never`, `rare`, `occasional` or `frequent` |
|
|
3692
3653
|
|
|
3654
|
+
#### Why a place exists
|
|
3655
|
+
|
|
3656
|
+
`data.purpose` selects one of the place's own `placeCharacter` tags. It is
|
|
3657
|
+
optional on settlements, sites, and structures. A mining settlement on a coast
|
|
3658
|
+
can carry `tags: [mining, coastal]` and `data.purpose: mining`: the coast locates
|
|
3659
|
+
it; the mine explains its existence. The value must belong to the declared
|
|
3660
|
+
`placeCharacter` vocabulary and also appear among that note's tags. The tags
|
|
3661
|
+
include `ford`, `portage`, `pass`, and `well` for places founded around a crossing,
|
|
3662
|
+
a break in navigation, a mountain route, or scarce water. The body explains the
|
|
3663
|
+
specific history; the selected tag gives tables a consistent grouping value.
|
|
3664
|
+
|
|
3693
3665
|
#### What a body states about itself
|
|
3694
3666
|
|
|
3695
3667
|
**The four groups above are the world's own facts, and they are legal on a
|
|
@@ -3941,28 +3913,11 @@ settlement layer names the notable places and is complete nowhere, so the ratio
|
|
|
3941
3913
|
reports how much of a region has been written rather than how much of it is
|
|
3942
3914
|
urban.
|
|
3943
3915
|
|
|
3944
|
-
**A place declares
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
`sohl.system.commonSkills` holds them. The authored corpus agrees: of 206
|
|
3950
|
-
places carrying `languages`, 190 were settlements and 16 were regions, and not one
|
|
3951
|
-
was a site, a structure or a feature. A ruin has no language.
|
|
3952
|
-
|
|
3953
|
-
**`peoples` widens to `lore`.** It was the only lore-pointing property a place
|
|
3954
|
-
had, so a place with a calendar, a body of law or a local history had nowhere to
|
|
3955
|
-
cite it. Nothing is lost by widening: the target's own subType already
|
|
3956
|
-
distinguishes a `folk` from a `law`, which is the same reason `affiliation`
|
|
3957
|
-
carries no `pantheons`.
|
|
3958
|
-
|
|
3959
|
-
**`summary` duplicated `description`**, which every note already has and which is
|
|
3960
|
-
what the page renders.
|
|
3961
|
-
|
|
3962
|
-
**`affiliations` and `maps` were the wrong end of a relation.** `affiliations` is
|
|
3963
|
-
the inverse of `affiliation.domains`, and a relation authored from both ends
|
|
3964
|
-
drifts the moment one is edited. `maps` moves onto the map, which now names the
|
|
3965
|
-
place it depicts — see `type: map` below.
|
|
3916
|
+
**A place declares what is true of its ground.** Its governing affiliations
|
|
3917
|
+
carry their own `domains`; maps name the place they depict through `data.place`.
|
|
3918
|
+
The place's `lore` links cover its peoples, calendar, law and history. Political
|
|
3919
|
+
languages belong to a polity's `sohl.system.commonSkills`, while the note's
|
|
3920
|
+
`description` provides its page summary.
|
|
3966
3921
|
|
|
3967
3922
|
### type: scenario
|
|
3968
3923
|
|
|
@@ -3994,9 +3949,34 @@ Content prepared to be played — a situation with its cast, places, and possibl
|
|
|
3994
3949
|
- reference: Out-of-world lookup material about the setting or system — correspondences, conversions, glossaries.
|
|
3995
3950
|
- howto: A task with an outcome, written as the steps that reach it.
|
|
3996
3951
|
- concept: An explanation of how something works and why it is shaped that way, read to understand rather than to follow.
|
|
3952
|
+
- settingguide: An orientation to a setting or region, bringing its places, peoples, institutions, and daily life into one usable frame with links to detailed notes.
|
|
3997
3953
|
|
|
3998
3954
|
A `doc` declares no properties of its own.
|
|
3999
3955
|
|
|
3956
|
+
Choose `settingguide` for an entry point that stands on its own while guiding
|
|
3957
|
+
players and GMs into a setting. A `concept` explains one subject, a `reference`
|
|
3958
|
+
supports lookup, and a `userguide` explains how to operate the Foundry
|
|
3959
|
+
implementation. The setting guide can use ordinary SQL content tables and
|
|
3960
|
+
`:::secret` passages; its genre does not change its Address, journal, or page
|
|
3961
|
+
rendering.
|
|
3962
|
+
|
|
3963
|
+
```markdown
|
|
3964
|
+
---
|
|
3965
|
+
shortcode: reedflatsguide
|
|
3966
|
+
name: { full: The Reed Flats Guide }
|
|
3967
|
+
type: doc
|
|
3968
|
+
subType: settingguide
|
|
3969
|
+
description: A starting point for adventures in the Reed Flats.
|
|
3970
|
+
---
|
|
3971
|
+
|
|
3972
|
+
The Reed Flats are a network of marsh settlements linked by river trade.
|
|
3973
|
+
Their routes, customs, and rival groups shape everyday journeys.
|
|
3974
|
+
|
|
3975
|
+
:::secret
|
|
3976
|
+
The old ferry route is known to the local guides.
|
|
3977
|
+
:::
|
|
3978
|
+
```
|
|
3979
|
+
|
|
4000
3980
|
The field is a genre and only a genre: it says what kind of page this is, never
|
|
4001
3981
|
who reads it. A page written for a developer is a `howto` or a `concept` like
|
|
4002
3982
|
any other, and the audience is the section it sits in.
|
|
@@ -4066,13 +4046,6 @@ Foundry **Macro**, and these two describe that document.
|
|
|
4066
4046
|
| `macroType` | `script` | The Foundry macro type. Defaults to `script`, and `chat` is an error |
|
|
4067
4047
|
| `macroScope` | `global \| actors \| actor` | How far the macro reaches. Defaults to `global` |
|
|
4068
4048
|
|
|
4069
|
-
> **These fields are read from `sohl:` today, and should move to `data:`.** A
|
|
4070
|
-
> Macro is a core Foundry document — nothing about a script's type or scope is
|
|
4071
|
-
> system-specific — so authoring them under `sohl:` puts them where the only
|
|
4072
|
-
> available container was rather than where they belong. It is the same mistake
|
|
4073
|
-
> the map fields make, and no authored note carries either field today, so the
|
|
4074
|
-
> move costs nothing.
|
|
4075
|
-
|
|
4076
4049
|
**`macroType: chat` is an error, not an unimplemented feature.** A chat macro's
|
|
4077
4050
|
`command` is chat text rather than source, so none of the `{#script}` fence
|
|
4078
4051
|
rules describe it, and compiling one through this path would ship a macro whose
|
|
@@ -4185,8 +4158,7 @@ nothing.
|
|
|
4185
4158
|
|
|
4186
4159
|
**`color` must be quoted**, and YAML gives no third option: `color: #7a4b2a`
|
|
4187
4160
|
parses as `null` (a `#` after a space opens a comment) and `color: 000000` parses
|
|
4188
|
-
as the number `0`.
|
|
4189
|
-
written `"#RRGGBB"`.
|
|
4161
|
+
as the number `0`. Write `"#RRGGBB"` to retain the string.
|
|
4190
4162
|
|
|
4191
4163
|
`parent` is an address, so a dangling one is an ordinary dead-address finding
|
|
4192
4164
|
rather than a special-cased `Unknown folder id`, and a cycle is refused. Both are
|