@patterkit/model 0.16.0 → 0.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/dist/index.cjs +25 -0
- package/dist/index.d.cts +39 -10
- package/dist/index.d.ts +39 -10
- package/dist/index.js +23 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -57,6 +57,7 @@ __export(index_exports, {
|
|
|
57
57
|
gameIdify: () => gameIdify,
|
|
58
58
|
isCaseOnlyPropertyName: () => import_expr.isCaseOnlyPropertyName,
|
|
59
59
|
isContentlessBeat: () => isContentlessBeat,
|
|
60
|
+
isDialogueScene: () => isDialogueScene,
|
|
60
61
|
isValidGameId: () => isValidGameId,
|
|
61
62
|
isValidPropertyName: () => import_expr.isValidPropertyName,
|
|
62
63
|
projectLayout: () => projectLayout,
|
|
@@ -64,6 +65,7 @@ __export(index_exports, {
|
|
|
64
65
|
propertyNameify: () => import_expr.propertyNameify,
|
|
65
66
|
qualifierStringKey: () => qualifierStringKey,
|
|
66
67
|
speakerLabelKey: () => speakerLabelKey,
|
|
68
|
+
textIsAction: () => textIsAction,
|
|
67
69
|
usedQualifiers: () => usedQualifiers,
|
|
68
70
|
usedSpeakerPairs: () => usedSpeakerPairs,
|
|
69
71
|
walkNodes: () => walkNodes
|
|
@@ -141,6 +143,27 @@ function usedSpeakerPairs(scenes) {
|
|
|
141
143
|
}
|
|
142
144
|
return out;
|
|
143
145
|
}
|
|
146
|
+
function isDialogueScene(scene) {
|
|
147
|
+
let found = false;
|
|
148
|
+
for (const block of scene.blocks) {
|
|
149
|
+
walkNodes(block.children, (node) => {
|
|
150
|
+
if (found) return;
|
|
151
|
+
if (node.type === "group") {
|
|
152
|
+
if (node.prompt?.kind === "line" && node.prompt.character) found = true;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
for (const beat of node.beats ?? []) if (beat.kind === "line" && beat.character) {
|
|
156
|
+
found = true;
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
if (found) return true;
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
function textIsAction(project, scene) {
|
|
165
|
+
return !project.localiseDialogueText && isDialogueScene(scene);
|
|
166
|
+
}
|
|
144
167
|
var DEFAULT_PAD_AFTER = 0.6;
|
|
145
168
|
var PAD_AFTER_MIN = -10;
|
|
146
169
|
var PAD_AFTER_MAX = 60;
|
|
@@ -258,6 +281,7 @@ var UNRESOLVED_KEY = "unresolved";
|
|
|
258
281
|
gameIdify,
|
|
259
282
|
isCaseOnlyPropertyName,
|
|
260
283
|
isContentlessBeat,
|
|
284
|
+
isDialogueScene,
|
|
261
285
|
isValidGameId,
|
|
262
286
|
isValidPropertyName,
|
|
263
287
|
projectLayout,
|
|
@@ -265,6 +289,7 @@ var UNRESOLVED_KEY = "unresolved";
|
|
|
265
289
|
propertyNameify,
|
|
266
290
|
qualifierStringKey,
|
|
267
291
|
speakerLabelKey,
|
|
292
|
+
textIsAction,
|
|
268
293
|
usedQualifiers,
|
|
269
294
|
usedSpeakerPairs,
|
|
270
295
|
walkNodes
|
package/dist/index.d.cts
CHANGED
|
@@ -43,7 +43,7 @@ interface LineBeat {
|
|
|
43
43
|
tags?: string[];
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* Text - speaker-less prose (spec §2). Never voiced; its
|
|
47
47
|
* localised text always permits inline `{@name}` interpolation (spec §16). This
|
|
48
48
|
* is the on-screen-text role (e.g. "A door slams!") - distinct from a game-event
|
|
49
49
|
* beat, which is a pure engine instruction with no localised content.
|
|
@@ -63,6 +63,11 @@ interface TextBeat {
|
|
|
63
63
|
extensions?: NodeExtensions;
|
|
64
64
|
/** Author tags (#215). See LineBeat.tags. */
|
|
65
65
|
tags?: string[];
|
|
66
|
+
/** Bundle only: this text beat is ACTION, a direction to the people staging the scene that the player
|
|
67
|
+
* never sees (design/proposals/action-text.md). Set by the compiler on every text beat of a dialogue scene
|
|
68
|
+
* (`isDialogueScene`) when the project's `localiseDialogueText` is off; its text is then the source in
|
|
69
|
+
* every locale. Absent = shown text. Never in source. */
|
|
70
|
+
action?: true;
|
|
66
71
|
}
|
|
67
72
|
/**
|
|
68
73
|
* A GAME EVENT (spec §2): a pure engine instruction with no player-facing text - just `gameData` the host
|
|
@@ -394,6 +399,12 @@ declare function usedSpeakerPairs(scenes: Scene[]): {
|
|
|
394
399
|
character: string;
|
|
395
400
|
qualifier: string;
|
|
396
401
|
}[];
|
|
402
|
+
/** A DIALOGUE scene (design/proposals/action-text.md): one with at least one line beat that names a
|
|
403
|
+
* character, an option's prompt included. Any other scene is a TEXT scene. */
|
|
404
|
+
declare function isDialogueScene(scene: Scene): boolean;
|
|
405
|
+
/** Whether a scene's text beats are ACTION: a dialogue scene, in a project that doesn't localise dialogue
|
|
406
|
+
* scenes' text (`localiseDialogueText` off, the default). Its option prompts never are. */
|
|
407
|
+
declare function textIsAction(project: Pick<ProjectFile, "localiseDialogueText">, scene: Scene): boolean;
|
|
397
408
|
/** The built-in `padAfter`, in seconds, for a project that sets no default of its own: the same on every runtime
|
|
398
409
|
* and in Patterpad's Play window (design/proposals/line-padding.md section 4). */
|
|
399
410
|
declare const DEFAULT_PAD_AFTER = 0.6;
|
|
@@ -412,7 +423,7 @@ interface BundleQualifier {
|
|
|
412
423
|
* the bundle; this type states the resulting contract for anyone reading a bundle. */
|
|
413
424
|
type BundleCastMember = Omit<CastMember, "notes" | "actor" | "gender">;
|
|
414
425
|
/** A node TYPE that can carry author-defined gameData fields (the gameData schema, project-level).
|
|
415
|
-
* Beat kinds map straight through: dialogue = `line`,
|
|
426
|
+
* Beat kinds map straight through: dialogue = `line`, text = `text`, game event = `gameEvent`.
|
|
416
427
|
* `option` is a choice's option: a group that is a direct child of a `choice` group, whose gameData the
|
|
417
428
|
* host reads off the option `getChoices` hands it. Any other group's gameData stays undeclared. */
|
|
418
429
|
type GameDataNodeKind = "scene" | "block" | "snippet" | "line" | "text" | "gameEvent" | "option";
|
|
@@ -589,7 +600,7 @@ interface ProjectFile {
|
|
|
589
600
|
* opt-in even for a voiced project (a voiced story may want voice scripts without tracking recording status). */
|
|
590
601
|
trackAudioStatus?: boolean;
|
|
591
602
|
/**
|
|
592
|
-
* Inline text formatting. When true, authors can mark dialogue /
|
|
603
|
+
* Inline text formatting. When true, authors can mark dialogue / text / direction /
|
|
593
604
|
* choice-prompt text bold, italic, or bold+italic; it is stored INSIDE the localised strings
|
|
594
605
|
* (and the flow's `direction`) as `<b>…</b>`, `<i>…</i>`, `<bi>…</bi>`, with literal `<`, `>`,
|
|
595
606
|
* `&` escaped to `<` / `>` / `&`. The runtime treats the string as opaque - it is the
|
|
@@ -662,13 +673,19 @@ interface ProjectFile {
|
|
|
662
673
|
/** The project's default `padAfter` for every line and text beat that sets none and has no default above it.
|
|
663
674
|
* Absent = `DEFAULT_PAD_AFTER`. */
|
|
664
675
|
padAfterDefault?: number;
|
|
676
|
+
/** Localise text lines in dialogue scenes (design/proposals/action-text.md). Off (absent) by default: a
|
|
677
|
+
* dialogue scene's text beats (`isDialogueScene`) are then ACTION, left out of the loc files and the
|
|
678
|
+
* written word counts, and compiled with `action: true`. On: they're localised and shown as a text
|
|
679
|
+
* scene's are. A text scene is localised whatever this says, and an option's prompt always is. */
|
|
680
|
+
localiseDialogueText?: boolean;
|
|
665
681
|
gameDataFields?: GameDataFields;
|
|
666
682
|
/**
|
|
667
683
|
* The Patter extensions this project takes, by id (ruled 2026-10-18: the project opts in), each pinned to a
|
|
668
684
|
* version, with its settings (the host fields its claims present, by setting name). The manifest itself
|
|
669
685
|
* sits in `extensions/<id>.extension.json`, and the data in `.patterextension` shards. Authoring config:
|
|
670
|
-
* the bundle carries each one's compiled declarations
|
|
671
|
-
*
|
|
686
|
+
* the bundle carries each one's compiled declarations, values, and resolved settings
|
|
687
|
+
* (`BundleExtension.settings`), never this block itself. An extension named here whose manifest is missing
|
|
688
|
+
* is a warning, and its data is left untouched.
|
|
672
689
|
*/
|
|
673
690
|
extensions?: Record<string, ProjectExtension>;
|
|
674
691
|
/** Ordered writing-status ladder (not-done -> done); default `DEFAULT_WRITING_STATUSES`. */
|
|
@@ -706,6 +723,11 @@ interface LocaleFile {
|
|
|
706
723
|
scene: string;
|
|
707
724
|
locale: string;
|
|
708
725
|
default?: boolean;
|
|
726
|
+
/** A translated shard only: its scene's text beats were action (`textIsAction`) when loc import last wrote
|
|
727
|
+
* it, so they aren't in it. Loc export and `patter validate` compare this with the scene now, to report
|
|
728
|
+
* text that has dropped out of the loc files or come into them. Absent = shown text, or a shard written
|
|
729
|
+
* before the setting existed. */
|
|
730
|
+
textAction?: true;
|
|
709
731
|
/** beatId -> text. */
|
|
710
732
|
strings: Record<string, string>;
|
|
711
733
|
}
|
|
@@ -918,7 +940,7 @@ interface HandoffFile {
|
|
|
918
940
|
}
|
|
919
941
|
/** An editable line as sent. */
|
|
920
942
|
interface HandoffLine {
|
|
921
|
-
/** The beat id (a line, a
|
|
943
|
+
/** The beat id (a line, a text beat, or an option prompt). */
|
|
922
944
|
id: string;
|
|
923
945
|
kind: "line" | "narration" | "option";
|
|
924
946
|
/** The speaker, speaker qualifier (`gameId`), and direction as sent (spoken lines only). */
|
|
@@ -1072,9 +1094,9 @@ interface Bundle {
|
|
|
1072
1094
|
gameDataFields?: GameDataFields;
|
|
1073
1095
|
/**
|
|
1074
1096
|
* The extensions the project takes, by id: each one's version and its compiled declarations by node kind,
|
|
1075
|
-
* every default resolved (what `extensionDecls` reads),
|
|
1076
|
-
* sit on the node, under `extensions`. Absent
|
|
1077
|
-
* byte for byte what it was.
|
|
1097
|
+
* every default resolved (what `extensionDecls` reads), the project node's own values, and its settings,
|
|
1098
|
+
* resolved (what `extensionSettings` reads). A node's values sit on the node, under `extensions`. Absent
|
|
1099
|
+
* when the project takes none, so a bundle without them is byte for byte what it was.
|
|
1078
1100
|
*/
|
|
1079
1101
|
extensions?: Record<string, BundleExtension>;
|
|
1080
1102
|
scenes: Record<string, CompiledScene>;
|
|
@@ -1325,6 +1347,13 @@ interface BundleExtension {
|
|
|
1325
1347
|
fields: Record<string, ExtensionFieldDecl[]>;
|
|
1326
1348
|
/** The project node's values, raw, when it has any. */
|
|
1327
1349
|
project?: Record<string, unknown>;
|
|
1350
|
+
/**
|
|
1351
|
+
* Every setting the manifest declares, by setting name, keys sorted: the project's value (`ProjectExtension.
|
|
1352
|
+
* settings`), or else the setting's default (`@wildwinter/toolkit/extensions`' `settingValues`). A setting
|
|
1353
|
+
* names a host field, so a game reads here which gameData field holds what the extension claims. Present
|
|
1354
|
+
* only when the manifest declares settings.
|
|
1355
|
+
*/
|
|
1356
|
+
settings?: Record<string, string>;
|
|
1328
1357
|
}
|
|
1329
1358
|
/**
|
|
1330
1359
|
* A compiled extension field declaration (`@wildwinter/toolkit/extensions`' FieldDecl, less the editor's
|
|
@@ -1354,4 +1383,4 @@ interface ExtensionFieldDecl {
|
|
|
1354
1383
|
/** A node's extension values in a bundle: extension id -> field -> value, raw. */
|
|
1355
1384
|
type NodeExtensions = Record<string, Record<string, unknown>>;
|
|
1356
1385
|
|
|
1357
|
-
export { AUTHORING_SCHEMA, type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, type BundleExtension, type BundleQualifier, COMMON_GENDERS, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_LAYOUT, DEFAULT_PAD_AFTER, DEFAULT_QUALIFIERS, DEFAULT_RECORDING_STATUSES, DEFAULT_SPEAKER_PATTERN, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, EXTENSIONS_DIR, EXTENSION_SCHEMA, EXTENSION_SHARD, type EditRecord, type Effect, type EngineSave, type EstimatingConfig, type Expression, type ExtensionFieldDecl, type ExtensionShard, FLOW_SCHEMA, type FlowCursor, type FlowFile, type FlowNode, type FlowSnapshot, type FlowSnapshotV2, type FlowState, type FlowValues, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, HANDOFF_SCHEMA, type HandoffFile, type HandoffImport, type HandoffLine, type HandoffRow, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, MANIFEST_EXTENSION, type NodeExtensions, PAD_AFTER_MAX, PAD_AFTER_MIN, PROJECT_EXTENSION_STEM, PROJECT_LOCALE_SCENE, PROJECT_SCHEMA, type ProjectDictionary, type ProjectExtension, type ProjectFile, type ProjectLayout, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL, type RecordingFolder, type RecordingStatusDecl, SAVE_SCHEMA, SAVE_VERSION, SPEAKER_PATTERN_KEY, STRINGS_SCHEMA, type SaveEnvelope, type SaveGame, type SaveGameV2, type SavedChoice, type SavedChoiceOption, type SavedChoicePrompt, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SelectorSnapshot, type SequenceOptions, type Snippet, type SpeakerQualifier, type StackFrame, type Suggestion, type SuggestionSource, type TextBeat, UNRESOLVED_KEY, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, formatSpeakerLabel, gameIdify, isContentlessBeat, isValidGameId, projectLayout, projectQualifiers, qualifierStringKey, speakerLabelKey, usedQualifiers, usedSpeakerPairs, walkNodes };
|
|
1386
|
+
export { AUTHORING_SCHEMA, type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, type BundleExtension, type BundleQualifier, COMMON_GENDERS, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_LAYOUT, DEFAULT_PAD_AFTER, DEFAULT_QUALIFIERS, DEFAULT_RECORDING_STATUSES, DEFAULT_SPEAKER_PATTERN, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, EXTENSIONS_DIR, EXTENSION_SCHEMA, EXTENSION_SHARD, type EditRecord, type Effect, type EngineSave, type EstimatingConfig, type Expression, type ExtensionFieldDecl, type ExtensionShard, FLOW_SCHEMA, type FlowCursor, type FlowFile, type FlowNode, type FlowSnapshot, type FlowSnapshotV2, type FlowState, type FlowValues, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, HANDOFF_SCHEMA, type HandoffFile, type HandoffImport, type HandoffLine, type HandoffRow, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, MANIFEST_EXTENSION, type NodeExtensions, PAD_AFTER_MAX, PAD_AFTER_MIN, PROJECT_EXTENSION_STEM, PROJECT_LOCALE_SCENE, PROJECT_SCHEMA, type ProjectDictionary, type ProjectExtension, type ProjectFile, type ProjectLayout, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL, type RecordingFolder, type RecordingStatusDecl, SAVE_SCHEMA, SAVE_VERSION, SPEAKER_PATTERN_KEY, STRINGS_SCHEMA, type SaveEnvelope, type SaveGame, type SaveGameV2, type SavedChoice, type SavedChoiceOption, type SavedChoicePrompt, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SelectorSnapshot, type SequenceOptions, type Snippet, type SpeakerQualifier, type StackFrame, type Suggestion, type SuggestionSource, type TextBeat, UNRESOLVED_KEY, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, formatSpeakerLabel, gameIdify, isContentlessBeat, isDialogueScene, isValidGameId, projectLayout, projectQualifiers, qualifierStringKey, speakerLabelKey, textIsAction, usedQualifiers, usedSpeakerPairs, walkNodes };
|
package/dist/index.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ interface LineBeat {
|
|
|
43
43
|
tags?: string[];
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* Text - speaker-less prose (spec §2). Never voiced; its
|
|
47
47
|
* localised text always permits inline `{@name}` interpolation (spec §16). This
|
|
48
48
|
* is the on-screen-text role (e.g. "A door slams!") - distinct from a game-event
|
|
49
49
|
* beat, which is a pure engine instruction with no localised content.
|
|
@@ -63,6 +63,11 @@ interface TextBeat {
|
|
|
63
63
|
extensions?: NodeExtensions;
|
|
64
64
|
/** Author tags (#215). See LineBeat.tags. */
|
|
65
65
|
tags?: string[];
|
|
66
|
+
/** Bundle only: this text beat is ACTION, a direction to the people staging the scene that the player
|
|
67
|
+
* never sees (design/proposals/action-text.md). Set by the compiler on every text beat of a dialogue scene
|
|
68
|
+
* (`isDialogueScene`) when the project's `localiseDialogueText` is off; its text is then the source in
|
|
69
|
+
* every locale. Absent = shown text. Never in source. */
|
|
70
|
+
action?: true;
|
|
66
71
|
}
|
|
67
72
|
/**
|
|
68
73
|
* A GAME EVENT (spec §2): a pure engine instruction with no player-facing text - just `gameData` the host
|
|
@@ -394,6 +399,12 @@ declare function usedSpeakerPairs(scenes: Scene[]): {
|
|
|
394
399
|
character: string;
|
|
395
400
|
qualifier: string;
|
|
396
401
|
}[];
|
|
402
|
+
/** A DIALOGUE scene (design/proposals/action-text.md): one with at least one line beat that names a
|
|
403
|
+
* character, an option's prompt included. Any other scene is a TEXT scene. */
|
|
404
|
+
declare function isDialogueScene(scene: Scene): boolean;
|
|
405
|
+
/** Whether a scene's text beats are ACTION: a dialogue scene, in a project that doesn't localise dialogue
|
|
406
|
+
* scenes' text (`localiseDialogueText` off, the default). Its option prompts never are. */
|
|
407
|
+
declare function textIsAction(project: Pick<ProjectFile, "localiseDialogueText">, scene: Scene): boolean;
|
|
397
408
|
/** The built-in `padAfter`, in seconds, for a project that sets no default of its own: the same on every runtime
|
|
398
409
|
* and in Patterpad's Play window (design/proposals/line-padding.md section 4). */
|
|
399
410
|
declare const DEFAULT_PAD_AFTER = 0.6;
|
|
@@ -412,7 +423,7 @@ interface BundleQualifier {
|
|
|
412
423
|
* the bundle; this type states the resulting contract for anyone reading a bundle. */
|
|
413
424
|
type BundleCastMember = Omit<CastMember, "notes" | "actor" | "gender">;
|
|
414
425
|
/** A node TYPE that can carry author-defined gameData fields (the gameData schema, project-level).
|
|
415
|
-
* Beat kinds map straight through: dialogue = `line`,
|
|
426
|
+
* Beat kinds map straight through: dialogue = `line`, text = `text`, game event = `gameEvent`.
|
|
416
427
|
* `option` is a choice's option: a group that is a direct child of a `choice` group, whose gameData the
|
|
417
428
|
* host reads off the option `getChoices` hands it. Any other group's gameData stays undeclared. */
|
|
418
429
|
type GameDataNodeKind = "scene" | "block" | "snippet" | "line" | "text" | "gameEvent" | "option";
|
|
@@ -589,7 +600,7 @@ interface ProjectFile {
|
|
|
589
600
|
* opt-in even for a voiced project (a voiced story may want voice scripts without tracking recording status). */
|
|
590
601
|
trackAudioStatus?: boolean;
|
|
591
602
|
/**
|
|
592
|
-
* Inline text formatting. When true, authors can mark dialogue /
|
|
603
|
+
* Inline text formatting. When true, authors can mark dialogue / text / direction /
|
|
593
604
|
* choice-prompt text bold, italic, or bold+italic; it is stored INSIDE the localised strings
|
|
594
605
|
* (and the flow's `direction`) as `<b>…</b>`, `<i>…</i>`, `<bi>…</bi>`, with literal `<`, `>`,
|
|
595
606
|
* `&` escaped to `<` / `>` / `&`. The runtime treats the string as opaque - it is the
|
|
@@ -662,13 +673,19 @@ interface ProjectFile {
|
|
|
662
673
|
/** The project's default `padAfter` for every line and text beat that sets none and has no default above it.
|
|
663
674
|
* Absent = `DEFAULT_PAD_AFTER`. */
|
|
664
675
|
padAfterDefault?: number;
|
|
676
|
+
/** Localise text lines in dialogue scenes (design/proposals/action-text.md). Off (absent) by default: a
|
|
677
|
+
* dialogue scene's text beats (`isDialogueScene`) are then ACTION, left out of the loc files and the
|
|
678
|
+
* written word counts, and compiled with `action: true`. On: they're localised and shown as a text
|
|
679
|
+
* scene's are. A text scene is localised whatever this says, and an option's prompt always is. */
|
|
680
|
+
localiseDialogueText?: boolean;
|
|
665
681
|
gameDataFields?: GameDataFields;
|
|
666
682
|
/**
|
|
667
683
|
* The Patter extensions this project takes, by id (ruled 2026-10-18: the project opts in), each pinned to a
|
|
668
684
|
* version, with its settings (the host fields its claims present, by setting name). The manifest itself
|
|
669
685
|
* sits in `extensions/<id>.extension.json`, and the data in `.patterextension` shards. Authoring config:
|
|
670
|
-
* the bundle carries each one's compiled declarations
|
|
671
|
-
*
|
|
686
|
+
* the bundle carries each one's compiled declarations, values, and resolved settings
|
|
687
|
+
* (`BundleExtension.settings`), never this block itself. An extension named here whose manifest is missing
|
|
688
|
+
* is a warning, and its data is left untouched.
|
|
672
689
|
*/
|
|
673
690
|
extensions?: Record<string, ProjectExtension>;
|
|
674
691
|
/** Ordered writing-status ladder (not-done -> done); default `DEFAULT_WRITING_STATUSES`. */
|
|
@@ -706,6 +723,11 @@ interface LocaleFile {
|
|
|
706
723
|
scene: string;
|
|
707
724
|
locale: string;
|
|
708
725
|
default?: boolean;
|
|
726
|
+
/** A translated shard only: its scene's text beats were action (`textIsAction`) when loc import last wrote
|
|
727
|
+
* it, so they aren't in it. Loc export and `patter validate` compare this with the scene now, to report
|
|
728
|
+
* text that has dropped out of the loc files or come into them. Absent = shown text, or a shard written
|
|
729
|
+
* before the setting existed. */
|
|
730
|
+
textAction?: true;
|
|
709
731
|
/** beatId -> text. */
|
|
710
732
|
strings: Record<string, string>;
|
|
711
733
|
}
|
|
@@ -918,7 +940,7 @@ interface HandoffFile {
|
|
|
918
940
|
}
|
|
919
941
|
/** An editable line as sent. */
|
|
920
942
|
interface HandoffLine {
|
|
921
|
-
/** The beat id (a line, a
|
|
943
|
+
/** The beat id (a line, a text beat, or an option prompt). */
|
|
922
944
|
id: string;
|
|
923
945
|
kind: "line" | "narration" | "option";
|
|
924
946
|
/** The speaker, speaker qualifier (`gameId`), and direction as sent (spoken lines only). */
|
|
@@ -1072,9 +1094,9 @@ interface Bundle {
|
|
|
1072
1094
|
gameDataFields?: GameDataFields;
|
|
1073
1095
|
/**
|
|
1074
1096
|
* The extensions the project takes, by id: each one's version and its compiled declarations by node kind,
|
|
1075
|
-
* every default resolved (what `extensionDecls` reads),
|
|
1076
|
-
* sit on the node, under `extensions`. Absent
|
|
1077
|
-
* byte for byte what it was.
|
|
1097
|
+
* every default resolved (what `extensionDecls` reads), the project node's own values, and its settings,
|
|
1098
|
+
* resolved (what `extensionSettings` reads). A node's values sit on the node, under `extensions`. Absent
|
|
1099
|
+
* when the project takes none, so a bundle without them is byte for byte what it was.
|
|
1078
1100
|
*/
|
|
1079
1101
|
extensions?: Record<string, BundleExtension>;
|
|
1080
1102
|
scenes: Record<string, CompiledScene>;
|
|
@@ -1325,6 +1347,13 @@ interface BundleExtension {
|
|
|
1325
1347
|
fields: Record<string, ExtensionFieldDecl[]>;
|
|
1326
1348
|
/** The project node's values, raw, when it has any. */
|
|
1327
1349
|
project?: Record<string, unknown>;
|
|
1350
|
+
/**
|
|
1351
|
+
* Every setting the manifest declares, by setting name, keys sorted: the project's value (`ProjectExtension.
|
|
1352
|
+
* settings`), or else the setting's default (`@wildwinter/toolkit/extensions`' `settingValues`). A setting
|
|
1353
|
+
* names a host field, so a game reads here which gameData field holds what the extension claims. Present
|
|
1354
|
+
* only when the manifest declares settings.
|
|
1355
|
+
*/
|
|
1356
|
+
settings?: Record<string, string>;
|
|
1328
1357
|
}
|
|
1329
1358
|
/**
|
|
1330
1359
|
* A compiled extension field declaration (`@wildwinter/toolkit/extensions`' FieldDecl, less the editor's
|
|
@@ -1354,4 +1383,4 @@ interface ExtensionFieldDecl {
|
|
|
1354
1383
|
/** A node's extension values in a bundle: extension id -> field -> value, raw. */
|
|
1355
1384
|
type NodeExtensions = Record<string, Record<string, unknown>>;
|
|
1356
1385
|
|
|
1357
|
-
export { AUTHORING_SCHEMA, type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, type BundleExtension, type BundleQualifier, COMMON_GENDERS, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_LAYOUT, DEFAULT_PAD_AFTER, DEFAULT_QUALIFIERS, DEFAULT_RECORDING_STATUSES, DEFAULT_SPEAKER_PATTERN, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, EXTENSIONS_DIR, EXTENSION_SCHEMA, EXTENSION_SHARD, type EditRecord, type Effect, type EngineSave, type EstimatingConfig, type Expression, type ExtensionFieldDecl, type ExtensionShard, FLOW_SCHEMA, type FlowCursor, type FlowFile, type FlowNode, type FlowSnapshot, type FlowSnapshotV2, type FlowState, type FlowValues, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, HANDOFF_SCHEMA, type HandoffFile, type HandoffImport, type HandoffLine, type HandoffRow, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, MANIFEST_EXTENSION, type NodeExtensions, PAD_AFTER_MAX, PAD_AFTER_MIN, PROJECT_EXTENSION_STEM, PROJECT_LOCALE_SCENE, PROJECT_SCHEMA, type ProjectDictionary, type ProjectExtension, type ProjectFile, type ProjectLayout, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL, type RecordingFolder, type RecordingStatusDecl, SAVE_SCHEMA, SAVE_VERSION, SPEAKER_PATTERN_KEY, STRINGS_SCHEMA, type SaveEnvelope, type SaveGame, type SaveGameV2, type SavedChoice, type SavedChoiceOption, type SavedChoicePrompt, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SelectorSnapshot, type SequenceOptions, type Snippet, type SpeakerQualifier, type StackFrame, type Suggestion, type SuggestionSource, type TextBeat, UNRESOLVED_KEY, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, formatSpeakerLabel, gameIdify, isContentlessBeat, isValidGameId, projectLayout, projectQualifiers, qualifierStringKey, speakerLabelKey, usedQualifiers, usedSpeakerPairs, walkNodes };
|
|
1386
|
+
export { AUTHORING_SCHEMA, type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, type BundleExtension, type BundleQualifier, COMMON_GENDERS, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_LAYOUT, DEFAULT_PAD_AFTER, DEFAULT_QUALIFIERS, DEFAULT_RECORDING_STATUSES, DEFAULT_SPEAKER_PATTERN, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, EXTENSIONS_DIR, EXTENSION_SCHEMA, EXTENSION_SHARD, type EditRecord, type Effect, type EngineSave, type EstimatingConfig, type Expression, type ExtensionFieldDecl, type ExtensionShard, FLOW_SCHEMA, type FlowCursor, type FlowFile, type FlowNode, type FlowSnapshot, type FlowSnapshotV2, type FlowState, type FlowValues, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, HANDOFF_SCHEMA, type HandoffFile, type HandoffImport, type HandoffLine, type HandoffRow, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, MANIFEST_EXTENSION, type NodeExtensions, PAD_AFTER_MAX, PAD_AFTER_MIN, PROJECT_EXTENSION_STEM, PROJECT_LOCALE_SCENE, PROJECT_SCHEMA, type ProjectDictionary, type ProjectExtension, type ProjectFile, type ProjectLayout, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL, type RecordingFolder, type RecordingStatusDecl, SAVE_SCHEMA, SAVE_VERSION, SPEAKER_PATTERN_KEY, STRINGS_SCHEMA, type SaveEnvelope, type SaveGame, type SaveGameV2, type SavedChoice, type SavedChoiceOption, type SavedChoicePrompt, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SelectorSnapshot, type SequenceOptions, type Snippet, type SpeakerQualifier, type StackFrame, type Suggestion, type SuggestionSource, type TextBeat, UNRESOLVED_KEY, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, formatSpeakerLabel, gameIdify, isContentlessBeat, isDialogueScene, isValidGameId, projectLayout, projectQualifiers, qualifierStringKey, speakerLabelKey, textIsAction, usedQualifiers, usedSpeakerPairs, walkNodes };
|
package/dist/index.js
CHANGED
|
@@ -76,6 +76,27 @@ function usedSpeakerPairs(scenes) {
|
|
|
76
76
|
}
|
|
77
77
|
return out;
|
|
78
78
|
}
|
|
79
|
+
function isDialogueScene(scene) {
|
|
80
|
+
let found = false;
|
|
81
|
+
for (const block of scene.blocks) {
|
|
82
|
+
walkNodes(block.children, (node) => {
|
|
83
|
+
if (found) return;
|
|
84
|
+
if (node.type === "group") {
|
|
85
|
+
if (node.prompt?.kind === "line" && node.prompt.character) found = true;
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
for (const beat of node.beats ?? []) if (beat.kind === "line" && beat.character) {
|
|
89
|
+
found = true;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
if (found) return true;
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
function textIsAction(project, scene) {
|
|
98
|
+
return !project.localiseDialogueText && isDialogueScene(scene);
|
|
99
|
+
}
|
|
79
100
|
var DEFAULT_PAD_AFTER = 0.6;
|
|
80
101
|
var PAD_AFTER_MIN = -10;
|
|
81
102
|
var PAD_AFTER_MAX = 60;
|
|
@@ -192,6 +213,7 @@ export {
|
|
|
192
213
|
gameIdify,
|
|
193
214
|
isCaseOnlyPropertyName,
|
|
194
215
|
isContentlessBeat,
|
|
216
|
+
isDialogueScene,
|
|
195
217
|
isValidGameId,
|
|
196
218
|
isValidPropertyName,
|
|
197
219
|
projectLayout,
|
|
@@ -199,6 +221,7 @@ export {
|
|
|
199
221
|
propertyNameify,
|
|
200
222
|
qualifierStringKey,
|
|
201
223
|
speakerLabelKey,
|
|
224
|
+
textIsAction,
|
|
202
225
|
usedQualifiers,
|
|
203
226
|
usedSpeakerPairs,
|
|
204
227
|
walkNodes
|
package/package.json
CHANGED