narraleaf-studio 1.2.0 → 1.4.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/_api.d.ts CHANGED
@@ -1707,6 +1707,17 @@ type BlueprintDiagnostic = {
1707
1707
  /** Source span or module location; M1 opaque */
1708
1708
  location?: Record<string, unknown>;
1709
1709
  };
1710
+ type LocaleCode = string;
1711
+ type LocalizationUnitStatus = "untranslated" | "machine" | "translated" | "reviewed";
1712
+ type LocalizationUnit = {
1713
+ /** Translated text; `{n}` placeholders map to the source segment's inline interpolations. */
1714
+ target: string;
1715
+ /** Hash of the source text at translation time (see shared/utils/localizationText). */
1716
+ sourceHash: string;
1717
+ status: LocalizationUnitStatus;
1718
+ /** Optional translator note. */
1719
+ note?: string;
1720
+ };
1710
1721
  type BlueprintAssetPinKind = "image" | "audio" | "font";
1711
1722
  type BlueprintAssetPinRef = {
1712
1723
  kind: BlueprintAssetPinKind;
@@ -1764,6 +1775,38 @@ type BlueprintOpenExternalResult = {
1764
1775
  };
1765
1776
  type BlueprintGraphKind = "event" | "function" | "macro";
1766
1777
  type GameBuildPlatform = "windows" | "macos" | "linux" | "web" | "android" | "ios";
1778
+ declare const UI_STRUCT_FIELD_TYPES: readonly [
1779
+ "string",
1780
+ "number",
1781
+ "boolean",
1782
+ "image",
1783
+ "color",
1784
+ "json"
1785
+ ];
1786
+ type UIStructFieldType = (typeof UI_STRUCT_FIELD_TYPES)[number];
1787
+ type UIStructField = {
1788
+ /**
1789
+ * Stable identity. Value bindings, node params and generated pins all address a field by this,
1790
+ * so renaming `key` costs nothing and reshuffling the list costs nothing.
1791
+ */
1792
+ id: string;
1793
+ /** The property name this field occupies inside an item object. */
1794
+ key: string;
1795
+ /**
1796
+ * What the author called it, shown in the item table header and in every field picker.
1797
+ *
1798
+ * Optional because `key` is usually already the readable name; a label is what lets a field
1799
+ * whose key has to stay ASCII (it travels in JSON to a plugin, a save file, a story variable)
1800
+ * still read as words in the editor.
1801
+ */
1802
+ label?: string;
1803
+ type: UIStructFieldType;
1804
+ };
1805
+ type UIStructId = string;
1806
+ type UIStructDef = {
1807
+ id: UIStructId;
1808
+ fields: UIStructField[];
1809
+ };
1767
1810
  type PluginPermissionPersistence = "temporary" | "permanent";
1768
1811
  type PluginFileSystemPermissionMode = "read" | "write" | "readwrite";
1769
1812
  /**
@@ -2113,7 +2156,7 @@ type PluginBuildConfigFieldContribution = {
2113
2156
  /** A build that would ship without a value for this field is refused. */
2114
2157
  required?: boolean;
2115
2158
  };
