@pkmn/engine 0.1.0-dev.729b1e87 → 0.1.0-dev.73fa6bda

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 (85) hide show
  1. package/LICENSE +1 -3
  2. package/README.md +155 -81
  3. package/build/pkg/addon/browser.d.ts +3 -0
  4. package/build/pkg/addon/browser.js +47 -0
  5. package/build/pkg/addon/browser.js.map +1 -0
  6. package/build/pkg/addon/node.d.ts +3 -0
  7. package/build/pkg/addon/node.js +110 -0
  8. package/build/pkg/addon/node.js.map +1 -0
  9. package/build/pkg/addon/wasm.d.ts +2 -0
  10. package/build/pkg/addon/wasm.js +53 -0
  11. package/build/pkg/addon/wasm.js.map +1 -0
  12. package/build/pkg/addon.d.ts +29 -0
  13. package/build/pkg/addon.js +80 -0
  14. package/build/pkg/addon.js.map +1 -0
  15. package/build/pkg/data/ids.json +12 -12
  16. package/build/pkg/data/layout.json +40 -5
  17. package/build/pkg/data/protocol.json +84 -13
  18. package/build/pkg/data.d.ts +28 -7
  19. package/build/pkg/data.js +3 -5
  20. package/build/pkg/data.js.map +1 -1
  21. package/build/pkg/gen1.d.ts +18 -20
  22. package/build/pkg/gen1.js +76 -51
  23. package/build/pkg/gen1.js.map +1 -1
  24. package/build/pkg/index.d.ts +57 -103
  25. package/build/pkg/index.js +23 -70
  26. package/build/pkg/index.js.map +1 -1
  27. package/build/pkg/protocol.d.ts +33 -3
  28. package/build/pkg/protocol.js +127 -104
  29. package/build/pkg/protocol.js.map +1 -1
  30. package/build/tools/debug.js +144 -0
  31. package/build/tools/debug.js.map +1 -0
  32. package/build/tools/display/debug.jsx +66 -0
  33. package/build/tools/display/debug.jsx.map +1 -0
  34. package/build/tools/display/index.js +152 -0
  35. package/build/tools/display/index.js.map +1 -0
  36. package/build/tools/display/ui.jsx +360 -0
  37. package/build/tools/display/ui.jsx.map +1 -0
  38. package/build/tools/display/util.js +157 -0
  39. package/build/tools/display/util.js.map +1 -0
  40. package/build.zig +342 -175
  41. package/package.json +94 -133
  42. package/src/bin/install-pkmn-engine +100 -42
  43. package/src/bin/pkmn-debug +62 -0
  44. package/src/lib/bindings/c.zig +200 -0
  45. package/src/lib/bindings/node.zig +117 -0
  46. package/src/lib/bindings/wasm.zig +50 -0
  47. package/src/lib/common/array.zig +70 -0
  48. package/src/lib/common/battle.zig +17 -0
  49. package/src/lib/common/data.zig +19 -31
  50. package/src/lib/common/debug.zig +47 -32
  51. package/src/lib/common/js.zig +114 -0
  52. package/src/lib/common/optional.zig +61 -0
  53. package/src/lib/common/options.zig +18 -3
  54. package/src/lib/common/protocol.zig +1072 -497
  55. package/src/lib/common/rational.zig +440 -0
  56. package/src/lib/common/rng.zig +31 -24
  57. package/src/lib/common/util.zig +44 -0
  58. package/src/lib/gen1/calc.zig +975 -0
  59. package/src/lib/gen1/chance.zig +1222 -0
  60. package/src/lib/gen1/data/moves.zig +203 -193
  61. package/src/lib/gen1/data/species.zig +6 -8
  62. package/src/lib/gen1/data/types.zig +12 -13
  63. package/src/lib/gen1/data.zig +105 -94
  64. package/src/lib/gen1/helpers.zig +138 -55
  65. package/src/lib/gen1/mechanics.zig +1439 -935
  66. package/src/lib/gen2/calc.zig +150 -0
  67. package/src/lib/gen2/chance.zig +896 -0
  68. package/src/lib/gen2/data/items.zig +15 -23
  69. package/src/lib/gen2/data/moves.zig +665 -573
  70. package/src/lib/gen2/data/species.zig +3 -5
  71. package/src/lib/gen2/data/types.zig +141 -36
  72. package/src/lib/gen2/data.zig +140 -104
  73. package/src/lib/gen2/generated.zig +801 -0
  74. package/src/lib/gen2/helpers.zig +58 -45
  75. package/src/lib/gen2/mechanics.zig +3582 -30
  76. package/src/lib/napi.h +2 -0
  77. package/src/lib/node.zig +14 -0
  78. package/src/lib/pkmn.zig +177 -22
  79. package/src/lib/wasm.zig +13 -0
  80. package/src/tools/display/dom.ts +108 -0
  81. package/src/tools/display/ui.css +354 -0
  82. package/src/lib/binding/node.zig +0 -229
  83. package/src/lib/binding/wasm.zig +0 -10
  84. package/src/lib/gen1/README.md +0 -778
  85. package/src/lib/gen2/README.md +0 -309
