@pkmn/engine 0.1.0-dev.84cc1a02 → 0.1.0-dev.886adbe3
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/LICENSE +1 -3
- package/README.md +137 -71
- package/build/pkg/addon.d.ts +7 -0
- package/build/pkg/addon.js +111 -0
- package/build/pkg/addon.js.map +1 -0
- package/build/pkg/data/ids.json +12 -12
- package/build/pkg/data/layout.json +27 -5
- package/build/pkg/data/protocol.json +69 -12
- package/build/pkg/data.d.ts +5 -6
- package/build/pkg/data.js +3 -5
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.d.ts +5 -4
- package/build/pkg/gen1.js +49 -33
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +20 -20
- package/build/pkg/index.js +2 -5
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +4 -2
- package/build/pkg/protocol.js +65 -44
- package/build/pkg/protocol.js.map +1 -1
- package/build/test/display.js +405 -0
- package/build/test/display.js.map +1 -0
- package/build/tools/debug.js +134 -0
- package/build/tools/debug.js.map +1 -0
- package/build.zig +300 -153
- package/package.json +89 -46
- package/src/bin/install-pkmn-engine +71 -37
- package/src/bin/pkmn-debug +62 -0
- package/src/lib/common/array.zig +77 -0
- package/src/lib/common/battle.zig +17 -0
- package/src/lib/common/data.zig +19 -31
- package/src/lib/common/debug.zig +23 -13
- package/src/lib/common/js.zig +120 -0
- package/src/lib/common/optional.zig +71 -0
- package/src/lib/common/options.zig +14 -3
- package/src/lib/common/protocol.zig +947 -403
- package/src/lib/common/rational.zig +447 -0
- package/src/lib/common/rng.zig +31 -22
- package/src/lib/common/util.zig +61 -0
- package/src/lib/gen1/calc.zig +804 -0
- package/src/lib/gen1/chance.zig +1167 -0
- package/src/lib/gen1/data/moves.zig +202 -190
- package/src/lib/gen1/data/species.zig +5 -5
- package/src/lib/gen1/data/types.zig +10 -10
- package/src/lib/gen1/data.zig +98 -83
- package/src/lib/gen1/helpers.zig +142 -40
- package/src/lib/gen1/mechanics.zig +1296 -871
- package/src/lib/gen2/calc.zig +161 -0
- package/src/lib/gen2/chance.zig +902 -0
- package/src/lib/gen2/data/items.zig +14 -20
- package/src/lib/gen2/data/moves.zig +664 -570
- package/src/lib/gen2/data/species.zig +2 -2
- package/src/lib/gen2/data/types.zig +137 -34
- package/src/lib/gen2/data.zig +129 -90
- package/src/lib/gen2/generated.zig +806 -0
- package/src/lib/gen2/helpers.zig +54 -32
- package/src/lib/gen2/mechanics.zig +3564 -15
- package/src/lib/node.zig +131 -0
- package/src/lib/pkmn.zig +88 -12
- package/src/lib/wasm.zig +13 -0
- package/src/test/display/pkmn.html.tmpl +368 -0
- package/src/lib/binding/node.zig +0 -229
- package/src/lib/binding/wasm.zig +0 -10
- package/src/lib/gen1/README.md +0 -778
- package/src/lib/gen2/README.md +0 -309
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pkmn/engine",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.886adbe3",
|
|
4
4
|
"description": "A minimal, complete, Pokémon battle simulation engine optimized for performance",
|
|
5
5
|
"repository": "github:pkmn/engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -9,86 +9,109 @@
|
|
|
9
9
|
"types": "build/pkg/index.d.ts",
|
|
10
10
|
"files": [
|
|
11
11
|
"build.zig",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
12
|
+
"build/pkg/data.d.ts",
|
|
13
|
+
"build/pkg/data.js.map",
|
|
14
|
+
"build/pkg/addon.d.ts",
|
|
15
|
+
"build/pkg/addon.js.map",
|
|
16
|
+
"build/pkg/addon.js",
|
|
17
|
+
"build/pkg/data.js",
|
|
18
|
+
"build/pkg/data/ids.json",
|
|
19
|
+
"build/pkg/data/layout.json",
|
|
20
|
+
"build/pkg/data/protocol.json",
|
|
21
|
+
"build/pkg/gen1.d.ts",
|
|
22
|
+
"build/pkg/gen1.js.map",
|
|
23
|
+
"build/pkg/gen1.js",
|
|
24
|
+
"build/pkg/index.d.ts",
|
|
25
|
+
"build/pkg/index.js.map",
|
|
26
|
+
"build/pkg/index.js",
|
|
27
|
+
"build/pkg/protocol.d.ts",
|
|
28
|
+
"build/pkg/protocol.js.map",
|
|
29
|
+
"build/pkg/protocol.js",
|
|
30
|
+
"build/test/display.js.map",
|
|
31
|
+
"build/test/display.js",
|
|
32
|
+
"build/tools/debug.js.map",
|
|
33
|
+
"build/tools/debug.js",
|
|
34
|
+
"src/lib/common/battle.zig",
|
|
15
35
|
"src/lib/common/data.zig",
|
|
16
36
|
"src/lib/common/debug.zig",
|
|
37
|
+
"src/lib/common/js.zig",
|
|
38
|
+
"src/lib/common/array.zig",
|
|
39
|
+
"src/lib/common/optional.zig",
|
|
17
40
|
"src/lib/common/options.zig",
|
|
18
41
|
"src/lib/common/protocol.zig",
|
|
42
|
+
"src/lib/common/rational.zig",
|
|
19
43
|
"src/lib/common/rng.zig",
|
|
44
|
+
"src/lib/common/util.zig",
|
|
45
|
+
"src/lib/gen1/calc.zig",
|
|
46
|
+
"src/lib/gen1/chance.zig",
|
|
47
|
+
"src/lib/gen1/data.zig",
|
|
20
48
|
"src/lib/gen1/data/moves.zig",
|
|
21
49
|
"src/lib/gen1/data/species.zig",
|
|
22
50
|
"src/lib/gen1/data/types.zig",
|
|
23
|
-
"src/lib/gen1/data.zig",
|
|
24
51
|
"src/lib/gen1/helpers.zig",
|
|
25
52
|
"src/lib/gen1/mechanics.zig",
|
|
53
|
+
"src/lib/gen2/calc.zig",
|
|
54
|
+
"src/lib/gen2/chance.zig",
|
|
55
|
+
"src/lib/gen2/data.zig",
|
|
26
56
|
"src/lib/gen2/data/items.zig",
|
|
27
57
|
"src/lib/gen2/data/moves.zig",
|
|
28
58
|
"src/lib/gen2/data/species.zig",
|
|
29
59
|
"src/lib/gen2/data/types.zig",
|
|
30
|
-
"src/lib/gen2/
|
|
60
|
+
"src/lib/gen2/generated.zig",
|
|
31
61
|
"src/lib/gen2/helpers.zig",
|
|
32
62
|
"src/lib/gen2/mechanics.zig",
|
|
63
|
+
"src/lib/node.zig",
|
|
33
64
|
"src/lib/pkmn.zig",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
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"
|
|
65
|
+
"src/lib/wasm.zig",
|
|
66
|
+
"src/test/display/pkmn.html.tmpl"
|
|
49
67
|
],
|
|
50
68
|
"engines": {
|
|
51
69
|
"node": ">=16.0.0"
|
|
52
70
|
},
|
|
53
71
|
"bin": {
|
|
54
|
-
"install-pkmn-engine": "src/bin/install-pkmn-engine"
|
|
72
|
+
"install-pkmn-engine": "src/bin/install-pkmn-engine",
|
|
73
|
+
"pkmn-debug": "src/bin/pkmn-debug"
|
|
55
74
|
},
|
|
56
75
|
"publishConfig": {
|
|
57
76
|
"access": "public"
|
|
58
77
|
},
|
|
59
78
|
"dependencies": {
|
|
60
|
-
"@pkmn/data": "^0.
|
|
61
|
-
"@pkmn/protocol": "^0.6.
|
|
79
|
+
"@pkmn/data": "^0.9.13",
|
|
80
|
+
"@pkmn/protocol": "^0.6.26"
|
|
62
81
|
},
|
|
63
82
|
"devDependencies": {
|
|
64
|
-
"@pkmn/eslint-config": "^3.0
|
|
65
|
-
"@pkmn/img": "^0.2.
|
|
66
|
-
"@pkmn/sets": "^5.
|
|
67
|
-
"@pkmn/sim": "0.
|
|
68
|
-
"@types/html-minifier": "^4.0.
|
|
69
|
-
"@types/jest": "^29.5.
|
|
70
|
-
"@types/minimist": "^1.2.
|
|
71
|
-
"@types/mustache": "^4.2.
|
|
72
|
-
"@types/node": "^
|
|
73
|
-
"@
|
|
74
|
-
"
|
|
75
|
-
"
|
|
83
|
+
"@pkmn/eslint-config": "^8.3.0",
|
|
84
|
+
"@pkmn/img": "^0.2.32",
|
|
85
|
+
"@pkmn/sets": "^5.1.2",
|
|
86
|
+
"@pkmn/sim": "0.9.13",
|
|
87
|
+
"@types/html-minifier": "^4.0.5",
|
|
88
|
+
"@types/jest": "^29.5.12",
|
|
89
|
+
"@types/minimist": "^1.2.5",
|
|
90
|
+
"@types/mustache": "^4.2.5",
|
|
91
|
+
"@types/node": "^22.5.3",
|
|
92
|
+
"@types/semver": "^7.5.8",
|
|
93
|
+
"@vitest/coverage-v8": "^2.0.5",
|
|
94
|
+
"binaryen": "^118.0.0",
|
|
95
|
+
"eslint": "<=8",
|
|
76
96
|
"html-minifier": "^4.0.0",
|
|
77
|
-
"json-stringify-pretty-compact": "
|
|
97
|
+
"json-stringify-pretty-compact": "4.0.0",
|
|
78
98
|
"minimist": "^1.2.8",
|
|
79
99
|
"mustache": "^4.2.0",
|
|
100
|
+
"semver": "^7.6.3",
|
|
80
101
|
"source-map-support": "^0.5.21",
|
|
102
|
+
"table": "^6.8.2",
|
|
81
103
|
"trakr": "^0.2.0",
|
|
82
|
-
"typescript": "^5.
|
|
83
|
-
"vitest": "^0.
|
|
104
|
+
"typescript": "^5.5.4",
|
|
105
|
+
"vitest": "^2.0.5"
|
|
84
106
|
},
|
|
85
107
|
"scripts": {
|
|
86
|
-
"lint": "eslint --cache src --ext ts,js && eslint src/bin
|
|
87
|
-
"fix": "eslint --fix src --ext ts,js && eslint --fix src/bin
|
|
108
|
+
"lint": "eslint --cache src --ext ts,js && eslint src/bin/*",
|
|
109
|
+
"fix": "eslint --fix src --ext ts,js && eslint --fix src/bin/*",
|
|
88
110
|
"compile": "tsc -p .",
|
|
89
111
|
"build": "npm run compile",
|
|
90
112
|
"test": "vitest src/pkg",
|
|
91
113
|
"test:integration": "vitest src/test",
|
|
114
|
+
"debug": "npm run compile && node build/tools/debug",
|
|
92
115
|
"fuzz": "npm run compile && node build/test/fuzz",
|
|
93
116
|
"generate": "npm run compile && node build/tools/generate",
|
|
94
117
|
"release": "npm run compile && node build/tools/release",
|
|
@@ -101,7 +124,7 @@
|
|
|
101
124
|
"ignorePatterns": [
|
|
102
125
|
"dist/",
|
|
103
126
|
"node_modules/",
|
|
104
|
-
"
|
|
127
|
+
"examples/zig",
|
|
105
128
|
"build/"
|
|
106
129
|
],
|
|
107
130
|
"env": {
|
|
@@ -117,10 +140,18 @@
|
|
|
117
140
|
"parserOptions": {
|
|
118
141
|
"project": [
|
|
119
142
|
"./tsconfig.json",
|
|
120
|
-
"./
|
|
143
|
+
"./examples/js/tsconfig.json"
|
|
121
144
|
]
|
|
122
145
|
}
|
|
123
146
|
},
|
|
147
|
+
{
|
|
148
|
+
"files": [
|
|
149
|
+
"src/test/display.ts"
|
|
150
|
+
],
|
|
151
|
+
"rules": {
|
|
152
|
+
"@typescript-eslint/no-unnecessary-type-assertion": "off"
|
|
153
|
+
}
|
|
154
|
+
},
|
|
124
155
|
{
|
|
125
156
|
"files": [
|
|
126
157
|
"src/pkg/index.ts",
|
|
@@ -130,7 +161,8 @@
|
|
|
130
161
|
"rules": {
|
|
131
162
|
"no-control-regex": "off",
|
|
132
163
|
"@typescript-eslint/no-empty-interface": "off",
|
|
133
|
-
"@typescript-eslint/no-shadow": "off"
|
|
164
|
+
"@typescript-eslint/no-shadow": "off",
|
|
165
|
+
"@typescript-eslint/no-unsafe-declaration-merging": "off"
|
|
134
166
|
}
|
|
135
167
|
},
|
|
136
168
|
{
|
|
@@ -146,12 +178,23 @@
|
|
|
146
178
|
"src/test/benchmark*.ts"
|
|
147
179
|
],
|
|
148
180
|
"rules": {
|
|
149
|
-
"@typescript-eslint/no-unused-vars": "off"
|
|
181
|
+
"@typescript-eslint/no-unused-vars": "off",
|
|
182
|
+
"@typescript-eslint/no-redundant-type-constituents": "off"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"files": [
|
|
187
|
+
"src/pkg/protocol.test.ts"
|
|
188
|
+
],
|
|
189
|
+
"rules": {
|
|
190
|
+
"jest/no-standalone-expect": "off",
|
|
191
|
+
"jest/no-conditional-expect": "off"
|
|
150
192
|
}
|
|
151
193
|
},
|
|
152
194
|
{
|
|
153
195
|
"files": [
|
|
154
|
-
"src/test/*.test.ts"
|
|
196
|
+
"src/test/*.test.ts",
|
|
197
|
+
"src/test/regression/*.test.ts"
|
|
155
198
|
],
|
|
156
199
|
"rules": {
|
|
157
200
|
"jest/no-standalone-expect": "off"
|
|
@@ -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
|
|
13
|
+
const ZIG_VERSION = {major: 0, minor: 11, 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
|
-
|
|
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
|
-
|
|
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
|
|
@@ -120,10 +122,10 @@ const find = zig => {
|
|
|
120
122
|
(!ZIG_VERSION.dev || (dev && dev >= ZIG_VERSION.dev)));
|
|
121
123
|
|
|
122
124
|
if (compatible) {
|
|
123
|
-
|
|
125
|
+
log('Found existing compatible Zig executable:', zig_exe);
|
|
124
126
|
return zig_exe;
|
|
125
127
|
} else {
|
|
126
|
-
|
|
128
|
+
log(`Existing Zig executable is not compatible (${version} < ${VERSION}):`, zig_exe);
|
|
127
129
|
}
|
|
128
130
|
} catch (err) {
|
|
129
131
|
if (err.code !== 'ENOENT') throw err;
|
|
@@ -161,18 +163,20 @@ const install = async () => {
|
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
const index = JSON.parse(await fetch(INDEX));
|
|
164
|
-
|
|
165
|
-
const
|
|
166
|
+
// TODO: ziglang/zig#17768
|
|
167
|
+
// const version = Object.keys(index)[+!ZIG_VERSION.dev];
|
|
168
|
+
const version = VERSION;
|
|
169
|
+
const release = index[VERSION][`${arch}-${platform}`];
|
|
166
170
|
const url = release.tarball;
|
|
167
171
|
|
|
168
172
|
let base = path.basename(url);
|
|
169
173
|
const archive = path.join(dir, path.basename(url));
|
|
170
174
|
|
|
171
|
-
|
|
175
|
+
log(`Downloading Zig tarball from ${url} to ${archive}`);
|
|
172
176
|
try {
|
|
173
177
|
await download(url, archive, release.shasum);
|
|
174
178
|
|
|
175
|
-
|
|
179
|
+
log(`Extracting tarball and installing to ${dir}`);
|
|
176
180
|
await unpack(archive, dir);
|
|
177
181
|
if (archive.endsWith('.zip')) {
|
|
178
182
|
base = base.slice(0, -4);
|
|
@@ -187,17 +191,17 @@ const install = async () => {
|
|
|
187
191
|
} catch (err) {
|
|
188
192
|
if (err.code !== 'ENOENT') throw err;
|
|
189
193
|
}
|
|
190
|
-
|
|
194
|
+
log(`Zig${version === 'master' ? '' : ` v${version}`} executable:`, zig,
|
|
191
195
|
'(this version of Zig will be retained to speed up future updates)');
|
|
192
196
|
const [pre, post] = tty.isatty(1) ? ['\x1b[1m\x1b[35m', '\x1b[0m'] : ['', ''];
|
|
193
|
-
|
|
197
|
+
log(
|
|
194
198
|
`${pre}Consider moving the ${path.dirname(zig)} directory and adding it to your PATH`,
|
|
195
199
|
`to use Zig on other projects, or delete this if you wish to save space.${post}`
|
|
196
200
|
);
|
|
197
201
|
|
|
198
202
|
return zig;
|
|
199
203
|
} finally {
|
|
200
|
-
|
|
204
|
+
log(`Cleaning up ${archive}`);
|
|
201
205
|
try { fs.rmSync(archive); } catch {}
|
|
202
206
|
}
|
|
203
207
|
};
|
|
@@ -206,17 +210,17 @@ const install = async () => {
|
|
|
206
210
|
const downloadHeaders = async () => {
|
|
207
211
|
const include = path.resolve(process.execPath, '..', '..', 'include', 'node');
|
|
208
212
|
if (fs.existsSync(path.join(include, 'node.h'))) {
|
|
209
|
-
|
|
213
|
+
log('Node headers:', include);
|
|
210
214
|
return include;
|
|
211
215
|
}
|
|
212
216
|
|
|
213
217
|
const dir = path.join(ROOT, 'build', 'include');
|
|
214
218
|
const dest = path.join(dir, 'node');
|
|
215
219
|
if (fs.existsSync(path.join(dest, 'node.h'))) {
|
|
216
|
-
|
|
220
|
+
log('Node headers:', dest);
|
|
217
221
|
return dest;
|
|
218
222
|
} else {
|
|
219
|
-
|
|
223
|
+
log(`Could not find Node headers at ${include}, downloading...`);
|
|
220
224
|
}
|
|
221
225
|
|
|
222
226
|
try {
|
|
@@ -229,14 +233,14 @@ const downloadHeaders = async () => {
|
|
|
229
233
|
const targz = path.join(dir, path.basename(url));
|
|
230
234
|
const unpacked = path.join(dir, `node-${process.version}`, 'include');
|
|
231
235
|
|
|
232
|
-
|
|
236
|
+
log(`Downloading Node headers from ${url} to ${targz}`);
|
|
233
237
|
|
|
234
238
|
try {
|
|
235
239
|
await download(url, targz);
|
|
236
240
|
await unpack(targz, dir);
|
|
237
241
|
fs.renameSync(path.join(unpacked, 'node'), dest);
|
|
238
242
|
|
|
239
|
-
|
|
243
|
+
log('Node headers:', dest);
|
|
240
244
|
|
|
241
245
|
return dest;
|
|
242
246
|
} finally {
|
|
@@ -248,7 +252,7 @@ const downloadHeaders = async () => {
|
|
|
248
252
|
const downloadImportLib = async () => {
|
|
249
253
|
const library = path.resolve(process.execPath, '..', 'node.lib');
|
|
250
254
|
if (fs.existsSync(path.join(library, 'node.h'))) {
|
|
251
|
-
|
|
255
|
+
log('Node import library:', library);
|
|
252
256
|
return library;
|
|
253
257
|
}
|
|
254
258
|
|
|
@@ -256,10 +260,10 @@ const downloadImportLib = async () => {
|
|
|
256
260
|
const url = new URL('./win-x64/node.lib', process.release.headersUrl).href;
|
|
257
261
|
const dest = path.join(dir, path.basename(url));
|
|
258
262
|
if (fs.existsSync(path.join(dest))) {
|
|
259
|
-
|
|
263
|
+
log('Node import library:', dest);
|
|
260
264
|
return dest;
|
|
261
265
|
} else {
|
|
262
|
-
|
|
266
|
+
log(`Could not find Node import library at ${library}, downloading...`);
|
|
263
267
|
}
|
|
264
268
|
|
|
265
269
|
try {
|
|
@@ -268,24 +272,41 @@ const downloadImportLib = async () => {
|
|
|
268
272
|
if (err.code !== 'EEXIST') throw err;
|
|
269
273
|
}
|
|
270
274
|
|
|
271
|
-
|
|
275
|
+
log(`Downloading Node import library from ${url} to ${dest}`);
|
|
272
276
|
await download(url, dest);
|
|
273
|
-
|
|
277
|
+
log('Node import library:', dest);
|
|
274
278
|
|
|
275
279
|
return dest;
|
|
276
280
|
};
|
|
277
281
|
|
|
278
282
|
(async () => {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
+
let only = false;
|
|
284
|
+
let options = undefined;
|
|
285
|
+
let error = false;
|
|
286
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
287
|
+
switch (process.argv[i]) {
|
|
288
|
+
case "--silent": {
|
|
289
|
+
SILENT = true;
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
case "--zig": {
|
|
293
|
+
if (options || only) error = true;
|
|
294
|
+
only = true;
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
default: {
|
|
298
|
+
if (options || only || !process.argv[i].startsWith('--options=')) error = true;
|
|
299
|
+
options = process.argv[i].slice(10).split(' ');
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (error) {
|
|
283
304
|
console.error('Invalid arguments');
|
|
284
305
|
process.exit(1);
|
|
285
306
|
}
|
|
286
307
|
|
|
287
308
|
const zig = await install();
|
|
288
|
-
if (
|
|
309
|
+
if (only) process.exit(0);
|
|
289
310
|
|
|
290
311
|
let tmp;
|
|
291
312
|
try {
|
|
@@ -317,14 +338,18 @@ const downloadImportLib = async () => {
|
|
|
317
338
|
node = true;
|
|
318
339
|
if (!options) {
|
|
319
340
|
const addon = require(copy);
|
|
320
|
-
if (addon.options.showdown) opts.push('-Dshowdown');
|
|
321
|
-
if (addon.options.
|
|
341
|
+
if (addon.engine.options.showdown) opts.push('-Dshowdown');
|
|
342
|
+
if (addon.engine.options.log) opts.push('-Dlog');
|
|
343
|
+
if (addon.engine.options.chance) opts.push('-Dchance');
|
|
344
|
+
if (addon.engine.options.calc) opts.push('-Dcalc');
|
|
322
345
|
}
|
|
323
346
|
} else if (!options) {
|
|
324
347
|
const addon = await WebAssembly.instantiate(fs.readFileSync(copy));
|
|
325
348
|
const values = new Uint8Array(addon.instance.exports.memory.buffer);
|
|
326
349
|
if (values[addon.instance.exports.SHOWDOWN.value]) opts.push('-Dshowdown');
|
|
327
|
-
if (values[addon.instance.exports.
|
|
350
|
+
if (values[addon.instance.exports.LOG.value]) opts.push('-Dlog');
|
|
351
|
+
if (values[addon.instance.exports.CHANCE.value]) opts.push('-Dchance');
|
|
352
|
+
if (values[addon.instance.exports.CALC.value]) opts.push('-Dcalc');
|
|
328
353
|
}
|
|
329
354
|
const key = `${type} ${opts.sort().join(' ')}`;
|
|
330
355
|
if (!configs.has(key)) configs.set(key, {type, options: opts});
|
|
@@ -335,8 +360,9 @@ const downloadImportLib = async () => {
|
|
|
335
360
|
// either the default options or whatever was passed in
|
|
336
361
|
if (!configs.size) {
|
|
337
362
|
node = true;
|
|
338
|
-
|
|
339
|
-
configs.set('
|
|
363
|
+
const DEFAULT = ['-Dshowdown'];
|
|
364
|
+
configs.set('node', {type: 'node', options: options || DEFAULT});
|
|
365
|
+
configs.set('wasm', {type: 'wasm', options: options || DEFAULT});
|
|
340
366
|
}
|
|
341
367
|
|
|
342
368
|
const headers = node ? await downloadHeaders() : undefined;
|
|
@@ -346,8 +372,10 @@ const downloadImportLib = async () => {
|
|
|
346
372
|
const args = ['build', '-p', 'build', ...opts];
|
|
347
373
|
if (!process.env.DEBUG_PKMN_ENGINE) args.push('-Doptimize=ReleaseFast', '-Dstrip');
|
|
348
374
|
if (config.type === 'node') {
|
|
349
|
-
args.push(`-Dnode-headers=${headers}`);
|
|
350
|
-
if (process.platform === 'win32')
|
|
375
|
+
args.push(`-Dnode-headers=${path.relative(ROOT, headers)}`);
|
|
376
|
+
if (process.platform === 'win32') {
|
|
377
|
+
args.push(`-Dnode-import-library=${path.relative(ROOT, lib)}`);
|
|
378
|
+
}
|
|
351
379
|
} else {
|
|
352
380
|
args.push('-Dwasm');
|
|
353
381
|
}
|
|
@@ -355,15 +383,21 @@ const downloadImportLib = async () => {
|
|
|
355
383
|
opts.includes('-Dshowdown') || opts.includes('-Dshowdown=true') ? '-showdown' : '';
|
|
356
384
|
const flags = opts.length ? ` (${opts.join(' ')})` : '';
|
|
357
385
|
const artifact = path.join('build', 'lib', `pkmn${suffix}.${config.type}`);
|
|
358
|
-
|
|
386
|
+
log(`Building ${artifact}${flags}`);
|
|
359
387
|
sh(zig, args);
|
|
360
388
|
// TODO: ziglang/zig#14647 broke emit_to so we get to rename the file ourselves...
|
|
361
389
|
if (config.type === 'node') {
|
|
362
390
|
const prefix = process.platform === 'win32' ? '' : 'lib';
|
|
363
391
|
const ext = process.platform === 'darwin'
|
|
364
392
|
? 'dylib' : process.platform === 'win32' ? 'dll' : 'so';
|
|
365
|
-
|
|
366
|
-
|
|
393
|
+
try {
|
|
394
|
+
const actual = path.join(ROOT, 'build', 'lib', `${prefix}pkmn${suffix}.node.${ext}`);
|
|
395
|
+
fs.renameSync(actual, artifact);
|
|
396
|
+
} catch (err) {
|
|
397
|
+
// ziglang/zig#19743 changed this path
|
|
398
|
+
const actual = path.join(ROOT, 'build', 'bin', `${prefix}pkmn${suffix}.node.${ext}`);
|
|
399
|
+
fs.renameSync(actual, artifact);
|
|
400
|
+
}
|
|
367
401
|
}
|
|
368
402
|
}
|
|
369
403
|
})().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', 'mustache']) {
|
|
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
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
|
|
3
|
+
const expectEqual = std.testing.expectEqual;
|
|
4
|
+
const assert = std.debug.assert;
|
|
5
|
+
|
|
6
|
+
const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
|
|
7
|
+
const Enum = if (@hasField(std.builtin.Type, "enum")) .@"enum" else .Enum;
|
|
8
|
+
|
|
9
|
+
/// Helpers for working with bit-packed arrays of non-powers-of-2 types.
|
|
10
|
+
/// NOTE: ziglang/zig#12547
|
|
11
|
+
pub fn Array(comptime n: comptime_int, comptime U: type) type {
|
|
12
|
+
return struct {
|
|
13
|
+
const size = @bitSizeOf(U);
|
|
14
|
+
const options = .{ .signedness = .unsigned, .bits = size * n };
|
|
15
|
+
pub const T = @Type(if (@hasField(std.builtin.Type, "int"))
|
|
16
|
+
.{ .int = options }
|
|
17
|
+
else
|
|
18
|
+
.{ .Int = options });
|
|
19
|
+
|
|
20
|
+
/// Returns the value stored at index `i` in the array `a`.
|
|
21
|
+
pub fn get(a: T, i: usize) U {
|
|
22
|
+
assert(i < n);
|
|
23
|
+
const shift = i * size;
|
|
24
|
+
const mask: T = (1 << size) - 1;
|
|
25
|
+
const result = (a >> @intCast(shift)) & mask;
|
|
26
|
+
return switch (@typeInfo(U)) {
|
|
27
|
+
Enum => @enumFromInt(result),
|
|
28
|
+
Int => @intCast(result),
|
|
29
|
+
else => unreachable,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// Sets the value at index `i` to `val` in the array `a`.
|
|
34
|
+
pub fn set(a: T, i: usize, val: U) T {
|
|
35
|
+
assert(i < n);
|
|
36
|
+
const v: T = switch (@typeInfo(U)) {
|
|
37
|
+
Enum => @intFromEnum(val),
|
|
38
|
+
Int => @intCast(val),
|
|
39
|
+
else => unreachable,
|
|
40
|
+
};
|
|
41
|
+
const shift = i * size;
|
|
42
|
+
const mask: T = @as(T, @intCast((1 << size) - 1)) << @intCast(shift);
|
|
43
|
+
const result: T = a & ~mask;
|
|
44
|
+
return result | (v << @intCast(shift));
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
test Array {
|
|
50
|
+
const A = Array(5, u8);
|
|
51
|
+
var a: A.T = 0;
|
|
52
|
+
try expectEqual(u40, @TypeOf(a));
|
|
53
|
+
|
|
54
|
+
a = A.set(a, 4, 241);
|
|
55
|
+
try expectEqual(@as(u8, 241), A.get(a, 4));
|
|
56
|
+
a = A.set(a, 4, 1);
|
|
57
|
+
try expectEqual(@as(u8, 1), A.get(a, 4));
|
|
58
|
+
|
|
59
|
+
for (0..5) |i| a = A.set(a, i, @intCast(i));
|
|
60
|
+
for (0..5) |i| try expectEqual(@as(u8, @intCast(i)), A.get(a, i));
|
|
61
|
+
|
|
62
|
+
const Optional = @import("optional.zig").Optional;
|
|
63
|
+
|
|
64
|
+
const B = Array(4, Optional(bool));
|
|
65
|
+
var b: B.T = 0;
|
|
66
|
+
try expectEqual(u8, @TypeOf(b));
|
|
67
|
+
|
|
68
|
+
b = B.set(b, 2, .true);
|
|
69
|
+
try expectEqual(Optional(bool).None, B.get(b, 1));
|
|
70
|
+
try expectEqual(Optional(bool).true, B.get(b, 2));
|
|
71
|
+
try expectEqual(@as(u8, 0b00100000), b);
|
|
72
|
+
b = B.set(b, 2, .None);
|
|
73
|
+
b = B.set(b, 0, .false);
|
|
74
|
+
try expectEqual(Optional(bool).None, B.get(b, 2));
|
|
75
|
+
try expectEqual(Optional(bool).false, B.get(b, 0));
|
|
76
|
+
try expectEqual(@as(u8, 0b0000001), b);
|
|
77
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// Stores state required by optional features to the engine that can be passed to a generation's
|
|
2
|
+
/// `Battle.update` function. All generations generically support protocol logging (enabled via
|
|
3
|
+
/// `-Dlog`), chance actions and probability tracking (enabled via `-Dchance`), and damage
|
|
4
|
+
/// computation and chance overrides (`-Dcalc`), though the concrete types for these features are
|
|
5
|
+
/// generation dependent.
|
|
6
|
+
pub fn Options(comptime Log: type, comptime Chance: type, comptime Calc: type) type {
|
|
7
|
+
return struct { log: Log, chance: Chance, calc: Calc };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/// Helper to create a battle `Options` object with the provided `log`, `chance`, and `calc`.
|
|
11
|
+
pub fn options(
|
|
12
|
+
log: anytype,
|
|
13
|
+
chance: anytype,
|
|
14
|
+
calc: anytype,
|
|
15
|
+
) Options(@TypeOf(log), @TypeOf(chance), @TypeOf(calc)) {
|
|
16
|
+
return .{ .log = log, .chance = chance, .calc = calc };
|
|
17
|
+
}
|