@datamoc/mw_games 0.42.0 → 0.44.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 +126 -0
- package/README.md +84 -1
- package/REFERENCE.md +134 -6
- package/api-surface.json +1814 -116
- package/data/microgm-essential.PROVENANCE.md +13 -0
- package/data/microgm-essential.sf2 +0 -0
- package/data/soundfont-catalog.json +8 -0
- package/dist/actors/Resource.d.ts.map +1 -1
- package/dist/actors/Resource.js +2 -3
- package/dist/actors/Resource.js.map +1 -1
- package/dist/audio/AdaptiveMusic.d.ts +85 -0
- package/dist/audio/AdaptiveMusic.d.ts.map +1 -0
- package/dist/audio/AdaptiveMusic.js +230 -0
- package/dist/audio/AdaptiveMusic.js.map +1 -0
- package/dist/audio/AudioLoader.d.ts +33 -0
- package/dist/audio/AudioLoader.d.ts.map +1 -0
- package/dist/audio/AudioLoader.js +58 -0
- package/dist/audio/AudioLoader.js.map +1 -0
- package/dist/audio/AudioViews.d.ts +70 -0
- package/dist/audio/AudioViews.d.ts.map +1 -0
- package/dist/audio/AudioViews.js +119 -0
- package/dist/audio/AudioViews.js.map +1 -0
- package/dist/audio/BusBudget.d.ts +89 -0
- package/dist/audio/BusBudget.d.ts.map +1 -0
- package/dist/audio/BusBudget.js +120 -0
- package/dist/audio/BusBudget.js.map +1 -0
- package/dist/audio/Channels.d.ts +66 -1
- package/dist/audio/Channels.d.ts.map +1 -1
- package/dist/audio/Channels.js +119 -31
- package/dist/audio/Channels.js.map +1 -1
- package/dist/audio/CoreHost.d.ts +114 -0
- package/dist/audio/CoreHost.d.ts.map +1 -0
- package/dist/audio/CoreHost.js +335 -0
- package/dist/audio/CoreHost.js.map +1 -0
- package/dist/audio/DecoderGuard.d.ts +139 -0
- package/dist/audio/DecoderGuard.d.ts.map +1 -0
- package/dist/audio/DecoderGuard.js +208 -0
- package/dist/audio/DecoderGuard.js.map +1 -0
- package/dist/audio/Fft.d.ts +3 -0
- package/dist/audio/Fft.d.ts.map +1 -0
- package/dist/audio/Fft.js +45 -0
- package/dist/audio/Fft.js.map +1 -0
- package/dist/audio/LoopTags.d.ts +18 -0
- package/dist/audio/LoopTags.d.ts.map +1 -1
- package/dist/audio/LoopTags.js +20 -0
- package/dist/audio/LoopTags.js.map +1 -1
- package/dist/audio/Midi.d.ts +35 -0
- package/dist/audio/Midi.d.ts.map +1 -1
- package/dist/audio/Midi.js +71 -1
- package/dist/audio/Midi.js.map +1 -1
- package/dist/audio/MidiRender.d.ts +47 -0
- package/dist/audio/MidiRender.d.ts.map +1 -1
- package/dist/audio/MidiRender.js +100 -2
- package/dist/audio/MidiRender.js.map +1 -1
- package/dist/audio/MidiSynth.d.ts +147 -0
- package/dist/audio/MidiSynth.d.ts.map +1 -0
- package/dist/audio/MidiSynth.js +205 -0
- package/dist/audio/MidiSynth.js.map +1 -0
- package/dist/audio/MusicPlayer.d.ts +80 -0
- package/dist/audio/MusicPlayer.d.ts.map +1 -0
- package/dist/audio/MusicPlayer.js +147 -0
- package/dist/audio/MusicPlayer.js.map +1 -0
- package/dist/audio/Playable.d.ts +7 -0
- package/dist/audio/Playable.d.ts.map +1 -1
- package/dist/audio/Playable.js.map +1 -1
- package/dist/audio/Positional.d.ts +12 -4
- package/dist/audio/Positional.d.ts.map +1 -1
- package/dist/audio/Positional.js +5 -2
- package/dist/audio/Positional.js.map +1 -1
- package/dist/audio/Resample.d.ts +61 -0
- package/dist/audio/Resample.d.ts.map +1 -0
- package/dist/audio/Resample.js +97 -0
- package/dist/audio/Resample.js.map +1 -0
- package/dist/audio/SampleDecoder.d.ts +16 -2
- package/dist/audio/SampleDecoder.d.ts.map +1 -1
- package/dist/audio/SampleDecoder.js +10 -6
- package/dist/audio/SampleDecoder.js.map +1 -1
- package/dist/audio/Settings.d.ts +99 -0
- package/dist/audio/Settings.d.ts.map +1 -0
- package/dist/audio/Settings.js +134 -0
- package/dist/audio/Settings.js.map +1 -0
- package/dist/audio/Sfx.d.ts +148 -0
- package/dist/audio/Sfx.d.ts.map +1 -0
- package/dist/audio/Sfx.js +213 -0
- package/dist/audio/Sfx.js.map +1 -0
- package/dist/audio/Sound.d.ts +2 -0
- package/dist/audio/Sound.d.ts.map +1 -1
- package/dist/audio/Sound.js +3 -0
- package/dist/audio/Sound.js.map +1 -1
- package/dist/audio/SoundFont.d.ts +5 -3
- package/dist/audio/SoundFont.d.ts.map +1 -1
- package/dist/audio/SoundFont.js +10 -8
- package/dist/audio/SoundFont.js.map +1 -1
- package/dist/audio/SpectralDistance.d.ts +34 -0
- package/dist/audio/SpectralDistance.d.ts.map +1 -0
- package/dist/audio/SpectralDistance.js +64 -0
- package/dist/audio/SpectralDistance.js.map +1 -0
- package/dist/audio/StreamChannel.d.ts +150 -0
- package/dist/audio/StreamChannel.d.ts.map +1 -0
- package/dist/audio/StreamChannel.js +390 -0
- package/dist/audio/StreamChannel.js.map +1 -0
- package/dist/audio/StreamPlayable.d.ts +73 -0
- package/dist/audio/StreamPlayable.d.ts.map +1 -0
- package/dist/audio/StreamPlayable.js +130 -0
- package/dist/audio/StreamPlayable.js.map +1 -0
- package/dist/audio/Synth.d.ts +1 -1
- package/dist/audio/Synth.d.ts.map +1 -1
- package/dist/audio/Synth.js +4 -0
- package/dist/audio/Synth.js.map +1 -1
- package/dist/audio/SyxBank.d.ts +73 -0
- package/dist/audio/SyxBank.d.ts.map +1 -0
- package/dist/audio/SyxBank.js +130 -0
- package/dist/audio/SyxBank.js.map +1 -0
- package/dist/audio/Underrun.d.ts +25 -0
- package/dist/audio/Underrun.d.ts.map +1 -0
- package/dist/audio/Underrun.js +18 -0
- package/dist/audio/Underrun.js.map +1 -0
- package/dist/audio/Wav.d.ts +56 -0
- package/dist/audio/Wav.d.ts.map +1 -0
- package/dist/audio/Wav.js +164 -0
- package/dist/audio/Wav.js.map +1 -0
- package/dist/audio/WebMidi.d.ts +58 -0
- package/dist/audio/WebMidi.d.ts.map +1 -0
- package/dist/audio/WebMidi.js +79 -0
- package/dist/audio/WebMidi.js.map +1 -0
- package/dist/audio/humanize/Onsets.d.ts.map +1 -1
- package/dist/audio/humanize/Onsets.js +1 -44
- package/dist/audio/humanize/Onsets.js.map +1 -1
- package/dist/audio/index.d.ts +43 -7
- package/dist/audio/index.d.ts.map +1 -1
- package/dist/audio/index.js +21 -3
- package/dist/audio/index.js.map +1 -1
- package/dist/battle/AttackPreview.d.ts.map +1 -1
- package/dist/battle/AttackPreview.js +8 -8
- package/dist/battle/AttackPreview.js.map +1 -1
- package/dist/battle/StatStages.d.ts.map +1 -1
- package/dist/battle/StatStages.js +2 -1
- package/dist/battle/StatStages.js.map +1 -1
- package/dist/board/Engine.d.ts +2 -0
- package/dist/board/Engine.d.ts.map +1 -1
- package/dist/board/Engine.js +1 -1
- package/dist/board/Engine.js.map +1 -1
- package/dist/board/HexSkirmish.d.ts.map +1 -1
- package/dist/board/HexSkirmish.js +11 -72
- package/dist/board/HexSkirmish.js.map +1 -1
- package/dist/board/Tactics.d.ts.map +1 -1
- package/dist/board/Tactics.js +3 -5
- package/dist/board/Tactics.js.map +1 -1
- package/dist/board/tourney.d.ts.map +1 -1
- package/dist/board/tourney.js +2 -19
- package/dist/board/tourney.js.map +1 -1
- package/dist/core/Handles.js +7 -7
- package/dist/core/Handles.js.map +1 -1
- package/dist/mw_games.global.js +25 -22
- package/dist/mwl/conditions.d.ts +12 -0
- package/dist/mwl/conditions.d.ts.map +1 -1
- package/dist/mwl/conditions.js +49 -8
- package/dist/mwl/conditions.js.map +1 -1
- package/dist/mwl/index.d.ts +13 -0
- package/dist/mwl/index.d.ts.map +1 -1
- package/dist/mwl/index.js +7 -0
- package/dist/mwl/index.js.map +1 -1
- package/dist/mwl/objects.d.ts +31 -0
- package/dist/mwl/objects.d.ts.map +1 -0
- package/dist/mwl/objects.js +83 -0
- package/dist/mwl/objects.js.map +1 -0
- package/dist/mwl/package-container.d.ts +185 -0
- package/dist/mwl/package-container.d.ts.map +1 -0
- package/dist/mwl/package-container.js +446 -0
- package/dist/mwl/package-container.js.map +1 -0
- package/dist/mwl/package-document.d.ts +217 -0
- package/dist/mwl/package-document.d.ts.map +1 -0
- package/dist/mwl/package-document.js +639 -0
- package/dist/mwl/package-document.js.map +1 -0
- package/dist/mwl/package-rom.d.ts +37 -0
- package/dist/mwl/package-rom.d.ts.map +1 -0
- package/dist/mwl/package-rom.js +96 -0
- package/dist/mwl/package-rom.js.map +1 -0
- package/dist/mwl/package-verify.d.ts +34 -0
- package/dist/mwl/package-verify.d.ts.map +1 -0
- package/dist/mwl/package-verify.js +111 -0
- package/dist/mwl/package-verify.js.map +1 -0
- package/dist/mwl/package.d.ts +184 -0
- package/dist/mwl/package.d.ts.map +1 -0
- package/dist/mwl/package.js +382 -0
- package/dist/mwl/package.js.map +1 -0
- package/dist/mwl/schema.d.ts +1 -1
- package/dist/mwl/schema.d.ts.map +1 -1
- package/dist/mwl/tables.d.ts +2 -0
- package/dist/mwl/tables.d.ts.map +1 -1
- package/dist/mwl/tables.js +13 -0
- package/dist/mwl/tables.js.map +1 -1
- package/dist/physics/PhysicsWorld.d.ts.map +1 -1
- package/dist/physics/PhysicsWorld.js +4 -3
- package/dist/physics/PhysicsWorld.js.map +1 -1
- package/dist/physics/XpbdWorld.d.ts +23 -5
- package/dist/physics/XpbdWorld.d.ts.map +1 -1
- package/dist/physics/XpbdWorld.js +91 -6
- package/dist/physics/XpbdWorld.js.map +1 -1
- package/dist/testing/FakeAudio.d.ts +149 -0
- package/dist/testing/FakeAudio.d.ts.map +1 -0
- package/dist/testing/FakeAudio.js +219 -0
- package/dist/testing/FakeAudio.js.map +1 -0
- package/dist/testing/index.d.ts +18 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +22 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/threads/index.d.ts +2 -2
- package/dist/threads/index.d.ts.map +1 -1
- package/dist/threads/index.js +1 -1
- package/dist/threads/index.js.map +1 -1
- package/dist/threads/spawn.d.ts +32 -0
- package/dist/threads/spawn.d.ts.map +1 -1
- package/dist/threads/spawn.js +35 -11
- package/dist/threads/spawn.js.map +1 -1
- package/dist/three-d/Collision3D.d.ts +46 -2
- package/dist/three-d/Collision3D.d.ts.map +1 -1
- package/dist/three-d/Collision3D.js +46 -2
- package/dist/three-d/Collision3D.js.map +1 -1
- package/dist/three-d/Grid.d.ts +12 -1
- package/dist/three-d/Grid.d.ts.map +1 -1
- package/dist/three-d/Grid.js +12 -1
- package/dist/three-d/Grid.js.map +1 -1
- package/dist/three-d/Vox.d.ts +13 -1
- package/dist/three-d/Vox.d.ts.map +1 -1
- package/dist/three-d/Vox.js +13 -1
- package/dist/three-d/Vox.js.map +1 -1
- package/dist/two-d/Game.d.ts +32 -1
- package/dist/two-d/Game.d.ts.map +1 -1
- package/dist/two-d/Game.js +105 -14
- package/dist/two-d/Game.js.map +1 -1
- package/dist/two-d/Scene2D.d.ts +24 -0
- package/dist/two-d/Scene2D.d.ts.map +1 -1
- package/dist/two-d/Scene2D.js +30 -0
- package/dist/two-d/Scene2D.js.map +1 -1
- package/dist/two-d/render/HazeLayer.d.ts.map +1 -1
- package/dist/two-d/render/HazeLayer.js +2 -1
- package/dist/two-d/render/HazeLayer.js.map +1 -1
- package/dist/two-d/render/ImageModifiers.d.ts +4 -2
- package/dist/two-d/render/ImageModifiers.d.ts.map +1 -1
- package/dist/two-d/render/ImageModifiers.js +13 -8
- package/dist/two-d/render/ImageModifiers.js.map +1 -1
- package/dist/two-d/render/NeonGlow.d.ts.map +1 -1
- package/dist/two-d/render/NeonGlow.js +2 -1
- package/dist/two-d/render/NeonGlow.js.map +1 -1
- package/dist/two-d/render/Particles.d.ts.map +1 -1
- package/dist/two-d/render/Particles.js +2 -1
- package/dist/two-d/render/Particles.js.map +1 -1
- package/dist/two-d/render/SceneTransition.d.ts +301 -0
- package/dist/two-d/render/SceneTransition.d.ts.map +1 -0
- package/dist/two-d/render/SceneTransition.js +458 -0
- package/dist/two-d/render/SceneTransition.js.map +1 -0
- package/dist/two-d/render/ScreenEffects.d.ts.map +1 -1
- package/dist/two-d/render/ScreenEffects.js +2 -1
- package/dist/two-d/render/ScreenEffects.js.map +1 -1
- package/dist/two-d/render/SkeletalSprite.d.ts.map +1 -1
- package/dist/two-d/render/SkeletalSprite.js +2 -1
- package/dist/two-d/render/SkeletalSprite.js.map +1 -1
- package/dist/two-d/render/Types2D.d.ts +2 -2
- package/dist/two-d/render/Types2D.d.ts.map +1 -1
- package/dist/two-d/render/Types2D.js +2 -2
- package/dist/two-d/render/Types2D.js.map +1 -1
- package/dist/two-d/render/index.d.ts +2 -0
- package/dist/two-d/render/index.d.ts.map +1 -1
- package/dist/two-d/render/index.js +1 -0
- package/dist/two-d/render/index.js.map +1 -1
- package/dist/two-d/ui/Bar.d.ts.map +1 -1
- package/dist/two-d/ui/Bar.js +3 -5
- package/dist/two-d/ui/Bar.js.map +1 -1
- package/dist/two-d/ui/Button.d.ts +23 -0
- package/dist/two-d/ui/Button.d.ts.map +1 -1
- package/dist/two-d/ui/Button.js +37 -0
- package/dist/two-d/ui/Button.js.map +1 -1
- package/dist/two-d/ui/Dropdown.d.ts +5 -1
- package/dist/two-d/ui/Dropdown.d.ts.map +1 -1
- package/dist/two-d/ui/Dropdown.js +8 -1
- package/dist/two-d/ui/Dropdown.js.map +1 -1
- package/dist/two-d/ui/DropdownView.d.ts +63 -3
- package/dist/two-d/ui/DropdownView.d.ts.map +1 -1
- package/dist/two-d/ui/DropdownView.js +168 -9
- package/dist/two-d/ui/DropdownView.js.map +1 -1
- package/dist/two-d/ui/FloatingText.d.ts.map +1 -1
- package/dist/two-d/ui/FloatingText.js +2 -1
- package/dist/two-d/ui/FloatingText.js.map +1 -1
- package/dist/two-d/ui/IconGrid.d.ts.map +1 -1
- package/dist/two-d/ui/IconGrid.js +2 -1
- package/dist/two-d/ui/IconGrid.js.map +1 -1
- package/dist/two-d/ui/ListView.d.ts.map +1 -1
- package/dist/two-d/ui/ListView.js +2 -1
- package/dist/two-d/ui/ListView.js.map +1 -1
- package/dist/two-d/ui/ScrollBox.d.ts +96 -0
- package/dist/two-d/ui/ScrollBox.d.ts.map +1 -1
- package/dist/two-d/ui/ScrollBox.js +218 -5
- package/dist/two-d/ui/ScrollBox.js.map +1 -1
- package/dist/two-d/ui/ScrollText.d.ts +131 -0
- package/dist/two-d/ui/ScrollText.d.ts.map +1 -0
- package/dist/two-d/ui/ScrollText.js +218 -0
- package/dist/two-d/ui/ScrollText.js.map +1 -0
- package/dist/two-d/ui/Slider.d.ts.map +1 -1
- package/dist/two-d/ui/Slider.js +4 -4
- package/dist/two-d/ui/Slider.js.map +1 -1
- package/dist/two-d/ui/Tooltip.d.ts +70 -1
- package/dist/two-d/ui/Tooltip.d.ts.map +1 -1
- package/dist/two-d/ui/Tooltip.js +115 -3
- package/dist/two-d/ui/Tooltip.js.map +1 -1
- package/dist/two-d/ui/Window.d.ts +35 -2
- package/dist/two-d/ui/Window.d.ts.map +1 -1
- package/dist/two-d/ui/Window.js +58 -3
- package/dist/two-d/ui/Window.js.map +1 -1
- package/dist/two-d/ui/index.d.ts +7 -5
- package/dist/two-d/ui/index.d.ts.map +1 -1
- package/dist/two-d/ui/index.js +3 -2
- package/dist/two-d/ui/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +14 -3
- package/sbom.cdx.json +19 -260
- package/tools/audio.d.mts +75 -0
- package/tools/audio.mjs +437 -0
- package/tools/browser-driver.mjs +3 -3
- package/tools/browser-smoke.mjs +19 -2
- package/tools/build-tablebases.mjs +7 -3
- package/tools/compile-openings.mjs +7 -3
- package/tools/compile-resources.d.mts +2 -0
- package/tools/compile-resources.mjs +13 -1
- package/tools/emit-page.d.mts +6 -0
- package/tools/emit-page.mjs +43 -3
- package/tools/find-chrome.mjs +4 -2
- package/tools/init.mjs +11 -3
- package/tools/mwl.mjs +144 -2
- package/tools/play-uci.mjs +9 -5
- package/tools/vite.mjs +9 -1
- package/tools.md +2 -1
package/tools/find-chrome.mjs
CHANGED
|
@@ -17,9 +17,11 @@ async function playwright() {
|
|
|
17
17
|
/**
|
|
18
18
|
* The browser to drive: the platform's usual Chrome (or, on Windows, Edge), then a Chromium that
|
|
19
19
|
* Playwright itself installed (`PLAYWRIGHT_BROWSERS_PATH`, common in CI images and containers),
|
|
20
|
-
* then whatever is on PATH. `CHROME_PATH` overrides all of them
|
|
20
|
+
* then whatever is on PATH. `CHROME_PATH` or `CHROME` overrides all of them.
|
|
21
21
|
*/
|
|
22
22
|
export async function findChrome() {
|
|
23
|
+
const override = process.env.CHROME_PATH || process.env.CHROME;
|
|
24
|
+
if (override) return override;
|
|
23
25
|
const candidates =
|
|
24
26
|
process.platform === 'win32'
|
|
25
27
|
? [
|
|
@@ -93,7 +95,7 @@ async function playwrightChromium() {
|
|
|
93
95
|
* page setup and assertions; this is the launch they all had in common.
|
|
94
96
|
*/
|
|
95
97
|
export async function launchChrome({ argsEnv = 'MWG_BENCHMARK_CHROME_ARGS' } = {}) {
|
|
96
|
-
const executablePath =
|
|
98
|
+
const executablePath = await findChrome();
|
|
97
99
|
const extraArgs = (process.env[argsEnv] ?? '').split(' ').filter(Boolean);
|
|
98
100
|
const { chromium } = await playwright();
|
|
99
101
|
return chromium.launch({
|
package/tools/init.mjs
CHANGED
|
@@ -26,7 +26,13 @@ export function initFiles(name) {
|
|
|
26
26
|
private: true,
|
|
27
27
|
version: '0.0.0',
|
|
28
28
|
type: 'module',
|
|
29
|
-
scripts: {
|
|
29
|
+
scripts: {
|
|
30
|
+
dev: 'vite',
|
|
31
|
+
build: 'vite build',
|
|
32
|
+
check: 'tsc --noEmit',
|
|
33
|
+
test: 'node --test',
|
|
34
|
+
'hooks:install': 'git config core.hooksPath .githooks',
|
|
35
|
+
},
|
|
30
36
|
dependencies: { '@datamoc/mw_games': `^${PACKAGE_VERSION}`, 'pixi.js': '^8.20.1' },
|
|
31
37
|
devDependencies: { typescript: '^7.0.2', vite: '^8.2.2' },
|
|
32
38
|
},
|
|
@@ -101,7 +107,9 @@ export function initFiles(name) {
|
|
|
101
107
|
'',
|
|
102
108
|
].join('\n'),
|
|
103
109
|
'assets/.gitkeep': '',
|
|
104
|
-
'
|
|
110
|
+
'.gitignore': 'node_modules/\ndist/\n.opencode/\n.coord-session\n',
|
|
111
|
+
'.githooks/pre-commit': '#!/bin/sh\nset -e\nnpm run check\nnpm test\n',
|
|
112
|
+
'README.md': `# ${name}\n\n\`npm install\`, then \`npm run dev\` to play it while you edit, \`npm run build\` to write \`dist/\`.\nOpen \`dist/index.html\` (or \`dist/standalone.html\`) by double-clicking it: no server needed.\n\nPut images and sounds under \`assets/\`; the build compiles them into the page. An \`assets/credits.json\`\n(\`[{ "name": "...", "license": "...", "author": "...", "url": "..." }]\`) becomes \`dist/CREDITS.txt\`.\n\nAfter \`git init\`, run \`npm run hooks:install\` to enable the included pre-commit hook.\nIt runs \`npm run check\` and \`npm test\`; add your tests under \`tests/\`.\n`,
|
|
105
113
|
};
|
|
106
114
|
}
|
|
107
115
|
|
|
@@ -121,7 +129,7 @@ export function initProject(folder) {
|
|
|
121
129
|
)) {
|
|
122
130
|
const file = join(target, path);
|
|
123
131
|
mkdirSync(dirname(file), { recursive: true });
|
|
124
|
-
writeFileSync(file, content, 'utf8');
|
|
132
|
+
writeFileSync(file, content, { encoding: 'utf8', mode: path === '.githooks/pre-commit' ? 0o755 : 0o644 });
|
|
125
133
|
written.push(path);
|
|
126
134
|
}
|
|
127
135
|
return { folder: target, files: written };
|
package/tools/mwl.mjs
CHANGED
|
@@ -8,15 +8,24 @@ import {
|
|
|
8
8
|
collectHookReferences,
|
|
9
9
|
compile,
|
|
10
10
|
compileAndEmitSources,
|
|
11
|
+
compilePackages,
|
|
11
12
|
compileSources,
|
|
12
13
|
contentReport,
|
|
14
|
+
decodePackage,
|
|
15
|
+
emitArtifacts,
|
|
13
16
|
emitHooksDeclaration,
|
|
14
17
|
emitModule,
|
|
18
|
+
encodePackage,
|
|
15
19
|
extractCatalog,
|
|
20
|
+
generateCredits,
|
|
21
|
+
loadPackage,
|
|
22
|
+
mergePackage,
|
|
23
|
+
packageContent,
|
|
16
24
|
parse,
|
|
17
25
|
preprocess,
|
|
18
26
|
validate,
|
|
19
27
|
validateHookReferences,
|
|
28
|
+
verifyPackage,
|
|
20
29
|
} from '../dist/mwl/index.js';
|
|
21
30
|
|
|
22
31
|
/**
|
|
@@ -54,6 +63,9 @@ const commands = [
|
|
|
54
63
|
'ci',
|
|
55
64
|
'hooks',
|
|
56
65
|
'build',
|
|
66
|
+
'pack',
|
|
67
|
+
'unpack',
|
|
68
|
+
'verify',
|
|
57
69
|
];
|
|
58
70
|
const [command, input] = args;
|
|
59
71
|
const outputFlag = args.indexOf('-o');
|
|
@@ -67,16 +79,18 @@ const target = targetFlag === -1 ? undefined : args[targetFlag + 1];
|
|
|
67
79
|
|
|
68
80
|
if (args.includes('--help') || args.includes('-h')) {
|
|
69
81
|
console.log(
|
|
70
|
-
'usage: mwg-mwl <validate|compile|format|migrate|extract-i18n|assets|report|diagnostics|ci|hooks|build> input.mwl [-o output] [--to 1.0] [--manifest hooks.json] [--asset-root directory]',
|
|
82
|
+
'usage: mwg-mwl <validate|compile|format|migrate|extract-i18n|assets|report|diagnostics|ci|hooks|build|pack|unpack|verify> input.mwl|input.mwp|directory [-o output] [--to 1.0] [--manifest hooks.json] [--asset-root directory] [--audio-converter module] [--allow capabilities] [--json]',
|
|
71
83
|
);
|
|
72
84
|
process.exit(0);
|
|
73
85
|
}
|
|
74
86
|
|
|
75
87
|
if (!command || !input || !commands.includes(command)) {
|
|
76
88
|
console.error(
|
|
77
|
-
'Usage: mwl <validate|compile|format|migrate|extract-i18n|assets|report|diagnostics|ci|hooks|build> input.mwl [-o output] [--to 1.0] [--manifest hooks.json] [--asset-root directory]',
|
|
89
|
+
'Usage: mwl <validate|compile|format|migrate|extract-i18n|assets|report|diagnostics|ci|hooks|build|pack|unpack|verify> input.mwl|input.mwp|directory [-o output] [--to 1.0] [--manifest hooks.json] [--asset-root directory] [--audio-converter module] [--allow capabilities] [--json]',
|
|
78
90
|
);
|
|
79
91
|
process.exitCode = 2;
|
|
92
|
+
} else if (command === 'pack' || command === 'unpack' || command === 'verify' || /.mwp$/i.test(input)) {
|
|
93
|
+
process.exitCode = await packageCommand();
|
|
80
94
|
} else {
|
|
81
95
|
const files = fs.statSync(input).isDirectory()
|
|
82
96
|
? collectSources(input)
|
|
@@ -322,3 +336,131 @@ async function hooks(files) {
|
|
|
322
336
|
fs.rmSync(entryFile, { force: true });
|
|
323
337
|
}
|
|
324
338
|
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* `pack <dir> -o x.mwp` writes a folder (`content.mwl` plus its media) as one package, refusing to
|
|
342
|
+
* write one that `verify` would reject. `unpack x.mwp -o dir` writes the files back. `verify x.mwp`
|
|
343
|
+
* checks digests, limits, schema, references, licences, ROM images and the capabilities requested
|
|
344
|
+
* (`--allow audio,script` applies a game policy, `--json` prints the report). Any other command
|
|
345
|
+
* given a `.mwp` runs on the content the package's characters expand to.
|
|
346
|
+
*
|
|
347
|
+
* Audio conversion to MWA belongs to the retro-audio package, not to mwg: `--audio-converter module`
|
|
348
|
+
* names an ES module whose default export is `(path, bytes) => { path, data } | undefined`, called
|
|
349
|
+
* for chip-music files (.ym .vgm .nsf .sid .dro .imf .cmf). Without it those files are packed as
|
|
350
|
+
* they are, with a warning.
|
|
351
|
+
*/
|
|
352
|
+
async function packageCommand() {
|
|
353
|
+
const flag = (name) => {
|
|
354
|
+
const at = args.indexOf(name);
|
|
355
|
+
return at === -1 ? undefined : args[at + 1];
|
|
356
|
+
};
|
|
357
|
+
if (command === 'pack') {
|
|
358
|
+
const root = path.resolve(input);
|
|
359
|
+
const converter = flag('--audio-converter');
|
|
360
|
+
const convert = converter ? (await import(pathToFileURL(path.resolve(converter)).href)).default : undefined;
|
|
361
|
+
if (converter && typeof convert !== 'function') throw new Error(`${converter} must default-export a function`);
|
|
362
|
+
const files = [];
|
|
363
|
+
const visit = (directory) => {
|
|
364
|
+
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
365
|
+
if (entry.name.startsWith('.')) continue;
|
|
366
|
+
const full = path.join(directory, entry.name);
|
|
367
|
+
if (entry.isDirectory()) visit(full);
|
|
368
|
+
else
|
|
369
|
+
files.push({
|
|
370
|
+
path: path.relative(root, full).split(path.sep).join('/'),
|
|
371
|
+
data: new Uint8Array(fs.readFileSync(full)),
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
visit(root);
|
|
376
|
+
const chip = /.(?:ym|vgm|nsf|sid|dro|imf|cmf)$/i;
|
|
377
|
+
const packed = [];
|
|
378
|
+
for (const file of files) {
|
|
379
|
+
if (!chip.test(file.path)) {
|
|
380
|
+
packed.push(file);
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
if (!convert)
|
|
384
|
+
console.error(`warning: ${file.path} is packed as it is; pass --audio-converter to store it as MWA`);
|
|
385
|
+
packed.push((convert && (await convert(file.path, file.data))) || file);
|
|
386
|
+
}
|
|
387
|
+
const bytes = await encodePackage(packed, { main: flag('--main') });
|
|
388
|
+
const report = await verifyPackage(bytes);
|
|
389
|
+
for (const warning of report.warnings) console.error(`warning: ${warning}`);
|
|
390
|
+
if (!report.ok) {
|
|
391
|
+
for (const error of report.errors) console.error(`error: ${error}`);
|
|
392
|
+
console.error('nothing was written');
|
|
393
|
+
return 1;
|
|
394
|
+
}
|
|
395
|
+
const target = path.resolve(output ?? `${root}.mwp`);
|
|
396
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
397
|
+
fs.writeFileSync(target, bytes);
|
|
398
|
+
console.log(`packed ${packed.length} file(s) into ${target} (${report.ref})`);
|
|
399
|
+
return 0;
|
|
400
|
+
}
|
|
401
|
+
const bytes = new Uint8Array(fs.readFileSync(input));
|
|
402
|
+
if (command === 'verify') {
|
|
403
|
+
const allow = flag('--allow');
|
|
404
|
+
const report = await verifyPackage(
|
|
405
|
+
bytes,
|
|
406
|
+
allow === undefined ? {} : { policy: { allow: allow.split(',').filter(Boolean) } },
|
|
407
|
+
);
|
|
408
|
+
if (args.includes('--json')) console.log(JSON.stringify(report, null, ' '));
|
|
409
|
+
else {
|
|
410
|
+
for (const warning of report.warnings) console.error(`warning: ${warning}`);
|
|
411
|
+
for (const error of report.errors) console.error(`error: ${error}`);
|
|
412
|
+
if (report.ok)
|
|
413
|
+
console.log(
|
|
414
|
+
`${input}: valid package ${report.ref} (capabilities: ${report.capabilities.join(', ') || 'none'})`,
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
return report.ok ? 0 : 1;
|
|
418
|
+
}
|
|
419
|
+
if (command === 'unpack') {
|
|
420
|
+
const decoded = await decodePackage(bytes);
|
|
421
|
+
const target = path.resolve(output ?? input.replace(/.mwp$/i, ''));
|
|
422
|
+
for (const file of decoded.files) {
|
|
423
|
+
const destination = path.resolve(target, file.path);
|
|
424
|
+
if (!destination.startsWith(target + path.sep))
|
|
425
|
+
throw new Error(`${file.path} escapes the output directory`);
|
|
426
|
+
fs.mkdirSync(path.dirname(destination), { recursive: true });
|
|
427
|
+
fs.writeFileSync(destination, file.data);
|
|
428
|
+
}
|
|
429
|
+
console.log(`unpacked ${decoded.files.length} file(s) into ${target}`);
|
|
430
|
+
return 0;
|
|
431
|
+
}
|
|
432
|
+
if (!['validate', 'compile', 'extract-i18n', 'assets', 'report', 'build'].includes(command)) {
|
|
433
|
+
console.error(`mwl ${command} does not take a package; unpack it first`);
|
|
434
|
+
return 2;
|
|
435
|
+
}
|
|
436
|
+
const loaded = await loadPackage(bytes);
|
|
437
|
+
const set = mergePackage(loaded);
|
|
438
|
+
const game = compilePackages(set);
|
|
439
|
+
if (command === 'validate') {
|
|
440
|
+
console.log(`${input}: valid package`);
|
|
441
|
+
return 0;
|
|
442
|
+
}
|
|
443
|
+
if (command === 'build') {
|
|
444
|
+
const directory = path.resolve(output ?? 'generated');
|
|
445
|
+
fs.mkdirSync(directory, { recursive: true });
|
|
446
|
+
const content = JSON.stringify(packageContent(set), null, ' ');
|
|
447
|
+
for (const artifact of emitArtifacts(game, {
|
|
448
|
+
artifacts: {
|
|
449
|
+
'package-content.json': `${content}
|
|
450
|
+
`,
|
|
451
|
+
},
|
|
452
|
+
}))
|
|
453
|
+
fs.writeFileSync(path.join(directory, artifact.name), artifact.content);
|
|
454
|
+
const credits = generateCredits([loaded.document]);
|
|
455
|
+
if (credits) fs.writeFileSync(path.join(directory, 'CREDITS.txt'), credits);
|
|
456
|
+
console.log(`built package ${loaded.document.meta.id} into ${directory}`);
|
|
457
|
+
return 0;
|
|
458
|
+
}
|
|
459
|
+
const values =
|
|
460
|
+
command === 'extract-i18n' ? extractCatalog(game) : command === 'assets' ? game.assets : contentReport(game);
|
|
461
|
+
const text = `${JSON.stringify(values, null, ' ')}
|
|
462
|
+
`;
|
|
463
|
+
if (output) fs.writeFileSync(output, text);
|
|
464
|
+
else process.stdout.write(text);
|
|
465
|
+
return 0;
|
|
466
|
+
}
|
package/tools/play-uci.mjs
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import { readFileSync, readdirSync, realpathSync } from 'node:fs';
|
|
3
|
+
import { existsSync, readFileSync, readdirSync, realpathSync } from 'node:fs';
|
|
4
4
|
import { join, extname } from 'node:path';
|
|
5
5
|
import { createInterface } from 'node:readline';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
//the framework's own modules: the TypeScript sources inside this repository, the built `dist` inside an
|
|
7
|
+
//installed package, which ships no `src`
|
|
8
|
+
const fromSource = existsSync(new URL('../src/board/chess.ts', import.meta.url));
|
|
9
|
+
const load = (path) => import(fromSource ? `../src/${path}.ts` : `../dist/${path}.js`);
|
|
10
|
+
const { applyMove, cloneChess, legalMoves, parseFen, squareName, startingChess } = await load('board/chess');
|
|
11
|
+
const { parseUciMove, probeBook } = await load('board/openings');
|
|
12
|
+
const { searchTourney } = await load('board/tourney');
|
|
13
|
+
const { loadTablebaseEnding, probeTablebase } = await load('board/tablebase');
|
|
10
14
|
|
|
11
15
|
/**
|
|
12
16
|
* A UCI adapter over the tournament engine: `position`/`go` on stdin, `bestmove`
|
package/tools/vite.mjs
CHANGED
|
@@ -80,7 +80,15 @@ export function mwgPage(options = {}) {
|
|
|
80
80
|
const { assets: _assets, sbom = true, ...emitOptions } = options;
|
|
81
81
|
const source = assets ? resolve(root, assets) : undefined;
|
|
82
82
|
const dist = resolve(root, outDir);
|
|
83
|
-
await emitPage({
|
|
83
|
+
const page = await emitPage({
|
|
84
|
+
...emitOptions,
|
|
85
|
+
dist,
|
|
86
|
+
assets: source && existsSync(source) ? source : undefined,
|
|
87
|
+
});
|
|
88
|
+
if (page.unusedAssets.length > 0)
|
|
89
|
+
console.warn(
|
|
90
|
+
`mwg-page: ${page.unusedAssets.length} embedded asset(s) are never named in the game code: ${page.unusedAssets.join(', ')}`,
|
|
91
|
+
);
|
|
84
92
|
if (sbom) {
|
|
85
93
|
const manifest = join(root, 'package.json');
|
|
86
94
|
const packageJson = existsSync(manifest)
|
package/tools.md
CHANGED
|
@@ -13,7 +13,7 @@ by double-clicking. Run from the repo root.
|
|
|
13
13
|
| `soundfonts` | Picks a SoundFont other than the bundled `microgm-opt` (WTFPL, 2.6 MB, the default). `list` prints the catalogue (`data/soundfont-catalog.json`, a licence-classified snapshot of the marmooo free-soundfonts collection: public domain, MIT and CC-BY fonts fetch freely, share-alike, copyleft and unclear ones need `--accept-licence`); `fetch <font>` downloads only the instruments the game's MIDI files use (`--midi`) or a list (`--programs 0,24,128:0`), and merges them into one SoundFont 3 (the compressed samples untouched, no decoding, no `ffmpeg`) beside a `.credits.txt` that keeps the licence with the file; the game decodes it where it runs with `loadSoundFont`. `fetch --sf2` and `convert <in.sf3> <out.sf2>` decode to a plain SoundFont 2 instead, about eight times larger, which needs `ffmpeg` on PATH (developer machines only). The result goes in the asset folder, where the build subsets it to the programs the game plays | `npx mwg-soundfonts list`, `npx mwg-soundfonts fetch GeneralUser_GS_v2.0.3 --midi assets/*.mid --accept-licence`, or `fetchSoundFont` from `@datamoc/mw_games/tools/soundfonts` |
|
|
14
14
|
| `extract-rgssad` | Decrypts an RPG Maker XP/VX archive to plain files (vendored MIT decoder, developer-side only); an entry whose name would land outside `outDir` is refused (item 389) | `npm run extract:rgssad -- <archive.rgssad> <outDir>` here; `npx mwg-extract-rgssad <archive> <outDir>` or `extractRgssad` from `@datamoc/mw_games/tools/extract-rgssad` in a game |
|
|
15
15
|
| `multiplayer-server` | The reference lockstep server for `core.LockstepClient`: rooms, one shared tick, `null` for a missed input, messages capped at `maxMessageBytes` (64 KB) and read through `parseInbound`, room names bounded, `maxClientsPerRoom` (64). Speaks `ws:`, so a deployment puts it behind a TLS proxy (items 129, 385) | `npx mwg-lockstep-server [port] [--host=]` (127.0.0.1 unless `--host`), or `createLockstepServer(options)` from `@datamoc/mw_games/tools/multiplayer-server`; needs the optional peer `ws` |
|
|
16
|
-
| `mwl` | Compiles MWL content (`[game]`/`[scenario]`/`[side]`/`[unit]`/`[event]`/`[campaign]`) into a game-data module, an i18n catalog and an asset manifest | `npm run mwl -- build <contentDir> -o <outDir>`, or `node node_modules/@datamoc/mw_games/tools/mwl.mjs build <contentDir> -o <outDir>` from an install. It is a command line, not an importable module (it dispatches when loaded), so it has no package subpath; script against the typed library instead: `@datamoc/mw_games/mwl` |
|
|
16
|
+
| `mwl` | Compiles MWL content (`[game]`/`[scenario]`/`[side]`/`[unit]`/`[event]`/`[campaign]`) into a game-data module, an i18n catalog and an asset manifest. Also packs a folder (`content.mwl` plus media) into one `.mwp` content package (`pack`), unpacks it, and verifies it (`verify`: digests, limits, schema, licences, instrument ROM refusal, requested capabilities); `build`, `validate`, `extract-i18n` and `assets` accept a `.mwp` in place of a folder. `pack --audio-converter <module>` is the hook for converting chip music to MWA, which lives in the retro-audio package | `npm run mwl -- build <contentDir> -o <outDir>`, or `node node_modules/@datamoc/mw_games/tools/mwl.mjs build <contentDir> -o <outDir>` from an install. It is a command line, not an importable module (it dispatches when loaded), so it has no package subpath; script against the typed library instead: `@datamoc/mw_games/mwl` |
|
|
17
17
|
| `extract-html` | Splits the resources embedded in an HTML file (scripts, CSS, images) back out into files | `npm run extract:html -- <page.html> -o <outDir>`, or `extractHtml` from `@datamoc/mw_games/tools/extract-html` |
|
|
18
18
|
| `compile-openings` | Compiles opening tables (`eco`, `name`, `pgn` TSV rows) into a position-keyed book JSON a game checks in beside its own code: SAN resolved against the real move generator, every position keeping its continuations, the longest line ending there naming it. Rows are vendored CC0 data (`data/openings/`), never fetched | `node tools/compile-openings.mjs <tsv folder> <book.json>`, or `npx mwg-openings <tsv folder> <book.json>` in a game |
|
|
19
19
|
| `build-tablebases` | Solves pawnless white-extras-against-lone-king endings by retrograde analysis and ships them compiled as Huffman-coded JSON under `data/tablebases` (3-piece: `KQK KRK KBK KNK`; 4-piece like `KBNK KBBK` generate the same way but stay a tool run away, full 4-piece tables are tens of megabytes each). One `threads.spawn` task per ending over capped lanes (4-piece lanes stay narrow: hundreds of megabytes of arrays each); captures convert into the already-solved smaller tables, so 3-piece endings solve first. Golden counts: KQK 0/200896/99448/223944, KRK 0/201700/98644/223944, KBK/KNK all draws, KBBK 0/5628080/21071792/6854560, KBNK 0/11188168/8816020/13550244 (unknown/loss/draw/win) | `node tools/build-tablebases.mjs <outDir> [ending ...] [--jobs=N]`, or `npx mwg-tablebases <outDir> [ending ...]` in a game |
|
|
@@ -201,6 +201,7 @@ same build.
|
|
|
201
201
|
| --- | --- | --- |
|
|
202
202
|
| `roadmap-progress` | Reports CLOSED.md + ROADMAP.md completion: numbered items in batches of 25, plus the 1.0 exit checklist on its own row (checks to run, not capabilities, so they stay out of the numbered totals), optionally in a browser | `npm run roadmap:progress` |
|
|
203
203
|
| `build-webpage-examples` / `build-webpage-docs` | Generate the live examples and Documentation page under `webpage/` (`REFERENCE.md` guide + TypeDoc under `documentation/api/` + the examples index) | `npm run webpage:examples`, `npm run webpage:docs` |
|
|
204
|
+
| `build-bridge-tutorial` / `bins-smoke` | `build-bridge-tutorial` writes `webpage/tutorials/bridge/index.html` from `tools/templates/bridge-tutorial.html`, quoting the code blocks of `examples/bridge` so a test can check them. `bins-smoke` packs the project, installs the tarball in an empty folder and runs every `mwg-*` bin with `--help` on the Node that runs it; CI runs it on Node 20.19.0. Repository tools, not shipped | `npm run build:bridge-tutorial`, `npm run bins:smoke` |
|
|
204
205
|
| `build-example-index` | Writes `documentation/examples.html`, read from source text (no typedoc, no renderer): for each public module the symbols that carry an `@example`, each linked to its typedoc page when one exists, with the runnable `examples/` that import the module. Part of `webpage:docs`; a repository tool, not shipped (item 430) | `npm run webpage:docs`, or `node tools/build-example-index.mjs [outFile]` |
|
|
205
206
|
| `make-example-diagrams` / `make-architecture-diagrams` | Rebuild the generated diagrams under `webpage/assets` (never hand-drawn) | `npm run webpage:diagrams` |
|
|
206
207
|
| `api-report` | Regenerates `API_REPORT.md` from the built declarations; `--check` compares instead. A CI gate | `npm run api:report`, `npm run api:check` |
|