package/package.json CHANGED
@@ -1,192 +1,153 @@
1
1
  {
2
2
  "name": "@pkmn/engine",
3
- "version": "0.1.0-dev.729b1e87",
3
+ "version": "0.1.0-dev.73fa6bda",
4
4
  "description": "A minimal, complete, Pokémon battle simulation engine optimized for performance",
5
5
  "repository": "github:pkmn/engine",
6
6
  "license": "MIT",
7
7
  "sideEffects": false,
8
8
  "main": "build/pkg/index.js",
9
9
  "types": "build/pkg/index.d.ts",
10
+ "browser": {
11
+ "./build/pkg/addon/node.js": "./build/pkg/addon/browser.js"
12
+ },
10
13
  "files": [
11
14
  "build.zig",
12
- "src/bin/install-pkmn-engine",
13
- "src/lib/binding/node.zig",
14
- "src/lib/binding/wasm.zig",
15
+ "build/pkg/addon.d.ts",
16
+ "build/pkg/addon.js.map",
17
+ "build/pkg/addon.js",
18
+ "build/pkg/addon/browser.d.ts",
19
+ "build/pkg/addon/browser.js.map",
20
+ "build/pkg/addon/browser.js",
21
+ "build/pkg/addon/node.d.ts",
22
+ "build/pkg/addon/node.js.map",
23
+ "build/pkg/addon/node.js",
24
+ "build/pkg/addon/wasm.d.ts",
25
+ "build/pkg/addon/wasm.js.map",
26
+ "build/pkg/addon/wasm.js",
27
+ "build/pkg/data.d.ts",
28
+ "build/pkg/data.js.map",
29
+ "build/pkg/data.js",
30
+ "build/pkg/data/ids.json",
31
+ "build/pkg/data/layout.json",
32
+ "build/pkg/data/protocol.json",
33
+ "build/pkg/gen1.d.ts",
34
+ "build/pkg/gen1.js.map",
35
+ "build/pkg/gen1.js",
36
+ "build/pkg/index.d.ts",
37
+ "build/pkg/index.js.map",
38
+ "build/pkg/index.js",
39
+ "build/pkg/protocol.d.ts",
40
+ "build/pkg/protocol.js.map",
41
+ "build/pkg/protocol.js",
42
+ "build/tools/debug.js.map",
43
+ "build/tools/debug.js",
44
+ "build/tools/display/index.js.map",
45
+ "build/tools/display/index.js",
46
+ "build/tools/display/debug.jsx.map",
47
+ "build/tools/display/debug.jsx",
48
+ "build/tools/display/ui.jsx.map",
49
+ "build/tools/display/ui.jsx",
50
+ "build/tools/display/util.js.map",
51
+ "build/tools/display/util.js",
52
+ "src/lib/bindings/c.zig",
53
+ "src/lib/bindings/node.zig",
54
+ "src/lib/bindings/wasm.zig",
55
+ "src/lib/common/array.zig",
56
+ "src/lib/common/battle.zig",
15
57
  "src/lib/common/data.zig",
16
58
  "src/lib/common/debug.zig",
59
+ "src/lib/common/js.zig",
60
+ "src/lib/common/optional.zig",
17
61
  "src/lib/common/options.zig",
18
62
  "src/lib/common/protocol.zig",
63
+ "src/lib/common/rational.zig",
19
64
  "src/lib/common/rng.zig",
65
+ "src/lib/common/util.zig",
66
+ "src/lib/gen1/calc.zig",
67
+ "src/lib/gen1/chance.zig",
68
+ "src/lib/gen1/data.zig",
20
69
  "src/lib/gen1/data/moves.zig",
21
70
  "src/lib/gen1/data/species.zig",
22
71
  "src/lib/gen1/data/types.zig",
23
- "src/lib/gen1/data.zig",
24
72
  "src/lib/gen1/helpers.zig",
25
73
  "src/lib/gen1/mechanics.zig",
74
+ "src/lib/gen2/calc.zig",
75
+ "src/lib/gen2/chance.zig",
76
+ "src/lib/gen2/data.zig",
26
77
  "src/lib/gen2/data/items.zig",
27
78
  "src/lib/gen2/data/moves.zig",
28
79
  "src/lib/gen2/data/species.zig",
29
80
  "src/lib/gen2/data/types.zig",
30
- "src/lib/gen2/data.zig",
81
+ "src/lib/gen2/generated.zig",
31
82
  "src/lib/gen2/helpers.zig",
32
83
  "src/lib/gen2/mechanics.zig",
84
+ "src/lib/napi.h",
85
+ "src/lib/node.zig",
33
86
  "src/lib/pkmn.zig",
34
- "build/pkg/data/ids.json",
35
- "build/pkg/data/layout.json",
36
- "build/pkg/data/protocol.json",
37
- "build/pkg/data.d.ts",
38
- "build/pkg/data.js",
39
- "build/pkg/data.js.map",
40
- "build/pkg/gen1.d.ts",
41
- "build/pkg/gen1.js",
42
- "build/pkg/gen1.js.map",
43
- "build/pkg/index.d.ts",
44
- "build/pkg/index.js",
45
- "build/pkg/index.js.map",
46
- "build/pkg/protocol.d.ts",
47
- "build/pkg/protocol.js",
48
- "build/pkg/protocol.js.map"
87
+ "src/lib/wasm.zig",
88
+ "src/tools/display/dom.ts",
89
+ "src/tools/display/ui.css"
49
90
  ],
50
91
  "engines": {
51
92
  "node": ">=16.0.0"
52
93
  },
53
94
  "bin": {
54
- "install-pkmn-engine": "src/bin/install-pkmn-engine"
95
+ "install-pkmn-engine": "src/bin/install-pkmn-engine",
96
+ "pkmn-debug": "src/bin/pkmn-debug"
55
97
  },
56
98
  "publishConfig": {
57
99
  "access": "public"
58
100
  },
59
101
  "dependencies": {
60
- "@pkmn/data": "^0.7.34",
61
- "@pkmn/protocol": "^0.6.11"
102
+ "@pkmn/data": "0.9.35",
103
+ "@pkmn/protocol": "^0.7.2"
62
104
  },
63
105
  "devDependencies": {
64
- "@pkmn/eslint-config": "^3.0.0-alpha.0",
65
- "@pkmn/img": "^0.2.8",
66
- "@pkmn/sets": "^5.0.4",
67
- "@pkmn/sim": "0.7.34",
68
- "@types/html-minifier": "^4.0.2",
69
- "@types/jest": "^29.5.0",
70
- "@types/minimist": "^1.2.2",
71
- "@types/mustache": "^4.2.2",
72
- "@types/node": "^18.15.11",
73
- "@vitest/coverage-c8": "^0.29.8",
74
- "binaryen": "^112.0.0",
75
- "eslint": "^8.37.0",
106
+ "@pkmn/dex-types": "0.9.35",
107
+ "@pkmn/eslint-config": "^9.27.0",
108
+ "@pkmn/img": "^0.3.3",
109
+ "@pkmn/sets": "^5.2.0",
110
+ "@pkmn/sim": "0.9.31",
111
+ "@pkmn/smogon": "0.5.21",
112
+ "@types/html-minifier": "^4.0.6",
113
+ "@types/jest": "^30.0.0",
114
+ "@types/minimist": "^1.2.5",
115
+ "@types/mustache": "^4.2.6",
116
+ "@types/node": "^25.6.0",
117
+ "@types/react": "^19.2.14",
118
+ "@types/semver": "^7.7.1",
119
+ "@types/vscode": "^1.118.0",
120
+ "@vitest/coverage-v8": "^4.1.5",
121
+ "@vscode/vsce": "^3.9.1",
122
+ "binaryen": "^129.0.0",
123
+ "esbuild": "^0.28.0",
124
+ "eslint": "<10",
76
125
  "html-minifier": "^4.0.0",
77
126
  "json-stringify-pretty-compact": "3.0.0",
78
127
  "minimist": "^1.2.8",
79
128
  "mustache": "^4.2.0",
129
+ "semver": "^7.7.4",
80
130
  "source-map-support": "^0.5.21",
131
+ "table": "^6.9.0",
81
132
  "trakr": "^0.2.0",
82
- "typescript": "^5.0.2",
83
- "vitest": "^0.29.8"
133
+ "typescript": "^6.0.3",
134
+ "vitest": "^4.1.5"
84
135
  },
85
136
  "scripts": {
86
- "lint": "eslint --cache src --ext ts,js && eslint src/bin/install-pkmn-engine",
87
- "fix": "eslint --fix src --ext ts,js && eslint --fix src/bin/install-pkmn-engine",
137
+ "lint": "eslint --cache src",
138
+ "fix": "eslint --fix src",
88
139
  "compile": "tsc -p .",
89
140
  "build": "npm run compile",
90
141
  "test": "vitest src/pkg",
91
142
  "test:integration": "vitest src/test",
143
+ "debug": "npm run compile && node build/tools/debug",
144
+ "demo": "npm run compile && node build/tools/demo",
92
145
  "fuzz": "npm run compile && node build/test/fuzz",
93
146
  "generate": "npm run compile && node build/tools/generate",
94
147
  "release": "npm run compile && node build/tools/release",
95
148
  "benchmark": "npm run compile && node build/test/benchmark",
96
149
  "integration": "npm run compile && node build/test/integration",
150
+ "extension": "npm -C src/tools/vscode run build",
97
151
  "postinstall": "node src/bin/install-pkmn-engine"
98
- },
99
- "eslintConfig": {
100
- "extends": "@pkmn",
101
- "ignorePatterns": [
102
- "dist/",
103
- "node_modules/",
104
- "src/examples/zig",
105
- "build/"
106
- ],
107
- "env": {
108
- "es6": true,
109
- "node": true,
110
- "browser": true
111
- },
112
- "overrides": [
113
- {
114
- "files": [
115
- "**/*.ts"
116
- ],
117
- "parserOptions": {
118
- "project": [
119
- "./tsconfig.json",
120
- "./src/examples/js/tsconfig.json"
121
- ]
122
- }
123
- },
124
- {
125
- "files": [
126
- "src/pkg/index.ts",
127
- "src/test/display.ts",
128
- "src/test/integration.ts"
129
- ],
130
- "rules": {
131
- "no-control-regex": "off",
132
- "@typescript-eslint/no-empty-interface": "off",
133
- "@typescript-eslint/no-shadow": "off"
134
- }
135
- },
136
- {
137
- "files": [
138
- "src/pkg/addon.ts"
139
- ],
140
- "rules": {
141
- "@typescript-eslint/no-var-requires": "off"
142
- }
143
- },
144
- {
145
- "files": [
146
- "src/test/benchmark*.ts"
147
- ],
148
- "rules": {
149
- "@typescript-eslint/no-unused-vars": "off"
150
- }
151
- },
152
- {
153
- "files": [
154
- "src/test/*.test.ts"
155
- ],
156
- "rules": {
157
- "jest/no-standalone-expect": "off"
158
- }
159
- },
160
- {
161
- "files": [
162
- "src/test/showdown/**"
163
- ],
164
- "rules": {
165
- "jest/expect-expect": [
166
- "warn",
167
- {
168
- "assertFunctionNames": [
169
- "expect",
170
- "expectLog",
171
- "verify"
172
- ]
173
- }
174
- ]
175
- }
176
- },
177
- {
178
- "files": [
179
- "src/tools/generate.ts"
180
- ],
181
- "rules": {
182
- "@typescript-eslint/restrict-template-expressions": [
183
- "error",
184
- {
185
- "allowBoolean": true
186
- }
187
- ]
188
- }
189
- }
190
- ]
191
152
  }
192
153
  }
