@datamoc/mw_games 0.6.0 → 0.7.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.
Files changed (56) hide show
  1. package/README.md +66 -1
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/mw_games.global.js +22 -19
  7. package/dist/mwl/actors.d.ts +16 -0
  8. package/dist/mwl/actors.d.ts.map +1 -0
  9. package/dist/mwl/actors.js +33 -0
  10. package/dist/mwl/actors.js.map +1 -0
  11. package/dist/mwl/catalog.d.ts +13 -0
  12. package/dist/mwl/catalog.d.ts.map +1 -0
  13. package/dist/mwl/catalog.js +67 -0
  14. package/dist/mwl/catalog.js.map +1 -0
  15. package/dist/mwl/compiler.d.ts +51 -0
  16. package/dist/mwl/compiler.d.ts.map +1 -0
  17. package/dist/mwl/compiler.js +119 -0
  18. package/dist/mwl/compiler.js.map +1 -0
  19. package/dist/mwl/content.d.ts +90 -0
  20. package/dist/mwl/content.d.ts.map +1 -0
  21. package/dist/mwl/content.js +146 -0
  22. package/dist/mwl/content.js.map +1 -0
  23. package/dist/mwl/expression.d.ts +21 -0
  24. package/dist/mwl/expression.d.ts.map +1 -0
  25. package/dist/mwl/expression.js +110 -0
  26. package/dist/mwl/expression.js.map +1 -0
  27. package/dist/mwl/grammar.d.ts +39 -0
  28. package/dist/mwl/grammar.d.ts.map +1 -0
  29. package/dist/mwl/grammar.js +204 -0
  30. package/dist/mwl/grammar.js.map +1 -0
  31. package/dist/mwl/hooks.d.ts +81 -0
  32. package/dist/mwl/hooks.d.ts.map +1 -0
  33. package/dist/mwl/hooks.js +78 -0
  34. package/dist/mwl/hooks.js.map +1 -0
  35. package/dist/mwl/index.d.ts +21 -0
  36. package/dist/mwl/index.d.ts.map +1 -0
  37. package/dist/mwl/index.js +11 -0
  38. package/dist/mwl/index.js.map +1 -0
  39. package/dist/mwl/persistence.d.ts +15 -0
  40. package/dist/mwl/persistence.d.ts.map +1 -0
  41. package/dist/mwl/persistence.js +41 -0
  42. package/dist/mwl/persistence.js.map +1 -0
  43. package/dist/mwl/runtime.d.ts +196 -0
  44. package/dist/mwl/runtime.d.ts.map +1 -0
  45. package/dist/mwl/runtime.js +587 -0
  46. package/dist/mwl/runtime.js.map +1 -0
  47. package/dist/mwl/schema.d.ts +20 -0
  48. package/dist/mwl/schema.d.ts.map +1 -0
  49. package/dist/mwl/schema.js +379 -0
  50. package/dist/mwl/schema.js.map +1 -0
  51. package/dist/version.d.ts +1 -1
  52. package/dist/version.js +1 -1
  53. package/package.json +15 -4
  54. package/tools/extract-html.d.mts +18 -0
  55. package/tools/extract-html.mjs +235 -0
  56. package/tools/mwl.mjs +197 -0