2116
- type PluginContributes = {
2159
+ export type PluginContributes = {
2117
2160
  /** Blueprint node types this plugin provides (editor def + runtime execute). */
2118
2161
  blueprintNodes?: string[];
2119
2162
  /** Widget element types this plugin provides (editor module + runtime renderer). */
@@ -2219,6 +2262,67 @@ type PluginContributes = {
2219
2262
  * install - and the list shows them attributed to this plugin rather than quietly making room.
2220
2263
  */
2221
2264
  network?: string[];
2265
+ /**
2266
+ * The props of a contributed widget that hold words a player reads, by widget type.
2267
+ *
2268
+ * Each type named here must also be in {@link widgets}. A declared prop is treated as Studio's own
2269
+ * text and button labels are: the properties panel offers its words written directly or read
2270
+ * from a translation key, the canvas draws a key's words, the words go into the project's
2271
+ * translation table and exports, the project checks report a missing translation or key, and
2272
+ * the glyph check reads them. In the game the widget's renderer is handed the words already in
2273
+ * the player's language, in the prop it declared - it never resolves a key itself.
2274
+ *
2275
+ * Declared in the manifest rather than at registration because both entries need it - the
2276
+ * studio entry's widget is edited by it and the runtime entry's is drawn by it - and a
2277
+ * declaration only one of them made would be the half that drifts.
2278
+ */
2279
+ widgetText?: Record<string, PluginWidgetTextContribution[]>;
2280
+ /**
2281
+ * The shapes of the rows this plugin's nodes hand out, so a list can be given one and a field
2282
+ * read from one by name.
2283
+ *
2284
+ * A node pin carrying them says `struct:<id>` or `array<struct:<id>>` - `Get Gallery` answers
2285
+ * `array<struct:narraleaf.gallery.entry>` - and from then on the plugin's rows are what the
2286
+ * engine's own are: a list picks the shape under Edit content and its fields are the plugin's
2287
+ * and locked, Get Field offers them, and a list handed rows that lack them is reported.
2288
+ *
2289
+ * Declared in the manifest rather than at registration because the editor, the running game and
2290
+ * the command-line checker all need the shape, and only the manifest is read by all three before
2291
+ * any plugin code runs. Ids must start with the plugin id.
2292
+ */
2293
+ structs?: PluginStructContribution[];
2294
+ };
2295
+ type PluginStructContribution = {
2296
+ /** Prefixed with the plugin id: `narraleaf.gallery.entry`. */
2297
+ id: string;
2298
+ /** What the editor calls the shape - "Gallery entry". */
2299
+ name: string;
2300
+ /** `name` per editor locale, matched exactly as `localized` names are. */
2301
+ localized?: Record<string, string>;
2302
+ /** In the order the rows are read: the list's content editor shows them in this order. */
2303
+ fields: {
2304
+ key: string;
2305
+ type: UIStructFieldType;
2306
+ }[];
2307
+ };
2308
+ /**
2309
+ * One prop of a contributed widget whose value is words a player reads.
2310
+ *
2311
+ * `keyProp` is the prop the widget's translation key is kept in when the author reads the words from
2312
+ * one. It defaults to `<prop>LocalizationKey`, and it is the host's to write: the widget never reads it
2313
+ * to draw, because the words in `prop` already come from the key when there is one.
2314
+ */
2315
+ export type PluginWidgetTextContribution = {
2316
+ /** The prop holding the words. */
2317
+ prop: string;
2318
+ /** The prop the translation key is kept in; `<prop>LocalizationKey` when not declared. */
2319
+ keyProp?: string;
2320
+ /** What the properties panel calls the words. The prop name when not declared. */
2321
+ label?: string;
2322
+ /** `label` per editor locale, matched exactly as `localized` names are. */
2323
+ localized?: Record<string, string>;
2324
+ /** Whether the words may run over several lines; one line when not declared. */
2325
+ multiline?: boolean;
2222
2326
  };
2223
2327
  /**
2224
2328
  * The plugin's name and description in one editor language. Either may be left out, and the plain
@@ -2336,6 +2440,7 @@ export type RuntimePluginDescriptor = {
2336
2440
  type GameMenuLabel = {
2337
2441
  readonly key?: string | null;
2338
2442
  readonly text: string;
2443
+ readonly words?: string | null;
2339
2444
  };
2340
2445
  declare const GAME_MENU_DYNAMIC_SOURCES: readonly [
2341
2446
  "textLanguage",
@@ -2512,6 +2617,9 @@ type UIInputBinding = {
2512
2617
  } | {
2513
2618
  kind: "key";
2514
2619
  key: string;
2620
+ } | {
2621
+ kind: "gamepad";
2622
+ button: string;
2515
2623
  };
2516
2624
  type UIInputActionDef = {
2517
2625
  id: string;
@@ -2564,38 +2672,6 @@ type UIPageAnimationSettings = {
2564
2672
  /** Surfaces only: hold the incoming Page until this exit has finished. */
2565
2673
  exitBlocking: boolean;
2566
2674
  };
2567
- declare const UI_STRUCT_FIELD_TYPES: readonly [
2568
- "string",
2569
- "number",
2570
- "boolean",
2571
- "image",
2572
- "color",
2573
- "json"
2574
- ];
2575
- type UIStructFieldType = (typeof UI_STRUCT_FIELD_TYPES)[number];
2576
- type UIStructField = {
2577
- /**
2578
- * Stable identity. Value bindings, node params and generated pins all address a field by this,
2579
- * so renaming `key` costs nothing and reshuffling the list costs nothing.
2580
- */
2581
- id: string;
2582
- /** The property name this field occupies inside an item object. */
2583
- key: string;
2584
- /**
2585
- * What the author called it, shown in the item table header and in every field picker.
2586
- *
2587
- * Optional because `key` is usually already the readable name; a label is what lets a field
2588
- * whose key has to stay ASCII (it travels in JSON to a plugin, a save file, a story variable)
2589
- * still read as words in the editor.
2590
- */
2591
- label?: string;
2592
- type: UIStructFieldType;
2593
- };
2594
- type UIStructId = string;
2595
- type UIStructDef = {
2596
- id: UIStructId;
2597
- fields: UIStructField[];
2598
- };
2599
2675
  type UISurfaceBackgroundFillMode = "cover" | "contain" | "stretch" | "tile";
2600
2676
  type UISurfaceBackgroundImage = {
2601
2677
  /** Image library asset id. Absent background = absent field, so this is never empty. */
@@ -2679,7 +2755,27 @@ type UIAppSurface = {
2679
2755
  * whether what it just did leaves anything for the surface behind to do.
2680
2756
  */
2681
2757
  actions?: UISurfaceActionEnablement[];
2758
+ /** The values this page is opened with, in author order. See {@link UIPageParam}. */
2759
+ params?: UIPageParam[];
2682
2760
  };
2761
+ type UIPageParam = {
2762
+ id: string;
2763
+ name: string;
2764
+ type: UIPageParamType;
2765
+ /**
2766
+ * For a `list`: the shape each row has, as a struct id (an engine shape such as `nl.confirmButton`,
2767
+ * a plugin's, or one of the project's). It types the value on both ends - the inputs that give it
2768
+ * and `Get Page Param` - and a list on the page bound to it is checked against it. Absent for
2769
+ * every other type, and for a list of rows of no declared shape.
2770
+ */
2771
+ struct?: string;
2772
+ /**
2773
+ * What the page reads when whoever opened it gave nothing for this name, in the declared type.
2774
+ * Absent reads as the type's empty value (`uiPageParamDefaultValue`).
2775
+ */
2776
+ defaultValue?: unknown;
2777
+ };
2778
+ type UIPageParamType = "string" | "text" | "number" | "boolean" | "list" | "json";
2683
2779
  type UIStageSurface = {
2684
2780
  id: UISurfaceId;
2685
2781
  name: string;
@@ -2738,10 +2834,15 @@ type UIComponentParam = {
2738
2834
  id: string;
2739
2835
  /** What the author called it, shown in the instance's inspector. */
2740
2836
  name: string;
2741
- type: "string";
2742
- /** Used by an instance that has not overridden it, and by the definition's own preview. */
2837
+ type: UIComponentParamType;
2838
+ /**
2839
+ * Used by an instance that has not overridden it, and by the definition's own preview. For a
2840
+ * `text` parameter these are words written directly, translated through the definition's own unit
2841
+ * (`uiComponentParamUnitId(componentId, paramId)`).
2842
+ */
2743
2843
  defaultValue: string;
2744
2844
  };
2845
+ type UIComponentParamType = "string" | "text";
2745
2846
  type UIElement = {
2746
2847
  id: UIElementId;
2747
2848
  type: string;
@@ -2801,6 +2902,34 @@ type UIElementValueBinding = {
2801
2902
  | {
2802
2903
  kind: "listItemField";
2803
2904
  fieldId: string;
2905
+ }
2906
+ /**
2907
+ * Show the value one placement gives a text parameter of the component this element is part of.
2908
+ *
2909
+ * The component's counterpart of `listItemField`, and the same kind of read: no graph, nothing
2910
+ * kept alive - the value is taken from the placement being drawn (`resolveUIComponentTextParams`),
2911
+ * so the editing canvas draws each placement with its own words, and the game translates each
2912
+ * through the placement's own unit or reads the key it names. Only a text parameter answers one,
2913
+ * and only a widget's words take one; outside a placement (the component's own editor) the
2914
+ * element's own words are drawn, as sample text.
2915
+ */
2916
+ | {
2917
+ kind: "componentParam";
2918
+ paramId: string;
2919
+ }
2920
+ /**
2921
+ * Show the value the page this element is on was opened with for one of its text parameters.
2922
+ *
2923
+ * The page's counterpart of `componentParam`, read the same way: no graph - the value is taken from
2924
+ * the props the page was opened with (`resolveUIPageTextParams`), words given at the opening shown
2925
+ * as given, the declared default translated through the page's own unit. Only a text parameter
2926
+ * answers one, only a widget's words take one, and only on a page: a component's insides and a
2927
+ * Game UI have no page parameters to show. The editing canvas, where the page has not been opened,
2928
+ * draws the default, or the element's own words as sample text while the default is empty.
2929
+ */
2930
+ | {
2931
+ kind: "pageParam";
2932
+ paramId: string;
2804
2933
  };
2805
2934
  type UILayout = {
2806
2935
  x: number;
@@ -3337,6 +3466,10 @@ declare const en: {
3337
3466
  readonly downloadRewrites: {
3338
3467
  readonly label: "Download address rewrites";
3339
3468
  };
3469
+ readonly useSystemProxy: {
3470
+ readonly label: "Use this computer's proxy";
3471
+ readonly description: "Studio downloads follow the proxy this computer already uses.";
3472
+ };
3340
3473
  readonly pluginRegistryUrl: {
3341
3474
  readonly label: "Plugin registry URL";
3342
3475
  readonly description: "Where the plugin store looks for its index.";
@@ -3849,7 +3982,7 @@ declare const en: {
3849
3982
  readonly table: {
3850
3983
  readonly storyLabel: "Source";
3851
3984
  readonly sourceUi: "Interface text";
3852
- readonly sourceKeys: "Named keys";
3985
+ readonly sourceKeys: "Translation keys";
3853
3986
  readonly modeTranslate: "Translate";
3854
3987
  readonly modeReview: "Review";
3855
3988
  readonly filterAll: "All";
@@ -3870,11 +4003,12 @@ declare const en: {
3870
4003
  readonly removeKey: "Remove key";
3871
4004
  readonly removeKeyConfirm: "Remove {name}?";
3872
4005
  readonly removeKeyConfirmDetail: "Existing translations of this key stay in the language files.";
3873
- readonly removeKeyUsedBy: "Used by:";
4006
+ readonly removeKeyWidgets: "These widgets keep the key's words and translations as their own:";
4007
+ readonly removeKeyBlueprints: "Blueprints that use the key:";
3874
4008
  readonly removeKeyUsedByElement: "{owner} \u25B8 {element}";
3875
4009
  readonly removeKeyUsedByBlueprint: "Blueprint \u201C{name}\u201D";
3876
4010
  readonly removeKeyUsedByMore: "and {count} more";
3877
- readonly removeKeyUsedByAfter: "Once the key is removed, the project check reports each of them.";
4011
+ readonly removeKeyUsedByAfter: "Once the key is removed, the project check reports each of these blueprints.";
3878
4012
  readonly sourceColumn: "Source";
3879
4013
  readonly targetColumn: "Translation";
3880
4014
  readonly targetPlaceholder: "Translate\u2026";
@@ -3996,6 +4130,18 @@ declare const en: {
3996
4130
  readonly findPlaceholder: "Find in lines";
3997
4131
  };
3998
4132
  };
4133
+ readonly textSourceMigration: {
4134
+ readonly message: {
4135
+ readonly one: "Interface text was upgraded. The words of {count} widget now come from a different source.";
4136
+ readonly other: "Interface text was upgraded. The words of {count} widgets now come from a different source.";
4137
+ };
4138
+ readonly place: "{n}. {owner} \u25B8 {element}: {change}";
4139
+ readonly marksKept: "now Direct, keeping its marks, and no longer uses the key {key}";
4140
+ readonly bindingDropped: "a binding that never showed was removed, and the key {key} shows";
4141
+ readonly missingKey: "the key {key} does not exist, so it is now Direct, with the same words and translations";
4142
+ readonly keyDiffered: "now Direct, keeping the words it showed, and no longer uses the key {key}";
4143
+ readonly locate: "Locate {n}";
4144
+ };
3999
4145
  readonly recovery: {
4000
4146
  readonly enter: "Open in recovery mode";
4001
4147
  readonly enterFailed: "Could not open recovery mode: {error}";
@@ -4205,7 +4351,7 @@ declare const en: {
4205
4351
  readonly liveCheckpointNone: "There was nothing uncommitted to record.";
4206
4352
  readonly livePendingOne: "1 change is waiting for the host.";
4207
4353
  readonly livePendingMany: "{count} changes are waiting for the host.";
4208
- readonly liveFrozenWhat: "The stories, the cast, the translations, the whole asset library - files included - and the project's own tables (the dictionary, the audio tracks, the asset sets, the variables, the named strings, the build variants, the DLC and the palette) are saved. Everything else here is current and read-only until the session ends.";
4354
+ readonly liveFrozenWhat: "The stories, the cast, the translations, the whole asset library - files included - and the project's own tables (the dictionary, the audio tracks, the asset sets, the variables, the translation keys, the build variants, the DLC and the palette) are saved. Everything else here is current and read-only until the session ends.";
4209
4355
  readonly liveUnavailableHere: "Unavailable in a live session.";
4210
4356
  readonly liveClaimsLabel: "Lines being written";
4211
4357
  readonly liveClaimOne: "{name} is writing 1 line.";
@@ -4243,6 +4389,7 @@ declare const en: {
4243
4389
  readonly panelRenderError: "This panel hit a rendering error";
4244
4390
  readonly mainEditorRegion: "Main editor";
4245
4391
  readonly resizeSplit: "Resize split";
4392
+ readonly resizeSections: "Resize sections";
4246
4393
  readonly noActiveEditor: "No active editor";
4247
4394
  readonly closePanel: "Close panel";
4248
4395
  readonly closeTab: "Close {name}";
@@ -4407,6 +4554,7 @@ declare const en: {
4407
4554
  readonly runStatus: "Run status";
4408
4555
  readonly projectTrust: "Project trust";
4409
4556
  readonly studioTasks: "Background work";
4557
+ readonly problems: "Problems";
4410
4558
  readonly unsavedChanges: "Unsaved changes";
4411
4559
  readonly wordCount: "Story stats";
4412
4560
  readonly shortcuts: "Shortcuts and mouse actions";
@@ -4818,6 +4966,15 @@ declare const en: {
4818
4966
  readonly alignBottom: "Align bottom";
4819
4967
  readonly distributeHorizontal: "Distribute horizontally";
4820
4968
  readonly distributeVertical: "Distribute vertically";
4969
+ readonly nudgeLeft: "Move left 1 px";
4970
+ readonly nudgeRight: "Move right 1 px";
4971
+ readonly nudgeUp: "Move up 1 px";
4972
+ readonly nudgeDown: "Move down 1 px";
4973
+ readonly nudgeLeftLarge: "Move left 10 px";
4974
+ readonly nudgeRightLarge: "Move right 10 px";
4975
+ readonly nudgeUpLarge: "Move up 10 px";
4976
+ readonly nudgeDownLarge: "Move down 10 px";
4977
+ readonly snapToGrid: "Snap to grid";
4821
4978
  };
4822
4979
  readonly blueprint: {
4823
4980
  readonly undo: "Undo";
@@ -4941,7 +5098,7 @@ declare const en: {
4941
5098
  readonly placeholder: "Search project\u2026";
4942
5099
  readonly titleBarPlaceholder: "Search in {name}";
4943
5100
  readonly building: "Building search index\u2026";
4944
- readonly idle: "Search scenes, characters, story text, assets and blueprints.";
5101
+ readonly idle: "Search scenes, characters, story text, interface text, assets and blueprints.";
4945
5102
  readonly empty: "No results";
4946
5103
  readonly more: "{count} more";
4947
5104
  readonly caseSensitive: "Match case";
@@ -4961,8 +5118,9 @@ declare const en: {
4961
5118
  readonly blueprint: "Blueprints";
4962
5119
  readonly asset: "Assets";
4963
5120
  readonly storyText: "Story Text";
5121
+ readonly uiText: "Interface Text";
4964
5122
  readonly variable: "Variables";
4965
- readonly uiTextKey: "UI Text Keys";
5123
+ readonly uiTextKey: "Translation Keys";
4966
5124
  readonly blueprintNode: "Blueprint Nodes";
4967
5125
  };
4968
5126
  readonly occurrences: "\u00D7{count}";
@@ -5325,6 +5483,8 @@ declare const en: {
5325
5483
  readonly forkCondition: "Condition";
5326
5484
  readonly fallsThrough: "continues";
5327
5485
  readonly fallsThroughTitle: "No jump of its own; the scene continues past the fork";
5486
+ readonly ends: "ends";
5487
+ readonly endsTitle: "The story ends in this branch: {names}";
5328
5488
  readonly forkCount: {
5329
5489
  readonly one: "{count} branch";
5330
5490
  readonly other: "{count} branches";
@@ -5788,6 +5948,15 @@ declare const en: {
5788
5948
  readonly appliesTo: "Also filed under";
5789
5949
  readonly star: "Star";
5790
5950
  readonly unstar: "Unstar";
5951
+ readonly abbreviations: "Your abbreviations";
5952
+ readonly addAbbreviation: "Add abbreviation";
5953
+ readonly removeAbbreviation: "Remove {word}";
5954
+ readonly abbreviationPlaceholder: "Abbreviation";
5955
+ readonly abbreviationSpace: "An abbreviation cannot contain spaces.";
5956
+ readonly abbreviationCharacter: "Quotes, =, /, @ and # cannot be used.";
5957
+ readonly abbreviationBuiltIn: "Already a spelling of {command}.";
5958
+ readonly abbreviationTaken: "Already your abbreviation for {command}.";
5959
+ readonly abbreviationShadowed: "Now a spelling of {command}. This abbreviation has no effect.";
5791
5960
  readonly type: {
5792
5961
  readonly image: "Image asset";
5793
5962
  readonly audio: "Audio asset";
@@ -5866,6 +6035,7 @@ declare const en: {
5866
6035
  readonly cutPointTitle: "The {name} build ends at this line. No other build contains this line.";
5867
6036
  readonly cutPointInactive: "variant deleted";
5868
6037
  readonly cutPointInactiveTitle: "The variant this line ended has been deleted, so it ends nothing.";
6038
+ readonly problem: "{message} ({rule})";
5869
6039
  readonly tempSpeaker: "name only";
5870
6040
  readonly createCharacter: "Create character \u201C{name}\u201D";
5871
6041
  readonly createCharacterUnavailable: "Unavailable in a live session. Choose an existing character.";
@@ -5914,7 +6084,7 @@ declare const en: {
5914
6084
  readonly openPreview: "Open live preview";
5915
6085
  readonly closePreview: "Close live preview";
5916
6086
  readonly title: "Live Preview";
5917
- readonly dock: "Dock to sidebar";
6087
+ readonly dock: "Dock in the scene editor";
5918
6088
  readonly pip: "Picture-in-picture";
5919
6089
  readonly selectRow: "Select a story row to preview its stage state.";
5920
6090
  readonly failed: "Preview failed";
@@ -6646,7 +6816,7 @@ declare const en: {
6646
6816
  };
6647
6817
  };
6648
6818
  readonly storyInspector: {
6649
- readonly textId: "Localization key";
6819
+ readonly textId: "Unit ID";
6650
6820
  readonly advanced: "Advanced";
6651
6821
  readonly advancedParams: "Advanced params";
6652
6822
  readonly noVariablesDeclared: "No variables declared";
@@ -7864,6 +8034,7 @@ declare const en: {
7864
8034
  readonly goTo: "Go to {target}";
7865
8035
  readonly goToNth: "Go to {target} ({n})";
7866
8036
  readonly goToConnected: "Go to connected node";
8037
+ readonly name: "Wire from {from} to {to}";
7867
8038
  };
7868
8039
  readonly crossProject: {
7869
8040
  readonly pasted: {
@@ -7891,6 +8062,25 @@ declare const en: {
7891
8062
  readonly targetTooltip: "Target: {label} ({type})";
7892
8063
  readonly fromPin: "Create from pin";
7893
8064
  readonly connectEmpty: "No nodes can connect to this pin.";
8065
+ readonly fieldsCategory: "Fields";
8066
+ readonly readField: "Get {field}";
8067
+ readonly filterByField: "Filter by {field}";
8068
+ readonly sortByField: "Sort by {field}";
8069
+ readonly findByField: "Find by {field}";
8070
+ };
8071
+ readonly struct: {
8072
+ readonly any: "Struct";
8073
+ readonly listRow: "List row";
8074
+ readonly arrayOf: "{name} list";
8075
+ readonly choiceItem: "Choice";
8076
+ readonly notificationItem: "Notification";
8077
+ readonly nvlItem: "NVL line";
8078
+ readonly historyEntry: "History entry";
8079
+ readonly saveEntry: "Save entry";
8080
+ readonly confirmButton: "Confirm button";
8081
+ readonly ending: "Ending";
8082
+ readonly language: "Language";
8083
+ readonly voiceLanguage: "Voice language";
7894
8084
  };
7895
8085
  readonly diagnostics: {
7896
8086
  readonly empty: "No diagnostics.";
@@ -7909,7 +8099,7 @@ declare const en: {
7909
8099
  };
7910
8100
  readonly interaction: {
7911
8101
  readonly hiddenEvents: "Element \u201C{name}\u201D is not visible but still has interaction bindings";
7912
- readonly hiddenEventsHint: "Remove the events, or make the element visible. A hidden element receives no input.";
8102
+ readonly hiddenEventsHint: "Remove the events, make the element visible, or show it from a blueprint. A hidden element receives no input.";
7913
8103
  readonly opaqueEvents: "Element \u201C{name}\u201D is nearly invisible (opacity) but has interaction bindings";
7914
8104
  readonly opaqueEventsHint: "Players may not see this control. Check it in Dev Mode.";
7915
8105
  readonly smallHit: "Element \u201C{name}\u201D has a small hit area with interactions";
@@ -7965,11 +8155,16 @@ declare const en: {
7965
8155
  readonly noRuntime: "Node \"{node}\": no runtime for type \"{type}\".";
7966
8156
  readonly inputMissing: "\"{node}\" has nothing connected to \"{pin}\".";
7967
8157
  readonly stepLimit: "\"{head}\" stopped at \"{node}\" after {steps} steps without a wait.";
7968
- readonly stepLimitGlobal: "\"{head}\" in the global blueprint stopped at \"{node}\" after {steps} steps without a wait.";
8158
+ readonly stepLimitGlobal: "\"{head}\" in App logic stopped at \"{node}\" after {steps} steps without a wait.";
7969
8159
  readonly unknownType: "Node \"{node}\": unknown type \"{type}\". Its plugin may be uninstalled or disabled.";
7970
8160
  readonly variableIdInvalid: "Node \"{node}\": pick a variable.";
7971
8161
  readonly persistentVariableIdInvalid: "Node \"{node}\": pick a persistent variable.";
7972
8162
  readonly savedVariableIdInvalid: "Node \"{node}\": pick a saved variable.";
8163
+ readonly fieldMissing: "\"{node}\": {struct} has no field \"{field}\".";
8164
+ readonly fieldUnpicked: "Node \"{node}\": pick a field.";
8165
+ readonly keyNotAField: "\"{node}\": {struct} has no field \"{key}\". No item matches.";
8166
+ readonly listShapeMismatch: "\"{node}\": {struct} does not match this list's fields. Fields that differ show empty.";
8167
+ readonly pageParamMissing: "\"{node}\": the page does not declare this param.";
7973
8168
  };
7974
8169
  readonly fn: {
7975
8170
  readonly nameMissing: "Fn \"{node}\": set a function name.";
@@ -8242,6 +8437,7 @@ declare const en: {
8242
8437
  readonly editValue: "Edit value on card";
8243
8438
  readonly removeOutput: "Remove output pin";
8244
8439
  readonly jsonFieldName: "JSON object field name";
8440
+ readonly readsRow: "Current row";
8245
8441
  };
8246
8442
  readonly comment: {
8247
8443
  readonly color: {
@@ -8334,6 +8530,7 @@ declare const en: {
8334
8530
  readonly missingCharacter: "Missing character";
8335
8531
  readonly unnamedInputAction: "Unnamed action";
8336
8532
  readonly missingInputAction: "Missing action";
8533
+ readonly missingField: "Missing field \u201C{field}\u201D";
8337
8534
  };
8338
8535
  readonly script: {
8339
8536
  readonly fileLabel: "Script file";
@@ -8564,6 +8761,8 @@ declare const en: {
8564
8761
  readonly height: "Height";
8565
8762
  readonly held: "Held";
8566
8763
  readonly device: "Device";
8764
+ readonly connected: "Connected";
8765
+ readonly axis: "Axis";
8567
8766
  readonly hide: "Hide";
8568
8767
  readonly holdFinalValue: "Hold final value";
8569
8768
  readonly id: "Id";
@@ -8635,6 +8834,7 @@ declare const en: {
8635
8834
  readonly page: "Page";
8636
8835
  readonly pageProps: "Page props";
8637
8836
  readonly param: "Param";
8837
+ readonly parameter: "Parameter";
8638
8838
  readonly persistent: "Persistent";
8639
8839
  readonly pointer: "Pointer";
8640
8840
  readonly center: "Center";
@@ -8994,7 +9194,7 @@ declare const en: {
8994
9194
  readonly getLineHeight: "Get Line Height";
8995
9195
  readonly findItemByField: "Find Item By Field";
8996
9196
  readonly getItemAt: "Get Item At";
8997
- readonly getItemField: "Get Item Field";
9197
+ readonly getField: "Get Field";
8998
9198
  readonly getListContent: "Get List Content";
8999
9199
  readonly getListLength: "Get List Length";
9000
9200
  readonly setItemFieldAt: "Set Item Field At";
@@ -9056,6 +9256,9 @@ declare const en: {
9056
9256
  readonly isLayerMounted: "Is Layer Mounted";
9057
9257
  readonly isActionHeld: "Is Action Held";
9058
9258
  readonly getInputDevice: "Get Input Device";
9259
+ readonly isGamepadConnected: "Is Gamepad Connected";
9260
+ readonly isGamepadButtonHeld: "Is Gamepad Button Held";
9261
+ readonly getGamepadAxis: "Get Gamepad Axis";
9059
9262
  readonly showConfirm: "Show Confirm";
9060
9263
  readonly memo: "Memo";
9061
9264
  readonly clearPage: "Clear Page";
@@ -9154,6 +9357,10 @@ declare const en: {
9154
9357
  readonly onAction: "On Action";
9155
9358
  readonly onKeyDown: "On Key Down";
9156
9359
  readonly onKeyUp: "On Key Up";
9360
+ readonly onGamepadButtonDown: "On Gamepad Button Down";
9361
+ readonly onGamepadButtonUp: "On Gamepad Button Up";
9362
+ readonly anyGamepadButtonDown: "Any Gamepad Button Down";
9363
+ readonly anyGamepadButtonUp: "Any Gamepad Button Up";
9157
9364
  readonly onPreferenceChanged: "On Preference Changed";
9158
9365
  readonly openLink: "Open Link";
9159
9366
  readonly openScreenshotsFolder: "Open Screenshots Folder";
@@ -9263,6 +9470,7 @@ declare const en: {
9263
9470
  readonly toggle: "Toggle";
9264
9471
  readonly toggleDialogDisplay: "Toggle Dialog Display";
9265
9472
  readonly toggleSwitch: "Toggle Switch";
9473
+ readonly translationKeyText: "Translation Key Text";
9266
9474
  readonly trim: "Trim";
9267
9475
  readonly trimEnd: "Trim End";
9268
9476
  readonly trimStart: "Trim Start";
@@ -9302,6 +9510,8 @@ declare const en: {
9302
9510
  readonly getTotalPlaytime: "Get Total Playtime";
9303
9511
  };
9304
9512
  readonly nodeDescription: {
9513
+ readonly getComponentParam: "The value this placement sets for the chosen parameter, or the parameter's default when it sets none. A Text parameter that reads from a translation key gives the key's name; Translation Key Text gives its words.";
9514
+ readonly getPageParam: "The value the page was opened with for the chosen param, or the param's default when it was given none. Params are declared in the page's properties.";
9305
9515
  readonly compareEqual: "True when A and B are the same value of the same type. The number 1 and the text \"1\" are not equal.";
9306
9516
  readonly compareNotEqual: "True when A and B differ in value or in type. The number 1 and the text \"1\" count as different.";
9307
9517
  readonly compareGreaterThan: "True when A is greater than B. Both sides are compared as numbers; a side that cannot be read as a number gives false.";
@@ -9316,7 +9526,12 @@ declare const en: {
9316
9526
  readonly gameReady: "Runs when the game is ready, before any story starts and before the first screen shows; the screen waits for it to finish. Runs before App Boot, and can run again when a game is started or loaded.";
9317
9527
  readonly goBack: "Closes the current page and returns to the page beneath it. On the bottom page it does nothing.";
9318
9528
  readonly replacePage: "Opens a page in place of the current page, and closes the current page. Go back and Go Page set to None do not return to it.";
9319
- readonly isGameOverlay: "True when this page, layer or Game UI is shown over a running game. In the global blueprint, true while a page or a modal layer covers the story.";
9529
+ readonly isGameOverlay: "True when this page, layer or Game UI is shown over a running game. In App logic, true while a page or a modal layer covers the story.";
9530
+ readonly localizationGetText: "Gets a translation key's text in the player's current language, or its source text when that language has no translation. A key that does not exist gives its name. Translation Key Text gives the same text and can also be used in Blueprint Value and functions.";
9531
+ readonly translationKeyText: "A translation key's text in the player's current language, or its source text when that language has no translation. A key that does not exist gives its name. The same text as Get Text, and also usable in Blueprint Value and functions. A Blueprint Value that shows it updates when the player changes language.";
9532
+ readonly format: "Replaces the placeholders in Template with values: {0}, {1} and so on with the items of an array, {name} with the field of that name in an object. A placeholder with no value becomes empty. A translated template comes from Translation Key Text.";
9533
+ readonly formatText: "Replaces {0}, {1} and so on in Text with the items of Values. Format does the same, also fills {name} from an object, and can be used in Blueprint Value and functions.";
9534
+ readonly getField: "One field of the struct wired into Object, picked from that struct's fields. Inside a list row, leave Object unwired to read the row. Use Get JSON Field for an object whose fields are not declared.";
9320
9535
  };
9321
9536
  readonly live: {
9322
9537
  readonly nodeClaimed: "{name} is editing this node";
@@ -9721,6 +9936,33 @@ declare const en: {
9721
9936
  readonly remove: "Remove param";
9722
9937
  readonly namePlaceholder: "Name";
9723
9938
  readonly defaultPlaceholder: "Default";
9939
+ readonly type: "Type";
9940
+ readonly typeString: "String";
9941
+ readonly typeText: "Text";
9942
+ readonly bindLabel: "Parameter";
9943
+ readonly bindNone: "No parameter";
9944
+ readonly bindMissing: "Missing parameter";
9945
+ };
9946
+ readonly pageParams: {
9947
+ readonly title: "Params";
9948
+ readonly none: "No params";
9949
+ readonly hint: "Given by whatever opens this page. A text param can be shown by a text directly; read the others with Get Page Param.";
9950
+ readonly rowShape: "Row struct";
9951
+ readonly anyShape: "Unspecified";
9952
+ readonly bindLabel: "Page param";
9953
+ readonly bindNone: "No param";
9954
+ readonly bindMissing: "Missing param";
9955
+ readonly add: "Add param";
9956
+ readonly remove: "Remove {name}";
9957
+ readonly namePlaceholder: "Name";
9958
+ readonly default: "Default";
9959
+ readonly type: "Type";
9960
+ readonly typeString: "String";
9961
+ readonly typeText: "Text";
9962
+ readonly typeNumber: "Number";
9963
+ readonly typeBoolean: "Boolean";
9964
+ readonly typeList: "List";
9965
+ readonly typeJson: "JSON";
9724
9966
  };
9725
9967
  readonly binding: {
9726
9968
  readonly notReady: "Blueprint not ready for this control.";
@@ -9817,6 +10059,7 @@ declare const en: {
9817
10059
  readonly character: "Character";
9818
10060
  readonly voice: "Voice";
9819
10061
  readonly design: "Design";
10062
+ readonly projectSettings: "Settings";
9820
10063
  readonly plugin: "Plugin";
9821
10064
  };
9822
10065
  };
@@ -10135,10 +10378,15 @@ declare const en: {
10135
10378
  readonly newName: "Field";
10136
10379
  readonly none: "No fields";
10137
10380
  readonly engineOwned: "This list receives its fields from the engine.";
10381
+ readonly pluginOwned: "This list receives its fields from a plugin.";
10138
10382
  readonly picker: "Field";
10139
10383
  readonly visiblePicker: "Visible from field";
10140
10384
  readonly pickerEmpty: "No field";
10141
10385
  };
10386
+ readonly shape: {
10387
+ readonly label: "Struct";
10388
+ readonly custom: "Custom";
10389
+ };
10142
10390
  readonly row: {
10143
10391
  readonly add: "Add row";
10144
10392
  readonly remove: "Remove row";
@@ -10232,13 +10480,14 @@ declare const en: {
10232
10480
  readonly nvl: "Full-screen novel-mode dialog history.";
10233
10481
  };
10234
10482
  readonly panel: {
10483
+ readonly interfaces: "Interfaces";
10235
10484
  readonly interfaceType: "Interface Type";
10236
10485
  readonly createPage: "Create Page";
10237
10486
  readonly createGameUi: "Create Game UI";
10238
10487
  readonly globalSubtitle: "Global";
10239
10488
  readonly blueprintType: "Blueprint";
10240
- readonly openGlobalBlueprint: "Open global blueprint";
10241
- readonly globalBlueprintUnavailable: "Global blueprint unavailable";
10489
+ readonly openGlobalBlueprint: "Open App logic";
10490
+ readonly globalBlueprintUnavailable: "App logic unavailable";
10242
10491
  readonly openSurface: "Open {label}";
10243
10492
  readonly renameSurface: "Rename {label}";
10244
10493
  readonly duplicateSurface: "Duplicate {label}";
@@ -10267,6 +10516,15 @@ declare const en: {
10267
10516
  readonly history: {
10268
10517
  readonly moveSurface: "move interface {name}";
10269
10518
  readonly setEntryPage: "set entry page {name}";
10519
+ readonly createComponent: "create component {name}";
10520
+ readonly duplicateComponent: "duplicate component {name}";
10521
+ readonly duplicateComponents: "duplicate {count} components";
10522
+ readonly deleteComponent: "delete component {name}";
10523
+ readonly deleteComponents: "delete {count} components";
10524
+ readonly importSurface: "add interface {name}";
10525
+ readonly importSurfaces: "add {count} interfaces";
10526
+ readonly importComponent: "add component {name}";
10527
+ readonly importComponents: "add {count} components";
10270
10528
  };
10271
10529
  readonly inputActions: {
10272
10530
  readonly title: "Input Actions";
@@ -10303,6 +10561,7 @@ declare const en: {
10303
10561
  readonly trackpad: "Trackpad";
10304
10562
  readonly touch: "Touch screen";
10305
10563
  readonly key: "Keyboard";
10564
+ readonly gamepad: "Gamepad";
10306
10565
  };
10307
10566
  readonly gesture: {
10308
10567
  readonly click: "Click";
@@ -10368,6 +10627,8 @@ declare const en: {
10368
10627
  readonly widgetRenderFailed: "Widget failed to draw";
10369
10628
  readonly wordsFromRowField: "These words come from the list row field \u201C{field}\u201D.";
10370
10629
  readonly wordsFromBlueprintValue: "These words come from the blueprint value \u201C{name}\u201D.";
10630
+ readonly wordsFromComponentParam: "These words come from the component parameter \u201C{param}\u201D, set on each placement.";
10631
+ readonly wordsFromPageParam: "These words come from the page param \u201C{param}\u201D, given when the page is opened.";
10371
10632
  };
10372
10633
  readonly editor: {
10373
10634
  readonly componentNotFound: "Component not found";
@@ -10379,6 +10640,9 @@ declare const en: {
10379
10640
  readonly selectTool: "Select tool";
10380
10641
  readonly panTool: "Pan the canvas";
10381
10642
  readonly openInDevMode: "Open this interface in Dev Mode";
10643
+ readonly showInLivePreview: "Show this interface in the live preview";
10644
+ readonly livePreviewShowsNoNotifications: "Notifications are not shown in the live preview";
10645
+ readonly livePreviewNoRow: "No row in the story shows this interface";
10382
10646
  readonly componentDefinitionHint: "Components are edited as definitions";
10383
10647
  readonly bindElement: "Bind Element";
10384
10648
  readonly bindSelectHint: "Select one element on this Surface";
@@ -10406,6 +10670,11 @@ declare const en: {
10406
10670
  readonly canvasLayout: "Canvas layout (edges & center)";
10407
10671
  readonly elementBorders: "Element borders (edge to edge)";
10408
10672
  readonly elementLayout: "Element layout (centers)";
10673
+ readonly grid: "Grid";
10674
+ readonly gridStyle: "Grid style";
10675
+ readonly gridLines: "Lines";
10676
+ readonly gridDots: "Dots";
10677
+ readonly gridSize: "Grid size";
10409
10678
  };
10410
10679
  readonly contextMenu: {
10411
10680
  readonly pasteIntoContainer: "Paste into container";
@@ -10454,6 +10723,12 @@ declare const en: {
10454
10723
  readonly left: "left";
10455
10724
  };
10456
10725
  };
10726
+ readonly reference: {
10727
+ readonly label: "Game UI reference";
10728
+ readonly heading: "Other game UI";
10729
+ readonly none: "This project has no other game UI.";
10730
+ readonly sizeDiffers: "Different size: {name} {width}\u00D7{height}";
10731
+ };
10457
10732
  readonly crossProject: {
10458
10733
  readonly pasted: {
10459
10734
  readonly one: "{count} element pasted";
@@ -10598,14 +10873,23 @@ declare const en: {
10598
10873
  readonly hint: "Shown in the editor only. The game shows the story's current line.";
10599
10874
  readonly bindingNoEffect: "This binding has no effect in the {slot} slot.";
10600
10875
  readonly removeBinding: "Remove";
10876
+ readonly hintBlueprintValue: "Shown in the editor only. The game shows the Blueprint Value's result.";
10877
+ readonly hintComponentParam: "Shown while editing the component only. Each placement shows the value it sets for the parameter.";
10878
+ readonly hintPageParam: "Shown while editing the page, when the param's default is empty. In the game the page shows the text it is opened with, or the default.";
10879
+ };
10880
+ readonly textWriters: {
10881
+ readonly title: "Written in the game by";
10882
+ readonly entry: "{blueprint} \u203A {node}";
10883
+ readonly count: "\u00D7{count}";
10884
+ readonly defaultValue: "Default value";
10885
+ readonly defaultValueHint: "The game shows this text until one of the blueprints below writes to it.";
10601
10886
  };
10602
10887
  readonly localization: {
10603
10888
  readonly direct: "Direct";
10604
10889
  readonly translationKey: "Translation key";
10605
- readonly noSourceLanguage: "The project has no source language";
10606
10890
  readonly none: "None";
10607
10891
  readonly createKey: "Create new key\u2026";
10608
- readonly createKeyTitle: "New localization key";
10892
+ readonly createKeyTitle: "New translation key";
10609
10893
  readonly keyName: "Key name";
10610
10894
  readonly keyNamePlaceholder: "menu.start\u2026";
10611
10895
  readonly keyNameHint: "Letters, digits, and dots/underscores/hyphens between them.";
@@ -10627,6 +10911,9 @@ declare const en: {
10627
10911
  readonly stateKeyPlaceholder: "choices";
10628
10912
  readonly propName: "Prop name";
10629
10913
  readonly propNamePlaceholder: "choices";
10914
+ readonly pageParam: "Param";
10915
+ readonly pageParamUndeclared: "not declared on this page";
10916
+ readonly noPageParams: "This page declares no params";
10630
10917
  readonly placeholderCount: "Placeholder rows";
10631
10918
  readonly contentTitle: "List content";
10632
10919
  readonly fields: "Fields";
@@ -10714,11 +11001,9 @@ declare const en: {
10714
11001
  readonly sectionColor: "Color";
10715
11002
  readonly sectionBehavior: "Behavior";
10716
11003
  readonly interactionDisabled: "Interaction disabled";
10717
- readonly localizeLabel: "Localize label";
10718
11004
  };
10719
11005
  readonly text: {
10720
11006
  readonly title: "Text";
10721
- readonly localizeText: "Localize text";
10722
11007
  };
10723
11008
  readonly textMarks: {
10724
11009
  readonly title: "Marks";
@@ -10728,6 +11013,7 @@ declare const en: {
10728
11013
  readonly title: "Page";
10729
11014
  readonly page: "Page";
10730
11015
  readonly props: "Props";
11016
+ readonly params: "Params";
10731
11017
  readonly animation: "Animation";
10732
11018
  readonly usePageAnimation: "Use Page animation";
10733
11019
  readonly pageLogic: "Page component logic";
@@ -11394,7 +11680,7 @@ declare const en: {
11394
11680
  };
11395
11681
  readonly settings: {
11396
11682
  readonly title: "Settings";
11397
- readonly description: "Security, signing, compression, loading, and mobile";
11683
+ readonly description: "Security, signing, compression, loading, letterbox, and mobile";
11398
11684
  };
11399
11685
  };
11400
11686
  readonly group: {
@@ -11424,6 +11710,7 @@ declare const en: {
11424
11710
  readonly videoCompression: "Video compression";
11425
11711
  readonly loading: "Loading";
11426
11712
  readonly crash: "Crashes";
11713
+ readonly letterbox: "Letterbox";
11427
11714
  readonly mobile: "Mobile";
11428
11715
  };
11429
11716
  readonly compressionMode: {
@@ -11808,6 +12095,10 @@ declare const en: {
11808
12095
  readonly portrait: "Portrait";
11809
12096
  readonly auto: "Follow device";
11810
12097
  };
12098
+ readonly letterboxColorTitle: "Letterbox color";
12099
+ readonly letterboxColorDescription: "Shown around the stage on screens of another aspect ratio.";
12100
+ readonly letterboxImageTitle: "Letterbox image";
12101
+ readonly letterboxImageDescription: "Drawn over the letterbox color. The stage covers its middle.";
11811
12102
  readonly stageFitTitle: "Screen fit";
11812
12103
  readonly stageFitDescription: "Mobile builds and Dev Mode. Desktop and web always letterbox.";
11813
12104
  readonly stageFit: {
@@ -12157,6 +12448,7 @@ declare const en: {
12157
12448
  readonly voice: "Voice";
12158
12449
  readonly assets: "Assets";
12159
12450
  readonly console: "Console";
12451
+ readonly problems: "Problems";
12160
12452
  readonly storyMotion: "Story Motion";
12161
12453
  readonly dashboard: "Dashboard";
12162
12454
  readonly audioPreview: "Audio Preview";
@@ -13194,6 +13486,8 @@ declare const en: {
13194
13486
  readonly mirror: {
13195
13487
  readonly official: "official source";
13196
13488
  readonly change: "Change";
13489
+ readonly downloadFailed: "A file the build needed could not be downloaded. If this network reaches github.com slowly or not at all, choose a mirror for the build's downloads in Settings \u203A {section} and build again.";
13490
+ readonly certificateFailed: "The download's certificate could not be verified. That usually means a proxy, network accelerator or antivirus program on this computer is intercepting HTTPS; turning it off may fix this without a mirror.";
13197
13491
  };
13198
13492
  readonly preflight: {
13199
13493
  readonly "no-targets": "Select at least one platform and format.";
@@ -13506,185 +13800,209 @@ declare const en: {
13506
13800
  readonly description: "Nothing in the project references this asset";
13507
13801
  readonly message: "{asset} is not used anywhere";
13508
13802
  readonly messageIndexUnresolved: "Unused assets not listed: {location} points at an asset that cannot be identified";
13509
- readonly messageIndexUnreadable: "Unused assets not listed: {location} could not be read";
13803
+ readonly messageIndexUnreadable: "Unused assets not listed: which assets {location} uses could not be determined";
13510
13804
  readonly messageIndexNotBuilt: "Unused assets not listed: the project could not be scanned";
13805
+ readonly help: string;
13511
13806
  };
13512
13807
  readonly assetsMissing: {
13513
13808
  readonly title: "Missing asset";
13514
13809
  readonly description: "A reference names an asset the library no longer has";
13515
13810
  readonly message: "{location} references a missing asset";
13811
+ readonly help: string;
13516
13812
  };
13517
13813
  readonly assetsUnreadable: {
13518
13814
  readonly title: "Unreadable asset";
13519
13815
  readonly description: "The file cannot be read or decoded";
13520
- readonly message: "{asset} cannot be decoded";
13816
+ readonly message: "{asset} is damaged or is not in a format Studio can open";
13521
13817
  readonly messageMissingBytes: "{asset} cannot be read from disk";
13818
+ readonly help: string;
13522
13819
  };
13523
13820
  readonly assetsOversized: {
13524
13821
  readonly title: "Large file";
13525
13822
  readonly description: "A file a build carries that is over the size this project allows";
13526
13823
  readonly message: "{asset} is {size}, over the {limit} a build should carry";
13824
+ readonly help: string;
13527
13825
  };
13528
13826
  readonly assetsGroupIncomplete: {
13529
13827
  readonly title: "Unfinished asset set";
13530
13828
  readonly description: "A set that does not resolve to exactly one file for every variant it declares";
13531
13829
  readonly message: "{set} has no file for {variant}";
13532
13830
  readonly messageAmbiguous: "{set} has {count} files for {variant}";
13533
- readonly messageResidency: "{set} resolves {axis} while the game runs, inside {outerAxis}, which the build resolves";
13534
- readonly messageDeclaration: "{set} declares no variants to resolve";
13535
- readonly messageFallback: "{set} does not say which variant the others fall back to";
13536
- };
13537
- readonly portabilityAssetName: {
13538
- readonly title: "Unsafe file name";
13539
- readonly description: "Characters or names some filesystems reject";
13540
- readonly message: "{asset} cannot be written on every platform";
13541
- };
13542
- readonly portabilityCaseCollision: {
13543
- readonly title: "Case collision";
13544
- readonly description: "Names that differ only by letter case";
13545
- readonly message: "{asset} collides with {other} on case-insensitive filesystems";
13831
+ readonly messageResidency: "{set} varies by variant and sits under a set that varies by language, which no build can resolve";
13832
+ readonly messageDeclaration: "{set} declares no values to resolve";
13833
+ readonly messageFallback: "{set} does not say which value the others fall back to";
13834
+ readonly help: string;
13546
13835
  };
13547
13836
  readonly portabilityMediaFormat: {
13548
13837
  readonly title: "Unplayable format";
13549
13838
  readonly description: "A codec some selected build targets cannot play";
13550
13839
  readonly message: "{asset} does not play on {platform}";
13840
+ readonly help: string;
13551
13841
  };
13552
13842
  readonly portabilityVfxAlpha: {
13553
13843
  readonly title: "Transparent overlay clip";
13554
13844
  readonly description: "An overlay clip whose transparency some selected build targets ignore";
13555
13845
  readonly message: "{asset} covers the stage on {platform}";
13846
+ readonly help: string;
13556
13847
  };
13557
13848
  readonly networkFetchNotAllowlisted: {
13558
13849
  readonly title: "Address not on the allowlist";
13559
13850
  readonly description: "A Fetch node aimed at an address this project does not allow";
13560
13851
  readonly message: "{url} is not on this project's network request allowlist";
13852
+ readonly help: string;
13561
13853
  };
13562
13854
  readonly networkFetchDisallowed: {
13563
13855
  readonly title: "Network node without network access";
13564
13856
  readonly description: "A network node in a project whose network policy is off";
13565
13857
  readonly message: "{blueprint} makes a network request, which this project does not allow";
13858
+ readonly help: string;
13566
13859
  };
13567
13860
  readonly storyUnreadable: {
13568
13861
  readonly title: "Unreadable story";
13569
13862
  readonly description: "A story document this Studio cannot open";
13863
+ readonly help: string;
13570
13864
  };
13571
13865
  readonly storyInvalidCommand: {
13572
13866
  readonly title: "Invalid command";
13573
13867
  readonly description: "A row the compiler refuses";
13574
13868
  readonly message: "This row does not compile";
13869
+ readonly help: string;
13575
13870
  };
13576
13871
  readonly storyGotoMissing: {
13577
13872
  readonly title: "Missing label";
13578
13873
  readonly description: "A goto naming a label the scene does not declare";
13579
13874
  readonly message: "Jumps to {label}, which this scene never declares";
13875
+ readonly messageEmpty: "Names no label to go to";
13876
+ readonly help: string;
13580
13877
  };
13581
13878
  readonly storyLabelDuplicate: {
13582
13879
  readonly title: "Duplicate label";
13583
13880
  readonly description: "Two declarations of one label; only the first is reached";
13584
- readonly message: "{label} is already declared above, so this one is never reached";
13881
+ readonly message: "{label} is already declared above, so every /goto to it lands there and not here";
13882
+ readonly help: string;
13585
13883
  };
13586
13884
  readonly storyLabelUnused: {
13587
13885
  readonly title: "Unused label";
13588
13886
  readonly description: "A label nothing jumps to";
13589
13887
  readonly message: "Nothing jumps to {label}";
13888
+ readonly help: string;
13590
13889
  };
13591
13890
  readonly storyJumpMissing: {
13592
13891
  readonly title: "Missing scene";
13593
13892
  readonly description: "A jump naming a scene the project does not have";
13594
- readonly message: "Jumps to a scene the story no longer has";
13893
+ readonly message: "The target scene is not set, or is not in this story";
13894
+ readonly help: string;
13595
13895
  };
13596
13896
  readonly storyEmptyChoice: {
13597
13897
  readonly title: "Empty choice";
13598
13898
  readonly description: "A choice with nothing the player can pick";
13599
13899
  readonly message: "This choice has no options";
13600
13900
  readonly messageEmptyOption: "This option has no text";
13901
+ readonly help: string;
13601
13902
  };
13602
13903
  readonly storyDeadEnd: {
13603
13904
  readonly title: "Dead end";
13604
13905
  readonly description: "A scene that leaves on some paths and reaches its end on another";
13605
13906
  readonly message: "Play runs off the end of the scene here";
13907
+ readonly help: string;
13606
13908
  };
13607
13909
  readonly storyCallCycle: {
13608
13910
  readonly title: "Circular call";
13609
13911
  readonly description: "A returnable jump reaching a scene that can call its own back";
13610
13912
  readonly message: "Calls a scene that can call this one back";
13913
+ readonly help: string;
13611
13914
  };
13612
13915
  readonly storyUnreachableScene: {
13613
13916
  readonly title: "Unreachable scene";
13614
13917
  readonly description: "A scene nothing can reach from the start";
13615
13918
  readonly message: "Nothing reaches this scene";
13919
+ readonly help: string;
13616
13920
  };
13617
13921
  readonly storyEmptyScene: {
13618
13922
  readonly title: "Empty scene";
13619
13923
  readonly description: "A scene with no content";
13620
- readonly message: "This scene has no rows";
13924
+ readonly message: "This scene has no enabled rows";
13925
+ readonly help: string;
13621
13926
  };
13622
13927
  readonly storyAppTagUnknown: {
13623
13928
  readonly title: "Unknown build variant";
13624
13929
  readonly description: "A row compared with a variant the project does not have";
13625
- readonly message: "No build variant is named \"{name}\", so this row is in no build";
13930
+ readonly message: "No build variant is named \"{name}\", so this comparison has the same result in every build";
13931
+ readonly help: string;
13626
13932
  };
13627
13933
  readonly storyRowsAfterEnding: {
13628
13934
  readonly title: "Rows after an ending";
13629
13935
  readonly description: "Rows written after an /ending row in the same list, which never play";
13630
13936
  readonly message: "This row comes after an ending and is never played. Move it before the ending, or delete it";
13937
+ readonly help: string;
13631
13938
  };
13632
13939
  readonly storyQuitPageMissing: {
13633
13940
  readonly title: "Quit with no page";
13634
13941
  readonly description: "A /quit row that names no page, or one the project no longer has";
13635
- readonly message: "This row names no page, so the playthrough ends with nothing on screen";
13636
- readonly deleted: "This project has no page \"{page}\", so the playthrough ends with nothing on screen";
13942
+ readonly message: "This row names no page, so no page opens and the rows after it in this list never play";
13943
+ readonly deleted: "The page this row names is no longer in the project, so the playthrough ends with nothing on screen";
13944
+ readonly help: string;
13637
13945
  };
13638
13946
  readonly storyEndingNameDuplicate: {
13639
13947
  readonly title: "Two endings with one name";
13640
13948
  readonly description: "More than one ending sharing a display name";
13641
13949
  readonly message: "Another ending is also called \"{name}\". A screen listing endings shows the name twice";
13950
+ readonly help: string;
13642
13951
  };
13643
13952
  readonly storyCutPointOrphan: {
13644
13953
  readonly title: "Cut point with no variant";
13645
13954
  readonly description: "A cut point written while the project has no build variant";
13646
13955
  readonly message: "This project has no build variant, so this cut point ends nothing. Add a variant, or delete the row";
13956
+ readonly help: string;
13647
13957
  };
13648
13958
  readonly storyCutPointUnreachable: {
13649
13959
  readonly title: "Cut point out of reach";
13650
13960
  readonly description: "A cut point in a scene nothing can get to";
13651
13961
  readonly message: "Nothing can reach this scene, so this cut point never ends a build";
13962
+ readonly help: string;
13652
13963
  };
13653
13964
  readonly storyStageObjectMissing: {
13654
13965
  readonly title: "Missing stage object";
13655
13966
  readonly description: "A row acting on an object no row in the scene creates";
13656
- readonly message: "Nothing creates {object}, so this row has nothing to act on";
13657
- readonly messageCharacter: "Nothing brings {object} on stage, so this row has nothing to act on";
13967
+ readonly message: "No row in this scene creates {object}, so this row has nothing to act on";
13968
+ readonly messageCharacter: "No row in this scene brings {object} on stage, so this row has nothing to act on";
13969
+ readonly help: string;
13658
13970
  };
13659
13971
  readonly storyDeclaredNeverShown: {
13660
13972
  readonly title: "Unshown stage object";
13661
13973
  readonly description: "A create row declares an object no row shows";
13662
13974
  readonly message: "{object} is declared here and no row shows it";
13975
+ readonly help: string;
13663
13976
  };
13664
13977
  readonly storyStageObjectDuplicate: {
13665
13978
  readonly title: "Duplicate stage object";
13666
13979
  readonly description: "Two rows creating one stage name; the second reuses the first";
13667
13980
  readonly message: "{object} is already created above, so this row acts on that one";
13981
+ readonly help: string;
13668
13982
  };
13669
13983
  readonly storyVideoControlAfterEnd: {
13670
13984
  readonly title: "Video already finished";
13671
13985
  readonly description: "A row pausing, resuming, seeking or stopping a video after a play that waits for its end";
13672
13986
  readonly message: "{object} has already finished playing at this line; to continue while it plays, turn off \u201CWait for the video\u201D on its play row";
13987
+ readonly help: string;
13673
13988
  };
13674
13989
  readonly storyCharacterMissing: {
13675
13990
  readonly title: "Missing character";
13676
13991
  readonly description: "A row naming a character the project does not have";
13677
13992
  readonly message: "This row names a character the project does not have";
13993
+ readonly help: string;
13678
13994
  };
13679
13995
  readonly storyTransitionUnavailable: {
13680
13996
  readonly title: "Unavailable transition";
13681
13997
  readonly description: "A row naming a transition this version cannot play";
13682
13998
  readonly message: "The transition {transition} is not available, so this change plays as a cut";
13999
+ readonly help: string;
13683
14000
  };
13684
14001
  readonly storyBackgroundUnchanged: {
13685
14002
  readonly title: "Unchanged background";
13686
14003
  readonly description: "A row transitioning to the background already on screen";
13687
14004
  readonly message: "This background is already on screen, so the transition changes nothing";
14005
+ readonly help: string;
13688
14006
  };
13689
14007
  readonly blueprintReferenceMissing: {
13690
14008
  readonly title: "Missing target";
@@ -13696,40 +14014,47 @@ declare const en: {
13696
14014
  readonly messageChoice: "Names a choice that no longer exists";
13697
14015
  readonly messageEnding: "Names an ending that no longer exists";
13698
14016
  readonly messageCharacter: "Names a character that no longer exists";
13699
- readonly messageTextKey: "Names a text key the project does not declare";
14017
+ readonly messageTextKey: "Names a translation key the project does not declare";
13700
14018
  readonly messageDlc: "Names a DLC the project does not have";
13701
14019
  readonly messageInputAction: "Names an input action the project does not declare";
14020
+ readonly help: string;
13702
14021
  };
13703
14022
  readonly blueprintElementRefMissing: {
13704
14023
  readonly title: "Missing widget";
13705
14024
  readonly description: "A node bound to a widget the project no longer has";
13706
14025
  readonly message: "Bound to a widget that no longer exists";
14026
+ readonly help: string;
13707
14027
  };
13708
14028
  readonly blueprintFnTargetMissing: {
13709
14029
  readonly title: "Missing function";
13710
14030
  readonly description: "A Call Fn node whose function does not exist in its scope";
13711
14031
  readonly message: "Calls a function that does not exist in this scope";
13712
14032
  readonly messageNamed: "Calls {name}, which does not exist in this scope";
14033
+ readonly help: string;
13713
14034
  };
13714
14035
  readonly blueprintUnreachableNode: {
13715
14036
  readonly title: "Unreachable node";
13716
14037
  readonly description: "A node no entry point in its graph can reach";
13717
14038
  readonly message: "Nothing reaches this node, so it never runs";
14039
+ readonly help: string;
13718
14040
  };
13719
14041
  readonly blueprintDlcEntranceUnguarded: {
13720
14042
  readonly title: "Unguarded DLC entrance";
13721
- readonly description: "A Start Story into a DLC's story, with nothing asking whether the DLC is here";
13722
- readonly message: "Nothing in this graph asks whether the DLC is installed";
14043
+ readonly description: "A Start Game node starting a DLC's story, with nothing asking whether the DLC is installed";
14044
+ readonly message: "No Is DLC Installed in this layer asks about this story's DLC";
14045
+ readonly help: string;
13723
14046
  };
13724
14047
  readonly blueprintEmptyEvent: {
13725
14048
  readonly title: "Empty event";
13726
14049
  readonly description: "An event layer with nothing wired to run";
13727
14050
  readonly message: "This event runs nothing";
14051
+ readonly help: string;
13728
14052
  };
13729
14053
  readonly blueprintUnknownNode: {
13730
14054
  readonly title: "Unknown node type";
13731
14055
  readonly description: "A node whose type the project cannot load";
13732
14056
  readonly message: "{type} is not loaded, so this node will not run in the game";
14057
+ readonly help: string;
13733
14058
  };
13734
14059
  readonly blueprintAssembledAssetName: {
13735
14060
  readonly title: "Asset name assembled at run time";
@@ -13738,105 +14063,174 @@ declare const en: {
13738
14063
  readonly messageBinding: "\"{prop}\" on \"{element}\" is bound to an asset name assembled at run time (from \"{origin}\"). A game package carries only the assets whose names are written in the project, so nothing will be there in the released game. Choose the asset in the asset picker, or read one already chosen from a list row or a variable";
13739
14064
  readonly messageUnloadedNode: "\"{pin}\" on \"{node}\" receives an asset name from {origin}, which is not loaded, so the asset it names will not be in the released game. Install or switch on the plugin that provides this node type, then build again";
13740
14065
  readonly messageUnloadedNodeBinding: "\"{prop}\" on \"{element}\" is bound to an asset name from {origin}, which is not loaded, so the asset it names will not be in the released game. Install or switch on the plugin that provides this node type, then build again";
13741
- };
13742
- readonly uiUnlocalizedText: {
13743
- readonly title: "Unlocalized text";
13744
- readonly description: "Text written straight onto a widget in a project that has a second language";
13745
- readonly message: "{text} is not bound to a localization key";
14066
+ readonly help: string;
13746
14067
  };
13747
14068
  readonly uiPageUnreachable: {
13748
14069
  readonly title: "Unreachable page";
13749
14070
  readonly description: "A page nothing opens, embeds, or starts on";
13750
14071
  readonly message: "Nothing opens this page";
14072
+ readonly help: string;
13751
14073
  };
13752
14074
  readonly uiEmptyBehavior: {
13753
14075
  readonly title: "Button with no handler";
13754
14076
  readonly description: "A clickable widget nothing listens to";
13755
14077
  readonly message: "Nothing runs when this is clicked";
14078
+ readonly help: string;
13756
14079
  };
13757
14080
  readonly uiUnknownWidget: {
13758
14081
  readonly title: "Unknown widget type";
13759
14082
  readonly description: "A widget whose type the project cannot load";
13760
14083
  readonly message: "{type} is not loaded, so this widget will not be drawn in the game";
14084
+ readonly help: string;
13761
14085
  };
13762
14086
  readonly uiComponentMissing: {
13763
14087
  readonly title: "Missing component";
13764
14088
  readonly description: "An instance of a component the project does not have";
13765
14089
  readonly message: "This instance points at a component the project does not have";
14090
+ readonly help: string;
13766
14091
  };
13767
14092
  readonly uiFrameTargetMissing: {
13768
14093
  readonly title: "Missing embedded page";
13769
14094
  readonly description: "A Page widget embedding a page the project does not have";
13770
14095
  readonly message: "This Page widget embeds a page the project does not have";
14096
+ readonly help: string;
13771
14097
  };
13772
14098
  readonly uiFrameLoop: {
13773
14099
  readonly title: "Circular embedded page";
13774
14100
  readonly description: "A Page widget embedding a page that leads back to it";
13775
14101
  readonly message: "This Page widget embeds a page that leads back to it";
14102
+ readonly help: string;
13776
14103
  };
13777
14104
  readonly uiListItemFieldMissing: {
13778
14105
  readonly title: "Missing item field";
13779
14106
  readonly description: "A widget bound to an item field the list drawing it does not declare";
13780
14107
  readonly message: "This is bound to an item field the list does not declare, so every row shows the same value";
14108
+ readonly help: string;
14109
+ };
14110
+ readonly uiPagePropUndeclared: {
14111
+ readonly title: "Undeclared page param";
14112
+ readonly description: "A list showing a page prop the page does not declare as a param";
14113
+ readonly message: "This list shows the page prop \"{name}\", which the page does not declare as a param";
14114
+ readonly help: string;
14115
+ };
14116
+ readonly uiPageParamUnknown: {
14117
+ readonly title: "Unknown page param";
14118
+ readonly description: "A Page widget giving a value the page it shows does not declare";
14119
+ readonly message: "This Page widget gives \"{name}\", which the page it shows does not declare";
14120
+ readonly help: string;
14121
+ };
14122
+ readonly uiPageTextParamMissing: {
14123
+ readonly title: "Missing page text param";
14124
+ readonly description: "A text on a page showing a param the page does not declare as text";
14125
+ readonly message: "This shows a page param the page does not declare as text, so the game shows no words here";
14126
+ readonly messageOutside: "This shows a page param but is not on a page, so the game shows no words here";
14127
+ readonly help: string;
14128
+ };
14129
+ readonly uiPageParamListMismatch: {
14130
+ readonly title: "List not matching its page param";
14131
+ readonly description: "A list showing a page param that is not a list, or whose rows lack fields the list draws";
14132
+ readonly messageNotList: "This list shows the page param \"{name}\", which is not a list";
14133
+ readonly message: "This list shows the page param \"{name}\", whose rows lack fields the list draws: {fields}";
14134
+ readonly help: string;
14135
+ };
14136
+ readonly uiComponentParamMissing: {
14137
+ readonly title: "Missing text parameter";
14138
+ readonly description: "A widget in a component showing a parameter the component does not declare as text";
14139
+ readonly message: "This shows a parameter the component does not declare as text, so every placement shows no words here";
14140
+ readonly messageOutside: "This shows a component parameter but is not inside a component, so the game shows no words here";
14141
+ readonly help: string;
13781
14142
  };
13782
14143
  readonly uiListTextUntranslated: {
13783
14144
  readonly title: "Untranslated list content";
13784
14145
  readonly description: "Words written into a list's content in a project that has a second language";
13785
14146
  readonly message: "{text} and the rest of this list's content show as written in every language";
14147
+ readonly help: string;
13786
14148
  };
13787
14149
  readonly uiLocalizationKeyMissing: {
13788
- readonly title: "Missing localization key";
14150
+ readonly title: "Missing translation key";
13789
14151
  readonly description: "A widget reading its words from a key the project does not have";
13790
14152
  readonly message: "Reads its words from {key}, which the project does not have";
14153
+ readonly help: string;
13791
14154
  };
13792
14155
  readonly uiGestureAnsweredTwice: {
13793
14156
  readonly title: "Gesture answered twice";
13794
14157
  readonly description: "A widget with a pointer handler of its own, on a page whose action answers the same gesture";
13795
14158
  readonly message: "{action} on this page answers the same gesture this widget does, so both run";
14159
+ readonly help: string;
13796
14160
  };
13797
14161
  readonly blueprintSaveFieldEmpty: {
13798
14162
  readonly title: "Empty save field";
13799
14163
  readonly description: "A Save Game node that will run with a declared save field left empty";
13800
14164
  readonly message: "{field} is empty, so this save is written with its default instead";
14165
+ readonly help: string;
13801
14166
  };
13802
14167
  readonly blueprintRequiredInputUnwired: {
13803
14168
  readonly title: "Empty input";
13804
14169
  readonly description: "A node that will run with a required input left unconnected";
13805
14170
  readonly message: "{node} has nothing connected to {pin}";
14171
+ readonly help: string;
14172
+ };
14173
+ readonly blueprintFieldMissing: {
14174
+ readonly title: "Field not in shape";
14175
+ readonly description: "A node that names a field the value it reads does not have";
14176
+ readonly message: "{node}: {struct} has no field {field}";
14177
+ readonly help: string;
14178
+ };
14179
+ readonly blueprintPageParamMissing: {
14180
+ readonly title: "Missing page param";
14181
+ readonly description: "Get Page Param reading a param the page does not declare";
14182
+ readonly message: "{node} reads a param the page does not declare";
14183
+ readonly help: string;
14184
+ };
14185
+ readonly blueprintListShapeMismatch: {
14186
+ readonly title: "List fields do not match";
14187
+ readonly description: "Rows of another shape given to a list";
14188
+ readonly message: "{node}: {struct} does not match the list's fields";
14189
+ readonly help: string;
13806
14190
  };
13807
14191
  readonly blueprintStartSceneForeign: {
13808
14192
  readonly title: "Scene from another story";
13809
14193
  readonly description: "A Start Game node whose scene is not in the story it names";
13810
- readonly message: "This scene is in {owner}, not in {story}, so starting the game here stops it";
14194
+ readonly message: "This scene is in {owner}, not in {story}, so the game cannot start from it";
14195
+ readonly help: string;
13811
14196
  };
13812
14197
  readonly variablesUndeclared: {
13813
14198
  readonly title: "Undeclared variable";
13814
14199
  readonly description: "A variable used without a declaration";
13815
14200
  readonly message: "{variable} is used but never declared";
14201
+ readonly messageUnnamed: "This row uses a variable that is not declared anywhere";
14202
+ readonly help: string;
13816
14203
  };
13817
14204
  readonly variablesUnused: {
13818
14205
  readonly title: "Unused variable";
13819
14206
  readonly description: "A variable declared but never read or written";
13820
14207
  readonly message: "{variable} is declared but never used";
14208
+ readonly help: string;
13821
14209
  };
13822
14210
  readonly variablesNameCollision: {
13823
14211
  readonly title: "Variable name collision";
13824
14212
  readonly description: "One name declared in two places";
13825
14213
  readonly message: "{variable} is declared twice as a persistent variable";
14214
+ readonly messageSaved: "{variable} is declared twice as a saved variable";
14215
+ readonly help: string;
13826
14216
  };
13827
14217
  readonly variablesConditionNeverHolds: {
13828
14218
  readonly title: "Condition no path can satisfy";
13829
14219
  readonly description: "A condition whose variable can never reach the value it tests for";
13830
- readonly message: "{variable} is never more than {bound} here, so this condition cannot hold";
14220
+ readonly message: "{variable} is always within {bound} here, so this condition cannot hold";
14221
+ readonly messageUnnamed: "A variable with no declaration is always within {bound} here, so this condition cannot hold";
14222
+ readonly help: string;
13831
14223
  };
13832
14224
  readonly variablesReadNeverWritten: {
13833
14225
  readonly title: "Condition nothing can change";
13834
14226
  readonly description: "A variable a condition tests, that nothing in the project ever assigns";
13835
14227
  readonly message: "{variable} is tested by {conditions} but nothing ever sets it";
14228
+ readonly messageUnnamed: "A variable with no declaration is tested by {conditions} and nothing ever sets it";
13836
14229
  readonly conditionCount: {
13837
14230
  readonly one: "{count} condition";
13838
14231
  readonly other: "{count} conditions";
13839
14232
  };
14233
+ readonly help: string;
13840
14234
  };
13841
14235
  readonly variablesRandomOutsideAssignment: {
13842
14236
  readonly title: "Random outside an assignment";
@@ -13844,33 +14238,39 @@ declare const en: {
13844
14238
  readonly message: "{fn}() is re-rolled every time this condition is tested, so the branch can change between checks. Roll it once with /set, then test that variable";
13845
14239
  readonly messageChoiceOption: "{fn}() is re-rolled every time the menu draws, so this option flickers. Roll it once with /set, then test that variable";
13846
14240
  readonly messageInterpolation: "{fn}() is re-rolled every time this line draws, so the value changes on every redraw. Roll it once with /set, then show that variable";
14241
+ readonly help: string;
13847
14242
  };
13848
14243
  readonly textOverlong: {
13849
14244
  readonly title: "Overlong line";
13850
14245
  readonly description: "A line wider than the dialogue box holds";
13851
- readonly message: "{width} characters wide, over {max}";
14246
+ readonly message: "{width} columns wide, over {max}";
14247
+ readonly help: string;
13852
14248
  };
13853
14249
  readonly textEmpty: {
13854
14250
  readonly title: "Empty line";
13855
- readonly description: "A dialogue row with no text";
14251
+ readonly description: "A narration, dialogue or choice option row with no text";
13856
14252
  readonly message: "This line has no text";
14253
+ readonly help: string;
13857
14254
  };
13858
14255
  readonly localizationMissing: {
13859
14256
  readonly title: "Missing translation";
13860
14257
  readonly description: "A line or interface text with no translation in a target language";
13861
14258
  readonly message: "No {locale} translation";
13862
14259
  readonly messageInterface: "No {locale} translation of {text}";
14260
+ readonly help: string;
13863
14261
  };
13864
14262
  readonly localizationStale: {
13865
14263
  readonly title: "Stale translation";
13866
14264
  readonly description: "The source line changed after it was translated";
13867
14265
  readonly message: "{locale} translation is older than the line";
13868
14266
  readonly messageInterface: "{locale} translation of {text} is older than the text";
14267
+ readonly help: string;
13869
14268
  };
13870
14269
  readonly localizationMarkup: {
13871
14270
  readonly title: "Translation drops styling";
13872
- readonly description: "The line is styled and the translation renders it plainly";
13873
- readonly message: "{locale} translation does not carry this line's styling";
14271
+ readonly description: "The line has styling, pauses or inline events the translation does not carry";
14272
+ readonly message: "{locale} translation does not carry all of this line's styling, pauses and inline events";
14273
+ readonly help: string;
13874
14274
  };
13875
14275
  readonly localizationOrphan: {
13876
14276
  readonly title: "Orphan translation";
@@ -13880,16 +14280,19 @@ declare const en: {
13880
14280
  readonly one: "{count} {locale} translation";
13881
14281
  readonly other: "{count} {locale} translations";
13882
14282
  };
14283
+ readonly help: string;
13883
14284
  };
13884
14285
  readonly voiceMissing: {
13885
14286
  readonly title: "Missing voice";
13886
14287
  readonly description: "A line with no recording in a voiced language";
13887
14288
  readonly message: "No {locale} recording";
14289
+ readonly help: string;
13888
14290
  };
13889
14291
  readonly voiceStale: {
13890
14292
  readonly title: "Stale voice";
13891
14293
  readonly description: "The line changed after it was recorded";
13892
14294
  readonly message: "{locale} recording is older than the line";
14295
+ readonly help: string;
13893
14296
  };
13894
14297
  readonly voiceOrphan: {
13895
14298
  readonly title: "Orphan voice";
@@ -13899,13 +14302,15 @@ declare const en: {
13899
14302
  readonly one: "{count} {locale} recording";
13900
14303
  readonly other: "{count} {locale} recordings";
13901
14304
  };
14305
+ readonly help: string;
13902
14306
  };
13903
14307
  readonly brandBrokenLink: {
13904
14308
  readonly title: "Broken color link";
13905
14309
  readonly description: "A color pointing at a palette entry that resolves to nothing";
13906
- readonly message: "{where} uses {color}, which the palette does not have";
13907
- readonly messageChain: "{where} uses {color}, which links on to {missing}, a color the palette does not have";
14310
+ readonly message: "{where} uses a color the palette does not have";
14311
+ readonly messageChain: "{where} uses {color}, which follows a color the palette does not have";
13908
14312
  readonly messageCycle: "{where} uses {color}, whose links lead back to themselves";
14313
+ readonly help: string;
13909
14314
  };
13910
14315
  readonly typographyGlyphCoverage: {
13911
14316
  readonly title: "Missing glyphs";
@@ -13916,19 +14321,23 @@ declare const en: {
13916
14321
  readonly other: "{count} times";
13917
14322
  };
13918
14323
  readonly messageInLanguage: "No project font can draw \u201C{character}\u201D in {language} ({occurrences})";
14324
+ readonly messageInState: "No project font can draw \u201C{character}\u201D in the \u201C{state}\u201D state ({occurrences})";
14325
+ readonly messageInLanguageInState: "No project font can draw \u201C{character}\u201D in {language} in the \u201C{state}\u201D state ({occurrences})";
13919
14326
  readonly messageMore: "{characters} no project font can draw";
13920
14327
  readonly moreCharacterCount: {
13921
14328
  readonly one: "{count} more character";
13922
14329
  readonly other: "{count} more characters";
13923
14330
  };
13924
14331
  readonly messageMoreInLanguage: "{characters} no project font can draw in {language}";
13925
- readonly messageUnreadable: "{font} could not be read, so glyph coverage was not checked";
14332
+ readonly messageUnreadable: "{font} could not be read, so no character was checked";
13926
14333
  readonly messageUnloadable: "{font} is a .{format} font, which the game cannot draw with";
14334
+ readonly help: string;
13927
14335
  };
13928
14336
  readonly typographyLocaleNoFont: {
13929
14337
  readonly title: "Language with no font";
13930
14338
  readonly description: "A language every font of the project is restricted away from";
13931
- readonly message: "No project font is set for {language}";
14339
+ readonly message: "Every project font is limited to languages other than {language}";
14340
+ readonly help: string;
13932
14341
  };
13933
14342
  };
13934
14343
  readonly message: {
@@ -13974,6 +14383,22 @@ declare const en: {
13974
14383
  readonly showAll: "Show all {count}";
13975
14384
  readonly lineAria: "Line {line}";
13976
14385
  readonly findPlaceholder: "Find in problems";
14386
+ readonly scopeProject: "Whole project";
14387
+ readonly scopeOpenEditors: "Open editors";
14388
+ readonly scopeActiveEditor: "Current editor";
14389
+ readonly scopeAria: "Show problems from";
14390
+ readonly severityAria: "Severity";
14391
+ readonly groupAria: "Group";
14392
+ readonly emptyOpenEditors: "No problems in the open editors";
14393
+ readonly emptyActiveEditor: "No problems in the current editor";
14394
+ readonly emptyFiltered: "No problems at the selected severity";
14395
+ readonly explain: "About this rule";
14396
+ readonly settings: "Check settings";
14397
+ readonly rerunHint: "Check the whole project again, re-reading the asset files on disk";
14398
+ readonly jumpFailed: "This location can no longer be opened";
14399
+ };
14400
+ readonly statusBar: {
14401
+ readonly counts: "Problems: {errors}, {warnings}, {infos}";
13977
14402
  };
13978
14403
  readonly command: {
13979
14404
  readonly runProject: "Check project";
@@ -13996,6 +14421,7 @@ declare const en: {
13996
14421
  };
13997
14422
  readonly blockedHint: "Change this in Project \u25B8 Project \u25B8 Check before building";
13998
14423
  readonly skipped: "Project check skipped";
14424
+ readonly viewProblems: "View problems";
13999
14425
  };
14000
14426
  readonly settings: {
14001
14427
  readonly runOnBuild: "Check before building";
@@ -14005,6 +14431,8 @@ declare const en: {
14005
14431
  readonly failBuildOnWarning: "Warnings and errors";
14006
14432
  readonly optionMaxChars: "Maximum width";
14007
14433
  readonly optionCountMode: "Counting";
14434
+ readonly optionMaxMegabytes: "Largest file (MB)";
14435
+ readonly optionMaxCharacters: "Characters listed";
14008
14436
  readonly countModeEastAsianWidth: "Wide = 2 columns";
14009
14437
  readonly countModeCodePoints: "All = 1 column";
14010
14438
  };
@@ -14066,7 +14494,7 @@ declare const en: {
14066
14494
  readonly characters: "Characters";
14067
14495
  readonly dictionaryTerms: "Dictionary terms";
14068
14496
  readonly transformPresets: "Transform presets";
14069
- readonly localizationKeys: "Localization keys";
14497
+ readonly localizationKeys: "Translation keys";
14070
14498
  readonly projectLanguages: "Languages";
14071
14499
  readonly projectPlugins: "Plugins";
14072
14500
  readonly saveFields: "Save fields";
@@ -14165,9 +14593,9 @@ declare const en: {
14165
14593
  readonly statusReviewed: "Now reviewed";
14166
14594
  };
14167
14595
  readonly localizationKeys: {
14168
- readonly added: "Named string added";
14169
- readonly removed: "Named string removed";
14170
- readonly changed: "Named string changed";
14596
+ readonly added: "Translation key added";
14597
+ readonly removed: "Translation key removed";
14598
+ readonly changed: "Translation key changed";
14171
14599
  };
14172
14600
  readonly uiDocument: {
14173
14601
  readonly renamed: "Interface renamed";
@@ -14840,6 +15268,7 @@ declare const en: {
14840
15268
  readonly quality: "Checks";
14841
15269
  readonly version: "Versions";
14842
15270
  readonly ship: "Shipping";
15271
+ readonly checks: "Check rules";
14843
15272
  };
14844
15273
  readonly ui: {
14845
15274
  readonly title: "Help";
@@ -15643,14 +16072,25 @@ export type SearchJumpTarget = {
15643
16072
  } | {
15644
16073
  kind: "character";
15645
16074
  characterId: string;
15646
- } | {
16075
+ }
16076
+ /**
16077
+ * A page or a stage layer. With `elementId`, the widget on it to select once its editor opens - an
16078
+ * optional field rather than a variant of its own, so every consumer that opens the page keeps
16079
+ * opening it and only the ones that can say which widget say so.
16080
+ */
16081
+ | {
15647
16082
  kind: "uiSurface";
15648
16083
  surfaceId: string;
16084
+ elementId?: string;
15649
16085
  }
15650
- /** A component definition: its own editor tab, the one the component library opens. */
16086
+ /**
16087
+ * A component definition: its own editor tab, the one the component library opens. With
16088
+ * `elementId`, the widget inside the definition to select, as for a page.
16089
+ */
15651
16090
  | {
15652
16091
  kind: "uiComponent";
15653
16092
  componentId: string;
16093
+ elementId?: string;
15654
16094
  } | {
15655
16095
  kind: "asset";
15656
16096
  assetId: string;
@@ -15676,21 +16116,73 @@ export type SearchJumpTarget = {
15676
16116
  focusEventId?: string;
15677
16117
  focusFunctionId?: string;
15678
16118
  focusNodeId?: string;
15679
- } | {
16119
+ }
16120
+ /**
16121
+ * A named string: its row in a translation table, which is the one place its words are edited.
16122
+ * Opens the table of the project's first translated language; a project with none has no table,
16123
+ * and the jump shows the Localization panel instead, where a language is added.
16124
+ */
16125
+ | {
15680
16126
  kind: "localizationKey";
15681
16127
  keyName: string;
15682
16128
  }
15683
16129
  /**
15684
- * A project-level story variable — the panel that owns it, since no row declares one.
15685
- *
15686
- * Carries the identity even though the jump can only reveal the panel today, for the reason
15687
- * `localizationKey` carries its key: the target says what it points at, and the day the panel can
15688
- * be told which row to reveal, nothing that produces one of these has to change.
16130
+ * A project-level story variable: its row in the Variables panel, selected and scrolled into view.
16131
+ * `variableId` is the registry entry's id, or the declaration row's for one a story declares.
15689
16132
  */
15690
16133
  | {
15691
16134
  kind: "storyVariable";
15692
16135
  scope: "saved" | "persistent";
15693
16136
  variableId: string;
16137
+ }
16138
+ /**
16139
+ * A translation table - one language's - and, with `unitId`, the row of one translation unit in
16140
+ * it, scrolled into view and marked.
16141
+ *
16142
+ * The table lists one source at a time, so a row is found under the source it belongs to:
16143
+ * `storyId` for a story's lines and scene names, absent for the interface's words, the named keys
16144
+ * and the plugins' words. A character's name heads every story's rows and needs neither.
16145
+ */
16146
+ | {
16147
+ kind: "translation";
16148
+ locale: string;
16149
+ unitId?: string;
16150
+ storyId?: string;
16151
+ }
16152
+ /**
16153
+ * A voice table - one voiced language's - and, with `unitId` (a line's text id), that line's row,
16154
+ * where its take is linked. `storyId` names the story the line is in; without it the table looks
16155
+ * the line up itself.
16156
+ */
16157
+ | {
16158
+ kind: "voiceLine";
16159
+ locale: string;
16160
+ unitId?: string;
16161
+ storyId?: string;
16162
+ }
16163
+ /** A story motion, open in its own editor. */
16164
+ | {
16165
+ kind: "storyMotion";
16166
+ animationId: string;
16167
+ }
16168
+ /**
16169
+ * A page of Project settings - the panel's sub-pages - and, with `part`, the part of it to scroll
16170
+ * into view: `fonts` is the project's font stack on the Design page, `letterbox` the letterbox
16171
+ * settings on the Settings page.
16172
+ */
16173
+ | {
16174
+ kind: "projectPage";
16175
+ page: "app" | "game" | "design" | "project" | "runtimes" | "settings";
16176
+ part?: "fonts" | "letterbox";
16177
+ }
16178
+ /**
16179
+ * A story's own row in the Story panel's list, selected and scrolled into view - the place a story
16180
+ * is renamed or deleted, and the one way into a story whose document cannot be opened.
16181
+ */
16182
+ | {
16183
+ kind: "storyEntry";
16184
+ storyId: string;
16185
+ storyName: string;
15694
16186
  };
15695
16187
  type ModelBundleFormat = "live2d-cubism4" | "live2d-cubism2" | "spine-binary" | "spine-json" | "unknown";
15696
16188
  export declare enum AssetType {
@@ -16726,6 +17218,23 @@ type SelectionState = {
16726
17218
  type: "storyBlock";
16727
17219
  data: StoryBlockSelection;
16728
17220
  };
17221
+ type UITextMigrationChangeKind = "marksKept" | "bindingDropped" | "missingKey" | "keyDiffered";
17222
+ type UITextMigrationChange = {
17223
+ kind: UITextMigrationChangeKind;
17224
+ elementId: string;
17225
+ /** The prop the words are in (`text`, `label`, `placeholder`). */
17226
+ prop: string;
17227
+ /** The key the element named. */
17228
+ keyName: string;
17229
+ /** Where the element is: a page, or a component definition. Absent for an element on neither. */
17230
+ surfaceId?: string;
17231
+ componentId?: string;
17232
+ };
17233
+ type UITextCarriedKeys = Record<string, {
17234
+ words: string;
17235
+ translations?: Record<string, LocalizationUnit>;
17236
+ }>;
17237
+ type CarriedTranslations = Record<LocaleCode, Record<string, LocalizationUnit>>;
16729
17238
  type LiveUIComponentShell = Omit<UIComponentDefinition, "elements">;
16730
17239
  type LiveUIParts = {
16731
17240
  /** Records of the shared element map. */
@@ -16811,6 +17320,20 @@ type UIEditorClipboardPayload = {
16811
17320
  source?: UIEditorClipboardSource;
16812
17321
  /** Absent when the copied selection references no importable file. */
16813
17322
  assets?: UIEditorClipboardAssets;
17323
+ /**
17324
+ * The words and translations of the translation keys the copied widgets name, filled when the copy
17325
+ * is published for other windows. A project that lacks one of the keys receives its words on the
17326
+ * widgets instead (`settleIncomingUITextSources`); absent on an in-window copy, whose project
17327
+ * has every key it names.
17328
+ */
17329
+ textKeys?: UITextCarriedKeys;
17330
+ /**
17331
+ * What every language of the copying project says about the words the copied widgets write
17332
+ * directly, by unit id under the originals' ids (`listUITextOwnUnits`). Filled when the copy is
17333
+ * published; the paste writes them under the copies' ids. A paste without them - an in-window copy
17334
+ * not yet published, a duplicate - reads the originals' translations from the project itself.
17335
+ */
17336
+ translations?: CarriedTranslations;
16814
17337
  sourceSurfaceId: string;
16815
17338
  /** Top-level roots in the copied selection (original ids). */
16816
17339
  topLevelElementIds: UIElementId[];
@@ -16851,6 +17374,25 @@ type ImportTemplateBundleInput = {
16851
17374
  graphs: unknown;
16852
17375
  placement: ImportTemplatePlacement;
16853
17376
  assetIdMap?: Record<string, string>;
17377
+ /**
17378
+ * The words, and translations, of the keys the document's widgets name - for the ones this
17379
+ * project lacks, which arrive holding those words themselves (`settleIncomingUITextSources`).
17380
+ */
17381
+ textKeys?: UITextCarriedKeys;
17382
+ /**
17383
+ * What every language says about the words the document's widgets write directly, by unit id
17384
+ * under the ids the widgets have in `document` - a page copied in another window brings them.
17385
+ * Without it, widgets whose ids this project already translates (a page copied in this window)
17386
+ * take those translations.
17387
+ */
17388
+ translations?: CarriedTranslations;
17389
+ /**
17390
+ * Whether the import is one step on the project's undo stack, which takes back every page and
17391
+ * definition it added. On unless a caller's own flow goes on to change more than the import did
17392
+ * - the starter title page also moves the entry page and removes the blank one, and a step that
17393
+ * took back only its middle would leave the project with neither page.
17394
+ */
17395
+ history?: boolean;
16854
17396
  };
16855
17397
  declare class UIDocumentService extends Service<UIDocumentService> implements IUIDocumentService {
16856
17398
  private document;
@@ -16864,6 +17406,8 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
16864
17406
  private opSink;
16865
17407
  private historySuppressionDepth;
16866
17408
  private readonly contentRevisions;
17409
+ /** What the v13 step changed that an author can see, until the workspace has said so. */
17410
+ private textSourceMigrationChanges;
16867
17411
  protected init(ctx: WorkspaceContext, depend: (services: Service[]) => Promise<void>): Promise<void>;
16868
17412
  getDocument(): UIDocument;
16869
17413
  /**
@@ -16944,8 +17488,70 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
16944
17488
  updateElementLayout(elementId: string, layoutPatch: Partial<UILayout>, options?: {
16945
17489
  skipHistory?: boolean;
16946
17490
  }): void;
16947
- updateElementLayouts(layoutPatches: Record<string, Partial<UILayout>>): void;
17491
+ /**
17492
+ * Write several elements' layouts as one change: one `documentChanged` and one undo step.
17493
+ *
17494
+ * `mergeKey` folds this step into the previous one when that carried the same key and was
17495
+ * recorded within the merge window - how a run of arrow-key nudges stays a single undo.
17496
+ */
17497
+ updateElementLayouts(layoutPatches: Record<string, Partial<UILayout>>, options?: {
17498
+ mergeKey?: string;
17499
+ }): void;
16948
17500
  updateElementProps(elementId: string, propsPatch: Record<string, unknown>): void;
17501
+ /**
17502
+ * Every widget that reads its words from `keyName`, turned into one that holds `words` itself.
17503
+ *
17504
+ * What removing a key does to the widgets that use it: each keeps showing what it showed, and none
17505
+ * is left naming a key the project no longer has. Component definitions' widgets are included; an
17506
+ * instance holds none of its definition's words, but a text parameter's value it reads from the key
17507
+ * becomes the key's words, given directly (prop `param.<paramId>`). One change to the document,
17508
+ * outside any page's undo history, like the removal of the key it goes with. Returns each site it
17509
+ * converted, for the translations that go with the words (`ui:<elementId>.<prop>`).
17510
+ */
17511
+ giveKeyedWidgetsTheirWords(keyName: string, words: string): {
17512
+ elementId: string;
17513
+ prop: string;
17514
+ }[];
17515
+ /**
17516
+ * Whether this project has a named key, for settling elements that arrive from elsewhere. A key
17517
+ * registry that has not been read answers yes for every key, so nothing is converted on a guess.
17518
+ */
17519
+ private readonly hasTextKey;
17520
+ /**
17521
+ * The translations of the keys arriving widgets were turned away from, filed under the widgets'
17522
+ * own units in this project's languages. `converted` carries the widgets' ids in this document.
17523
+ *
17524
+ * In the background: a language's library may still have to be read, and the elements have
17525
+ * arrived already. A language the keys came with no translation for gets none.
17526
+ */
17527
+ private adoptArrivingTranslations;
17528
+ /**
17529
+ * Give copied widgets the translations their originals' own words have, under the copies' ids.
17530
+ *
17531
+ * A widget's own words are translated through a unit named after the widget, so a copy - pasted,
17532
+ * duplicated, inside a duplicated page or component - would otherwise arrive translated in no
17533
+ * language. `table` is the arriving elements under their old ids, `idMap` what each became; `skip`
17534
+ * are the sites whose words came from a key this project lacks, which bring the key's translations
17535
+ * instead (`adoptArrivingTranslations`). `extra` are units owned by something other than an element
17536
+ * - a copied component's parameter defaults - already re-keyed, old id to new.
17537
+ *
17538
+ * `carried` is what a clipboard brought with it, which is what a paste from another project has
17539
+ * to go on, and a copy as it was when it was made. Without it the originals are this project's own
17540
+ * and their translations are read from its documents. Either way only languages this project
17541
+ * declares are written, a review is not inherited, and the write is not part of the paste's undo
17542
+ * step (`carriedTranslations.ts`).
17543
+ */
17544
+ private carryCopiedTranslations;
17545
+ /**
17546
+ * The changes the v13 step made on opening this document that an author can see, handed over
17547
+ * once: the workspace tells the author about them in one notice, and a second ask is empty.
17548
+ */
17549
+ takeTextSourceMigrationChanges(): UITextMigrationChange[];
17550
+ /**
17551
+ * The words a widget inserted into this project is given: in the project's source language, the
17552
+ * language its game is written in (`widgetDefaultWordsFor`).
17553
+ */
17554
+ private widgetDefaultWords;
16949
17555
  /** A fresh id for something this document will own. */
16950
17556
  generateId(): string;
16951
17557
  /**
@@ -16960,6 +17566,25 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
16960
17566
  * shape, and an instance that could redeclare it would be editing every other instance.
16961
17567
  */
16962
17568
  setListItemStructFields(elementId: string, fields: readonly UIStructField[]): void;
17569
+ /**
17570
+ * {@link setListItemStructFields} for a list inside a component definition, one step in the
17571
+ * definition's own history.
17572
+ *
17573
+ * The library's rules are the document's, not the page's: a shape another list names - on a page
17574
+ * or in any definition - is forked rather than reshaped (`applyUIStructFieldsForOwner` walks the
17575
+ * definitions too), and the pruning that follows counts what definitions name.
17576
+ */
17577
+ setComponentListItemStructFields(componentId: string, elementId: string, fields: readonly UIStructField[]): void;
17578
+ /**
17579
+ * Give one list one of the engine's shapes, or (`null`) a shape of its own again.
17580
+ *
17581
+ * One step: the pointer, the rows read into the new shape, the list's key field and its item
17582
+ * template's field bindings moved to the field of the same name, and the library pruned. Undo takes
17583
+ * all of it back, the library included (`UIEditorHistoryService` slices the shapes a page names).
17584
+ */
17585
+ setListItemStructShape(elementId: string, shapeId: string | null): void;
17586
+ /** {@link setListItemStructShape} for a list inside a component definition, in its own history. */
17587
+ setComponentListItemStructShape(componentId: string, elementId: string, shapeId: string | null): void;
16963
17588
  /** What the gestures of this project mean, keyed by id. */
16964
17589
  getInputActions(): Record<string, UIInputActionDef>;
16965
17590
  /**
@@ -17011,6 +17636,18 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
17011
17636
  * field id. Switching between them therefore goes through the clear, which is why it runs here.
17012
17637
  */
17013
17638
  setElementListItemFieldBinding(elementId: string, propPath: string, fieldId: string | null): void;
17639
+ /**
17640
+ * Show one of its page's text parameters in the words of an element on that page, or (`null`)
17641
+ * stop showing one. The page's counterpart of `setElementComponentParamBinding`: an element on a
17642
+ * Game UI, which declares no parameters, is left alone.
17643
+ */
17644
+ setElementPageParamBinding(elementId: string, propPath: string, paramId: string | null): void;
17645
+ /**
17646
+ * Bind one prop of one element on a surface to something that needs no blueprint - a field of its
17647
+ * list row, a text parameter of its page - or (`null`) unbind it. A Blueprint Value the prop was
17648
+ * bound to is torn down on the way (`clearElementBlueprintValueBinding`).
17649
+ */
17650
+ private setElementPlainValueBinding;
17014
17651
  ensureElementBlueprintValueBinding(elementId: string, propPath: string, input: {
17015
17652
  valueType: UIElementValueBindingValueType;
17016
17653
  displayName?: string;
@@ -17100,10 +17737,81 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
17100
17737
  private scheduleAutoSave;
17101
17738
  private setDirty;
17102
17739
  private getHistoryService;
17740
+ /**
17741
+ * Where an edit to a component definition is recorded: the definition's own undo stack, named by
17742
+ * the component editor's surface id (`UIEditorHistoryService` maps that to the definition's
17743
+ * scope). One stack per definition, so undoing in one component tab never touches another
17744
+ * definition or any page - and an instance on a page draws the definition from the library each
17745
+ * time, so putting the definition back puts every placement back with it.
17746
+ */
17747
+ private componentHistory;
17748
+ private getGraphService;
17749
+ /**
17750
+ * One step on the project's undo stack, for an operation on the library as a whole - adding,
17751
+ * copying, deleting or importing pages and definitions.
17752
+ *
17753
+ * The project's stack rather than any editor's, for the reason {@link reorderSurfaces} gives:
17754
+ * these are made from the rail, and that is the stack Ctrl+Z and the Edit menu reach from there
17755
+ * (`resolveWorkspaceUndoScope`). A definition's own stack holds edits *inside* it, and a deleted
17756
+ * definition has no tab to press Ctrl+Z in.
17757
+ *
17758
+ * Each step is a command over whole records, not a snapshot of the library: whichever direction
17759
+ * runs reads the records as they stand at that moment and writes them back exactly, and nothing
17760
+ * else in the library is touched. Tagged, so a live session drops these steps with the interface
17761
+ * editors' stacks (`LiveSessionService`): taking back an addition after a session would remove
17762
+ * whatever the room built inside it.
17763
+ */
17764
+ private pushLibraryStep;
17765
+ /**
17766
+ * Take pages and definitions out of the project, and return them as they stood.
17767
+ *
17768
+ * Empty when nothing left this copy of the document - ids it does not hold, or an operation sink
17769
+ * that took the gesture: inside a live session the removal arrives as an effect later, the
17770
+ * lifecycle sweep collects the blueprints then, and undo is the session's.
17771
+ */
17772
+ private takeLibraryRecords;
17773
+ /**
17774
+ * Put records {@link takeLibraryRecords} returned back where they stood.
17775
+ *
17776
+ * Blueprints first: the sweep that follows the document write gives a widget with no blueprint a
17777
+ * fresh, empty one, and it must find each record's own already in place.
17778
+ */
17779
+ private putLibraryRecords;
17780
+ /**
17781
+ * Leave the step that takes back pages and definitions an operation just added.
17782
+ *
17783
+ * Nothing is recorded when none of them is in this copy of the document, which is what an
17784
+ * operation sink taking the gesture looks like (the reasoning {@link reorderSurfaces} gives).
17785
+ */
17786
+ private recordLibraryAddition;
17103
17787
  private getElementSurfaceId;
17104
17788
  private getCommonSurfaceIdForElements;
17105
17789
  private filterLinkedComponentLayoutPatch;
17106
17790
  private migrateIfNeeded;
17791
+ /**
17792
+ * Every page's declared parameters, in the shape this build reads (`normalizeUIPageParams`).
17793
+ *
17794
+ * A normalizer for the reason {@link normalizeInputModel} is one: an empty list and no list mean
17795
+ * the same thing, so a page that declares none keeps its record as short as it was. A Game UI's
17796
+ * are dropped - the player mounts it with nothing, so nothing could ever fill them.
17797
+ */
17798
+ private normalizePageParams;
17799
+ /**
17800
+ * The v13 step, for the project's own document as it is opened (`textSourceMigration.ts`).
17801
+ *
17802
+ * Not part of {@link migrateIfNeeded}, which is also how a template or a page copied from another
17803
+ * project comes in: this step reads the project's key registry and translation files, and the
17804
+ * translation edits it makes are written here, through the localization service, before the
17805
+ * document itself is saved by `load`. Written first so that a document still at v12 on disk -
17806
+ * its own save failed - is migrated again on the next open, and the edits are such that applying
17807
+ * them twice changes nothing.
17808
+ *
17809
+ * A key registry or a language file that cannot be read stops the open rather than being read
17810
+ * as empty: an element whose key could not be found is turned into one that holds its own words,
17811
+ * and a registry that is merely unreadable today would turn every keyed element in the project
17812
+ * into one, for good.
17813
+ */
17814
+ private migrateTextSources;
17107
17815
  /**
17108
17816
  * Every `nl.image` written in the shape that came before `imageFill`, rewritten into it.
17109
17817
  *
@@ -17281,7 +17989,14 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
17281
17989
  getComponent(componentId: string): UIComponentDefinition | undefined;
17282
17990
  getComponentUsageCount(componentId: string): number;
17283
17991
  createEmptyComponent(name?: string): UIComponentDefinition;
17992
+ /**
17993
+ * A new definition made of copies of elements on a page, with the logic they carry.
17994
+ *
17995
+ * The page is not changed, so the step that takes this back is the library's - the project's
17996
+ * stack, the one {@link createEmptyComponent} uses - rather than the page's.
17997
+ */
17284
17998
  createComponentFromElements(surfaceId: string, elementIds: string[], name?: string): UIComponentDefinition | null;
17999
+ /** Recorded in the definition's own undo stack, as a page's name is in the page's. */
17285
18000
  renameComponent(componentId: string, name: string): void;
17286
18001
  /**
17287
18002
  * Replace a component's declared params.
@@ -17289,16 +18004,94 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
17289
18004
  * Instances keep values for ids that survive: a param is identified by `id`, so renaming one in
17290
18005
  * the inspector does not unset it anywhere. Values for ids that were removed are left on their
17291
18006
  * instances rather than swept - re-adding a param by the same id is how an author undoes a
17292
- * deletion, and sweeping would make that a data loss with no warning.
18007
+ * deletion, and sweeping would make that a data loss with no warning. That is also why undoing
18008
+ * this - one step in the definition's own stack - needs nothing from the instances: their values
18009
+ * were never touched, so the restored declaration finds them where it left them.
17293
18010
  */
17294
18011
  setComponentParams(componentId: string, params: UIComponentParam[]): void;
17295
- /** Set one param value on one instance. An empty string is a value, not a reset. */
18012
+ /**
18013
+ * Replace the parameters a page declares.
18014
+ *
18015
+ * A parameter is identified by `id`, so the nodes that open the page and the `Get Page Param`
18016
+ * nodes that read it keep pointing at it through a rename. What reads it by name - the key its
18017
+ * value travels under - is followed in the same step where it lives on the page itself: a list on
18018
+ * the page bound to the old name is bound to the new one. Anything elsewhere that names it (a Page
18019
+ * widget on another page giving it a value, a script) is left alone, because this page's undo must
18020
+ * not reach into another page; the project check reports those.
18021
+ *
18022
+ * A removed parameter's values are not swept from anywhere, as a component's are not: re-adding it
18023
+ * is how an author takes a deletion back.
18024
+ */
18025
+ setPageParams(surfaceId: string, params: UIPageParam[]): void;
18026
+ /**
18027
+ * Set one param value on one instance. An empty string is a value, not a reset.
18028
+ *
18029
+ * Words written for a text parameter replace a key the instance named for it: a value holds one
18030
+ * or the other (`UIComponentLink.paramKeys`).
18031
+ */
17296
18032
  setComponentInstanceParam(elementId: string, paramId: string, value: string): void;
18033
+ /**
18034
+ * Name the translation key one instance's text parameter is read from, or (`null`) name none.
18035
+ *
18036
+ * Naming a key removes the words the instance held for the parameter - a value holds one source -
18037
+ * and naming none leaves the parameter with neither, which falls back to the definition's default.
18038
+ */
18039
+ setComponentInstanceParamKey(elementId: string, paramId: string, keyName: string | null): void;
18040
+ /**
18041
+ * Remove definitions from the library, as one step on the project's undo stack.
18042
+ *
18043
+ * Placements of them on pages are left as they are, and draw as missing until the definition is
18044
+ * back or they are replaced. Undo puts each definition back at its place in the library with its
18045
+ * widgets' blueprints and the item shapes its lists name, and every placement draws it again.
18046
+ */
17297
18047
  deleteComponents(componentIds: string[]): void;
18048
+ /** One copy of a definition; see {@link duplicateComponents}. */
17298
18049
  duplicateComponent(componentId: string): UIComponentDefinition | null;
17299
- updateComponentElementLayout(componentId: string, elementId: string, layoutPatch: Partial<UILayout>): void;
18050
+ /**
18051
+ * A copy of each definition, added to the end of the library, as one step on the project's undo
18052
+ * stack. The copies' translations are written in the background and are not part of the step:
18053
+ * undoing leaves them unused, and redoing finds them again (`carryCopiedTranslations`).
18054
+ */
18055
+ duplicateComponents(componentIds: readonly string[]): UIComponentDefinition[];
18056
+ private copyComponent;
18057
+ /**
18058
+ * One element of a definition's layout, as `updateElementLayout` is one of a page's: an undo step
18059
+ * of its own, folded into the previous one when that wrote the same fields of the same element
18060
+ * within the merge window - so typing a number into the inspector is one step, not one a key.
18061
+ * `skipHistory` is for the write a gesture makes on its way to the one it records.
18062
+ */
18063
+ updateComponentElementLayout(componentId: string, elementId: string, layoutPatch: Partial<UILayout>, options?: {
18064
+ skipHistory?: boolean;
18065
+ }): void;
18066
+ /**
18067
+ * Several elements of one definition as one change: one `documentChanged` and one undo step, as
18068
+ * `updateElementLayouts` is on a page - a drag of three elements is undone by one Ctrl+Z.
18069
+ * `mergeKey` folds the step into the previous one when that carried the same key and was
18070
+ * recorded within the merge window, which is how a run of arrow-key nudges stays one undo.
18071
+ */
18072
+ updateComponentElementLayouts(componentId: string, layoutPatches: Record<string, Partial<UILayout>>, options?: {
18073
+ mergeKey?: string;
18074
+ }): void;
18075
+ private writeComponentElementLayout;
18076
+ /**
18077
+ * Bind one prop of one element of a component definition to a field of its list row or to a text
18078
+ * parameter of the component - the two value bindings that need no blueprint - or (`null`) unbind
18079
+ * it. A definition's elements take no Blueprint Value (`ComponentDocumentServiceAdapter`), so there
18080
+ * is no blueprint to clear on the way.
18081
+ */
18082
+ setComponentElementValueBinding(componentId: string, elementId: string, propPath: string, binding: Extract<UIElementValueBinding, {
18083
+ kind: "listItemField" | "componentParam";
18084
+ }> | null): void;
18085
+ /**
18086
+ * Show one of a component's text parameters in the words of an element of its definition, or
18087
+ * (`null`) stop showing one. The component is the one whose definition holds the element; an
18088
+ * element on a page has no parameters to show and is left alone.
18089
+ */
18090
+ setElementComponentParamBinding(elementId: string, propPath: string, paramId: string | null): void;
17300
18091
  updateComponentElementProps(componentId: string, elementId: string, propsPatch: Record<string, unknown>): void;
17301
- updateComponentElementAnimation(componentId: string, elementId: string, animation: UIPageAnimationSettings | null): void;
18092
+ updateComponentElementAnimation(componentId: string, elementId: string, animation: UIPageAnimationSettings | null, options?: {
18093
+ mergeKey?: string;
18094
+ }): void;
17302
18095
  updateComponentElementExtra(componentId: string, elementId: string, extraPatch: Record<string, unknown>): void;
17303
18096
  renameComponentElement(componentId: string, elementId: string, name: string): void;
17304
18097
  reorderComponentChildren(componentId: string, parentId: string, orderedChildIds: string[]): void;
@@ -17315,7 +18108,7 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
17315
18108
  */
17316
18109
  groupComponentElements(componentId: string, elementIds: readonly string[]): string | null;
17317
18110
  createComponentElement(componentId: string, parentId: string, type: string, layoutPatch?: Partial<UILayout>): UIElement | null;
17318
- pasteComponentClipboardPayload(componentId: string, targetParentId: string, beforeChildId: string | null, payload: UIEditorClipboardPayload): {
18111
+ pasteComponentClipboardPayload(componentId: string, targetParentId: string, beforeChildId: string | null, incoming: UIEditorClipboardPayload): {
17319
18112
  ok: true;
17320
18113
  newRootIds: string[];
17321
18114
  } | {
@@ -17325,7 +18118,7 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
17325
18118
  createComponentInstance(parentId: string, componentId: string, layoutPatch?: Partial<UILayout>): UIElement;
17326
18119
  unlinkComponentInstance(elementId: string): string[];
17327
18120
  createElement(parentId: string, type: string, layoutPatch?: Partial<UILayout>): UIElement;
17328
- pasteClipboardPayload(surfaceId: string, targetParentId: string, beforeChildId: string | null, payload: UIEditorClipboardPayload): {
18121
+ pasteClipboardPayload(surfaceId: string, targetParentId: string, beforeChildId: string | null, incoming: UIEditorClipboardPayload): {
17329
18122
  ok: true;
17330
18123
  newRootIds: string[];
17331
18124
  } | {
@@ -18157,6 +18950,18 @@ type BlueprintNodeDeclaration = {
18157
18950
  saveSchemaPins?: {
18158
18951
  kind: "input" | "output";
18159
18952
  };
18953
+ /**
18954
+ * Grow one input per parameter the page this node opens declares (`UIPageParam`).
18955
+ *
18956
+ * The page is the one picked on the card, read from `params[surfaceParam]` - the key the node's
18957
+ * page picker writes. Like {@link saveSchemaPins} the list comes from a project document rather
18958
+ * than from the node, so every node that opens one page grows the same inputs, in the page's
18959
+ * order, and renaming a parameter relabels all of them. The inputs belong to the picked page: a
18960
+ * different page arriving on a wire is opened with the node's `props` input alone.
18961
+ */
18962
+ pageParamPins?: {
18963
+ surfaceParam: string;
18964
+ };
18160
18965
  inspectorParams?: BlueprintInspectorParamDef[];
18161
18966
  role?: BlueprintNodeRole;
18162
18967
  /**
@@ -18657,7 +19462,9 @@ interface IUIDocumentService extends IService {
18657
19462
  updateElementLayout(elementId: string, layoutPatch: Partial<UILayout>, options?: {
18658
19463
  skipHistory?: boolean;
18659
19464
  }): void;
18660
- updateElementLayouts(layoutPatches: Record<string, Partial<UILayout>>): void;
19465
+ updateElementLayouts(layoutPatches: Record<string, Partial<UILayout>>, options?: {
19466
+ mergeKey?: string;
19467
+ }): void;
18661
19468
  updateElementProps(elementId: string, propsPatch: Record<string, unknown>): void;
18662
19469
  ensureElementBlueprintValueBinding(elementId: string, propPath: string, input: {
18663
19470
  valueType: UIElementValueBindingValueType;
@@ -18691,7 +19498,13 @@ interface IUIDocumentService extends IService {
18691
19498
  renameComponent(componentId: string, name: string): void;
18692
19499
  deleteComponents(componentIds: string[]): void;
18693
19500
  duplicateComponent(componentId: string): UIComponentDefinition | null;
18694
- updateComponentElementLayout(componentId: string, elementId: string, layoutPatch: Partial<UILayout>): void;
19501
+ duplicateComponents(componentIds: readonly string[]): UIComponentDefinition[];
19502
+ updateComponentElementLayout(componentId: string, elementId: string, layoutPatch: Partial<UILayout>, options?: {
19503
+ skipHistory?: boolean;
19504
+ }): void;
19505
+ updateComponentElementLayouts(componentId: string, layoutPatches: Record<string, Partial<UILayout>>, options?: {
19506
+ mergeKey?: string;
19507
+ }): void;
18695
19508
  updateComponentElementProps(componentId: string, elementId: string, propsPatch: Record<string, unknown>): void;
18696
19509
  updateComponentElementExtra(componentId: string, elementId: string, extraPatch: Record<string, unknown>): void;
18697
19510
  renameComponentElement(componentId: string, elementId: string, name: string): void;
@@ -18815,7 +19628,9 @@ declare const HELP_TOPIC_IDS: readonly [
18815
19628
  "screenEffects",
18816
19629
  "plugins"
18817
19630
  ];
18818
- type HelpTopicId = (typeof HELP_TOPIC_IDS)[number];
19631
+ type StaticHelpTopicId = (typeof HELP_TOPIC_IDS)[number];
19632
+ type LintRuleHelpTopicId = `lintRule.${string}`;
19633
+ type HelpTopicId = StaticHelpTopicId | LintRuleHelpTopicId;
18819
19634
  interface PanelComponentProps<TPayload = any> {
18820
19635
  panelId: string;
18821
19636
  payload?: TPayload;
@@ -19678,6 +20493,13 @@ export type RuntimePluginLocale = {
19678
20493
  * added after the plugin was installed. `null` when the project declares no such key.
19679
20494
  */
19680
20495
  text(key: string): string | null;
20496
+ /**
20497
+ * Words this plugin wrote directly and offered for translation from its studio entry
20498
+ * (`app.services.localization.registerWords`), in the language the game is running in: the
20499
+ * translation of the unit `id` names along the language's fallback chain, else `text` - the words
20500
+ * as written, which the plugin passes because the game carries translations and not source words.
20501
+ */
20502
+ words(id: string, text: string): string;
19681
20503
  };
19682
20504
  /**
19683
20505
  * `menu` - the whole menu bar above the game, declared at once.
@@ -20572,6 +21394,22 @@ export type FreezeGuard = {
20572
21394
  run<A extends unknown[], R>(handler: (...args: A) => R): (...args: A) => R | undefined;
20573
21395
  };
20574
21396
  declare function useFreezeGuard(scope?: string | readonly string[]): FreezeGuard;
21397
+ type WordsSourceValue = {
21398
+ /** The words written directly; with a key, what shows if the key is not in the running game. */
21399
+ text: string;
21400
+ /** The translation key the words are read from, or null for words written directly. */
21401
+ key: string | null;
21402
+ };
21403
+ type WordsSourceFieldProps = {
21404
+ value: WordsSourceValue;
21405
+ onChange: (next: WordsSourceValue) => void;
21406
+ /** Words over several lines; one line when absent. */
21407
+ multiline?: boolean;
21408
+ disabled?: boolean;
21409
+ /** Resets the box's draft when it changes - the id of whatever the words belong to. */
21410
+ draftResetKey?: string;
21411
+ };
21412
+ declare function WordsSourceField({ value, onChange, multiline, disabled, draftResetKey }: WordsSourceFieldProps): React$1.ReactElement;
20575
21413
  type DivProps = React$1.HTMLAttributes<HTMLDivElement>;
20576
21414
  declare function PluginAssetSelector(props: AssetSelectorProps): React$1.JSX.Element | null;
20577
21415
  export type PluginPanelRootProps = DivProps & {
@@ -20660,6 +21498,14 @@ declare const pluginUi: Readonly<{
20660
21498
  CardFooter: typeof CardFooter;
20661
21499
  InteractiveCard: typeof InteractiveCard;
20662
21500
  AssetSelector: typeof PluginAssetSelector;
21501
+ /**
21502
+ * Words a player reads, written directly or read from one of the project's translation keys - the
21503
+ * same choice, key list and in-place key editing as Studio's own text and button labels. Controlled:
21504
+ * `value` is `{ text, key }` with `key` null for words written directly, and `onChange` is
21505
+ * handed the next one. Words written directly are translated when the plugin offers them with
21506
+ * `app.services.localization.registerWords`; words read from a key are translated as the key.
21507
+ */
21508
+ WordsField: typeof WordsSourceField;
20663
21509
  Panel: Readonly<{
20664
21510
  Root: typeof PluginPanelRoot;
20665
21511
  Header: typeof PluginPanelHeader;
@@ -20758,6 +21604,7 @@ export declare const ui: Readonly<{
20758
21604
  CardFooter: typeof CardFooter;
20759
21605
  InteractiveCard: typeof InteractiveCard;
20760
21606
  AssetSelector: typeof PluginAssetSelector;
21607
+ WordsField: typeof WordsSourceField;
20761
21608
  Panel: Readonly<{
20762
21609
  Root: typeof PluginPanelRoot;
20763
21610
  Header: typeof PluginPanelHeader;
@@ -20939,7 +21786,7 @@ export type PluginAssetsService = {
20939
21786
  revokeObjectUrl(url: string): void;
20940
21787
  };
20941
21788
  /** An active editor locale code (built-in like "en"/"zh", or a plugin-provided locale). */
20942
- export type LocaleCode = string;
21789
+ type LocaleCode$1 = string;
20943
21790
  /**
20944
21791
  * A plugin's own message tables: `locale code -> (message key -> string)`. This
20945
21792
  * is the plugin's private catalog, unrelated to Studio's own translations.
@@ -20959,7 +21806,7 @@ export type PluginMessageBundle = {
20959
21806
  * {@link PluginI18n.onLocaleChange} to re-render on a language switch.
20960
21807
  */
20961
21808
  export type PluginTranslator = {
20962
- readonly locale: LocaleCode;
21809
+ readonly locale: LocaleCode$1;
20963
21810
  t(key: string, params?: Record<string, string | number>): string;
20964
21811
  };
20965
21812
  /**
@@ -20969,14 +21816,14 @@ export type PluginTranslator = {
20969
21816
  */
20970
21817
  export type PluginI18n = {
20971
21818
  /** The editor's active locale code. */
20972
- readonly locale: LocaleCode;
21819
+ readonly locale: LocaleCode$1;
20973
21820
  /**
20974
21821
  * Subscribe to editor-language changes. The listener fires with the new
20975
21822
  * locale code whenever the active editor language changes. Returns a
20976
21823
  * {@link PluginCleanup} (also tracked by the host, so it is reclaimed on
20977
21824
  * unload even if you forget to call it).
20978
21825
  */
20979
- onLocaleChange(listener: (locale: LocaleCode) => void): PluginCleanup;
21826
+ onLocaleChange(listener: (locale: LocaleCode$1) => void): PluginCleanup;
20980
21827
  /** Locale-aware number formatting bound to the editor's active locale. */
20981
21828
  formatNumber(value: number, options?: Intl.NumberFormatOptions): string;
20982
21829
  /** Locale-aware date formatting bound to the editor's active locale. */
@@ -21056,15 +21903,45 @@ export type PluginInterfaceService = {
21056
21903
  listGlobalFns(): PluginBlueprintFnEntry[];
21057
21904
  };
21058
21905
  /**
21059
- * The project's own localization keys, read-only.
21906
+ * One of the words a plugin puts in front of a player, offered for translation.
21907
+ *
21908
+ * `id` is the plugin's own (letters, digits, and `.` `_` `-` between them) and has to stay the same
21909
+ * while the words are the same thing - a translation is kept against it, so an id made from the words
21910
+ * themselves would lose every translation the moment the author corrected a letter. The translation
21911
+ * unit is `plugin:<pluginId>/<id>`, scoped to the plugin by the host.
21912
+ */
21913
+ export type PluginWordsEntry = {
21914
+ id: string;
21915
+ /** The words, in the project's source language. */
21916
+ text: string;
21917
+ /** Where a player meets them, for a translator: "File › Save". The plugin's name when absent. */
21918
+ context?: string;
21919
+ };
21920
+ /** A plugin's words as they are now, and a way for the host to hear that they changed. */
21921
+ export type PluginWordsSource = {
21922
+ list(): readonly PluginWordsEntry[];
21923
+ subscribe?(listener: () => void): () => void;
21924
+ };
21925
+ /**
21926
+ * The project's own localization keys, read-only, and a place to offer the plugin's own words.
21060
21927
  *
21061
- * A plugin that puts words in front of a player writes them as keys through this list rather than
21062
- * as literals, so they travel with everything else the project translates. Empty before the keys
21063
- * document has loaded, which is a moment rather than a state - subscribe through
21064
- * `services.workspace.registerReloader` if a panel has to re-read it.
21928
+ * A plugin that puts words in front of a player either names a key from this list - one of the
21929
+ * project's shared words - or writes them directly and offers them with `registerWords`, so they
21930
+ * travel with everything else the project translates. Empty before the keys document has loaded,
21931
+ * which is a moment rather than a state - subscribe through `services.workspace.registerReloader` if
21932
+ * a panel has to re-read it.
21065
21933
  */
21066
21934
  export type PluginLocalizationService = {
21067
21935
  listKeys(): PluginLocalizationKeyEntry[];
21936
+ /**
21937
+ * Offer the plugin's own words to the project's translation table and exports.
21938
+ *
21939
+ * Each listed entry with a letter in it gets a row under the plugin's name; the runtime entry
21940
+ * reads a word back in the player's language with `app.game.locale.words(id, text)`. List what
21941
+ * the author wrote directly; words read from a key are translated as the key and need no entry.
21942
+ * Call `subscribe`'s listener whenever the list would answer differently.
21943
+ */
21944
+ registerWords(source: PluginWordsSource): PluginCleanup;
21068
21945
  };
21069
21946
  export type PluginServices = {
21070
21947
  storage: PluginStorageService;
@@ -21182,6 +22059,7 @@ export {
21182
22059
  GameSurfaceMountDetail as RuntimePluginSurfaceMountTimelineDetail,
21183
22060
  GameTimelineSpanDetails as RuntimePluginTimelineSpanDetails,
21184
22061
  GameTimelineSpanName as RuntimePluginTimelineSpanName,
22062
+ LocaleCode$1 as LocaleCode,
21185
22063
  SelectOption$1 as SelectOption,
21186
22064
  };
21187
22065