@@ -10,13 +10,15 @@ const path = require('path');
10
10
  const {pipeline} = require('stream/promises');
11
11
  const tty = require('tty');
12
12
 
13
- const ZIG_VERSION = {major: 0, minor: 11, patch: 0, dev: 2168};
13
+ const ZIG_VERSION = {major: 0, minor: 16, patch: 0};
14
14
  const DEV = ZIG_VERSION.dev ? `-dev.${ZIG_VERSION.dev}` : '';
15
15
  const VERSION = `${ZIG_VERSION.major}.${ZIG_VERSION.minor}.${ZIG_VERSION.patch}${DEV}`;
16
16
  const INDEX = 'https://ziglang.org/download/index.json';
17
17
  const ROOT = path.resolve(__dirname, '..', '..');
18
+ let SILENT = false;
18
19
 
19
20
  const sh = (cmd, args) => execFileSync(cmd, args, {encoding: 'utf8', cwd: ROOT});
21
+ const log = (...args) => { if (!SILENT) console.log(...args); };
20
22
 
21
23
  // This is hardly the browser fetch API, but it works for our primitive needs
22
24
  const fetch = url => new Promise((resolve, reject) => {
@@ -61,7 +63,7 @@ const unpack7 = (input, output) => new Promise((resolve, reject) => {
61
63
  require.resolve('7zip-min');
62
64
  } catch (err) {
63
65
  if (err.code !== 'MODULE_NOT_FOUND') throw err;
64
- console.log('Installing 7zip-min package locally to unpack the archive...');
66
+ log('Installing 7zip-min package locally to unpack the archive...');
65
67
  sh('npm', ['install', '7zip-min', '--no-audit', '--no-save']);
66
68
  }
67
69
 
@@ -83,7 +85,7 @@ const unpack = async (input, output) => {
83
85
  sh('tar', ['xf', input, '-C', output]);
84
86
  return;
85
87
  } catch {
86
- console.log('tar command not found, falling back to 7z');
88
+ log('tar command not found, falling back to 7z');
87
89
  }
88
90
  }
89
91
  // Try to use a 7z binary if we can, and only install 7zip-min as a last resort
@@ -109,21 +111,37 @@ const unpack = async (input, output) => {
109
111
  }
110
112
  };
111
113
 
114
+ const parse = s => {
115
+ try {
116
+ return JSON.parse(s);
117
+ } catch (e) {
118
+ if (!(e instanceof SyntaxError)) throw e;
119
+ const json = s
120
+ // "key": -> "key": (ensures keys are quoted)
121
+ .replace(/\.([a-zA-Z_][a-zA-Z0-9_]*)\s*=/g, '"$1":')
122
+ // .{ -> { (converts ZON struct to JSON object)
123
+ .replace(/\.\{/g, '{')
124
+ // Remove trailing commas, which are invalid in JSON
125
+ .replace(/,\s*([}\]])/g, '$1');
126
+ return JSON.parse(json);
127
+ }
128
+ };
129
+
112
130
  const find = zig => {
113
131
  try {
114
- const {zig_exe, version} = JSON.parse(sh(zig, ['env']));
132
+ const {zig_exe, version} = parse(sh(zig, ['env']));
115
133
  const [major, minor, patch, dev] = version.split('.').map(n => parseInt(n));
116
134
 
117
135
  const compatible = major > ZIG_VERSION.major ||
118
136
  (major >= ZIG_VERSION.major && minor > ZIG_VERSION.minor) ||
119
137
  (major >= ZIG_VERSION.major && minor >= ZIG_VERSION.minor && patch >= ZIG_VERSION.patch &&
120
- (!ZIG_VERSION.dev || (dev && dev >= ZIG_VERSION.dev)));
138
+ (!ZIG_VERSION.dev || (dev && dev >= parseInt(ZIG_VERSION.dev))));
121
139
 
122
140
  if (compatible) {
123
- console.log('Found existing compatible Zig executable:', zig_exe);
141
+ log('Found existing compatible Zig executable:', zig_exe);
124
142
  return zig_exe;
125
143
  } else {
126
- console.log(`Existing Zig executable is not compatible (${version} < ${VERSION}):`, zig_exe);
144
+ log(`Existing Zig executable is not compatible (${version} < ${VERSION}):`, zig_exe);
127
145
  }
128
146
  } catch (err) {
129
147
  if (err.code !== 'ENOENT') throw err;
@@ -162,17 +180,18 @@ const install = async () => {
162
180
 
163
181
  const index = JSON.parse(await fetch(INDEX));
164
182
  const version = Object.keys(index)[+!ZIG_VERSION.dev];
183
+ // const version = VERSION; // TODO
165
184
  const release = index[version][`${arch}-${platform}`];
166
185
  const url = release.tarball;
167
186
 
168
187
  let base = path.basename(url);
169
188
  const archive = path.join(dir, path.basename(url));
170
189
 
171
- console.log(`Downloading Zig tarball from ${url} to ${archive}`);
190
+ log(`Downloading Zig tarball from ${url} to ${archive}`);
172
191
  try {
173
192
  await download(url, archive, release.shasum);
174
193
 
175
- console.log(`Extracting tarball and installing to ${dir}`);
194
+ log(`Extracting tarball and installing to ${dir}`);
176
195
  await unpack(archive, dir);
177
196
  if (archive.endsWith('.zip')) {
178
197
  base = base.slice(0, -4);
@@ -187,17 +206,17 @@ const install = async () => {
187
206
  } catch (err) {
188
207
  if (err.code !== 'ENOENT') throw err;
189
208
  }
190
- console.log(`Zig${version === 'master' ? '' : ` v${version}`} executable:`, zig,
209
+ log(`Zig${version === 'master' ? '' : ` v${version}`} executable:`, zig,
191
210
  '(this version of Zig will be retained to speed up future updates)');
192
211
  const [pre, post] = tty.isatty(1) ? ['\x1b[1m\x1b[35m', '\x1b[0m'] : ['', ''];
193
- console.log(
212
+ log(
194
213
  `${pre}Consider moving the ${path.dirname(zig)} directory and adding it to your PATH`,
195
214
  `to use Zig on other projects, or delete this if you wish to save space.${post}`
196
215
  );
197
216
 
198
217
  return zig;
199
218
  } finally {
200
- console.log(`Cleaning up ${archive}`);
219
+ log(`Cleaning up ${archive}`);
201
220
  try { fs.rmSync(archive); } catch {}
202
221
  }
203
222
  };
@@ -206,17 +225,17 @@ const install = async () => {
206
225
  const downloadHeaders = async () => {
207
226
  const include = path.resolve(process.execPath, '..', '..', 'include', 'node');
208
227
  if (fs.existsSync(path.join(include, 'node.h'))) {
209
- console.log('Node headers:', include);
228
+ log('Node headers:', include);
210
229
  return include;
211
230
  }
212
231
 
213
232
  const dir = path.join(ROOT, 'build', 'include');
214
- const dest = path.join(dir, `node-${process.version}`, 'include', 'node');
233
+ const dest = path.join(dir, 'node');
215
234
  if (fs.existsSync(path.join(dest, 'node.h'))) {
216
- console.log('Node headers:', dest);
235
+ log('Node headers:', dest);
217
236
  return dest;
218
237
  } else {
219
- console.log(`Could not find Node headers at ${include}, downloading...`);
238
+ log(`Could not find Node headers at ${include}, downloading...`);
220
239
  }
221
240
 
222
241
  try {
@@ -227,31 +246,39 @@ const downloadHeaders = async () => {
227
246
 
228
247
  const url = process.release.headersUrl;
229
248
  const targz = path.join(dir, path.basename(url));
249
+ const unpacked = path.join(dir, `node-${process.version}`, 'include');
230
250
 
231
- console.log(`Downloading Node headers from ${url} to ${targz}`);
232
- await download(url, targz);
233
- await unpack(targz, dir);
251
+ log(`Downloading Node headers from ${url} to ${targz}`);
234
252
 
235
- console.log('Node headers:', dest);
253
+ try {
254
+ await download(url, targz);
255
+ await unpack(targz, dir);
256
+ fs.renameSync(path.join(unpacked, 'node'), dest);
236
257
 
237
- return dest;
258
+ log('Node headers:', dest);
259
+
260
+ return dest;
261
+ } finally {
262
+ try { fs.rmSync(targz); } catch {}
263
+ try { fs.rmSync(unpacked, {recursive: true}); } catch {}
264
+ }
238
265
  };
239
266
 
240
267
  const downloadImportLib = async () => {
241
268
  const library = path.resolve(process.execPath, '..', 'node.lib');
242
269
  if (fs.existsSync(path.join(library, 'node.h'))) {
243
- console.log('Node import library:', library);
270
+ log('Node import library:', library);
244
271
  return library;
245
272
  }
246
273
 
247
274
  const dir = path.join(ROOT, 'build', 'lib');
248
- const url = new URL('./win-x64/node.lib', process.release.headersUrl).href;
275
+ const url = process.release.libUrl;
249
276
  const dest = path.join(dir, path.basename(url));
250
277
  if (fs.existsSync(path.join(dest))) {
251
- console.log('Node import library:', dest);
278
+ log('Node import library:', dest);
252
279
  return dest;
253
280
  } else {
254
- console.log(`Could not find Node import library at ${library}, downloading...`);
281
+ log(`Could not find Node import library at ${library}, downloading...`);
255
282
  }
256
283
 
257
284
  try {
@@ -260,24 +287,41 @@ const downloadImportLib = async () => {
260
287
  if (err.code !== 'EEXIST') throw err;
261
288
  }
262
289
 
263
- console.log(`Downloading Node import library from ${url} to ${dest}`);
290
+ log(`Downloading Node import library from ${url} to ${dest}`);
264
291
  await download(url, dest);
265
- console.log('Node import library:', dest);
292
+ log('Node import library:', dest);
266
293
 
267
294
  return dest;
268
295
  };
269
296
 
270
297
  (async () => {
271
- const options = (process.argv[2] || '').startsWith('--options=')
272
- ? process.argv[2].slice(10).split(' ') : undefined;
273
- if (process.argv.length > 3 ||
274
- process.argv.length === 3 && !(process.argv[2] === '--zig' || options)) {
298
+ let only = false;
299
+ let options = undefined;
300
+ let error = false;
301
+ for (let i = 2; i < process.argv.length; i++) {
302
+ switch (process.argv[i]) {
303
+ case "--silent": {
304
+ SILENT = true;
305
+ break;
306
+ }
307
+ case "--zig": {
308
+ if (options || only) error = true;
309
+ only = true;
310
+ break;
311
+ }
312
+ default: {
313
+ if (options || only || !process.argv[i].startsWith('--options=')) error = true;
314
+ options = process.argv[i].slice(10).split(' ');
315
+ }
316
+ }
317
+ }
318
+ if (error) {
275
319
  console.error('Invalid arguments');
276
320
  process.exit(1);
277
321
  }
278
322
 
279
323
  const zig = await install();
280
- if (process.argv[2] === '--zig') process.exit(0);
324
+ if (only) process.exit(0);
281
325
 
282
326
  let tmp;
283
327
  try {
@@ -296,6 +340,7 @@ const downloadImportLib = async () => {
296
340
  const libs = path.join(ROOT, 'build', 'lib');
297
341
  if (fs.existsSync(libs)) {
298
342
  for (const file of fs.readdirSync(libs)) {
343
+ if (!file.startsWith('pkmn')) continue;
299
344
  const type = path.extname(file).slice(1);
300
345
  if (type !== 'node' && type !== 'wasm') continue;
301
346
  // If we don't copy the addon before loading it Windows will return an
@@ -309,14 +354,18 @@ const downloadImportLib = async () => {
309
354
  node = true;
310
355
  if (!options) {
311
356
  const addon = require(copy);
312
- if (addon.options.showdown) opts.push('-Dshowdown');
313
- if (addon.options.trace) opts.push('-Dtrace');
357
+ if (addon.engine.options.showdown) opts.push('-Dshowdown');
358
+ if (addon.engine.options.log) opts.push('-Dlog');
359
+ if (addon.engine.options.chance) opts.push('-Dchance');
360
+ if (addon.engine.options.calc) opts.push('-Dcalc');
314
361
  }
315
362
  } else if (!options) {
316
363
  const addon = await WebAssembly.instantiate(fs.readFileSync(copy));
317
364
  const values = new Uint8Array(addon.instance.exports.memory.buffer);
318
365
  if (values[addon.instance.exports.SHOWDOWN.value]) opts.push('-Dshowdown');
319
- if (values[addon.instance.exports.TRACE.value]) opts.push('-Dtrace');
366
+ if (values[addon.instance.exports.LOG.value]) opts.push('-Dlog');
367
+ if (values[addon.instance.exports.CHANCE.value]) opts.push('-Dchance');
368
+ if (values[addon.instance.exports.CALC.value]) opts.push('-Dcalc');
320
369
  }
321
370
  const key = `${type} ${opts.sort().join(' ')}`;
322
371
  if (!configs.has(key)) configs.set(key, {type, options: opts});
@@ -327,8 +376,9 @@ const downloadImportLib = async () => {
327
376
  // either the default options or whatever was passed in
328
377
  if (!configs.size) {
329
378
  node = true;
330
- configs.set('node', {type: 'node', options: options || ['-Dshowdown']});
331
- configs.set('wasm', {type: 'wasm', options: options || ['-Dshowdown']});
379
+ const DEFAULT = ['-Dshowdown'];
380
+ configs.set('node', {type: 'node', options: options || DEFAULT});
381
+ configs.set('wasm', {type: 'wasm', options: options || DEFAULT});
332
382
  }
333
383
 
334
384
  const headers = node ? await downloadHeaders() : undefined;
@@ -338,8 +388,10 @@ const downloadImportLib = async () => {
338
388
  const args = ['build', '-p', 'build', ...opts];
339
389
  if (!process.env.DEBUG_PKMN_ENGINE) args.push('-Doptimize=ReleaseFast', '-Dstrip');
340
390
  if (config.type === 'node') {
341
- args.push(`-Dnode-headers=${headers}`);
342
- if (process.platform === 'win32') args.push(`-Dnode-import-library=${lib}`);
391
+ args.push(`-Dnode-headers=${path.relative(ROOT, headers)}`);
392
+ if (process.platform === 'win32') {
393
+ args.push(`-Dnode-import-library=${path.relative(ROOT, lib)}`);
394
+ }
343
395
  } else {
344
396
  args.push('-Dwasm');
345
397
  }
@@ -347,15 +399,21 @@ const downloadImportLib = async () => {
347
399
  opts.includes('-Dshowdown') || opts.includes('-Dshowdown=true') ? '-showdown' : '';
348
400
  const flags = opts.length ? ` (${opts.join(' ')})` : '';
349
401
  const artifact = path.join('build', 'lib', `pkmn${suffix}.${config.type}`);
350
- console.log(`Building ${artifact}${flags}`);
402
+ log(`Building ${artifact}${flags}`);
351
403
  sh(zig, args);
352
404
  // TODO: ziglang/zig#14647 broke emit_to so we get to rename the file ourselves...
353
405
  if (config.type === 'node') {
354
406
  const prefix = process.platform === 'win32' ? '' : 'lib';
355
407
  const ext = process.platform === 'darwin'
356
408
  ? 'dylib' : process.platform === 'win32' ? 'dll' : 'so';
357
- const actual = path.join('build', 'lib', `${prefix}pkmn${suffix}.node.${ext}`);
358
- fs.renameSync(actual, artifact);
409
+ try {
410
+ const actual = path.join(ROOT, 'build', 'lib', `${prefix}pkmn${suffix}.node.${ext}`);
411
+ fs.renameSync(actual, artifact);
412
+ } catch {
413
+ // ziglang/zig#19743 changed this path
414
+ const actual = path.join(ROOT, 'build', 'bin', `${prefix}pkmn${suffix}.node.${ext}`);
415
+ fs.renameSync(actual, artifact);
416
+ }
359
417
  }
360
418
  }
361
419
  })().catch(e => {
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ try {
5
+ require('source-map-support').install();
6
+ } catch (err) {
7
+ if (err.code !== 'MODULE_NOT_FOUND') throw err;
8
+ }
9
+
10
+ const {execFileSync} = require('child_process');
11
+ const {readFileSync} = require('fs');
12
+ const {join, resolve} = require('path');
13
+
14
+ const ROOT = resolve(__dirname, '..', '..');
15
+ const packageJSON = JSON.parse(readFileSync(join(ROOT, 'package.json'), 'utf8'));
16
+
17
+ const missing = [];
18
+ for (const dep of ['@pkmn/img', 'html-minifier', 'esbuild']) {
19
+ try {
20
+ require.resolve(dep);
21
+ } catch (e) {
22
+ if (e.code !== 'MODULE_NOT_FOUND') throw e;
23
+ missing.push(`${dep}@${packageJSON.devDependencies[dep]}`);
24
+ }
25
+ }
26
+
27
+ let Dex = undefined;
28
+ try {
29
+ Dex = require('@pkmn/sim').Dex;
30
+ } catch (err) {
31
+ if (err.code !== 'MODULE_NOT_FOUND') throw err;
32
+ try {
33
+ Dex = require('@pkmn/dex').Dex;
34
+ } catch (e) {
35
+ if (e.code !== 'MODULE_NOT_FOUND') throw e;
36
+ missing.push(`@pkmn/dex@${packageJSON.dependencies['@pkmn/data']}`);
37
+ }
38
+ }
39
+
40
+ if (missing.length) {
41
+ if (+/^v(\d+)/.exec(process.version)[1] < 16) {
42
+ console.error('pkmn-debug requires Node v16+');
43
+ process.exit(1);
44
+ }
45
+
46
+ execFileSync('npm', ['install', ...missing, '--global'], {encoding: 'utf8'});
47
+
48
+ const node_modules = execFileSync('npm', ['root', '--global'], {encoding: 'utf8'}).trim();
49
+ if (!process.env.NODE_PATH || !process.env.NODE_PATH.includes(node_modules)) {
50
+ console.error(`NODE_PATH must include npm's global node_modules directory: '${node_modules}'`);
51
+ process.exit(1);
52
+ }
53
+ }
54
+
55
+ const {Generations} = require('@pkmn/data');
56
+
57
+ const {run} = require('../../build/tools/debug');
58
+
59
+ run(new Generations(Dex)).catch(err => {
60
+ console.error(err.message);
61
+ process.exit(1);
62
+ });