@datamoc/mw_games 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +964 -0
- package/README.md +43 -3
- package/dist/actors/Affix.d.ts +7 -1
- package/dist/actors/Affix.d.ts.map +1 -1
- package/dist/actors/Affix.js +4 -2
- package/dist/actors/Affix.js.map +1 -1
- package/dist/actors/StatBlock.d.ts +20 -0
- package/dist/actors/StatBlock.d.ts.map +1 -1
- package/dist/actors/StatBlock.js +14 -3
- package/dist/actors/StatBlock.js.map +1 -1
- package/dist/actors/index.d.ts +2 -2
- package/dist/actors/index.d.ts.map +1 -1
- package/dist/actors/index.js +1 -1
- package/dist/actors/index.js.map +1 -1
- package/dist/ai/index.d.ts +118 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +203 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/lua.d.ts +47 -0
- package/dist/ai/lua.d.ts.map +1 -0
- package/dist/ai/lua.js +195 -0
- package/dist/ai/lua.js.map +1 -0
- package/dist/ai/search.d.ts +59 -0
- package/dist/ai/search.d.ts.map +1 -0
- package/dist/ai/search.js +100 -0
- package/dist/ai/search.js.map +1 -0
- package/dist/board/Engine.d.ts +14 -0
- package/dist/board/Engine.d.ts.map +1 -1
- package/dist/board/Engine.js +33 -45
- package/dist/board/Engine.js.map +1 -1
- package/dist/board/index.d.ts +1 -1
- package/dist/board/index.d.ts.map +1 -1
- package/dist/board/index.js +1 -1
- package/dist/board/index.js.map +1 -1
- package/dist/core/Csv.d.ts +10 -0
- package/dist/core/Csv.d.ts.map +1 -1
- package/dist/core/Csv.js +34 -3
- package/dist/core/Csv.js.map +1 -1
- package/dist/core/Entity.d.ts +2 -2
- package/dist/core/Entity.d.ts.map +1 -1
- package/dist/core/Entity.js +18 -4
- package/dist/core/Entity.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mw_games.global.js +97 -97
- package/dist/mwl/actors.d.ts +3 -1
- package/dist/mwl/actors.d.ts.map +1 -1
- package/dist/mwl/actors.js +15 -2
- package/dist/mwl/actors.js.map +1 -1
- package/dist/mwl/catalog.d.ts.map +1 -1
- package/dist/mwl/catalog.js +16 -9
- package/dist/mwl/catalog.js.map +1 -1
- package/dist/mwl/compiler.d.ts +20 -0
- package/dist/mwl/compiler.d.ts.map +1 -1
- package/dist/mwl/compiler.js +76 -3
- package/dist/mwl/compiler.js.map +1 -1
- package/dist/mwl/conditions.d.ts +9 -0
- package/dist/mwl/conditions.d.ts.map +1 -0
- package/dist/mwl/conditions.js +162 -0
- package/dist/mwl/conditions.js.map +1 -0
- package/dist/mwl/content.d.ts +61 -0
- package/dist/mwl/content.d.ts.map +1 -1
- package/dist/mwl/content.js +95 -34
- package/dist/mwl/content.js.map +1 -1
- package/dist/mwl/expression.d.ts.map +1 -1
- package/dist/mwl/expression.js +16 -6
- package/dist/mwl/expression.js.map +1 -1
- package/dist/mwl/fengari.d.ts +8 -0
- package/dist/mwl/fengari.d.ts.map +1 -0
- package/dist/mwl/fengari.js +136 -0
- package/dist/mwl/fengari.js.map +1 -0
- package/dist/mwl/hooks.d.ts +1 -1
- package/dist/mwl/hooks.d.ts.map +1 -1
- package/dist/mwl/hooks.js.map +1 -1
- package/dist/mwl/index.d.ts +16 -7
- package/dist/mwl/index.d.ts.map +1 -1
- package/dist/mwl/index.js +7 -3
- package/dist/mwl/index.js.map +1 -1
- package/dist/mwl/persistence.d.ts.map +1 -1
- package/dist/mwl/persistence.js +10 -2
- package/dist/mwl/persistence.js.map +1 -1
- package/dist/mwl/readers.d.ts +18 -0
- package/dist/mwl/readers.d.ts.map +1 -0
- package/dist/mwl/readers.js +58 -0
- package/dist/mwl/readers.js.map +1 -0
- package/dist/mwl/report.d.ts +9 -0
- package/dist/mwl/report.d.ts.map +1 -0
- package/dist/mwl/report.js +36 -0
- package/dist/mwl/report.js.map +1 -0
- package/dist/mwl/runtime.d.ts +65 -2
- package/dist/mwl/runtime.d.ts.map +1 -1
- package/dist/mwl/runtime.js +245 -26
- package/dist/mwl/runtime.js.map +1 -1
- package/dist/mwl/schema.d.ts +13 -1
- package/dist/mwl/schema.d.ts.map +1 -1
- package/dist/mwl/schema.js +222 -7
- package/dist/mwl/schema.js.map +1 -1
- package/dist/mwl/scripts.d.ts +15 -0
- package/dist/mwl/scripts.d.ts.map +1 -0
- package/dist/mwl/scripts.js +23 -0
- package/dist/mwl/scripts.js.map +1 -0
- package/dist/mwl/utils.d.ts +8 -0
- package/dist/mwl/utils.d.ts.map +1 -0
- package/dist/mwl/utils.js +37 -0
- package/dist/mwl/utils.js.map +1 -0
- package/dist/two-d/render/Types2D.d.ts +19 -4
- package/dist/two-d/render/Types2D.d.ts.map +1 -1
- package/dist/two-d/render/Types2D.js +25 -0
- package/dist/two-d/render/Types2D.js.map +1 -1
- package/dist/two-d/render/index.d.ts +2 -2
- package/dist/two-d/render/index.d.ts.map +1 -1
- package/dist/two-d/render/index.js +1 -1
- package/dist/two-d/render/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +27 -6
- package/tools/extract-html.d.mts +18 -0
- package/tools/extract-html.mjs +235 -0
- package/tools/mwl.mjs +86 -16
package/tools/mwl.mjs
CHANGED
|
@@ -6,6 +6,9 @@ import { pathToFileURL } from 'node:url';
|
|
|
6
6
|
import {
|
|
7
7
|
collectHookReferences,
|
|
8
8
|
compile,
|
|
9
|
+
compileAndEmitSources,
|
|
10
|
+
compileSources,
|
|
11
|
+
contentReport,
|
|
9
12
|
emitHooksDeclaration,
|
|
10
13
|
emitModule,
|
|
11
14
|
extractCatalog,
|
|
@@ -25,36 +28,53 @@ import {
|
|
|
25
28
|
*/
|
|
26
29
|
|
|
27
30
|
const args = process.argv.slice(2);
|
|
28
|
-
const commands = ['validate', 'compile', 'extract-i18n', 'assets', 'hooks', 'build'];
|
|
31
|
+
const commands = ['validate', 'compile', 'extract-i18n', 'assets', 'report', 'hooks', 'build'];
|
|
29
32
|
const [command, input] = args;
|
|
30
33
|
const outputFlag = args.indexOf('-o');
|
|
31
34
|
const output = outputFlag === -1 ? undefined : args[outputFlag + 1];
|
|
32
35
|
const manifestFlag = args.indexOf('--manifest');
|
|
33
36
|
const manifestPath = manifestFlag === -1 ? undefined : args[manifestFlag + 1];
|
|
37
|
+
const assetRootFlag = args.indexOf('--asset-root');
|
|
38
|
+
const assetRoot = assetRootFlag === -1 ? undefined : args[assetRootFlag + 1];
|
|
34
39
|
|
|
35
40
|
if (!command || !input || !commands.includes(command)) {
|
|
36
|
-
console.error(
|
|
41
|
+
console.error(
|
|
42
|
+
'Usage: mwl <validate|compile|extract-i18n|assets|report|hooks|build> input.mwl [-o output] [--manifest hooks.json] [--asset-root directory]',
|
|
43
|
+
);
|
|
37
44
|
process.exitCode = 2;
|
|
38
45
|
} else {
|
|
39
|
-
const
|
|
46
|
+
const files = fs.statSync(input).isDirectory()
|
|
47
|
+
? collectSources(input)
|
|
48
|
+
: [{ file: sourceLabel(input), source: fs.readFileSync(input, 'utf8') }];
|
|
40
49
|
if (command === 'validate') {
|
|
41
|
-
const diagnostics =
|
|
50
|
+
const diagnostics = files.flatMap((file) =>
|
|
51
|
+
validate(parse(preprocess(file.source, { file: file.file }), file.file)),
|
|
52
|
+
);
|
|
42
53
|
if (diagnostics.length) {
|
|
43
54
|
for (const diagnostic of diagnostics)
|
|
44
55
|
console.error(
|
|
45
56
|
`${diagnostic.location.file}:${diagnostic.location.line}:${diagnostic.location.column}: ${diagnostic.message}`,
|
|
46
57
|
);
|
|
47
58
|
process.exitCode = 1;
|
|
48
|
-
} else
|
|
59
|
+
} else {
|
|
60
|
+
try {
|
|
61
|
+
compileSources(files);
|
|
62
|
+
console.log(`${input}: valid MWL`);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
65
|
+
process.exitCode = 1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
49
68
|
} else if (command === 'hooks') {
|
|
50
|
-
await hooks(
|
|
69
|
+
await hooks(files);
|
|
51
70
|
} else if (command === 'build') {
|
|
52
|
-
build(
|
|
71
|
+
build(files);
|
|
53
72
|
} else {
|
|
54
|
-
const result =
|
|
73
|
+
const result = compileSources(files);
|
|
55
74
|
const values =
|
|
56
75
|
command === 'extract-i18n' ? extractCatalog(result) : command === 'assets' ? result.assets : result;
|
|
57
|
-
const
|
|
76
|
+
const report = command === 'report' ? contentReport(result) : values;
|
|
77
|
+
const text = command === 'compile' ? emitModule(result) : `${JSON.stringify(report, null, '\t')}\n`;
|
|
58
78
|
if (output) {
|
|
59
79
|
fs.mkdirSync(path.dirname(path.resolve(output)), { recursive: true });
|
|
60
80
|
fs.writeFileSync(output, text);
|
|
@@ -62,25 +82,75 @@ if (!command || !input || !commands.includes(command)) {
|
|
|
62
82
|
}
|
|
63
83
|
}
|
|
64
84
|
|
|
85
|
+
function collectSources(directory) {
|
|
86
|
+
const files = [];
|
|
87
|
+
const root = path.resolve(directory);
|
|
88
|
+
const label = sourceLabel(root);
|
|
89
|
+
const visit = (current) => {
|
|
90
|
+
for (const entry of fs
|
|
91
|
+
.readdirSync(current, { withFileTypes: true })
|
|
92
|
+
.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))) {
|
|
93
|
+
const full = path.join(current, entry.name);
|
|
94
|
+
if (entry.isDirectory()) visit(full);
|
|
95
|
+
else if (/\.mwl$/i.test(entry.name)) {
|
|
96
|
+
const relative = path.relative(root, full);
|
|
97
|
+
files.push({
|
|
98
|
+
file: path.join(label, relative).split(path.sep).join('/'),
|
|
99
|
+
source: fs.readFileSync(full, 'utf8'),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
visit(root);
|
|
105
|
+
if (!files.length) throw new Error(`no .mwl files found in ${directory}`);
|
|
106
|
+
return files;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function sourceLabel(file) {
|
|
110
|
+
const relative = path.relative(process.cwd(), path.resolve(file));
|
|
111
|
+
return (relative || path.basename(path.resolve(file))).split(path.sep).join('/');
|
|
112
|
+
}
|
|
113
|
+
|
|
65
114
|
/** One deterministic build step for the three files every MWL game consumes. */
|
|
66
|
-
function build(
|
|
67
|
-
const game =
|
|
115
|
+
function build(files) {
|
|
116
|
+
const game = compileSources(files);
|
|
117
|
+
if (assetRoot) validateAssets(game, path.resolve(assetRoot));
|
|
68
118
|
const directory = path.resolve(output ?? 'generated');
|
|
69
119
|
fs.mkdirSync(directory, { recursive: true });
|
|
70
|
-
|
|
71
|
-
fs.writeFileSync(path.join(directory,
|
|
72
|
-
fs.writeFileSync(path.join(directory, 'assets.json'), `${JSON.stringify({ assets: game.assets }, null, '\t')}\n`);
|
|
120
|
+
const artifacts = compileAndEmitSources(files);
|
|
121
|
+
for (const artifact of artifacts) fs.writeFileSync(path.join(directory, artifact.name), artifact.content);
|
|
73
122
|
console.log(`built MWL into ${directory}`);
|
|
74
123
|
}
|
|
75
124
|
|
|
125
|
+
function validateAssets(game, root) {
|
|
126
|
+
const missing = game.assets.filter(
|
|
127
|
+
(asset) => !asset.startsWith('data:') && !fs.existsSync(path.resolve(root, asset)),
|
|
128
|
+
);
|
|
129
|
+
if (!missing.length) return;
|
|
130
|
+
const locations = new Map();
|
|
131
|
+
const visit = (node) => {
|
|
132
|
+
for (const value of Object.values(node.attributes))
|
|
133
|
+
for (const asset of missing)
|
|
134
|
+
if (value.includes(asset) && !locations.has(asset)) locations.set(asset, node.location);
|
|
135
|
+
node.children.forEach(visit);
|
|
136
|
+
};
|
|
137
|
+
game.roots.forEach(visit);
|
|
138
|
+
for (const asset of missing) {
|
|
139
|
+
const location = locations.get(asset);
|
|
140
|
+
const prefix = location ? `${location.file}:${location.line}:${location.column}: ` : '';
|
|
141
|
+
console.error(`${prefix}missing MWL asset "${asset}" under ${root}`);
|
|
142
|
+
}
|
|
143
|
+
throw new Error(`${missing.length} MWL asset(s) not found`);
|
|
144
|
+
}
|
|
145
|
+
|
|
76
146
|
/**
|
|
77
147
|
* `mwl hooks game.mwl` prints the hook references content needs.
|
|
78
148
|
* `mwl hooks game.mwl --manifest hooks.json -o generated/hooks.mjs` resolves
|
|
79
149
|
* each reference against the manifest, bundles the hook sources with esbuild,
|
|
80
150
|
* and writes the matching declaration next to the bundle.
|
|
81
151
|
*/
|
|
82
|
-
async function hooks(
|
|
83
|
-
const game =
|
|
152
|
+
async function hooks(files) {
|
|
153
|
+
const game = compileSources(files);
|
|
84
154
|
const references = collectHookReferences(game);
|
|
85
155
|
if (!output) {
|
|
86
156
|
process.stdout.write(
|