@pkmn/engine 0.1.0-dev.c4dec0f7 → 0.1.0-dev.cf6f5d2c
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/README.md +50 -22
- 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.d.ts +1 -2
- package/build/pkg/data.js +3 -5
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.d.ts +3 -3
- package/build/pkg/gen1.js +11 -13
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +11 -10
- package/build/pkg/index.js.map +1 -1
- package/build/test/display.js +396 -0
- package/build/test/display.js.map +1 -0
- package/build/tools/debug.js +133 -0
- package/build/tools/debug.js.map +1 -0
- package/build.zig +24 -34
- package/package.json +40 -29
- package/src/bin/install-pkmn-engine +60 -33
- package/src/bin/pkmn-debug +62 -0
- package/src/lib/binding/node.zig +5 -5
- package/src/lib/binding/wasm.zig +3 -3
- package/src/lib/common/debug.zig +1 -0
- package/src/lib/common/options.zig +3 -3
- package/src/lib/common/protocol.zig +38 -38
- package/src/lib/gen1/README.md +65 -39
- package/src/lib/gen1/data.zig +6 -6
- package/src/lib/gen1/helpers.zig +10 -7
- package/src/lib/gen1/mechanics.zig +384 -290
- package/src/lib/gen2/data.zig +4 -4
- package/src/lib/pkmn.zig +7 -7
- package/src/test/display/pkmn.html.tmpl +368 -0
package/build.zig
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
const std = @import("std");
|
|
2
2
|
const builtin = @import("builtin");
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
pub const Options = struct { showdown: ?bool = null, trace: ?bool = null };
|
|
4
|
+
pub const Options = struct { showdown: ?bool = null, log: ?bool = null };
|
|
7
5
|
|
|
8
6
|
pub fn module(b: *std.Build, options: Options) *std.Build.Module {
|
|
9
7
|
const dirname = comptime std.fs.path.dirname(@src().file) orelse ".";
|
|
10
8
|
const build_options = b.addOptions();
|
|
11
9
|
build_options.addOption(?bool, "showdown", options.showdown);
|
|
12
|
-
build_options.addOption(?bool, "
|
|
10
|
+
build_options.addOption(?bool, "log", options.log);
|
|
13
11
|
return b.createModule(.{
|
|
14
12
|
.source_file = .{ .path = dirname ++ "/src/lib/pkmn.zig" },
|
|
15
13
|
.dependencies = &.{.{ .name = "build_options", .module = build_options.createModule() }},
|
|
@@ -29,8 +27,9 @@ pub fn build(b: *std.Build) !void {
|
|
|
29
27
|
const dynamic = b.option(bool, "dynamic", "Build a dynamic library") orelse false;
|
|
30
28
|
const strip = b.option(bool, "strip", "Strip debugging symbols from binary") orelse false;
|
|
31
29
|
const pic = b.option(bool, "pic", "Force position independent code") orelse false;
|
|
30
|
+
const emit_asm = b.option(bool, "emit-asm", "Output .s (assembly code)") orelse false;
|
|
32
31
|
|
|
33
|
-
const cmd = b.findProgram(
|
|
32
|
+
const cmd = b.findProgram(&.{"strip"}, &.{}) catch null;
|
|
34
33
|
|
|
35
34
|
var parser = std.json.Parser.init(b.allocator, false);
|
|
36
35
|
defer parser.deinit();
|
|
@@ -43,11 +42,11 @@ pub fn build(b: *std.Build) !void {
|
|
|
43
42
|
|
|
44
43
|
const showdown =
|
|
45
44
|
b.option(bool, "showdown", "Enable Pokémon Showdown compatibility mode") orelse false;
|
|
46
|
-
const
|
|
45
|
+
const log = b.option(bool, "log", "Enable protocol message logging") orelse false;
|
|
47
46
|
|
|
48
47
|
const options = b.addOptions();
|
|
49
48
|
options.addOption(?bool, "showdown", showdown);
|
|
50
|
-
options.addOption(?bool, "
|
|
49
|
+
options.addOption(?bool, "log", log);
|
|
51
50
|
|
|
52
51
|
const name = if (showdown) "pkmn-showdown" else "pkmn";
|
|
53
52
|
|
|
@@ -66,7 +65,7 @@ pub fn build(b: *std.Build) !void {
|
|
|
66
65
|
lib.linkLibC();
|
|
67
66
|
if (node_import_lib) |il| {
|
|
68
67
|
lib.addObjectFile(il);
|
|
69
|
-
} else if ((try NativeTargetInfo.detect(target)).target.os.tag == .windows) {
|
|
68
|
+
} else if ((try std.zig.system.NativeTargetInfo.detect(target)).target.os.tag == .windows) {
|
|
70
69
|
try std.io.getStdErr().writeAll("Must provide --node-import-library path on Windows\n");
|
|
71
70
|
std.process.exit(1);
|
|
72
71
|
}
|
|
@@ -74,14 +73,14 @@ pub fn build(b: *std.Build) !void {
|
|
|
74
73
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
75
74
|
if (pic) lib.force_pic = pic;
|
|
76
75
|
// Always emit to build/lib because this is where the driver code expects to find it
|
|
77
|
-
// TODO(ziglang/zig#2231): using the following used to work (though
|
|
76
|
+
// TODO(ziglang/zig#2231): using the following used to work (though was hacky):
|
|
78
77
|
//
|
|
79
78
|
// lib.emit_bin = .{ .emit_to = b.fmt("build/lib/{s}", .{addon}) };
|
|
80
79
|
// b.getInstallStep().dependOn(&lib.step);
|
|
81
80
|
//
|
|
82
81
|
// But ziglang/zig#14647 broke this so we now need to do an install() and then manually
|
|
83
82
|
// rename the file ourself in install-pkmn-engine
|
|
84
|
-
|
|
83
|
+
b.installArtifact(lib);
|
|
85
84
|
} else if (wasm) {
|
|
86
85
|
const lib = b.addSharedLibrary(.{
|
|
87
86
|
.name = name,
|
|
@@ -98,19 +97,16 @@ pub fn build(b: *std.Build) !void {
|
|
|
98
97
|
lib.rdynamic = true;
|
|
99
98
|
lib.strip = strip;
|
|
100
99
|
if (pic) lib.force_pic = pic;
|
|
101
|
-
const opt = b.findProgram(
|
|
102
|
-
&[_][]const u8{"wasm-opt"},
|
|
103
|
-
&[_][]const u8{"./node_modules/.bin"},
|
|
104
|
-
) catch null;
|
|
100
|
+
const opt = b.findProgram(&.{"wasm-opt"}, &.{"./node_modules/.bin"}) catch null;
|
|
105
101
|
if (optimize != .Debug and opt != null) {
|
|
106
102
|
const out = b.fmt("build/lib/{s}.wasm", .{name});
|
|
107
|
-
const sh = b.addSystemCommand(
|
|
103
|
+
const sh = b.addSystemCommand(&.{ opt.?, "-O4" });
|
|
108
104
|
sh.addArtifactArg(lib);
|
|
109
105
|
sh.addArg("-o");
|
|
110
106
|
sh.addFileSourceArg(.{ .path = out });
|
|
111
107
|
b.getInstallStep().dependOn(&sh.step);
|
|
112
108
|
}
|
|
113
|
-
|
|
109
|
+
b.installArtifact(lib);
|
|
114
110
|
} else if (dynamic) {
|
|
115
111
|
const lib = b.addSharedLibrary(.{
|
|
116
112
|
.name = name,
|
|
@@ -124,7 +120,7 @@ pub fn build(b: *std.Build) !void {
|
|
|
124
120
|
lib.addIncludePath("src/include");
|
|
125
121
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
126
122
|
if (pic) lib.force_pic = pic;
|
|
127
|
-
|
|
123
|
+
b.installArtifact(lib);
|
|
128
124
|
c = true;
|
|
129
125
|
} else {
|
|
130
126
|
const lib = b.addStaticLibrary(.{
|
|
@@ -139,7 +135,8 @@ pub fn build(b: *std.Build) !void {
|
|
|
139
135
|
lib.bundle_compiler_rt = true;
|
|
140
136
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
141
137
|
if (pic) lib.force_pic = pic;
|
|
142
|
-
lib.
|
|
138
|
+
if (emit_asm) lib.emit_asm = .emit;
|
|
139
|
+
b.installArtifact(lib);
|
|
143
140
|
c = true;
|
|
144
141
|
}
|
|
145
142
|
|
|
@@ -188,7 +185,7 @@ pub fn build(b: *std.Build) !void {
|
|
|
188
185
|
.general = config,
|
|
189
186
|
.tool = .{
|
|
190
187
|
.showdown = showdown,
|
|
191
|
-
.
|
|
188
|
+
.log = log,
|
|
192
189
|
.tests = if (tests.build) tests else null,
|
|
193
190
|
.exes = &exes,
|
|
194
191
|
},
|
|
@@ -210,7 +207,7 @@ pub fn build(b: *std.Build) !void {
|
|
|
210
207
|
const lint_exe =
|
|
211
208
|
b.addExecutable(.{ .name = "lint", .root_source_file = .{ .path = "src/tools/lint.zig" } });
|
|
212
209
|
if (tests.build) tests.step.dependOn(&lint_exe.step);
|
|
213
|
-
const lint =
|
|
210
|
+
const lint = b.addRunArtifact(lint_exe);
|
|
214
211
|
|
|
215
212
|
b.step("benchmark", "Run benchmark code").dependOn(&benchmark.step);
|
|
216
213
|
b.step("fuzz", "Run fuzz tester").dependOn(&fuzz.step);
|
|
@@ -235,7 +232,7 @@ fn maybeStrip(
|
|
|
235
232
|
if (mac and artifact.isDynamicLibrary()) return;
|
|
236
233
|
// Assuming GNU strip, which complains "illegal pathname found in archive member"...
|
|
237
234
|
if (!mac and artifact.isStaticLibrary()) return;
|
|
238
|
-
const sh = b.addSystemCommand(
|
|
235
|
+
const sh = b.addSystemCommand(&.{ cmd.?, if (mac) "-x" else "-s" });
|
|
239
236
|
sh.addArtifactArg(artifact);
|
|
240
237
|
step.dependOn(&sh.step);
|
|
241
238
|
}
|
|
@@ -248,7 +245,7 @@ const Config = struct {
|
|
|
248
245
|
cmd: ?[]const u8,
|
|
249
246
|
};
|
|
250
247
|
|
|
251
|
-
const TESTS =
|
|
248
|
+
const TESTS = .{
|
|
252
249
|
"src/lib/common/test.zig",
|
|
253
250
|
"src/lib/gen1/test.zig",
|
|
254
251
|
"src/lib/gen2/test.zig",
|
|
@@ -261,11 +258,8 @@ const TestStep = struct {
|
|
|
261
258
|
pub fn create(b: *std.Build, options: *std.Build.OptionsStep, config: Config) *TestStep {
|
|
262
259
|
const coverage = b.option([]const u8, "test-coverage", "Generate test coverage");
|
|
263
260
|
const test_file = b.option([]const u8, "test-file", "Input file for test");
|
|
264
|
-
const test_bin = b.option([]const u8, "test-bin", "Emit test binary to");
|
|
265
261
|
const test_filter =
|
|
266
262
|
b.option([]const u8, "test-filter", "Skip tests that do not match filter");
|
|
267
|
-
const test_no_exec =
|
|
268
|
-
b.option(bool, "test-no-exec", "Compiles test binary without running it") orelse false;
|
|
269
263
|
|
|
270
264
|
const self = b.allocator.create(TestStep) catch @panic("OOM");
|
|
271
265
|
const step = std.Build.Step.init(.{ .id = .custom, .name = "Run all tests", .owner = b });
|
|
@@ -279,21 +273,17 @@ const TestStep = struct {
|
|
|
279
273
|
.root_source_file = .{ .path = path },
|
|
280
274
|
.optimize = config.optimize,
|
|
281
275
|
.target = config.target,
|
|
276
|
+
.filter = test_filter,
|
|
282
277
|
});
|
|
283
278
|
tests.setMainPkgPath("./");
|
|
284
|
-
tests.setFilter(test_filter);
|
|
285
279
|
tests.addOptions("build_options", options);
|
|
286
280
|
tests.single_threaded = true;
|
|
287
281
|
maybeStrip(b, tests, &tests.step, config.strip, config.cmd);
|
|
288
282
|
if (config.pic) tests.force_pic = config.pic;
|
|
289
|
-
if (test_bin) |bin| {
|
|
290
|
-
tests.name = std.fs.path.basename(bin);
|
|
291
|
-
if (std.fs.path.dirname(bin)) |dir| tests.setOutputDir(dir);
|
|
292
|
-
}
|
|
293
283
|
if (coverage) |c| {
|
|
294
284
|
tests.setExecCmd(&.{ "kcov", "--include-pattern=src/lib", c, null });
|
|
295
285
|
}
|
|
296
|
-
self.step.dependOn(
|
|
286
|
+
self.step.dependOn(&b.addRunArtifact(tests).step);
|
|
297
287
|
}
|
|
298
288
|
return self;
|
|
299
289
|
}
|
|
@@ -303,7 +293,7 @@ const ToolConfig = struct {
|
|
|
303
293
|
general: Config,
|
|
304
294
|
tool: struct {
|
|
305
295
|
showdown: bool,
|
|
306
|
-
|
|
296
|
+
log: bool,
|
|
307
297
|
tests: ?*TestStep,
|
|
308
298
|
name: ?[]const u8 = null,
|
|
309
299
|
exes: *std.ArrayList(*std.Build.CompileStep),
|
|
@@ -324,14 +314,14 @@ fn tool(b: *std.Build, path: []const u8, config: ToolConfig) *std.Build.RunStep
|
|
|
324
314
|
});
|
|
325
315
|
exe.addModule("pkmn", module(b, .{
|
|
326
316
|
.showdown = config.tool.showdown,
|
|
327
|
-
.
|
|
317
|
+
.log = config.tool.log,
|
|
328
318
|
}));
|
|
329
319
|
exe.single_threaded = true;
|
|
330
320
|
if (config.general.pic) exe.force_pic = config.general.pic;
|
|
331
321
|
if (config.tool.tests) |ts| ts.step.dependOn(&exe.step);
|
|
332
322
|
config.tool.exes.append(exe) catch @panic("OOM");
|
|
333
323
|
|
|
334
|
-
const run =
|
|
324
|
+
const run = b.addRunArtifact(exe);
|
|
335
325
|
maybeStrip(b, exe, &run.step, config.general.strip, config.general.cmd);
|
|
336
326
|
if (b.args) |args| run.addArgs(args);
|
|
337
327
|
|
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.cf6f5d2c",
|
|
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,6 +9,28 @@
|
|
|
9
9
|
"types": "build/pkg/index.d.ts",
|
|
10
10
|
"files": [
|
|
11
11
|
"build.zig",
|
|
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",
|
|
12
34
|
"src/bin/install-pkmn-engine",
|
|
13
35
|
"src/lib/binding/node.zig",
|
|
14
36
|
"src/lib/binding/wasm.zig",
|
|
@@ -17,78 +39,66 @@
|
|
|
17
39
|
"src/lib/common/options.zig",
|
|
18
40
|
"src/lib/common/protocol.zig",
|
|
19
41
|
"src/lib/common/rng.zig",
|
|
42
|
+
"src/lib/gen1/data.zig",
|
|
20
43
|
"src/lib/gen1/data/moves.zig",
|
|
21
44
|
"src/lib/gen1/data/species.zig",
|
|
22
45
|
"src/lib/gen1/data/types.zig",
|
|
23
|
-
"src/lib/gen1/data.zig",
|
|
24
46
|
"src/lib/gen1/helpers.zig",
|
|
25
47
|
"src/lib/gen1/mechanics.zig",
|
|
48
|
+
"src/lib/gen2/data.zig",
|
|
26
49
|
"src/lib/gen2/data/items.zig",
|
|
27
50
|
"src/lib/gen2/data/moves.zig",
|
|
28
51
|
"src/lib/gen2/data/species.zig",
|
|
29
52
|
"src/lib/gen2/data/types.zig",
|
|
30
|
-
"src/lib/gen2/data.zig",
|
|
31
53
|
"src/lib/gen2/helpers.zig",
|
|
32
54
|
"src/lib/gen2/mechanics.zig",
|
|
33
55
|
"src/lib/pkmn.zig",
|
|
34
|
-
"
|
|
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"
|
|
56
|
+
"src/test/display/pkmn.html.tmpl"
|
|
49
57
|
],
|
|
50
58
|
"engines": {
|
|
51
59
|
"node": ">=16.0.0"
|
|
52
60
|
},
|
|
53
61
|
"bin": {
|
|
54
|
-
"install-pkmn-engine": "src/bin/install-pkmn-engine"
|
|
62
|
+
"install-pkmn-engine": "src/bin/install-pkmn-engine",
|
|
63
|
+
"pkmn-debug": "src/bin/pkmn-debug"
|
|
55
64
|
},
|
|
56
65
|
"publishConfig": {
|
|
57
66
|
"access": "public"
|
|
58
67
|
},
|
|
59
68
|
"dependencies": {
|
|
60
|
-
"@pkmn/data": "^0.7.
|
|
69
|
+
"@pkmn/data": "^0.7.38",
|
|
61
70
|
"@pkmn/protocol": "^0.6.11"
|
|
62
71
|
},
|
|
63
72
|
"devDependencies": {
|
|
64
73
|
"@pkmn/eslint-config": "^3.0.0",
|
|
65
74
|
"@pkmn/img": "^0.2.8",
|
|
66
75
|
"@pkmn/sets": "^5.0.4",
|
|
67
|
-
"@pkmn/sim": "0.7.
|
|
76
|
+
"@pkmn/sim": "0.7.38",
|
|
68
77
|
"@types/html-minifier": "^4.0.2",
|
|
69
78
|
"@types/jest": "^29.5.0",
|
|
70
79
|
"@types/minimist": "^1.2.2",
|
|
71
80
|
"@types/mustache": "^4.2.2",
|
|
72
81
|
"@types/node": "^18.15.11",
|
|
73
|
-
"@vitest/coverage-c8": "^0.
|
|
82
|
+
"@vitest/coverage-c8": "^0.30.1",
|
|
74
83
|
"binaryen": "^112.0.0",
|
|
75
|
-
"eslint": "^8.
|
|
84
|
+
"eslint": "^8.38.0",
|
|
76
85
|
"html-minifier": "^4.0.0",
|
|
77
|
-
"json-stringify-pretty-compact": "
|
|
86
|
+
"json-stringify-pretty-compact": "4.0.0",
|
|
78
87
|
"minimist": "^1.2.8",
|
|
79
88
|
"mustache": "^4.2.0",
|
|
80
89
|
"source-map-support": "^0.5.21",
|
|
81
90
|
"trakr": "^0.2.0",
|
|
82
|
-
"typescript": "^5.0.
|
|
83
|
-
"vitest": "^0.
|
|
91
|
+
"typescript": "^5.0.4",
|
|
92
|
+
"vitest": "^0.30.1"
|
|
84
93
|
},
|
|
85
94
|
"scripts": {
|
|
86
|
-
"lint": "eslint --cache src --ext ts,js && eslint src/bin
|
|
87
|
-
"fix": "eslint --fix src --ext ts,js && eslint --fix src/bin
|
|
95
|
+
"lint": "eslint --cache src --ext ts,js && eslint src/bin/*",
|
|
96
|
+
"fix": "eslint --fix src --ext ts,js && eslint --fix src/bin/*",
|
|
88
97
|
"compile": "tsc -p .",
|
|
89
98
|
"build": "npm run compile",
|
|
90
99
|
"test": "vitest src/pkg",
|
|
91
100
|
"test:integration": "vitest src/test",
|
|
101
|
+
"debug": "npm run compile && node build/tools/debug",
|
|
92
102
|
"fuzz": "npm run compile && node build/test/fuzz",
|
|
93
103
|
"generate": "npm run compile && node build/tools/generate",
|
|
94
104
|
"release": "npm run compile && node build/tools/release",
|
|
@@ -151,7 +161,8 @@
|
|
|
151
161
|
},
|
|
152
162
|
{
|
|
153
163
|
"files": [
|
|
154
|
-
"src/test/*.test.ts"
|
|
164
|
+
"src/test/*.test.ts",
|
|
165
|
+
"src/test/regression/*.test.ts"
|
|
155
166
|
],
|
|
156
167
|
"rules": {
|
|
157
168
|
"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, dev:
|
|
13
|
+
const ZIG_VERSION = {major: 0, minor: 11, patch: 0, dev: 2750};
|
|
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;
|
|
@@ -168,11 +170,11 @@ const install = async () => {
|
|
|
168
170
|
let base = path.basename(url);
|
|
169
171
|
const archive = path.join(dir, path.basename(url));
|
|
170
172
|
|
|
171
|
-
|
|
173
|
+
log(`Downloading Zig tarball from ${url} to ${archive}`);
|
|
172
174
|
try {
|
|
173
175
|
await download(url, archive, release.shasum);
|
|
174
176
|
|
|
175
|
-
|
|
177
|
+
log(`Extracting tarball and installing to ${dir}`);
|
|
176
178
|
await unpack(archive, dir);
|
|
177
179
|
if (archive.endsWith('.zip')) {
|
|
178
180
|
base = base.slice(0, -4);
|
|
@@ -187,17 +189,17 @@ const install = async () => {
|
|
|
187
189
|
} catch (err) {
|
|
188
190
|
if (err.code !== 'ENOENT') throw err;
|
|
189
191
|
}
|
|
190
|
-
|
|
192
|
+
log(`Zig${version === 'master' ? '' : ` v${version}`} executable:`, zig,
|
|
191
193
|
'(this version of Zig will be retained to speed up future updates)');
|
|
192
194
|
const [pre, post] = tty.isatty(1) ? ['\x1b[1m\x1b[35m', '\x1b[0m'] : ['', ''];
|
|
193
|
-
|
|
195
|
+
log(
|
|
194
196
|
`${pre}Consider moving the ${path.dirname(zig)} directory and adding it to your PATH`,
|
|
195
197
|
`to use Zig on other projects, or delete this if you wish to save space.${post}`
|
|
196
198
|
);
|
|
197
199
|
|
|
198
200
|
return zig;
|
|
199
201
|
} finally {
|
|
200
|
-
|
|
202
|
+
log(`Cleaning up ${archive}`);
|
|
201
203
|
try { fs.rmSync(archive); } catch {}
|
|
202
204
|
}
|
|
203
205
|
};
|
|
@@ -206,17 +208,17 @@ const install = async () => {
|
|
|
206
208
|
const downloadHeaders = async () => {
|
|
207
209
|
const include = path.resolve(process.execPath, '..', '..', 'include', 'node');
|
|
208
210
|
if (fs.existsSync(path.join(include, 'node.h'))) {
|
|
209
|
-
|
|
211
|
+
log('Node headers:', include);
|
|
210
212
|
return include;
|
|
211
213
|
}
|
|
212
214
|
|
|
213
215
|
const dir = path.join(ROOT, 'build', 'include');
|
|
214
|
-
const dest = path.join(dir,
|
|
216
|
+
const dest = path.join(dir, 'node');
|
|
215
217
|
if (fs.existsSync(path.join(dest, 'node.h'))) {
|
|
216
|
-
|
|
218
|
+
log('Node headers:', dest);
|
|
217
219
|
return dest;
|
|
218
220
|
} else {
|
|
219
|
-
|
|
221
|
+
log(`Could not find Node headers at ${include}, downloading...`);
|
|
220
222
|
}
|
|
221
223
|
|
|
222
224
|
try {
|
|
@@ -227,20 +229,28 @@ const downloadHeaders = async () => {
|
|
|
227
229
|
|
|
228
230
|
const url = process.release.headersUrl;
|
|
229
231
|
const targz = path.join(dir, path.basename(url));
|
|
232
|
+
const unpacked = path.join(dir, `node-${process.version}`, 'include');
|
|
230
233
|
|
|
231
|
-
|
|
232
|
-
await download(url, targz);
|
|
233
|
-
await unpack(targz, dir);
|
|
234
|
+
log(`Downloading Node headers from ${url} to ${targz}`);
|
|
234
235
|
|
|
235
|
-
|
|
236
|
+
try {
|
|
237
|
+
await download(url, targz);
|
|
238
|
+
await unpack(targz, dir);
|
|
239
|
+
fs.renameSync(path.join(unpacked, 'node'), dest);
|
|
236
240
|
|
|
237
|
-
|
|
241
|
+
log('Node headers:', dest);
|
|
242
|
+
|
|
243
|
+
return dest;
|
|
244
|
+
} finally {
|
|
245
|
+
try { fs.rmSync(targz); } catch {}
|
|
246
|
+
try { fs.rmSync(unpacked, {recursive: true}); } catch {}
|
|
247
|
+
}
|
|
238
248
|
};
|
|
239
249
|
|
|
240
250
|
const downloadImportLib = async () => {
|
|
241
251
|
const library = path.resolve(process.execPath, '..', 'node.lib');
|
|
242
252
|
if (fs.existsSync(path.join(library, 'node.h'))) {
|
|
243
|
-
|
|
253
|
+
log('Node import library:', library);
|
|
244
254
|
return library;
|
|
245
255
|
}
|
|
246
256
|
|
|
@@ -248,10 +258,10 @@ const downloadImportLib = async () => {
|
|
|
248
258
|
const url = new URL('./win-x64/node.lib', process.release.headersUrl).href;
|
|
249
259
|
const dest = path.join(dir, path.basename(url));
|
|
250
260
|
if (fs.existsSync(path.join(dest))) {
|
|
251
|
-
|
|
261
|
+
log('Node import library:', dest);
|
|
252
262
|
return dest;
|
|
253
263
|
} else {
|
|
254
|
-
|
|
264
|
+
log(`Could not find Node import library at ${library}, downloading...`);
|
|
255
265
|
}
|
|
256
266
|
|
|
257
267
|
try {
|
|
@@ -260,24 +270,41 @@ const downloadImportLib = async () => {
|
|
|
260
270
|
if (err.code !== 'EEXIST') throw err;
|
|
261
271
|
}
|
|
262
272
|
|
|
263
|
-
|
|
273
|
+
log(`Downloading Node import library from ${url} to ${dest}`);
|
|
264
274
|
await download(url, dest);
|
|
265
|
-
|
|
275
|
+
log('Node import library:', dest);
|
|
266
276
|
|
|
267
277
|
return dest;
|
|
268
278
|
};
|
|
269
279
|
|
|
270
280
|
(async () => {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
281
|
+
let only = false;
|
|
282
|
+
let options = undefined;
|
|
283
|
+
let error = false;
|
|
284
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
285
|
+
switch (process.argv[i]) {
|
|
286
|
+
case "--silent": {
|
|
287
|
+
SILENT = true;
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
case "--zig": {
|
|
291
|
+
if (options || only) error = true;
|
|
292
|
+
only = true;
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
default: {
|
|
296
|
+
if (options || only || !process.argv[i].startsWith('--options=')) error = true;
|
|
297
|
+
options = process.argv[i].slice(10).split(' ');
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (error) {
|
|
275
302
|
console.error('Invalid arguments');
|
|
276
303
|
process.exit(1);
|
|
277
304
|
}
|
|
278
305
|
|
|
279
306
|
const zig = await install();
|
|
280
|
-
if (
|
|
307
|
+
if (only) process.exit(0);
|
|
281
308
|
|
|
282
309
|
let tmp;
|
|
283
310
|
try {
|
|
@@ -310,13 +337,13 @@ const downloadImportLib = async () => {
|
|
|
310
337
|
if (!options) {
|
|
311
338
|
const addon = require(copy);
|
|
312
339
|
if (addon.options.showdown) opts.push('-Dshowdown');
|
|
313
|
-
if (addon.options.
|
|
340
|
+
if (addon.options.log) opts.push('-Dlog');
|
|
314
341
|
}
|
|
315
342
|
} else if (!options) {
|
|
316
343
|
const addon = await WebAssembly.instantiate(fs.readFileSync(copy));
|
|
317
344
|
const values = new Uint8Array(addon.instance.exports.memory.buffer);
|
|
318
345
|
if (values[addon.instance.exports.SHOWDOWN.value]) opts.push('-Dshowdown');
|
|
319
|
-
if (values[addon.instance.exports.
|
|
346
|
+
if (values[addon.instance.exports.LOG.value]) opts.push('-Dlog');
|
|
320
347
|
}
|
|
321
348
|
const key = `${type} ${opts.sort().join(' ')}`;
|
|
322
349
|
if (!configs.has(key)) configs.set(key, {type, options: opts});
|
|
@@ -347,7 +374,7 @@ const downloadImportLib = async () => {
|
|
|
347
374
|
opts.includes('-Dshowdown') || opts.includes('-Dshowdown=true') ? '-showdown' : '';
|
|
348
375
|
const flags = opts.length ? ` (${opts.join(' ')})` : '';
|
|
349
376
|
const artifact = path.join('build', 'lib', `pkmn${suffix}.${config.type}`);
|
|
350
|
-
|
|
377
|
+
log(`Building ${artifact}${flags}`);
|
|
351
378
|
sh(zig, args);
|
|
352
379
|
// TODO: ziglang/zig#14647 broke emit_to so we get to rename the file ourselves...
|
|
353
380
|
if (config.type === 'node') {
|
|
@@ -355,7 +382,7 @@ const downloadImportLib = async () => {
|
|
|
355
382
|
const ext = process.platform === 'darwin'
|
|
356
383
|
? 'dylib' : process.platform === 'win32' ? 'dll' : 'so';
|
|
357
384
|
const actual = path.join('build', 'lib', `${prefix}pkmn${suffix}.node.${ext}`);
|
|
358
|
-
fs.renameSync(actual, artifact);
|
|
385
|
+
fs.renameSync(path.join(ROOT, actual), path.join(ROOT, artifact));
|
|
359
386
|
}
|
|
360
387
|
}
|
|
361
388
|
})().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
|
+
});
|