@@ -0,0 +1,16 @@
1
+ import type { EquipmentSlots } from '../actors/Equipment.ts';
2
+ import type { InventoryItem, ItemDefinition } from '../actors/Inventory.ts';
3
+ import type { Modifier } from '../actors/StatBlock.ts';
4
+ import type { MwlEffectDefinition, MwlItemDefinition } from './content.ts';
5
+ import { type MwlExpressionContext } from './expression.ts';
6
+ export interface MwlActorItem extends ItemDefinition {
7
+ readonly id: string;
8
+ readonly slot?: string;
9
+ readonly modifiers?: Modifier[];
10
+ }
11
+ /** Converts MWL's data shape into the actor layer without importing game rules. */
12
+ export declare function itemDefinition(item: MwlItemDefinition, context?: MwlExpressionContext): MwlActorItem;
13
+ export declare function inventoryItem(item: MwlActorItem, quantity?: number): InventoryItem;
14
+ export declare function effectToModifier(effect: MwlEffectDefinition, context?: MwlExpressionContext): Modifier;
15
+ export type MwlEquipment<Slot extends string> = EquipmentSlots<Slot, MwlActorItem>;
16
+ //# sourceMappingURL=actors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actors.d.ts","sourceRoot":"","sources":["../../src/mwl/actors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAsB,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEhF,MAAM,WAAW,YAAa,SAAQ,cAAc;IACnD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CAChC;AAED,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,GAAE,oBAAyB,GAAG,YAAY,CAQxG;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,SAAI,GAAG,aAAa,CAE7E;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,EAAE,OAAO,GAAE,oBAAyB,GAAG,QAAQ,CAkB1G;AAED,MAAM,MAAM,YAAY,CAAC,IAAI,SAAS,MAAM,IAAI,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { evaluateExpression } from './expression.js';
2
+ /** Converts MWL's data shape into the actor layer without importing game rules. */
3
+ export function itemDefinition(item, context = {}) {
4
+ return {
5
+ id: item.id,
6
+ stackable: item.stackable,
7
+ weight: item.weight,
8
+ slot: item.slot,
9
+ modifiers: item.effects.map((effect) => effectToModifier(effect, context)),
10
+ };
11
+ }
12
+ export function inventoryItem(item, quantity = 1) {
13
+ return { id: item.id, quantity, stackable: item.stackable, weight: item.weight };
14
+ }
15
+ export function effectToModifier(effect, context = {}) {
16
+ const operation = effect.operation;
17
+ if (operation !== 'add' &&
18
+ operation !== 'sub' &&
19
+ operation !== 'multiply' &&
20
+ operation !== 'divide' &&
21
+ operation !== 'set')
22
+ throw new Error(`MWL effect operation "${operation ?? ''}" is not a StatBlock modifier`);
23
+ const raw = effect.value;
24
+ if (raw === undefined)
25
+ throw new Error('MWL effect has no value');
26
+ const value = evaluateExpression(raw, context);
27
+ return {
28
+ stat: effect.applyTo,
29
+ op: operation === 'sub' ? 'add' : operation === 'divide' ? 'multiply' : operation,
30
+ value: operation === 'sub' ? -value : operation === 'divide' ? 1 / value : value,
31
+ };
32
+ }
33
+ //# sourceMappingURL=actors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actors.js","sourceRoot":"","sources":["../../src/mwl/actors.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAA6B,MAAM,iBAAiB,CAAC;AAQhF,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAAC,IAAuB,EAAE,OAAO,GAAyB,EAAE;IACzF,OAAO;QACN,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC1E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAkB,EAAE,QAAQ,GAAG,CAAC;IAC7D,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAA2B,EAAE,OAAO,GAAyB,EAAE;IAC/F,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACnC,IACC,SAAS,KAAK,KAAK;QACnB,SAAS,KAAK,KAAK;QACnB,SAAS,KAAK,UAAU;QACxB,SAAS,KAAK,QAAQ;QACtB,SAAS,KAAK,KAAK;QAEnB,MAAM,IAAI,KAAK,CAAC,yBAAyB,SAAS,IAAI,EAAE,+BAA+B,CAAC,CAAC;IAC1F,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;IACzB,IAAI,GAAG,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/C,OAAO;QACN,IAAI,EAAE,MAAM,CAAC,OAAO;QACpB,EAAE,EAAE,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QACjF,KAAK,EAAE,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK;KAChF,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { MwlCompiledGame } from './compiler.ts';
2
+ import type { MwlDiagnostic, MwlNode } from './grammar.ts';
3
+ export interface MwlValidationOptions {
4
+ /** Slots are game-defined. Supplying them enables unknown-slot diagnostics. */
5
+ readonly slots?: readonly string[];
6
+ /** Hook ids exported by the game's adapter. */
7
+ readonly hooks?: readonly string[];
8
+ }
9
+ /** Semantic checks shared by all games. Domain rules remain in the game adapter. */
10
+ export declare function validateCatalog(game: MwlCompiledGame, options?: MwlValidationOptions): MwlDiagnostic[];
11
+ /** Convenience for adapters that keep parsed nodes rather than compiled games. */
12
+ export declare function validateCatalogNodes(nodes: readonly MwlNode[], options?: MwlValidationOptions): MwlDiagnostic[];
13
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/mwl/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,eAAe,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAe,OAAO,EAAE,MAAM,cAAc,CAAC;AAGxE,MAAM,WAAW,oBAAoB;IACpC,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,GAAE,oBAAyB,GAAG,aAAa,EAAE,CAmE1G;AAeD,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,OAAO,GAAE,oBAAyB,GAAG,aAAa,EAAE,CAGnH"}
@@ -0,0 +1,67 @@
1
+ import { collectHookReferences, parseHookReference } from './hooks.js';
2
+ /** Semantic checks shared by all games. Domain rules remain in the game adapter. */
3
+ export function validateCatalog(game, options = {}) {
4
+ const diagnostics = [];
5
+ const ids = new Map();
6
+ const nodes = flatten(game.roots);
7
+ for (const node of nodes) {
8
+ const id = node.attributes.id;
9
+ if (id) {
10
+ const key = `${node.tag}:${id}`;
11
+ const previous = ids.get(key);
12
+ if (previous)
13
+ diagnostics.push(diagnostic('MWL_DUPLICATE_ID', `duplicate ${node.tag} id "${id}"`, node.location ?? previous.location));
14
+ else
15
+ ids.set(key, node);
16
+ }
17
+ if (node.tag === 'item' &&
18
+ options.slots &&
19
+ node.attributes.slot &&
20
+ !options.slots.includes(node.attributes.slot))
21
+ diagnostics.push(diagnostic('MWL_UNKNOWN_SLOT', `unknown equipment slot "${node.attributes.slot}"`, node.location));
22
+ if (node.tag === 'effect') {
23
+ const operations = [
24
+ 'add',
25
+ 'sub',
26
+ 'multiply',
27
+ 'divide',
28
+ 'set',
29
+ 'increase',
30
+ 'increase_total',
31
+ 'increase_damage',
32
+ ].filter((key) => node.attributes[key] !== undefined);
33
+ if (!node.attributes.apply_to || operations.length !== 1)
34
+ diagnostics.push(diagnostic('MWL_INCOMPLETE_EFFECT', 'an effect needs apply_to and exactly one operation', node.location));
35
+ }
36
+ }
37
+ const references = collectHookReferences(game);
38
+ const knownHooks = new Set(options.hooks ?? []);
39
+ for (const node of nodes) {
40
+ const raw = node.attributes.hook ?? (node.tag === 'hook' ? node.attributes.name : undefined);
41
+ if (raw !== undefined && !parseHookReference(raw))
42
+ diagnostics.push(diagnostic('MWL_INVALID_HOOK', `invalid hook reference "${raw}"`, node.location));
43
+ }
44
+ if (options.hooks)
45
+ for (const reference of references)
46
+ if (!knownHooks.has(`${reference.type}:${reference.name}`))
47
+ diagnostics.push(diagnostic('MWL_UNKNOWN_HOOK', `hook ${reference.type}:${reference.name} is not declared by the game`, reference.location));
48
+ return diagnostics;
49
+ }
50
+ function flatten(roots) {
51
+ const result = [];
52
+ const visit = (node) => {
53
+ result.push(node);
54
+ node.children.forEach(visit);
55
+ };
56
+ roots.forEach(visit);
57
+ return result;
58
+ }
59
+ function diagnostic(code, message, location) {
60
+ return { code, message, location: location ?? { file: '<mwl>', line: 1, column: 1 } };
61
+ }
62
+ /** Convenience for adapters that keep parsed nodes rather than compiled games. */
63
+ export function validateCatalogNodes(nodes, options = {}) {
64
+ const fake = { schema: '0.1', roots: nodes, assets: [], messages: [] };
65
+ return validateCatalog(fake, options);
66
+ }
67
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/mwl/catalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { type MwlLocation, type MwlNode, type MwlPreprocessOptions } from './grammar.ts';
2
+ import { type MwlTagSchema } from './schema.ts';
3
+ export interface MwlCompiledNode {
4
+ readonly tag: string;
5
+ readonly attributes: Readonly<Record<string, string>>;
6
+ readonly children: readonly MwlCompiledNode[];
7
+ /** source location, kept so the runtime and tools can report where a node came from */
8
+ readonly location?: MwlLocation;
9
+ /** attribute names that carried the gettext marker, when the node came from text */
10
+ readonly gettext?: readonly string[];
11
+ }
12
+ export interface MwlCompiledGame {
13
+ readonly schema: string;
14
+ readonly roots: readonly MwlCompiledNode[];
15
+ readonly assets: readonly string[];
16
+ readonly messages: readonly string[];
17
+ }
18
+ export interface MwlCompileOptions extends MwlPreprocessOptions {
19
+ readonly schemas?: Readonly<Record<string, MwlTagSchema>>;
20
+ }
21
+ export declare function compile(source: string, options?: MwlCompileOptions): MwlCompiledGame;
22
+ export interface MwlSourceFile {
23
+ readonly file: string;
24
+ readonly source: string;
25
+ }
26
+ /** Compiles a deterministic set of content files as one catalog. */
27
+ export declare function compileSources(files: readonly MwlSourceFile[], options?: MwlCompileOptions): MwlCompiledGame;
28
+ /**
29
+ * Compile an already-parsed MWL node tree. A game that builds its nodes from
30
+ * another format (the Wesnoth port converts its own parsed nodes this way) can
31
+ * validate and compile through the same schema without going back to text.
32
+ */
33
+ export declare function compileNodes(nodes: readonly MwlNode[], options?: MwlCompileOptions): MwlCompiledGame;
34
+ export interface MwlCatalogOptions {
35
+ /** BCP-47 tag for the extracted catalog; the message ids are the source text */
36
+ readonly locale?: string;
37
+ readonly direction?: 'ltr' | 'rtl';
38
+ }
39
+ export interface MwlCatalog {
40
+ readonly locale: string;
41
+ readonly direction: 'ltr' | 'rtl';
42
+ readonly messages: Record<string, string>;
43
+ }
44
+ /**
45
+ * Extract a translation catalog compatible with `mwg/i18n` from a compiled
46
+ * game. MWL keeps the source text as the message id, so the base-language
47
+ * catalog maps each id to itself and translators fill in the other locales.
48
+ */
49
+ export declare function extractCatalog(game: MwlCompiledGame, options?: MwlCatalogOptions): MwlCatalog;
50
+ export declare function emitModule(game: MwlCompiledGame, variable?: string): string;
51
+ //# sourceMappingURL=compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/mwl/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,WAAW,EAAE,KAAK,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC5G,OAAO,EAAY,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,uFAAuF;IACvF,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC;IAChC,oFAAoF;IACpF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,iBAAkB,SAAQ,oBAAoB;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;CAC1D;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,eAAe,CAGxF;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,EAAE,OAAO,GAAE,iBAAsB,GAAG,eAAe,CAOhH;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,OAAO,GAAE,iBAAsB,GAAG,eAAe,CAuCxG;AAiDD,MAAM,WAAW,iBAAiB;IACjC,gFAAgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,KAAK,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,GAAE,iBAAsB,GAAG,UAAU,CAIjG;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,SAAa,GAAG,MAAM,CAE/E"}
@@ -0,0 +1,119 @@
1
+ import { parse, preprocess } from './grammar.js';
2
+ import { validate } from './schema.js';
3
+ export function compile(source, options = {}) {
4
+ const expanded = preprocess(source, options);
5
+ return compileNodes(parse(expanded, options.file), options);
6
+ }
7
+ /** Compiles a deterministic set of content files as one catalog. */
8
+ export function compileSources(files, options = {}) {
9
+ const nodes = [];
10
+ for (const file of [...files].sort((a, b) => (a.file < b.file ? -1 : a.file > b.file ? 1 : 0))) {
11
+ const expanded = preprocess(file.source, { ...options, file: file.file });
12
+ nodes.push(...parse(expanded, file.file));
13
+ }
14
+ return compileNodes(nodes, options);
15
+ }
16
+ /**
17
+ * Compile an already-parsed MWL node tree. A game that builds its nodes from
18
+ * another format (the Wesnoth port converts its own parsed nodes this way) can
19
+ * validate and compile through the same schema without going back to text.
20
+ */
21
+ export function compileNodes(nodes, options = {}) {
22
+ const diagnostics = validate(nodes, options.schemas);
23
+ if (diagnostics.length) {
24
+ const first = diagnostics[0];
25
+ throw new Error(`${first.location.file}:${first.location.line}:${first.location.column}: ${first.message}`);
26
+ }
27
+ const assets = new Set();
28
+ const messages = new Set();
29
+ const convert = (node) => {
30
+ for (const [key, value] of Object.entries(node.attributes)) {
31
+ if (isAssetAttribute(key)) {
32
+ for (const asset of splitAssetReferences(value)
33
+ .map((part) => part.trim())
34
+ .filter(isAssetReference))
35
+ assets.add(stripAssetTransform(asset));
36
+ }
37
+ }
38
+ // Text-parsed nodes carry the exact set of gettext-marked attributes, so
39
+ // extraction is precise. Programmatically built nodes have no marker
40
+ // information, so fall back to the conventional display attributes.
41
+ const messageKeys = node.gettext ?? ['name', 'text', 'title'];
42
+ for (const key of messageKeys) {
43
+ const value = node.attributes[key];
44
+ if (value !== undefined)
45
+ messages.add(value);
46
+ }
47
+ const compiled = {
48
+ tag: node.tag,
49
+ attributes: { ...node.attributes },
50
+ children: node.children.map(convert),
51
+ location: node.location,
52
+ };
53
+ return node.gettext ? { ...compiled, gettext: [...node.gettext] } : compiled;
54
+ };
55
+ return {
56
+ schema: nodes.find((node) => node.tag === 'game')?.attributes.schema ?? '0.1',
57
+ roots: nodes.map(convert),
58
+ assets: [...assets].sort(),
59
+ messages: [...messages].sort(),
60
+ };
61
+ }
62
+ /** Common WML asset attributes, including the sound/image aliases used by CFG macros. */
63
+ function isAssetAttribute(name) {
64
+ return (name === 'file' ||
65
+ name === 'image' ||
66
+ name === 'image_icon' ||
67
+ name === 'icon' ||
68
+ name === 'profile' ||
69
+ name === 'sound' ||
70
+ name.endsWith('_sound') ||
71
+ name.endsWith('_image'));
72
+ }
73
+ function isAssetReference(value) {
74
+ return (value.includes('/') ||
75
+ /\.(?:png|jpg|jpeg|gif|svg|webp|wav|ogg|mp3|flac|glb|gltf|vox|map|cfg)$/i.test(value) ||
76
+ value.startsWith('data:'));
77
+ }
78
+ function splitAssetReferences(value) {
79
+ const parts = [];
80
+ let start = 0;
81
+ let parenDepth = 0;
82
+ let bracketDepth = 0;
83
+ for (let index = 0; index < value.length; index += 1) {
84
+ if (value[index] === '(')
85
+ parenDepth += 1;
86
+ else if (value[index] === ')' && parenDepth > 0)
87
+ parenDepth -= 1;
88
+ else if (value[index] === '[')
89
+ bracketDepth += 1;
90
+ else if (value[index] === ']' && bracketDepth > 0)
91
+ bracketDepth -= 1;
92
+ else if (value[index] === ',' && parenDepth === 0 && bracketDepth === 0) {
93
+ parts.push(value.slice(start, index));
94
+ start = index + 1;
95
+ }
96
+ }
97
+ parts.push(value.slice(start));
98
+ return parts;
99
+ }
100
+ /** Remove a renderer transform, but keep Wesnoth sound ranges such as [1~4]. */
101
+ function stripAssetTransform(value) {
102
+ const match = value.match(/~[A-Za-z][A-Za-z0-9_-]*(?:\(|$)/);
103
+ return match ? value.slice(0, match.index).trim() : value;
104
+ }
105
+ /**
106
+ * Extract a translation catalog compatible with `mwg/i18n` from a compiled
107
+ * game. MWL keeps the source text as the message id, so the base-language
108
+ * catalog maps each id to itself and translators fill in the other locales.
109
+ */
110
+ export function extractCatalog(game, options = {}) {
111
+ const messages = {};
112
+ for (const id of game.messages)
113
+ messages[id] = id;
114
+ return { locale: options.locale ?? 'en', direction: options.direction ?? 'ltr', messages };
115
+ }
116
+ export function emitModule(game, variable = 'gameData') {
117
+ return `export const ${variable} = ${JSON.stringify(game, null, '\t')} as const;\n`;
118
+ }
119
+ //# sourceMappingURL=compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../src/mwl/compiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import type { MwlCompiledGame } from './compiler.ts';
2
+ export interface MwlEffectDefinition {
3
+ readonly applyTo: string;
4
+ readonly operation?: string;
5
+ readonly value?: string;
6
+ readonly range?: string;
7
+ }
8
+ export interface MwlItemDefinition {
9
+ readonly id: string;
10
+ readonly name: string;
11
+ readonly slot?: string;
12
+ readonly stackable?: boolean;
13
+ readonly weight?: number;
14
+ readonly effects: readonly MwlEffectDefinition[];
15
+ }
16
+ export interface MwlMonsterDefinition {
17
+ readonly id: string;
18
+ readonly name?: string;
19
+ readonly hp: number;
20
+ readonly accuracy?: number;
21
+ readonly evasion?: number;
22
+ readonly damage?: readonly [number, number];
23
+ readonly armor?: readonly [number, number];
24
+ readonly experience?: number;
25
+ readonly maxLevel?: number;
26
+ readonly image?: string;
27
+ readonly types?: readonly string[];
28
+ readonly baseStats?: Readonly<Record<string, number>>;
29
+ }
30
+ export interface MwlMoveDefinition {
31
+ readonly id: string;
32
+ readonly type: string;
33
+ readonly target: string;
34
+ readonly power?: number;
35
+ readonly cost?: number;
36
+ }
37
+ export interface MwlTypeMatchupDefinition {
38
+ readonly attacker: string;
39
+ readonly defender: string;
40
+ readonly multiplier: number;
41
+ }
42
+ export interface MwlEvolutionDefinition {
43
+ readonly from: string;
44
+ readonly into: string;
45
+ readonly level: number;
46
+ }
47
+ export interface MwlStatusDefinition {
48
+ readonly id: string;
49
+ readonly name?: string;
50
+ readonly duration?: number;
51
+ readonly tick?: string;
52
+ readonly modifiers?: string;
53
+ }
54
+ export interface MwlLootDefinition {
55
+ readonly item: string;
56
+ readonly chance?: number;
57
+ readonly quantity?: number;
58
+ readonly weight?: number;
59
+ }
60
+ export interface MwlTurnClockDefinition {
61
+ readonly id: string;
62
+ readonly tick?: number;
63
+ readonly hunger?: number;
64
+ }
65
+ export interface MwlBehaviorDefinition {
66
+ readonly id: string;
67
+ readonly when?: string;
68
+ readonly action?: string;
69
+ readonly hook?: string;
70
+ }
71
+ export interface MwlAiDefinition {
72
+ readonly id: string;
73
+ readonly strategy?: string;
74
+ readonly target?: string;
75
+ readonly difficulty?: number;
76
+ readonly behaviors: readonly MwlBehaviorDefinition[];
77
+ }
78
+ export interface MwlContentCatalog {
79
+ readonly items: readonly MwlItemDefinition[];
80
+ readonly monsters: readonly MwlMonsterDefinition[];
81
+ readonly statuses: readonly MwlStatusDefinition[];
82
+ readonly loot: readonly MwlLootDefinition[];
83
+ readonly turnClocks: readonly MwlTurnClockDefinition[];
84
+ readonly ai: readonly MwlAiDefinition[];
85
+ readonly moves: readonly MwlMoveDefinition[];
86
+ readonly typeMatchups: readonly MwlTypeMatchupDefinition[];
87
+ readonly evolutions: readonly MwlEvolutionDefinition[];
88
+ }
89
+ export declare function contentCatalog(game: MwlCompiledGame): MwlContentCatalog;
90
+ //# sourceMappingURL=content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/mwl/content.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ export function contentCatalog(game) {
2
+ const nodes = flatten(game.roots);
3
+ return {
4
+ items: nodes
5
+ .filter((node) => node.tag === 'item')
6
+ .map((node) => ({
7
+ id: required(node, 'id'),
8
+ name: required(node, 'name'),
9
+ slot: node.attributes.slot,
10
+ stackable: bool(node, 'stackable'),
11
+ weight: num(node, 'weight'),
12
+ effects: node.children.filter((child) => child.tag === 'effect').map(effect),
13
+ })),
14
+ monsters: nodes
15
+ .filter((node) => node.tag === 'monster')
16
+ .map((node) => ({
17
+ id: required(node, 'id'),
18
+ name: node.attributes.name,
19
+ hp: integer(node, 'hp', 1),
20
+ accuracy: num(node, 'accuracy'),
21
+ evasion: num(node, 'evasion'),
22
+ damage: pair(node, 'damage_min', 'damage_max'),
23
+ armor: pair(node, 'armor_min', 'armor_max'),
24
+ experience: integer(node, 'experience'),
25
+ maxLevel: integer(node, 'max_level'),
26
+ image: node.attributes.image,
27
+ types: node.attributes.types
28
+ ?.split(',')
29
+ .map((type) => type.trim())
30
+ .filter(Boolean),
31
+ baseStats: ['attack', 'defense', 'speed', 'hp'].reduce((stats, name) => {
32
+ const value = num(node, name);
33
+ if (value !== undefined)
34
+ stats[name === 'hp' ? 'maxHp' : name] = value;
35
+ return stats;
36
+ }, {}),
37
+ })),
38
+ statuses: nodes
39
+ .filter((node) => node.tag === 'status')
40
+ .map((node) => ({
41
+ id: required(node, 'id'),
42
+ name: node.attributes.name,
43
+ duration: integer(node, 'duration'),
44
+ tick: node.attributes.tick,
45
+ modifiers: node.attributes.modifiers,
46
+ })),
47
+ loot: nodes
48
+ .filter((node) => node.tag === 'loot')
49
+ .map((node) => ({
50
+ item: required(node, 'item'),
51
+ chance: num(node, 'chance'),
52
+ quantity: integer(node, 'quantity'),
53
+ weight: num(node, 'weight'),
54
+ })),
55
+ turnClocks: nodes
56
+ .filter((node) => node.tag === 'turn_clock')
57
+ .map((node) => ({ id: required(node, 'id'), tick: num(node, 'tick'), hunger: num(node, 'hunger') })),
58
+ ai: nodes
59
+ .filter((node) => node.tag === 'ai')
60
+ .map((node) => ({
61
+ id: required(node, 'id'),
62
+ strategy: node.attributes.strategy,
63
+ target: node.attributes.target,
64
+ difficulty: num(node, 'difficulty'),
65
+ behaviors: node.children
66
+ .filter((child) => child.tag === 'behavior')
67
+ .map((child) => ({
68
+ id: required(child, 'id'),
69
+ when: child.attributes.when,
70
+ action: child.attributes.action,
71
+ hook: child.attributes.hook,
72
+ })),
73
+ })),
74
+ moves: nodes
75
+ .filter((node) => node.tag === 'battle_move')
76
+ .map((node) => ({
77
+ id: required(node, 'id'),
78
+ type: required(node, 'type'),
79
+ target: required(node, 'target'),
80
+ power: num(node, 'power'),
81
+ cost: num(node, 'cost'),
82
+ })),
83
+ typeMatchups: nodes
84
+ .filter((node) => node.tag === 'type_matchup')
85
+ .map((node) => ({
86
+ attacker: required(node, 'attacker'),
87
+ defender: required(node, 'defender'),
88
+ multiplier: num(node, 'multiplier') ?? 1,
89
+ })),
90
+ evolutions: nodes
91
+ .filter((node) => node.tag === 'evolution')
92
+ .map((node) => ({
93
+ from: required(node, 'from'),
94
+ into: required(node, 'into'),
95
+ level: integer(node, 'level', 1),
96
+ })),
97
+ };
98
+ }
99
+ function effect(node) {
100
+ const operation = ['add', 'sub', 'multiply', 'divide', 'set', 'increase', 'increase_total', 'increase_damage'].find((key) => node.attributes[key] !== undefined);
101
+ return {
102
+ applyTo: required(node, 'apply_to'),
103
+ operation,
104
+ value: operation ? node.attributes[operation] : undefined,
105
+ range: node.attributes.range,
106
+ };
107
+ }
108
+ function flatten(roots) {
109
+ const out = [];
110
+ const visit = (node) => {
111
+ out.push(node);
112
+ node.children.forEach(visit);
113
+ };
114
+ roots.forEach(visit);
115
+ return out;
116
+ }
117
+ function required(node, name) {
118
+ const value = node.attributes[name];
119
+ if (!value)
120
+ throw new Error(`MWL ${node.tag} is missing ${name}`);
121
+ return value;
122
+ }
123
+ function num(node, name) {
124
+ const value = node.attributes[name];
125
+ if (value === undefined)
126
+ return undefined;
127
+ const result = Number(value);
128
+ return Number.isFinite(result) ? result : undefined;
129
+ }
130
+ function integer(node, name, fallback) {
131
+ const value = node.attributes[name];
132
+ if (value === undefined)
133
+ return fallback;
134
+ const result = Number.parseInt(value, 10);
135
+ return Number.isFinite(result) ? result : fallback;
136
+ }
137
+ function pair(node, min, max) {
138
+ const a = num(node, min);
139
+ const b = num(node, max);
140
+ return a === undefined || b === undefined ? undefined : [a, b];
141
+ }
142
+ function bool(node, name) {
143
+ const value = node.attributes[name];
144
+ return value === undefined ? undefined : value === 'true' || value === 'yes';
145
+ }
146
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/mwl/content.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /** Small, game-neutral numeric expressions used by MWL effects.
2
+ *
3
+ * MWG only evaluates arithmetic. A game supplies the variables, so names such as
4
+ * `level` or `missing_hp_fraction` remain game vocabulary rather than MWG rules.
5
+ */
6
+ export type MwlExpression = {
7
+ readonly kind: 'number';
8
+ readonly value: number;
9
+ } | {
10
+ readonly kind: 'variable';
11
+ readonly name: string;
12
+ } | {
13
+ readonly kind: 'binary';
14
+ readonly op: '+' | '-' | '*' | '/' | '^';
15
+ readonly left: MwlExpression;
16
+ readonly right: MwlExpression;
17
+ };
18
+ export type MwlExpressionContext = Readonly<Record<string, number>>;
19
+ export declare function parseExpression(source: string): MwlExpression;
20
+ export declare function evaluateExpression(expression: MwlExpression | string, context: MwlExpressionContext): number;
21
+ //# sourceMappingURL=expression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../src/mwl/expression.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpD;IACA,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;CAC7B,CAAC;AAEL,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEpE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAM7D;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,aAAa,GAAG,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAmB5G"}