@px-lsp/protocol 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/calendar.d.ts +15 -13
- package/dist/calendar.js +26 -27
- package/dist/calendarFile.d.ts +26 -0
- package/dist/calendarFile.js +109 -0
- package/dist/calendarLoc.js +7 -11
- package/dist/configDir.d.ts +17 -0
- package/dist/configDir.js +79 -0
- package/dist/protocol.d.ts +481 -0
- package/dist/protocol.js +123 -1
- package/dist/workshopMeta.d.ts +3 -5
- package/dist/workshopMeta.js +6 -11
- package/package.json +1 -1
- package/src/calendar.ts +34 -35
- package/src/calendarFile.ts +81 -0
- package/src/calendarLoc.ts +7 -14
- package/src/configDir.ts +47 -0
- package/src/protocol.ts +487 -0
- package/src/workshopMeta.ts +6 -11
package/dist/protocol.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DefSource } from "./types";
|
|
1
2
|
/** Resolved extension settings, computed client-side (path validation, Steam
|
|
2
3
|
* detection fallbacks, workspace-folder default) and pushed to the server. */
|
|
3
4
|
export interface ParadoxSettings {
|
|
@@ -164,6 +165,39 @@ export interface LocEntryInfo {
|
|
|
164
165
|
source: "vanilla" | "parent" | "mod";
|
|
165
166
|
value?: string;
|
|
166
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Request: a localization value as the PLAYER reads it;
|
|
170
|
+
* {@link LocTextParams} -> {@link LocTextResult}.
|
|
171
|
+
*
|
|
172
|
+
* {@link lookupLocRequest} answers the value verbatim, which is what an editor
|
|
173
|
+
* needs. A panel that SHOWS the value needs the sentence: the games write a
|
|
174
|
+
* culture parameter as `"The [GetTrait('rough_terrain_expert').GetName(
|
|
175
|
+
* GetNullCharacter )] Commander Trait is more common"` (145 of the 280
|
|
176
|
+
* parameter values with a real call take that one shape), and a modder reading
|
|
177
|
+
* a form must not be shown the brackets.
|
|
178
|
+
*
|
|
179
|
+
* Everything the renderer knows is DERIVED: the words come from the loc index
|
|
180
|
+
* (mod entries shadow the game's), the kind a `Get<Something>('name')` chain
|
|
181
|
+
* names comes from the definition index, and the loc key that kind's names take
|
|
182
|
+
* comes from the active profile's schema. No table of function names, so a
|
|
183
|
+
* workspace of any of the games gets the same behavior from its own schema.
|
|
184
|
+
*/
|
|
185
|
+
export declare const locTextRequest = "paradox/locText";
|
|
186
|
+
export interface LocTextParams extends ModScopedParams {
|
|
187
|
+
keys: string[];
|
|
188
|
+
}
|
|
189
|
+
export interface LocTextValue {
|
|
190
|
+
/** The value verbatim, exactly as {@link lookupLocRequest} answers it. */
|
|
191
|
+
raw: string;
|
|
192
|
+
/** The same value as plain text: markup stripped, datafunctions resolved. */
|
|
193
|
+
text: string;
|
|
194
|
+
/** False when any part of the value stayed a word for something unresolved. */
|
|
195
|
+
resolved: boolean;
|
|
196
|
+
}
|
|
197
|
+
export interface LocTextResult {
|
|
198
|
+
/** Loc key -> its rendering. A key the loc index cannot find is ABSENT. */
|
|
199
|
+
values: Record<string, LocTextValue>;
|
|
200
|
+
}
|
|
167
201
|
/** Notification: data health for the status bar; payload {@link StatusPayload}. */
|
|
168
202
|
export declare const statusNotification = "paradox/status";
|
|
169
203
|
export interface StatusPayload {
|
|
@@ -206,6 +240,20 @@ export interface OverviewDef {
|
|
|
206
240
|
name: string;
|
|
207
241
|
file: string;
|
|
208
242
|
line: number;
|
|
243
|
+
/**
|
|
244
|
+
* The loc-resolved display name, when the kind's loc pattern resolves to one
|
|
245
|
+
* ({@link EventVocabularyItem.label}). Set by {@link definitionFormRequest}
|
|
246
|
+
* only, so a creator listing what the mod already has can show the player's
|
|
247
|
+
* word for it; absent everywhere else.
|
|
248
|
+
*/
|
|
249
|
+
label?: string;
|
|
250
|
+
/**
|
|
251
|
+
* Where the definition comes from. Set by {@link definitionFormRequest} only,
|
|
252
|
+
* whose list includes the game's and a dependency's definitions (a creator
|
|
253
|
+
* opens one to duplicate or override it) and must say which is which; absent
|
|
254
|
+
* everywhere else, where every definition listed is the mod's own.
|
|
255
|
+
*/
|
|
256
|
+
source?: "vanilla" | "parent" | "mod";
|
|
209
257
|
}
|
|
210
258
|
export interface OverviewKind {
|
|
211
259
|
kind: string;
|
|
@@ -1336,6 +1384,13 @@ export interface EventGraphParams {
|
|
|
1336
1384
|
/** Also read each mod event's `theme`. Off by default: it costs one parse per
|
|
1337
1385
|
* event file, and only a client that draws the theme's art needs it. */
|
|
1338
1386
|
themes?: boolean;
|
|
1387
|
+
/**
|
|
1388
|
+
* Leave out every definition that has no edge in the answer. ON by default
|
|
1389
|
+
* (absent = true): the pruned definitions are dropped before their cards
|
|
1390
|
+
* are read, so a mod with hundreds of standalone events stays cheap. `root`
|
|
1391
|
+
* is always kept. Send `false` to see the whole namespace, edges or not.
|
|
1392
|
+
*/
|
|
1393
|
+
connectedOnly?: boolean;
|
|
1339
1394
|
}
|
|
1340
1395
|
/**
|
|
1341
1396
|
* One row of a mod event's card, in EXECUTION order (immediate, then the
|
|
@@ -1458,10 +1513,38 @@ export interface EventVocabularyItem {
|
|
|
1458
1513
|
doc?: string;
|
|
1459
1514
|
/** Dimmer right-hand label: where the value comes from (mod / vanilla / a kind). */
|
|
1460
1515
|
hint?: string;
|
|
1516
|
+
/**
|
|
1517
|
+
* The name the PLAYER reads: the loc value of the kind's first loc pattern
|
|
1518
|
+
* with `$` replaced by the definition name (`trait_$` -> `trait_brave` ->
|
|
1519
|
+
* "Brave"). Set by {@link definitionFormRequest} only, and absent when
|
|
1520
|
+
* nothing resolves, so a client shows the key rather than an invented word.
|
|
1521
|
+
*/
|
|
1522
|
+
label?: string;
|
|
1523
|
+
/**
|
|
1524
|
+
* The family this definition belongs to, when one folder holds several and
|
|
1525
|
+
* the schema entry names the key that says so (`type = ethos` in
|
|
1526
|
+
* common/culture/pillars). Set by {@link definitionFormRequest} only, so a
|
|
1527
|
+
* creator can draw one picker per family; absent everywhere else.
|
|
1528
|
+
*/
|
|
1529
|
+
group?: string;
|
|
1461
1530
|
}
|
|
1462
1531
|
/** Caps: an editor lists a page at a time, and these ride on every open. */
|
|
1463
1532
|
export declare const EVENT_VOCABULARY_MAX_TOKENS = 600;
|
|
1464
1533
|
export declare const EVENT_VOCABULARY_MAX_VALUES = 400;
|
|
1534
|
+
/**
|
|
1535
|
+
* Most values {@link DefinitionFormKey.sampled} carries, and the point past
|
|
1536
|
+
* which a key is taken to have no value SET at all (a key whose value differs
|
|
1537
|
+
* per definition is a free field, not a list to offer).
|
|
1538
|
+
*/
|
|
1539
|
+
export declare const DEFINITION_FORM_MAX_SAMPLED = 80;
|
|
1540
|
+
/**
|
|
1541
|
+
* How long a block body {@link DefinitionFormKey.example} may be. A placeholder
|
|
1542
|
+
* is read at a glance, and the shortest bodies a game writes for a block key
|
|
1543
|
+
* (a trait's `triggered_opinion`, a culture's `parameters`) fit well inside
|
|
1544
|
+
* this; a longer one is cut with an ellipsis rather than dropped, because half
|
|
1545
|
+
* a real body still says what the key wants.
|
|
1546
|
+
*/
|
|
1547
|
+
export declare const DEFINITION_FORM_MAX_EXAMPLE = 120;
|
|
1465
1548
|
/**
|
|
1466
1549
|
* Request: the value set a VALUE belongs to, resolved through the definition
|
|
1467
1550
|
* index; {@link EventValueOptionsParams} -> {@link EventValueOptionsResult} |
|
|
@@ -1580,6 +1663,59 @@ export interface GuiUseSite {
|
|
|
1580
1663
|
*/
|
|
1581
1664
|
via: string[];
|
|
1582
1665
|
}
|
|
1666
|
+
/**
|
|
1667
|
+
* Request: the code snippets a host can offer for one open script document;
|
|
1668
|
+
* {@link SnippetsParams} -> {@link SnippetsResult}. Answers for OPEN script
|
|
1669
|
+
* documents only (the server reads the client's text, not the disk); a document
|
|
1670
|
+
* it does not know answers with an EMPTY list, never an error.
|
|
1671
|
+
*
|
|
1672
|
+
* Two sources, neither hand-written. The definition and child-block skeletons
|
|
1673
|
+
* are the measured shape of the document folder's own definition kind (at least
|
|
1674
|
+
* half of the game's definitions of that kind carry each key, in the median
|
|
1675
|
+
* order they hold there). The token entries are the block form of the `usage:`
|
|
1676
|
+
* example the game's own script_docs dump ships for an engine trigger or effect,
|
|
1677
|
+
* filtered to the block the cursor sits in.
|
|
1678
|
+
*
|
|
1679
|
+
* Every entry carries BOTH insert forms, exactly like completion does: `snippet`
|
|
1680
|
+
* for a host that expands `${1:…}` tabstops, `plain` for one that does not.
|
|
1681
|
+
*/
|
|
1682
|
+
export declare const snippetsRequest = "paradox/snippets";
|
|
1683
|
+
export interface SnippetsParams {
|
|
1684
|
+
uri: string;
|
|
1685
|
+
/** 0-based, as in LSP. Decides which engine block templates fit. */
|
|
1686
|
+
position: {
|
|
1687
|
+
line: number;
|
|
1688
|
+
character: number;
|
|
1689
|
+
};
|
|
1690
|
+
}
|
|
1691
|
+
/** One offer, ready to insert at the cursor. */
|
|
1692
|
+
export interface SnippetItem {
|
|
1693
|
+
/**
|
|
1694
|
+
* Stable id: the definition kind (`event`), the kind and its child block
|
|
1695
|
+
* (`event.option`), or the engine token (`if`) — plus `<token>.full` when the
|
|
1696
|
+
* token's example marks fields optional and an all-fields form follows it.
|
|
1697
|
+
* Suitable as a picker key.
|
|
1698
|
+
*/
|
|
1699
|
+
id: string;
|
|
1700
|
+
/** Reads as what it inserts: "new event", "option block", "if". */
|
|
1701
|
+
label: string;
|
|
1702
|
+
/** Provenance, with the measurement behind it. */
|
|
1703
|
+
detail: string;
|
|
1704
|
+
/**
|
|
1705
|
+
* `definition` = a whole definition of the document's kind, including the
|
|
1706
|
+
* file header line when the document declares none; `block` = one child block
|
|
1707
|
+
* of that kind; `token` = an engine trigger/effect's own dumped example.
|
|
1708
|
+
*/
|
|
1709
|
+
form: "definition" | "block" | "token";
|
|
1710
|
+
/** `${1:…}` tabstop form. */
|
|
1711
|
+
snippet: string;
|
|
1712
|
+
/** The same shape free of `${`, for hosts without snippet expansion. */
|
|
1713
|
+
plain: string;
|
|
1714
|
+
}
|
|
1715
|
+
export interface SnippetsResult {
|
|
1716
|
+
/** Skeletons first (definition, then its child blocks), then engine tokens. */
|
|
1717
|
+
snippets: SnippetItem[];
|
|
1718
|
+
}
|
|
1583
1719
|
/**
|
|
1584
1720
|
* Request: the inferred scope chain at a cursor position;
|
|
1585
1721
|
* {@link ScopeAtParams} -> {@link ScopeAtResult} | null. Answers for OPEN
|
|
@@ -1636,3 +1772,348 @@ export interface ScopeAtResult {
|
|
|
1636
1772
|
*/
|
|
1637
1773
|
savedScopes: SavedScopeInfo[];
|
|
1638
1774
|
}
|
|
1775
|
+
/**
|
|
1776
|
+
* Request: everything a visual creator needs to draw a form for one definition
|
|
1777
|
+
* kind; {@link DefinitionFormParams} -> {@link DefinitionForm} | null (null =
|
|
1778
|
+
* the active game's schema has no such kind, which is the honest answer for a
|
|
1779
|
+
* client asking about content this game does not have).
|
|
1780
|
+
*
|
|
1781
|
+
* Nothing in the answer is hand-written for the creator: the folder, the loc
|
|
1782
|
+
* key patterns and the icon folder come from the schema table, the keys from
|
|
1783
|
+
* the harvested `_*.info` structures, the option lists from the definition
|
|
1784
|
+
* index (the same resolver {@link eventValueOptionsRequest} answers with) and
|
|
1785
|
+
* `existing` from the same index walk {@link modOverviewRequest} does. A game
|
|
1786
|
+
* patch that adds a key or a value changes the form without a release.
|
|
1787
|
+
*/
|
|
1788
|
+
export declare const definitionFormRequest = "paradox/definitionForm";
|
|
1789
|
+
export interface DefinitionFormParams {
|
|
1790
|
+
/** Definition kind, as the schema table spells it ("trait"). */
|
|
1791
|
+
kind: string;
|
|
1792
|
+
/** Load this definition into `current` (edit rather than create). */
|
|
1793
|
+
name?: string;
|
|
1794
|
+
/** Restrict mod-side entries to one workspace mod (plus vanilla/parents). */
|
|
1795
|
+
modRoot?: string | null;
|
|
1796
|
+
}
|
|
1797
|
+
/** One key of a definition body, with what is known about the values it takes. */
|
|
1798
|
+
export interface DefinitionFormKey {
|
|
1799
|
+
key: string;
|
|
1800
|
+
/** The game's own one-line documentation, capped. Absent when it has none. */
|
|
1801
|
+
doc?: string;
|
|
1802
|
+
/** Coarse value hint from the schema: `loc`, `bool`, `block`, `enum:a|b|c`. */
|
|
1803
|
+
values?: string;
|
|
1804
|
+
/** Vanilla usage count from the harvest, the order the keys arrive in. */
|
|
1805
|
+
freq?: number;
|
|
1806
|
+
/**
|
|
1807
|
+
* Definition kinds this key's value names, when the profile says so. The
|
|
1808
|
+
* lists live in {@link DefinitionForm.options}, keyed by kind, so several
|
|
1809
|
+
* keys naming the same kind share one list.
|
|
1810
|
+
*/
|
|
1811
|
+
refKinds?: string[];
|
|
1812
|
+
/**
|
|
1813
|
+
* The values the indexed definitions of this kind actually write for this
|
|
1814
|
+
* key, most used first, for keys no definition index can answer (a culture's
|
|
1815
|
+
* `clothing_gfx` names an art set, not a definition). Measured from the game
|
|
1816
|
+
* and mod files the server has indexed, at request time, so a patch changes
|
|
1817
|
+
* the list without a release; absent when the key has no refKinds-free value
|
|
1818
|
+
* set of at most {@link DEFINITION_FORM_MAX_SAMPLED} entries, which is the
|
|
1819
|
+
* honest answer for a key whose value is different in every definition.
|
|
1820
|
+
*/
|
|
1821
|
+
sampled?: string[];
|
|
1822
|
+
/**
|
|
1823
|
+
* The literal the indexed definitions of this kind write most often for this
|
|
1824
|
+
* key: a real value, so a form can show it as the input's placeholder
|
|
1825
|
+
* instead of inventing one. Unlike {@link sampled} it counts numbers and
|
|
1826
|
+
* quoted text too (quotes stripped), and it survives the cap, so a key whose
|
|
1827
|
+
* value differs in every definition still has an example.
|
|
1828
|
+
*
|
|
1829
|
+
* A key whose value is a BLOCK gets the most written body instead, collapsed
|
|
1830
|
+
* onto one line and capped at {@link DEFINITION_FORM_MAX_EXAMPLE}
|
|
1831
|
+
* characters, so a script field has a placeholder too.
|
|
1832
|
+
*
|
|
1833
|
+
* A key whose value set is already stated (`bool`, `enum:`) carries an
|
|
1834
|
+
* example as well, though no {@link sampled}: a dropdown showing the value
|
|
1835
|
+
* the game itself writes says more than one reading "not set".
|
|
1836
|
+
*/
|
|
1837
|
+
example?: string;
|
|
1838
|
+
}
|
|
1839
|
+
export interface DefinitionForm {
|
|
1840
|
+
kind: string;
|
|
1841
|
+
/** Schema path the definition is written into, e.g. `common/traits`. */
|
|
1842
|
+
folder: string;
|
|
1843
|
+
/**
|
|
1844
|
+
* Every loc key the game reads for this kind, `$` being the definition name
|
|
1845
|
+
* (`trait_$_desc`). The full set a form should offer, not the conservative
|
|
1846
|
+
* `requiredLoc` subset a diagnostic is allowed to demand.
|
|
1847
|
+
*/
|
|
1848
|
+
locPatterns: string[];
|
|
1849
|
+
/** Where the game looks for this kind's icon, e.g. `gfx/interface/icons/traits`. */
|
|
1850
|
+
iconFolder?: string;
|
|
1851
|
+
/** Top-level keys, harvest order (most used first), curated keys ahead. */
|
|
1852
|
+
keys: DefinitionFormKey[];
|
|
1853
|
+
/** Named sub-blocks with their own keys, when the harvest has them. */
|
|
1854
|
+
blocks?: Record<string, DefinitionFormKey[]>;
|
|
1855
|
+
/** Ref kind -> every indexed definition of it, mod entries first, capped. */
|
|
1856
|
+
options: Record<string, EventVocabularyItem[]>;
|
|
1857
|
+
/**
|
|
1858
|
+
* Trigger name -> the values that trigger accepts, for the handful of
|
|
1859
|
+
* triggers a no-code condition builder offers rows for (`has_dlc_feature`,
|
|
1860
|
+
* `has_game_rule`, `scripted_trigger`). Which triggers those are, and where
|
|
1861
|
+
* each list comes from, is the game profile's own table; the values
|
|
1862
|
+
* themselves are read from what the server already holds (the trigger's own
|
|
1863
|
+
* script_docs entry, the definition index), never written for the creator.
|
|
1864
|
+
* A trigger with no resolvable list is ABSENT rather than empty, so a client
|
|
1865
|
+
* offers a free input instead of a picker with nothing in it.
|
|
1866
|
+
*/
|
|
1867
|
+
conditions?: Record<string, EventVocabularyItem[]>;
|
|
1868
|
+
/** The modifier vocabulary, most used first: what a modifier row may offer. */
|
|
1869
|
+
modifiers: {
|
|
1870
|
+
name: string;
|
|
1871
|
+
doc?: string;
|
|
1872
|
+
}[];
|
|
1873
|
+
/** Definitions of this kind the mod already has (modRoot or every workspace mod). */
|
|
1874
|
+
existing: OverviewDef[];
|
|
1875
|
+
/** The definition `params.name` asked for, when it is indexed. */
|
|
1876
|
+
current?: {
|
|
1877
|
+
file: string;
|
|
1878
|
+
/** 0-based. */
|
|
1879
|
+
line: number;
|
|
1880
|
+
source: DefSource;
|
|
1881
|
+
/** The block verbatim, `name = { ... }`, exactly as the file has it. */
|
|
1882
|
+
text: string;
|
|
1883
|
+
};
|
|
1884
|
+
}
|
|
1885
|
+
/**
|
|
1886
|
+
* Request: text edits that write a definition into a script file;
|
|
1887
|
+
* {@link DefinitionEditParams} -> {@link DefinitionEditResult}. The script
|
|
1888
|
+
* sibling of {@link guiSourceEditRequest}, over the same span model, and with
|
|
1889
|
+
* the same division of labour: the server never writes, it returns offsets
|
|
1890
|
+
* into the text it was handed and the host applies them as ONE
|
|
1891
|
+
* `WorkspaceEdit`, which keeps undo and dirty state in the editor.
|
|
1892
|
+
*
|
|
1893
|
+
* Offsets are UTF-16 into `params.text` (the document text, with no BOM, the
|
|
1894
|
+
* way an editor delivers it), computed against that one text and applied
|
|
1895
|
+
* end-first. Every edit is surgical, so a file's other definitions, its
|
|
1896
|
+
* comments, its CRLF and its indentation stay byte-identical.
|
|
1897
|
+
*/
|
|
1898
|
+
export declare const definitionEditRequest = "paradox/definitionEdit";
|
|
1899
|
+
export interface DefinitionEditParams {
|
|
1900
|
+
/** For display only; the text is authoritative. */
|
|
1901
|
+
uri: string;
|
|
1902
|
+
/** Authoritative document text every offset refers to. */
|
|
1903
|
+
text: string;
|
|
1904
|
+
/** Computed in order against the one text and answered as one edit set. */
|
|
1905
|
+
ops: DefinitionOp[];
|
|
1906
|
+
}
|
|
1907
|
+
export type DefinitionOp =
|
|
1908
|
+
/**
|
|
1909
|
+
* Set or (with a null value) remove keys on the top-level definition `name`.
|
|
1910
|
+
* `value` is raw script text: `2`, `{ craven }`, `"quoted"`.
|
|
1911
|
+
*/
|
|
1912
|
+
{
|
|
1913
|
+
op: "setProperties";
|
|
1914
|
+
name: string;
|
|
1915
|
+
properties: {
|
|
1916
|
+
key: string;
|
|
1917
|
+
value: string | null;
|
|
1918
|
+
}[];
|
|
1919
|
+
}
|
|
1920
|
+
/**
|
|
1921
|
+
* Write the whole `name = { ... }` block: replaces the top-level block of
|
|
1922
|
+
* that name, or appends it after a blank separator line when the file has
|
|
1923
|
+
* none.
|
|
1924
|
+
*/
|
|
1925
|
+
| {
|
|
1926
|
+
op: "upsertBlock";
|
|
1927
|
+
name: string;
|
|
1928
|
+
text: string;
|
|
1929
|
+
};
|
|
1930
|
+
export interface DefinitionEditResult {
|
|
1931
|
+
/** Every applied op's edits together. Apply the whole set as ONE change. */
|
|
1932
|
+
edits: GuiTextEdit[];
|
|
1933
|
+
/** One verdict per requested op, in request order; `refused` names why it wrote nothing. */
|
|
1934
|
+
ops: {
|
|
1935
|
+
refused?: string;
|
|
1936
|
+
}[];
|
|
1937
|
+
}
|
|
1938
|
+
/**
|
|
1939
|
+
* Request: how the GAME prints each modifier; {@link ModifierFormatsParams} ->
|
|
1940
|
+
* {@link ModifierFormatsResult} | null (null = the active profile names no
|
|
1941
|
+
* formats source, or the game folder is not configured).
|
|
1942
|
+
*
|
|
1943
|
+
* A creator that lets a modder add `monthly_income = 0.5` has to show what the
|
|
1944
|
+
* player will see, and the player sees "[gold_i] +0.50 Monthly Income" in
|
|
1945
|
+
* green. None of that is written here: the flags come from the game's own
|
|
1946
|
+
* `common/modifier_definition_formats/` (documented by `_definitions.info`
|
|
1947
|
+
* there), every word comes from the loc index, and every icon comes from the
|
|
1948
|
+
* `texticon` blocks of the game's `gui/texticons.gui`. A modifier no format
|
|
1949
|
+
* block names gets the file's documented defaults, so the answer covers every
|
|
1950
|
+
* modifier token the server knows rather than only the formatted ones.
|
|
1951
|
+
*/
|
|
1952
|
+
export declare const modifierFormatsRequest = "paradox/modifierFormats";
|
|
1953
|
+
export interface ModifierFormatsParams extends ModScopedParams {
|
|
1954
|
+
/**
|
|
1955
|
+
* Loc keys to render as parts too, through the same texticon chain the
|
|
1956
|
+
* prefixes take. A client that prints a line of the game's own UI (a cost
|
|
1957
|
+
* line such as `"[prestige_i] $VALUE|0$"`) asks for the key and gets its
|
|
1958
|
+
* icon and text back; a key the loc index cannot resolve is absent.
|
|
1959
|
+
*/
|
|
1960
|
+
lines?: string[];
|
|
1961
|
+
}
|
|
1962
|
+
/**
|
|
1963
|
+
* One piece of a prefix or suffix: a word, or a texticon. `[gold_i]` in a loc
|
|
1964
|
+
* value resolves through `game_concept_gold_i` = `"@gold_icon!"` to the
|
|
1965
|
+
* `texticon` block naming the sprite, which is what an icon part carries.
|
|
1966
|
+
*/
|
|
1967
|
+
export type FormatPart = {
|
|
1968
|
+
text: string;
|
|
1969
|
+
} | {
|
|
1970
|
+
icon: {
|
|
1971
|
+
texture: string;
|
|
1972
|
+
uv?: [number, number, number, number];
|
|
1973
|
+
};
|
|
1974
|
+
};
|
|
1975
|
+
/** How one modifier is printed, straight out of the game's own format files. */
|
|
1976
|
+
export interface ModifierFormat {
|
|
1977
|
+
/** The player's word for the modifier, loc-resolved; the key title-cased when it has none. */
|
|
1978
|
+
label: string;
|
|
1979
|
+
/** Digits after the point. The file's documented default is 2. */
|
|
1980
|
+
decimals: number;
|
|
1981
|
+
/** Scale the value by 100 and print a `%`. */
|
|
1982
|
+
percent?: boolean;
|
|
1983
|
+
/** Print a `%` without scaling: the value already is one. */
|
|
1984
|
+
alreadyPercent?: boolean;
|
|
1985
|
+
/** Which direction is good for the player. The file's documented default is `bad`. */
|
|
1986
|
+
color: "good" | "neutral" | "bad";
|
|
1987
|
+
/** `no_difference_sign`: print the number without a leading `+`/`-`. */
|
|
1988
|
+
noSign?: boolean;
|
|
1989
|
+
/** The game does not show this modifier at all. */
|
|
1990
|
+
hidden?: boolean;
|
|
1991
|
+
/** Drawn before the number (`[gold_i]`). */
|
|
1992
|
+
prefix?: FormatPart[];
|
|
1993
|
+
/** Drawn after the number (`/month`). */
|
|
1994
|
+
suffix?: FormatPart[];
|
|
1995
|
+
/** Used in place of `suffix` for negative values, when the game defines one. */
|
|
1996
|
+
negativeSuffix?: FormatPart[];
|
|
1997
|
+
}
|
|
1998
|
+
export interface ModifierFormatsResult {
|
|
1999
|
+
/** Modifier name -> its format. Every modifier token the server knows. */
|
|
2000
|
+
formats: Record<string, ModifierFormat>;
|
|
2001
|
+
/** Loc key -> its parts, for each `lines` entry the loc index resolved. */
|
|
2002
|
+
lines?: Record<string, FormatPart[]>;
|
|
2003
|
+
}
|
|
2004
|
+
/**
|
|
2005
|
+
* Request: a dynasty as a family tree; {@link DynastyTreeParams} ->
|
|
2006
|
+
* {@link DynastyTreeResult}.
|
|
2007
|
+
*
|
|
2008
|
+
* Two answers behind one method. Without `dynasty` the result is the picker
|
|
2009
|
+
* list: every dynasty the index knows, mod entries first. With `dynasty` it is
|
|
2010
|
+
* that dynasty's houses and members, read out of the game's own
|
|
2011
|
+
* `history/characters` files.
|
|
2012
|
+
*
|
|
2013
|
+
* Everything is DERIVED: the folders come from the active profile's schema
|
|
2014
|
+
* (`dynasty`, `dynasty_house`, `character` kinds), the members from the
|
|
2015
|
+
* character blocks themselves, the display names from the loc index. A profile
|
|
2016
|
+
* whose schema has no `dynasty` kind answers `supported: false` and empty
|
|
2017
|
+
* lists, which is what a client shows instead of an empty tree.
|
|
2018
|
+
*/
|
|
2019
|
+
export declare const dynastyTreeRequest = "paradox/dynastyTree";
|
|
2020
|
+
export interface DynastyTreeParams extends ModScopedParams {
|
|
2021
|
+
/** A dynasty id: answer that dynasty's houses and members instead of the list. */
|
|
2022
|
+
dynasty?: string;
|
|
2023
|
+
}
|
|
2024
|
+
/** One dynasty, as the picker lists it. */
|
|
2025
|
+
export interface DynastySummary {
|
|
2026
|
+
/** The block's own key, which is what a character's `dynasty = ` names. */
|
|
2027
|
+
id: string;
|
|
2028
|
+
/** The `name = ` value, a loc key (`dynn_Karling`). */
|
|
2029
|
+
nameKey: string;
|
|
2030
|
+
/** The loc text when the server can resolve it, else `nameKey` itself. */
|
|
2031
|
+
name: string;
|
|
2032
|
+
culture?: string;
|
|
2033
|
+
source: DefSource;
|
|
2034
|
+
file: string;
|
|
2035
|
+
/** 0-based. */
|
|
2036
|
+
line: number;
|
|
2037
|
+
/** Characters whose `dynasty`, or whose house's dynasty, is this one. */
|
|
2038
|
+
characterCount: number;
|
|
2039
|
+
houseCount: number;
|
|
2040
|
+
}
|
|
2041
|
+
/** One house of a dynasty (`house_karling = { name = … dynasty = 25061 }`). */
|
|
2042
|
+
export interface DynastyHouse {
|
|
2043
|
+
id: string;
|
|
2044
|
+
nameKey: string;
|
|
2045
|
+
name: string;
|
|
2046
|
+
/** The dynasty id the house belongs to. */
|
|
2047
|
+
dynasty: string;
|
|
2048
|
+
source: DefSource;
|
|
2049
|
+
file: string;
|
|
2050
|
+
/** 0-based. */
|
|
2051
|
+
line: number;
|
|
2052
|
+
}
|
|
2053
|
+
/**
|
|
2054
|
+
* The character-level skill keys, in the order a client shows them. MEASURED
|
|
2055
|
+
* over the vanilla `history/characters` corpus (2026-09-03): stewardship 8 964,
|
|
2056
|
+
* martial 8 940, diplomacy 8 908, intrigue 8 892, learning 495, prowess 150.
|
|
2057
|
+
*/
|
|
2058
|
+
export declare const DYNASTY_SKILLS: readonly ["diplomacy", "martial", "stewardship", "intrigue", "learning", "prowess"];
|
|
2059
|
+
/**
|
|
2060
|
+
* One character of `history/characters`. Dates are the game's own
|
|
2061
|
+
* `Y.M.D` strings, taken from the dated block that carries the `birth`/`death`
|
|
2062
|
+
* statement.
|
|
2063
|
+
*/
|
|
2064
|
+
export interface DynastyCharacter {
|
|
2065
|
+
/** The block's own key: numeric in vanilla, but `han_1234` shapes exist too. */
|
|
2066
|
+
id: string;
|
|
2067
|
+
/** The `name = ` value, a plain string in history, not a loc key. */
|
|
2068
|
+
name: string;
|
|
2069
|
+
female: boolean;
|
|
2070
|
+
dynasty?: string;
|
|
2071
|
+
/** `dynasty_house = `; a character carries the house OR the dynasty, not both. */
|
|
2072
|
+
house?: string;
|
|
2073
|
+
father?: string;
|
|
2074
|
+
mother?: string;
|
|
2075
|
+
culture?: string;
|
|
2076
|
+
religion?: string;
|
|
2077
|
+
/** `Y.M.D` of the dated block holding `birth`. */
|
|
2078
|
+
birth?: string;
|
|
2079
|
+
death?: string;
|
|
2080
|
+
/**
|
|
2081
|
+
* `dna = `, the portrait DNA name, without the quotes the file may put
|
|
2082
|
+
* around it (350 of 438 vanilla statements write it bare).
|
|
2083
|
+
*/
|
|
2084
|
+
dna?: string;
|
|
2085
|
+
/**
|
|
2086
|
+
* The skills the block sets, keyed by {@link DYNASTY_SKILLS}. A skill the
|
|
2087
|
+
* block does not name is absent, which is not the same as zero: the game
|
|
2088
|
+
* rolls one it was not given.
|
|
2089
|
+
*/
|
|
2090
|
+
skills?: Record<string, number>;
|
|
2091
|
+
traits: string[];
|
|
2092
|
+
/** Ids this character is married to (`add_spouse`), in file order. */
|
|
2093
|
+
spouses: string[];
|
|
2094
|
+
/**
|
|
2095
|
+
* Set when the character belongs to ANOTHER dynasty and is only in the
|
|
2096
|
+
* answer because a member names them as a parent or a spouse. A client draws
|
|
2097
|
+
* them, but the tree is not theirs.
|
|
2098
|
+
*/
|
|
2099
|
+
external?: true;
|
|
2100
|
+
source: DefSource;
|
|
2101
|
+
file: string;
|
|
2102
|
+
/** 0-based. */
|
|
2103
|
+
line: number;
|
|
2104
|
+
}
|
|
2105
|
+
export interface DynastyTreeResult {
|
|
2106
|
+
/** False when the active profile's schema has no `dynasty` kind. */
|
|
2107
|
+
supported: boolean;
|
|
2108
|
+
/** The picker list. Empty when `params.dynasty` asked for one dynasty. */
|
|
2109
|
+
dynasties: DynastySummary[];
|
|
2110
|
+
/** Present exactly when `params.dynasty` named a dynasty the index knows. */
|
|
2111
|
+
dynasty?: DynastySummary;
|
|
2112
|
+
houses?: DynastyHouse[];
|
|
2113
|
+
/** Members plus the external parents and spouses they name. */
|
|
2114
|
+
characters?: DynastyCharacter[];
|
|
2115
|
+
/** Largest numeric character id across game and mods, plus one. */
|
|
2116
|
+
nextCharacterId?: string;
|
|
2117
|
+
/** Largest numeric dynasty id across game and mods, plus one. */
|
|
2118
|
+
nextDynastyId?: string;
|
|
2119
|
+
}
|
package/dist/protocol.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.scopeAtRequest = exports.dependenciesRequest = exports.eventValueOptionsRequest = exports.EVENT_VOCABULARY_MAX_VALUES = exports.EVENT_VOCABULARY_MAX_TOKENS = exports.eventVocabularyRequest = exports.eventBannerRequest = exports.eventGraphRequest = exports.guiWidgetEditRequest = exports.guiSourceEditRequest = exports.guiSaveValuesRequest = exports.GUI_PREVIEW_MAX = exports.guiPreviewRequest = exports.guiVocabularyRequest = exports.guiDependenciesRequest = exports.guiWidgetInfoRequest = exports.guiLayoutRequest = exports.guiTreeRequest = exports.exampleWikiEntryRequest = exports.exampleWikiVocabularyKinds = exports.exampleWikiVariableKinds = exports.exampleWikiRequest = exports.eventDetailRequest = exports.overridesRequest = exports.locCoverageRequest = exports.modOverviewRequest = exports.progressNotification = exports.indexChangedNotification = exports.statusNotification = exports.lookupLocRequest = exports.indexStatsRequest = exports.reloadDocsRequest = exports.modFileChangedNotification = exports.configChangedNotification = exports.allClientCommandIds = exports.clientCommands = void 0;
|
|
3
|
+
exports.DYNASTY_SKILLS = exports.dynastyTreeRequest = exports.modifierFormatsRequest = exports.definitionEditRequest = exports.definitionFormRequest = exports.scopeAtRequest = exports.snippetsRequest = exports.dependenciesRequest = exports.eventValueOptionsRequest = exports.DEFINITION_FORM_MAX_EXAMPLE = exports.DEFINITION_FORM_MAX_SAMPLED = exports.EVENT_VOCABULARY_MAX_VALUES = exports.EVENT_VOCABULARY_MAX_TOKENS = exports.eventVocabularyRequest = exports.eventBannerRequest = exports.eventGraphRequest = exports.guiWidgetEditRequest = exports.guiSourceEditRequest = exports.guiSaveValuesRequest = exports.GUI_PREVIEW_MAX = exports.guiPreviewRequest = exports.guiVocabularyRequest = exports.guiDependenciesRequest = exports.guiWidgetInfoRequest = exports.guiLayoutRequest = exports.guiTreeRequest = exports.exampleWikiEntryRequest = exports.exampleWikiVocabularyKinds = exports.exampleWikiVariableKinds = exports.exampleWikiRequest = exports.eventDetailRequest = exports.overridesRequest = exports.locCoverageRequest = exports.modOverviewRequest = exports.progressNotification = exports.indexChangedNotification = exports.statusNotification = exports.locTextRequest = exports.lookupLocRequest = exports.indexStatsRequest = exports.reloadDocsRequest = exports.modFileChangedNotification = exports.configChangedNotification = exports.allClientCommandIds = exports.clientCommands = void 0;
|
|
4
4
|
// ---- client command ids ----------------------------------------------------
|
|
5
5
|
/**
|
|
6
6
|
* Client commands the server references in code actions and hover links (part
|
|
@@ -30,6 +30,24 @@ exports.indexStatsRequest = "paradox/indexStats";
|
|
|
30
30
|
/** Request: look up localization entries for a key; {@link LookupLocParams} -> {@link LocEntryInfo}[].
|
|
31
31
|
* Mod entries shadow vanilla ones (the full list is returned, mod first). */
|
|
32
32
|
exports.lookupLocRequest = "paradox/lookupLoc";
|
|
33
|
+
/**
|
|
34
|
+
* Request: a localization value as the PLAYER reads it;
|
|
35
|
+
* {@link LocTextParams} -> {@link LocTextResult}.
|
|
36
|
+
*
|
|
37
|
+
* {@link lookupLocRequest} answers the value verbatim, which is what an editor
|
|
38
|
+
* needs. A panel that SHOWS the value needs the sentence: the games write a
|
|
39
|
+
* culture parameter as `"The [GetTrait('rough_terrain_expert').GetName(
|
|
40
|
+
* GetNullCharacter )] Commander Trait is more common"` (145 of the 280
|
|
41
|
+
* parameter values with a real call take that one shape), and a modder reading
|
|
42
|
+
* a form must not be shown the brackets.
|
|
43
|
+
*
|
|
44
|
+
* Everything the renderer knows is DERIVED: the words come from the loc index
|
|
45
|
+
* (mod entries shadow the game's), the kind a `Get<Something>('name')` chain
|
|
46
|
+
* names comes from the definition index, and the loc key that kind's names take
|
|
47
|
+
* comes from the active profile's schema. No table of function names, so a
|
|
48
|
+
* workspace of any of the games gets the same behavior from its own schema.
|
|
49
|
+
*/
|
|
50
|
+
exports.locTextRequest = "paradox/locText";
|
|
33
51
|
// ---- server -> client ------------------------------------------------------
|
|
34
52
|
/** Notification: data health for the status bar; payload {@link StatusPayload}. */
|
|
35
53
|
exports.statusNotification = "paradox/status";
|
|
@@ -204,6 +222,20 @@ exports.eventVocabularyRequest = "paradox/eventVocabulary";
|
|
|
204
222
|
/** Caps: an editor lists a page at a time, and these ride on every open. */
|
|
205
223
|
exports.EVENT_VOCABULARY_MAX_TOKENS = 600;
|
|
206
224
|
exports.EVENT_VOCABULARY_MAX_VALUES = 400;
|
|
225
|
+
/**
|
|
226
|
+
* Most values {@link DefinitionFormKey.sampled} carries, and the point past
|
|
227
|
+
* which a key is taken to have no value SET at all (a key whose value differs
|
|
228
|
+
* per definition is a free field, not a list to offer).
|
|
229
|
+
*/
|
|
230
|
+
exports.DEFINITION_FORM_MAX_SAMPLED = 80;
|
|
231
|
+
/**
|
|
232
|
+
* How long a block body {@link DefinitionFormKey.example} may be. A placeholder
|
|
233
|
+
* is read at a glance, and the shortest bodies a game writes for a block key
|
|
234
|
+
* (a trait's `triggered_opinion`, a culture's `parameters`) fit well inside
|
|
235
|
+
* this; a longer one is cut with an ellipsis rather than dropped, because half
|
|
236
|
+
* a real body still says what the key wants.
|
|
237
|
+
*/
|
|
238
|
+
exports.DEFINITION_FORM_MAX_EXAMPLE = 120;
|
|
207
239
|
/**
|
|
208
240
|
* Request: the value set a VALUE belongs to, resolved through the definition
|
|
209
241
|
* index; {@link EventValueOptionsParams} -> {@link EventValueOptionsResult} |
|
|
@@ -222,6 +254,23 @@ exports.eventValueOptionsRequest = "paradox/eventValueOptions";
|
|
|
222
254
|
* (uri + position) or by name (optionally disambiguated by kind).
|
|
223
255
|
*/
|
|
224
256
|
exports.dependenciesRequest = "paradox/dependencies";
|
|
257
|
+
/**
|
|
258
|
+
* Request: the code snippets a host can offer for one open script document;
|
|
259
|
+
* {@link SnippetsParams} -> {@link SnippetsResult}. Answers for OPEN script
|
|
260
|
+
* documents only (the server reads the client's text, not the disk); a document
|
|
261
|
+
* it does not know answers with an EMPTY list, never an error.
|
|
262
|
+
*
|
|
263
|
+
* Two sources, neither hand-written. The definition and child-block skeletons
|
|
264
|
+
* are the measured shape of the document folder's own definition kind (at least
|
|
265
|
+
* half of the game's definitions of that kind carry each key, in the median
|
|
266
|
+
* order they hold there). The token entries are the block form of the `usage:`
|
|
267
|
+
* example the game's own script_docs dump ships for an engine trigger or effect,
|
|
268
|
+
* filtered to the block the cursor sits in.
|
|
269
|
+
*
|
|
270
|
+
* Every entry carries BOTH insert forms, exactly like completion does: `snippet`
|
|
271
|
+
* for a host that expands `${1:…}` tabstops, `plain` for one that does not.
|
|
272
|
+
*/
|
|
273
|
+
exports.snippetsRequest = "paradox/snippets";
|
|
225
274
|
/**
|
|
226
275
|
* Request: the inferred scope chain at a cursor position;
|
|
227
276
|
* {@link ScopeAtParams} -> {@link ScopeAtResult} | null. Answers for OPEN
|
|
@@ -234,3 +283,76 @@ exports.dependenciesRequest = "paradox/dependencies";
|
|
|
234
283
|
* asserts more than the derived link tables actually say.
|
|
235
284
|
*/
|
|
236
285
|
exports.scopeAtRequest = "paradox/scopeAt";
|
|
286
|
+
// ---- content creators --------------------------------------------------------
|
|
287
|
+
/**
|
|
288
|
+
* Request: everything a visual creator needs to draw a form for one definition
|
|
289
|
+
* kind; {@link DefinitionFormParams} -> {@link DefinitionForm} | null (null =
|
|
290
|
+
* the active game's schema has no such kind, which is the honest answer for a
|
|
291
|
+
* client asking about content this game does not have).
|
|
292
|
+
*
|
|
293
|
+
* Nothing in the answer is hand-written for the creator: the folder, the loc
|
|
294
|
+
* key patterns and the icon folder come from the schema table, the keys from
|
|
295
|
+
* the harvested `_*.info` structures, the option lists from the definition
|
|
296
|
+
* index (the same resolver {@link eventValueOptionsRequest} answers with) and
|
|
297
|
+
* `existing` from the same index walk {@link modOverviewRequest} does. A game
|
|
298
|
+
* patch that adds a key or a value changes the form without a release.
|
|
299
|
+
*/
|
|
300
|
+
exports.definitionFormRequest = "paradox/definitionForm";
|
|
301
|
+
/**
|
|
302
|
+
* Request: text edits that write a definition into a script file;
|
|
303
|
+
* {@link DefinitionEditParams} -> {@link DefinitionEditResult}. The script
|
|
304
|
+
* sibling of {@link guiSourceEditRequest}, over the same span model, and with
|
|
305
|
+
* the same division of labour: the server never writes, it returns offsets
|
|
306
|
+
* into the text it was handed and the host applies them as ONE
|
|
307
|
+
* `WorkspaceEdit`, which keeps undo and dirty state in the editor.
|
|
308
|
+
*
|
|
309
|
+
* Offsets are UTF-16 into `params.text` (the document text, with no BOM, the
|
|
310
|
+
* way an editor delivers it), computed against that one text and applied
|
|
311
|
+
* end-first. Every edit is surgical, so a file's other definitions, its
|
|
312
|
+
* comments, its CRLF and its indentation stay byte-identical.
|
|
313
|
+
*/
|
|
314
|
+
exports.definitionEditRequest = "paradox/definitionEdit";
|
|
315
|
+
/**
|
|
316
|
+
* Request: how the GAME prints each modifier; {@link ModifierFormatsParams} ->
|
|
317
|
+
* {@link ModifierFormatsResult} | null (null = the active profile names no
|
|
318
|
+
* formats source, or the game folder is not configured).
|
|
319
|
+
*
|
|
320
|
+
* A creator that lets a modder add `monthly_income = 0.5` has to show what the
|
|
321
|
+
* player will see, and the player sees "[gold_i] +0.50 Monthly Income" in
|
|
322
|
+
* green. None of that is written here: the flags come from the game's own
|
|
323
|
+
* `common/modifier_definition_formats/` (documented by `_definitions.info`
|
|
324
|
+
* there), every word comes from the loc index, and every icon comes from the
|
|
325
|
+
* `texticon` blocks of the game's `gui/texticons.gui`. A modifier no format
|
|
326
|
+
* block names gets the file's documented defaults, so the answer covers every
|
|
327
|
+
* modifier token the server knows rather than only the formatted ones.
|
|
328
|
+
*/
|
|
329
|
+
exports.modifierFormatsRequest = "paradox/modifierFormats";
|
|
330
|
+
/**
|
|
331
|
+
* Request: a dynasty as a family tree; {@link DynastyTreeParams} ->
|
|
332
|
+
* {@link DynastyTreeResult}.
|
|
333
|
+
*
|
|
334
|
+
* Two answers behind one method. Without `dynasty` the result is the picker
|
|
335
|
+
* list: every dynasty the index knows, mod entries first. With `dynasty` it is
|
|
336
|
+
* that dynasty's houses and members, read out of the game's own
|
|
337
|
+
* `history/characters` files.
|
|
338
|
+
*
|
|
339
|
+
* Everything is DERIVED: the folders come from the active profile's schema
|
|
340
|
+
* (`dynasty`, `dynasty_house`, `character` kinds), the members from the
|
|
341
|
+
* character blocks themselves, the display names from the loc index. A profile
|
|
342
|
+
* whose schema has no `dynasty` kind answers `supported: false` and empty
|
|
343
|
+
* lists, which is what a client shows instead of an empty tree.
|
|
344
|
+
*/
|
|
345
|
+
exports.dynastyTreeRequest = "paradox/dynastyTree";
|
|
346
|
+
/**
|
|
347
|
+
* The character-level skill keys, in the order a client shows them. MEASURED
|
|
348
|
+
* over the vanilla `history/characters` corpus (2026-09-03): stewardship 8 964,
|
|
349
|
+
* martial 8 940, diplomacy 8 908, intrigue 8 892, learning 495, prowess 150.
|
|
350
|
+
*/
|
|
351
|
+
exports.DYNASTY_SKILLS = [
|
|
352
|
+
"diplomacy",
|
|
353
|
+
"martial",
|
|
354
|
+
"stewardship",
|
|
355
|
+
"intrigue",
|
|
356
|
+
"learning",
|
|
357
|
+
"prowess",
|
|
358
|
+
];
|