@heroiclands/package-build 22.17.2 → 22.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/docs/authoring/frontmatter.md +2 -2
- package/docs/guides/icons.md +3 -0
- package/docs/reference/format-details.md +4 -0
- package/engine/actor-compiler.mjs +2 -3
- package/engine/art-fields.mjs +5 -10
- package/engine/infobox.mjs +13 -2
- package/package.json +1 -1
- package/types/engine/actor-compiler.d.mts +2 -3
- package/types/engine/art-fields.d.mts +5 -6
- package/types/engine/infobox.d.mts +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @heroiclands/package-build
|
|
2
2
|
|
|
3
|
+
## 22.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Beings use their subtype to choose default art.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
Being profiles identify each subject as Character, NPC, or Creature from its top-level subtype.
|
|
12
|
+
|
|
3
13
|
## 22.17.2
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
|
@@ -21,7 +21,7 @@ data: {}
|
|
|
21
21
|
---
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
`name.full` is the displayed name; `name.aliases` helps search. `description` is the short page summary. `tags` hold draft state and classification. `data` holds facts about the subject shared by systems. A YAML comment is the place for an author-only note: commented values remain valid YAML but do not enter the content index or generated documents.
|
|
24
|
+
`name.full` is the displayed name; `name.aliases` helps search. `description` is the short page summary. `tags` hold draft state and descriptive labels. The note type's classification belongs in `subType` where it is declared. `data` holds facts about the subject shared by systems. A YAML comment is the place for an author-only note: commented values remain valid YAML but do not enter the content index or generated documents.
|
|
25
25
|
|
|
26
26
|
Use `tags: [gm]` for a note intended only for the GM. It is absent from the public website and book. Foundry includes it only when its document routes to a pack with `private: true`. A note with `gm` that also creates a prose JournalEntry needs a private JournalEntry pack. Links from untagged notes to GM notes are errors; GM notes may link to one another.
|
|
27
27
|
|
|
@@ -37,4 +37,4 @@ One body describes the subject for both systems. A being's `{#appearance}` and `
|
|
|
37
37
|
|
|
38
38
|
## Publication and summaries
|
|
39
39
|
|
|
40
|
-
A note infobox draws from shared `data`. A system infobox draws from the system's fields, and a mapped system with no document says “Not available.” The same authored body appears in Foundry, on the website, and in the book; presentation adapts to each medium. [Infobox details](../reference/format-details.md#the-infobox) describe field order and empty values.
|
|
40
|
+
A note infobox draws from shared `data`. A being profile shows its top-level `subType` as `Type: Character`, `Type: NPC`, or `Type: Creature`. A system infobox draws from the system's fields, and a mapped system with no document says “Not available.” The same authored body appears in Foundry, on the website, and in the book; presentation adapts to each medium. [Infobox details](../reference/format-details.md#the-infobox) describe field order and empty values.
|
package/docs/guides/icons.md
CHANGED
|
@@ -58,6 +58,9 @@ it does not set a document's profile art. The
|
|
|
58
58
|
[art-slot reference](../reference/format-details.md#the-four-art-slots) gives each
|
|
59
59
|
slot's type and document destination.
|
|
60
60
|
|
|
61
|
+
A being's `subType` selects its compiled default art: `character` and `npc`
|
|
62
|
+
use person art, and `creature` uses creature art.
|
|
63
|
+
|
|
61
64
|
## Write an inline icon in prose
|
|
62
65
|
|
|
63
66
|
Declare the glyph vocabulary in `package-build.config.yaml` or a separate YAML
|
|
@@ -101,6 +101,10 @@ column regardless.
|
|
|
101
101
|
6. **Order is the toolchain's.** A medium renders boxes, sections and rows in
|
|
102
102
|
the order given.
|
|
103
103
|
|
|
104
|
+
A note profile begins with `Name`. For a being with a top-level `subType`, it
|
|
105
|
+
follows with `Type: Character`, `Type: NPC`, or `Type: Creature`. A being with
|
|
106
|
+
no subtype has no `Type` row.
|
|
107
|
+
|
|
104
108
|
**Embedded models link to documentation in an infobox.** The model Address
|
|
105
109
|
continues to identify the native Item used for compilation. Its displayed link
|
|
106
110
|
uses that same package, type and Shortcode under `note`, which names the
|
|
@@ -448,9 +448,8 @@ export class SystemActorCompiler extends BasePackCompiler {
|
|
|
448
448
|
* The actor's two pieces of art, resolved, with the being default beneath
|
|
449
449
|
* them.
|
|
450
450
|
*
|
|
451
|
-
* **The default follows the note's `subType
|
|
452
|
-
*
|
|
453
|
-
* to the package that ships them. A tree whose index cannot answer an
|
|
451
|
+
* **The default follows the note's `subType`**. Both addresses belong to
|
|
452
|
+
* the package that ships them. A tree whose index cannot answer an
|
|
454
453
|
* address — a dependency not yet fetched — falls through to the document
|
|
455
454
|
* subtype's own default, so the document is never left with no art.
|
|
456
455
|
*
|
package/engine/art-fields.mjs
CHANGED
|
@@ -45,7 +45,6 @@
|
|
|
45
45
|
*/
|
|
46
46
|
|
|
47
47
|
import { encodeAddresses } from "./address-values.mjs";
|
|
48
|
-
import { hasTag } from "./note-vocabulary.mjs";
|
|
49
48
|
import { ASSET_SYSTEM, isAssetType } from "./asset-types.mjs";
|
|
50
49
|
import { ASSETS_SEGMENT } from "./pathnames.mjs";
|
|
51
50
|
import { isAssetRecord } from "./index-records.mjs";
|
|
@@ -231,7 +230,7 @@ export function artPathname(index, value, defaultType, accepts) {
|
|
|
231
230
|
}
|
|
232
231
|
|
|
233
232
|
/**
|
|
234
|
-
* The art a being falls back to, by
|
|
233
|
+
* The art a being falls back to, by its subtype.
|
|
235
234
|
*
|
|
236
235
|
* Both files ship in `sohl`, under `assets/icons/other/`, and both are named
|
|
237
236
|
* here as addresses rather than as paths for the reason every art reference is:
|
|
@@ -239,8 +238,8 @@ export function artPathname(index, value, defaultType, accepts) {
|
|
|
239
238
|
* package borrowing the default gets the same file the system ships.
|
|
240
239
|
*
|
|
241
240
|
* **Only the compiler can choose between them**, because only the compiler
|
|
242
|
-
* reads the note's
|
|
243
|
-
* and covers a world document created by hand, which no note describes.
|
|
241
|
+
* reads the note's subtype. A schema default is the last resort beneath this
|
|
242
|
+
* one, and covers a world document created by hand, which no note describes.
|
|
244
243
|
*
|
|
245
244
|
* @type {Readonly<Record<string, string>>}
|
|
246
245
|
*/
|
|
@@ -252,20 +251,16 @@ export const BEING_DEFAULT_ART = Object.freeze({
|
|
|
252
251
|
/**
|
|
253
252
|
* The default art address a being's subtype chooses, or `null`.
|
|
254
253
|
*
|
|
255
|
-
* An NPC and a character use person art; a creature uses creature art.
|
|
256
|
-
* tag lookup preserves defaults for package trees that have not migrated.
|
|
254
|
+
* An NPC and a character use person art; a creature uses creature art.
|
|
257
255
|
*
|
|
258
256
|
* @param {object} fm - The note's frontmatter.
|
|
259
|
-
* @returns {string|null} The address, or `null` when no subtype
|
|
257
|
+
* @returns {string|null} The address, or `null` when no subtype selects one.
|
|
260
258
|
*/
|
|
261
259
|
export function beingDefaultArt(fm) {
|
|
262
260
|
if (fm?.subType === "npc" || fm?.subType === "character") {
|
|
263
261
|
return BEING_DEFAULT_ART.character;
|
|
264
262
|
}
|
|
265
263
|
if (fm?.subType === "creature") return BEING_DEFAULT_ART.creature;
|
|
266
|
-
for (const [tag, address] of Object.entries(BEING_DEFAULT_ART)) {
|
|
267
|
-
if (hasTag(fm, tag)) return address;
|
|
268
|
-
}
|
|
269
264
|
return null;
|
|
270
265
|
}
|
|
271
266
|
|
package/engine/infobox.mjs
CHANGED
|
@@ -187,6 +187,13 @@ export const NOTE_BOX_TITLE = "Profile";
|
|
|
187
187
|
/** The note infobox's single section id. @type {string} */
|
|
188
188
|
export const NOTE_SECTION_ID = "profile";
|
|
189
189
|
|
|
190
|
+
/** @type {Readonly<Record<string, string>>} */
|
|
191
|
+
const BEING_SUBTYPE_LABELS = Object.freeze({
|
|
192
|
+
npc: "NPC",
|
|
193
|
+
character: "Character",
|
|
194
|
+
creature: "Creature",
|
|
195
|
+
});
|
|
196
|
+
|
|
190
197
|
/**
|
|
191
198
|
* What a **duration pair** is called.
|
|
192
199
|
*
|
|
@@ -659,8 +666,9 @@ export function linkValue(ref, resolve, hint) {
|
|
|
659
666
|
*
|
|
660
667
|
* The rows are {@link NOTE_VOCABULARY}'s declaration for the type, in its
|
|
661
668
|
* order, minus what {@link NOTE_FIELD_PRESENTATION} withholds and minus every
|
|
662
|
-
* field the note left empty. A
|
|
663
|
-
*
|
|
669
|
+
* field the note left empty. A being's top-level `subType` adds its profile
|
|
670
|
+
* type. A type that declares no `data:` fields still gets the box, because
|
|
671
|
+
* `Name` is a fact about every note.
|
|
664
672
|
*
|
|
665
673
|
* @param {object} fm - The note's frontmatter.
|
|
666
674
|
* @param {object} [options] - Options.
|
|
@@ -698,6 +706,9 @@ function noteBox(
|
|
|
698
706
|
const shown = new Set();
|
|
699
707
|
const name = fm?.name?.full ?? fm?.title;
|
|
700
708
|
if (hasValue(name)) rows.push({ label: "Name", kind: "text", value: String(name) });
|
|
709
|
+
if (fm?.type === "being" && Object.hasOwn(BEING_SUBTYPE_LABELS, fm.subType)) {
|
|
710
|
+
rows.push({ label: "Type", kind: "text", value: BEING_SUBTYPE_LABELS[fm.subType] });
|
|
711
|
+
}
|
|
701
712
|
|
|
702
713
|
const data = isMapping(fm?.data) ? fm.data : {};
|
|
703
714
|
/** @type {Map<string, {label: string, entries: string[]}>} */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heroiclands/package-build",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.18.0",
|
|
4
4
|
"description": "Shared toolchain for building and shipping a HeroicLands Foundry VTT package — content compilation, manifest, localization, staging, bundle, release and deployment.",
|
|
5
5
|
"license": "GPL-3.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -230,9 +230,8 @@ export class SystemActorCompiler extends BasePackCompiler {
|
|
|
230
230
|
* The actor's two pieces of art, resolved, with the being default beneath
|
|
231
231
|
* them.
|
|
232
232
|
*
|
|
233
|
-
* **The default follows the note's `subType
|
|
234
|
-
*
|
|
235
|
-
* to the package that ships them. A tree whose index cannot answer an
|
|
233
|
+
* **The default follows the note's `subType`**. Both addresses belong to
|
|
234
|
+
* the package that ships them. A tree whose index cannot answer an
|
|
236
235
|
* address — a dependency not yet fetched — falls through to the document
|
|
237
236
|
* subtype's own default, so the document is never left with no art.
|
|
238
237
|
*
|
|
@@ -144,11 +144,10 @@ export function artPathname(index: object, value: unknown, defaultType: string,
|
|
|
144
144
|
/**
|
|
145
145
|
* The default art address a being's subtype chooses, or `null`.
|
|
146
146
|
*
|
|
147
|
-
* An NPC and a character use person art; a creature uses creature art.
|
|
148
|
-
* tag lookup preserves defaults for package trees that have not migrated.
|
|
147
|
+
* An NPC and a character use person art; a creature uses creature art.
|
|
149
148
|
*
|
|
150
149
|
* @param {object} fm - The note's frontmatter.
|
|
151
|
-
* @returns {string|null} The address, or `null` when no subtype
|
|
150
|
+
* @returns {string|null} The address, or `null` when no subtype selects one.
|
|
152
151
|
*/
|
|
153
152
|
export function beingDefaultArt(fm: object): string | null;
|
|
154
153
|
/**
|
|
@@ -180,7 +179,7 @@ export function unresolvedArtMessage(key: string, value: unknown): string;
|
|
|
180
179
|
export function unacceptedArtMessage(key: string, value: unknown, type: string, accepts: Iterable<string>): string;
|
|
181
180
|
export { ART_SLOTS } from "./art-slots.mjs";
|
|
182
181
|
/**
|
|
183
|
-
* The art a being falls back to, by
|
|
182
|
+
* The art a being falls back to, by its subtype.
|
|
184
183
|
*
|
|
185
184
|
* Both files ship in `sohl`, under `assets/icons/other/`, and both are named
|
|
186
185
|
* here as addresses rather than as paths for the reason every art reference is:
|
|
@@ -188,8 +187,8 @@ export { ART_SLOTS } from "./art-slots.mjs";
|
|
|
188
187
|
* package borrowing the default gets the same file the system ships.
|
|
189
188
|
*
|
|
190
189
|
* **Only the compiler can choose between them**, because only the compiler
|
|
191
|
-
* reads the note's
|
|
192
|
-
* and covers a world document created by hand, which no note describes.
|
|
190
|
+
* reads the note's subtype. A schema default is the last resort beneath this
|
|
191
|
+
* one, and covers a world document created by hand, which no note describes.
|
|
193
192
|
*
|
|
194
193
|
* @type {Readonly<Record<string, string>>}
|
|
195
194
|
*/
|
|
@@ -146,8 +146,9 @@ export function linkValue(ref: unknown, resolve: (ref: unknown, hint?: object) =
|
|
|
146
146
|
*
|
|
147
147
|
* The rows are {@link NOTE_VOCABULARY}'s declaration for the type, in its
|
|
148
148
|
* order, minus what {@link NOTE_FIELD_PRESENTATION} withholds and minus every
|
|
149
|
-
* field the note left empty. A
|
|
150
|
-
*
|
|
149
|
+
* field the note left empty. A being's top-level `subType` adds its profile
|
|
150
|
+
* type. A type that declares no `data:` fields still gets the box, because
|
|
151
|
+
* `Name` is a fact about every note.
|
|
151
152
|
*
|
|
152
153
|
* @param {object} fm - The note's frontmatter.
|
|
153
154
|
* @param {object} [options] - Options.
|