@pkmn/engine 0.1.0-dev.00879b8b

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 (60) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +368 -0
  3. package/build/pkg/addon.d.ts +7 -0
  4. package/build/pkg/addon.js +111 -0
  5. package/build/pkg/addon.js.map +1 -0
  6. package/build/pkg/data/ids.json +240 -0
  7. package/build/pkg/data/layout.json +108 -0
  8. package/build/pkg/data/protocol.json +230 -0
  9. package/build/pkg/data.d.ts +91 -0
  10. package/build/pkg/data.js +150 -0
  11. package/build/pkg/data.js.map +1 -0
  12. package/build/pkg/gen1.d.ts +110 -0
  13. package/build/pkg/gen1.js +684 -0
  14. package/build/pkg/gen1.js.map +1 -0
  15. package/build/pkg/index.d.ts +387 -0
  16. package/build/pkg/index.js +122 -0
  17. package/build/pkg/index.js.map +1 -0
  18. package/build/pkg/protocol.d.ts +73 -0
  19. package/build/pkg/protocol.js +473 -0
  20. package/build/pkg/protocol.js.map +1 -0
  21. package/build/test/display.js +400 -0
  22. package/build/test/display.js.map +1 -0
  23. package/build/tools/debug.js +134 -0
  24. package/build/tools/debug.js.map +1 -0
  25. package/build.zig +363 -0
  26. package/package.json +232 -0
  27. package/src/bin/install-pkmn-engine +404 -0
  28. package/src/bin/pkmn-debug +62 -0
  29. package/src/lib/common/battle.zig +17 -0
  30. package/src/lib/common/data.zig +117 -0
  31. package/src/lib/common/debug.zig +74 -0
  32. package/src/lib/common/js.zig +118 -0
  33. package/src/lib/common/optional.zig +67 -0
  34. package/src/lib/common/options.zig +51 -0
  35. package/src/lib/common/protocol.zig +1836 -0
  36. package/src/lib/common/rational.zig +357 -0
  37. package/src/lib/common/rng.zig +243 -0
  38. package/src/lib/common/util.zig +12 -0
  39. package/src/lib/gen1/calc.zig +507 -0
  40. package/src/lib/gen1/chance.zig +1063 -0
  41. package/src/lib/gen1/data/moves.zig +1866 -0
  42. package/src/lib/gen1/data/species.zig +1105 -0
  43. package/src/lib/gen1/data/types.zig +131 -0
  44. package/src/lib/gen1/data.zig +634 -0
  45. package/src/lib/gen1/helpers.zig +866 -0
  46. package/src/lib/gen1/mechanics.zig +3156 -0
  47. package/src/lib/gen2/calc.zig +143 -0
  48. package/src/lib/gen2/chance.zig +1315 -0
  49. package/src/lib/gen2/data/items.zig +230 -0
  50. package/src/lib/gen2/data/moves.zig +2878 -0
  51. package/src/lib/gen2/data/species.zig +1798 -0
  52. package/src/lib/gen2/data/types.zig +226 -0
  53. package/src/lib/gen2/data.zig +463 -0
  54. package/src/lib/gen2/generated.zig +806 -0
  55. package/src/lib/gen2/helpers.zig +249 -0
  56. package/src/lib/gen2/mechanics.zig +3632 -0
  57. package/src/lib/node.zig +131 -0
  58. package/src/lib/pkmn.zig +128 -0
  59. package/src/lib/wasm.zig +13 -0
  60. package/src/test/display/pkmn.html.tmpl +368 -0
package/build.zig ADDED
@@ -0,0 +1,363 @@
1
+ const std = @import("std");
2
+ const builtin = @import("builtin");
3
+
4
+ pub fn build(b: *std.Build) !void {
5
+ const target = b.standardTargetOptions(.{});
6
+ const optimize = b.standardOptimizeOption(.{});
7
+
8
+ const node_headers = b.option([]const u8, "node-headers", "Path to node-headers");
9
+ const node_import_lib =
10
+ b.option([]const u8, "node-import-library", "Path to node import library (Windows)");
11
+ const wasm = b.option(bool, "wasm", "Build a WASM library") orelse false;
12
+ const wasm_stack_size =
13
+ b.option(u64, "wasm-stack-size", "The size of WASM stack") orelse std.wasm.page_size;
14
+ const dynamic = b.option(bool, "dynamic", "Build a dynamic library") orelse false;
15
+ const strip = b.option(bool, "strip", "Strip debugging symbols from binary");
16
+ const pic = b.option(bool, "pic", "Force position independent code");
17
+ const emit_asm = b.option(bool, "emit-asm", "Output .s (assembly code)") orelse false;
18
+ const emit_ll = b.option(bool, "emit-ll", "Output .ll (LLVM IR)") orelse false;
19
+
20
+ const cmd = b.findProgram(&.{"strip"}, &.{}) catch null;
21
+
22
+ const json = @embedFile("package.json");
23
+ var parsed = try std.json.parseFromSlice(std.json.Value, b.allocator, json, .{});
24
+ defer parsed.deinit();
25
+ const version = parsed.value.object.get("version").?.string;
26
+ const description = parsed.value.object.get("description").?.string;
27
+ var repository = std.mem.splitSequence(u8, parsed.value.object.get("repository").?.string, ":");
28
+ std.debug.assert(std.mem.eql(u8, repository.first(), "github"));
29
+
30
+ const showdown =
31
+ b.option(bool, "showdown", "Enable Pokémon Showdown compatibility mode") orelse false;
32
+ const log = b.option(bool, "log", "Enable protocol message logging") orelse false;
33
+ const chance = b.option(bool, "chance", "Enable update probability tracking") orelse false;
34
+ const calc = b.option(bool, "calc", "Enable damage calculator support") orelse false;
35
+
36
+ const options = b.addOptions();
37
+ options.addOption(?bool, "showdown", showdown);
38
+ options.addOption(?bool, "log", log);
39
+ options.addOption(?bool, "chance", chance);
40
+ options.addOption(?bool, "calc", calc);
41
+
42
+ const name = if (showdown) "pkmn-showdown" else "pkmn";
43
+
44
+ const module = b.addModule("pkmn", .{
45
+ .root_source_file = b.path("src/lib/pkmn.zig"),
46
+ .optimize = optimize,
47
+ .target = target,
48
+ .imports = &.{.{ .name = "build_options", .module = options.createModule() }},
49
+ });
50
+
51
+ var c = false;
52
+ if (node_headers) |headers| {
53
+ const addon = b.fmt("{s}.node", .{name});
54
+ const lib = b.addSharedLibrary(.{
55
+ .name = addon,
56
+ .root_source_file = b.path("src/lib/node.zig"),
57
+ .optimize = optimize,
58
+ .target = target,
59
+ .strip = strip,
60
+ .pic = pic,
61
+ });
62
+ lib.root_module.addOptions("build_options", options);
63
+ lib.addSystemIncludePath(b.path(headers));
64
+ lib.linkLibC();
65
+ if (node_import_lib) |il| {
66
+ lib.addObjectFile(b.path(il));
67
+ } else if (target.result.os.tag == .windows) {
68
+ try std.io.getStdErr().writeAll("Must provide --node-import-library path on Windows\n");
69
+ std.process.exit(1);
70
+ }
71
+ lib.linker_allow_shlib_undefined = true;
72
+ maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
73
+ // Always emit to build/lib because this is where the driver code expects to find it
74
+ // TODO: ziglang/zig#2231 - using the following used to work (though was hacky):
75
+ //
76
+ // lib.emit_bin = .{ .emit_to = b.fmt("build/lib/{s}", .{addon}) };
77
+ // b.getInstallStep().dependOn(&lib.step);
78
+ //
79
+ // But ziglang/zig#14647 broke this so we now need to do an install() and then manually
80
+ // rename the file ourself in install-pkmn-engine
81
+ b.installArtifact(lib);
82
+ } else if (wasm) {
83
+ const exe = b.addExecutable(.{
84
+ .name = name,
85
+ .root_source_file = b.path("src/lib/wasm.zig"),
86
+ .optimize = switch (optimize) {
87
+ .ReleaseFast, .ReleaseSafe => .ReleaseSmall,
88
+ else => optimize,
89
+ },
90
+ .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
91
+ .strip = strip,
92
+ .pic = pic,
93
+ });
94
+ exe.root_module.addOptions("build_options", options);
95
+ exe.root_module.export_symbol_names = &[_][]const u8{
96
+ "SHOWDOWN",
97
+ "LOG",
98
+ "CHANCE",
99
+ "CALC",
100
+ "GEN1_CHOICES_SIZE",
101
+ "GEN1_LOGS_SIZE",
102
+ };
103
+ exe.entry = .disabled;
104
+ exe.stack_size = wasm_stack_size;
105
+ const opt = b.findProgram(&.{"wasm-opt"}, &.{"./node_modules/.bin"}) catch null;
106
+ if (optimize != .Debug and opt != null) {
107
+ const out = b.fmt("build/lib/{s}.wasm", .{name});
108
+ const sh = b.addSystemCommand(&.{ opt.?, "-O4" });
109
+ sh.addArtifactArg(exe);
110
+ sh.addArg("-o");
111
+ sh.addFileArg(b.path(out));
112
+ b.getInstallStep().dependOn(&sh.step);
113
+ } else {
114
+ b.getInstallStep().dependOn(&b.addInstallArtifact(exe, .{
115
+ .dest_dir = .{ .override = std.Build.InstallDir{ .lib = {} } },
116
+ }).step);
117
+ }
118
+ } else if (dynamic) {
119
+ const lib = b.addSharedLibrary(.{
120
+ .name = name,
121
+ .root_source_file = b.path("src/lib/c.zig"),
122
+ .version = try std.SemanticVersion.parse(version),
123
+ .optimize = optimize,
124
+ .target = target,
125
+ .strip = strip,
126
+ .pic = pic,
127
+ });
128
+ lib.root_module.addOptions("build_options", options);
129
+ lib.addIncludePath(b.path("src/include"));
130
+ maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
131
+ b.installArtifact(lib);
132
+ c = true;
133
+ } else {
134
+ const lib = b.addStaticLibrary(.{
135
+ .name = name,
136
+ .root_source_file = b.path("src/lib/c.zig"),
137
+ .optimize = optimize,
138
+ .target = target,
139
+ .strip = strip,
140
+ .pic = pic,
141
+ });
142
+ lib.root_module.addOptions("build_options", options);
143
+ lib.addIncludePath(b.path("src/include"));
144
+ lib.bundle_compiler_rt = true;
145
+ maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
146
+ if (emit_asm) {
147
+ b.getInstallStep().dependOn(&b.addInstallFileWithDir(
148
+ lib.getEmittedAsm(),
149
+ .prefix,
150
+ b.fmt("{s}.s", .{name}),
151
+ ).step);
152
+ }
153
+ if (emit_ll) {
154
+ b.getInstallStep().dependOn(&b.addInstallFileWithDir(
155
+ lib.getEmittedLlvmIr(),
156
+ .prefix,
157
+ b.fmt("{s}.ll", .{name}),
158
+ ).step);
159
+ }
160
+ b.installArtifact(lib);
161
+ c = true;
162
+ }
163
+
164
+ if (c) {
165
+ const header = b.addInstallFileWithDir(
166
+ b.path("src/include/pkmn.h"),
167
+ .header,
168
+ "pkmn.h",
169
+ );
170
+ b.getInstallStep().dependOn(&header.step);
171
+
172
+ const pc = b.fmt("lib{s}.pc", .{name});
173
+ const file = try std.fs.path.relative(
174
+ b.allocator,
175
+ try std.process.getCwdAlloc(b.allocator),
176
+ try b.cache_root.join(b.allocator, &.{pc}),
177
+ );
178
+ const pkgconfig_file = try std.fs.cwd().createFile(file, .{});
179
+
180
+ const dirname = comptime std.fs.path.dirname(@src().file) orelse ".";
181
+ const writer = pkgconfig_file.writer();
182
+ try writer.print(
183
+ \\prefix={0s}/{1s}
184
+ \\includedir=${{prefix}}/include
185
+ \\libdir=${{prefix}}/lib
186
+ \\
187
+ \\Name: lib{2s}
188
+ \\URL: https://github.com/{3s}
189
+ \\Description: {4s}
190
+ \\Version: {5s}
191
+ \\Cflags: -I${{includedir}}
192
+ \\Libs: -L${{libdir}} -l{2s}
193
+ , .{ dirname, b.install_path, name, repository.next().?, description, version });
194
+ defer pkgconfig_file.close();
195
+
196
+ b.installFile(file, b.fmt("share/pkgconfig/{s}", .{pc}));
197
+ }
198
+
199
+ const config = .{
200
+ .target = target,
201
+ .optimize = optimize,
202
+ .pic = pic,
203
+ .strip = strip,
204
+ .cmd = cmd,
205
+ };
206
+
207
+ // TODO: tests can be run multiple times due to @imports
208
+ const tests = TestStep.create(b, options, config);
209
+
210
+ var exes = std.ArrayList(*std.Build.Step.Compile).init(b.allocator);
211
+ const tools: ToolConfig = .{
212
+ .showdown = showdown,
213
+ .module = module,
214
+ .general = config,
215
+ .tool = .{
216
+ .tests = if (tests.build) tests else null,
217
+ .exes = &exes,
218
+ },
219
+ };
220
+
221
+ var benchmark_config = tools;
222
+ benchmark_config.general.optimize = .ReleaseFast;
223
+ benchmark_config.general.strip = true;
224
+ const benchmark = try tool(b, "src/test/benchmark.zig", benchmark_config);
225
+
226
+ var fuzz_config = tools;
227
+ fuzz_config.general.strip = false;
228
+ fuzz_config.tool.name = "fuzz";
229
+ const fuzz = try tool(b, "src/test/fuzz.zig", fuzz_config);
230
+
231
+ const analyze = try tool(b, "src/tools/analyze.zig", tools);
232
+ const dump = try tool(b, "src/tools/dump.zig", tools);
233
+ const transitions = try tool(b, "src/tools/transitions.zig", tools);
234
+
235
+ // FIXME: serde randomly fails to build in some release configurations
236
+ var hack = tools;
237
+ if (optimize != .Debug) hack.tool.tests = null;
238
+ const serde = try tool(b, "src/tools/serde.zig", hack);
239
+
240
+ if (analyze) |t| b.step("analyze", "Run LLVM analysis tool").dependOn(&t.step);
241
+ if (benchmark) |t| b.step("benchmark", "Run benchmark code").dependOn(&t.step);
242
+ if (dump) |t| b.step("dump", "Run protocol dump tool").dependOn(&t.step);
243
+ if (fuzz) |t| b.step("fuzz", "Run fuzz tester").dependOn(&t.step);
244
+ if (serde) |t| b.step("serde", "Run serialization/deserialization tool").dependOn(&t.step);
245
+ b.step("test", "Run all tests").dependOn(&tests.step);
246
+ b.step("tools", "Install tools").dependOn(&ToolsStep.create(b, &exes).step);
247
+ if (transitions) |t| {
248
+ b.step("transitions", "Visualize transitions algorithm search").dependOn(&t.step);
249
+ }
250
+ }
251
+
252
+ fn maybeStrip(
253
+ b: *std.Build,
254
+ artifact: *std.Build.Step.Compile,
255
+ step: *std.Build.Step,
256
+ strip: ?bool,
257
+ cmd: ?[]const u8,
258
+ ) void {
259
+ if (!(strip orelse false) or cmd == null) return;
260
+ // Using `strip -r -u` for dynamic libraries is supposed to work on macOS but doesn't...
261
+ const mac = builtin.os.tag == .macos;
262
+ if (mac and artifact.isDynamicLibrary()) return;
263
+ // Assuming GNU strip, which complains "illegal pathname found in archive member"...
264
+ if (!mac and artifact.isStaticLibrary()) return;
265
+ const sh = b.addSystemCommand(&.{ cmd.?, if (mac) "-x" else "-s" });
266
+ sh.addArtifactArg(artifact);
267
+ step.dependOn(&sh.step);
268
+ }
269
+
270
+ const Config = struct {
271
+ target: std.Build.ResolvedTarget,
272
+ optimize: std.builtin.OptimizeMode,
273
+ pic: ?bool,
274
+ strip: ?bool,
275
+ cmd: ?[]const u8,
276
+ };
277
+
278
+ const TestStep = struct {
279
+ step: std.Build.Step,
280
+ build: bool,
281
+
282
+ pub fn create(b: *std.Build, options: *std.Build.Step.Options, config: Config) *TestStep {
283
+ const coverage = b.option([]const u8, "test-coverage", "Generate test coverage");
284
+ const test_filter =
285
+ b.option([]const u8, "test-filter", "Skip tests that do not match filter");
286
+
287
+ const self = b.allocator.create(TestStep) catch @panic("OOM");
288
+ const step = std.Build.Step.init(.{ .id = .custom, .name = "Run all tests", .owner = b });
289
+ self.* = .{ .step = step, .build = test_filter == null };
290
+
291
+ const tests = b.addTest(.{
292
+ .root_source_file = b.path("src/lib/test.zig"),
293
+ .optimize = config.optimize,
294
+ .target = config.target,
295
+ .filter = test_filter,
296
+ .single_threaded = true,
297
+ .strip = config.strip,
298
+ .pic = config.pic,
299
+ });
300
+ tests.root_module.addOptions("build_options", options);
301
+ maybeStrip(b, tests, &tests.step, config.strip, config.cmd);
302
+ if (coverage) |c| {
303
+ tests.setExecCmd(&.{ "kcov", "--include-pattern=src/lib", c, null });
304
+ }
305
+ self.step.dependOn(&b.addRunArtifact(tests).step);
306
+
307
+ return self;
308
+ }
309
+ };
310
+
311
+ const ToolConfig = struct {
312
+ showdown: ?bool,
313
+ module: *std.Build.Module,
314
+ general: Config,
315
+ tool: struct {
316
+ tests: ?*TestStep,
317
+ name: ?[]const u8 = null,
318
+ exes: *std.ArrayList(*std.Build.Step.Compile),
319
+ },
320
+ };
321
+
322
+ fn tool(b: *std.Build, path: []const u8, config: ToolConfig) !?*std.Build.Step.Run {
323
+ std.fs.cwd().access(path, .{}) catch |err| switch (err) {
324
+ error.FileNotFound => return null,
325
+ else => |e| return e,
326
+ };
327
+ var name = config.tool.name orelse std.fs.path.basename(path);
328
+ const index = std.mem.lastIndexOfScalar(u8, name, '.');
329
+ if (index) |i| name = name[0..i];
330
+ if (config.showdown orelse false) name = b.fmt("{s}-showdown", .{name});
331
+
332
+ const exe = b.addExecutable(.{
333
+ .name = name,
334
+ .root_source_file = b.path(path),
335
+ .target = config.general.target,
336
+ .optimize = config.general.optimize,
337
+ .single_threaded = true,
338
+ .strip = config.general.strip,
339
+ .pic = config.general.pic,
340
+ });
341
+ exe.root_module.addImport("pkmn", config.module);
342
+
343
+ if (config.tool.tests) |ts| ts.step.dependOn(&exe.step);
344
+ config.tool.exes.append(exe) catch @panic("OOM");
345
+
346
+ const run = b.addRunArtifact(exe);
347
+ maybeStrip(b, exe, &run.step, config.general.strip, config.general.cmd);
348
+ if (b.args) |args| run.addArgs(args);
349
+
350
+ return run;
351
+ }
352
+
353
+ const ToolsStep = struct {
354
+ step: std.Build.Step,
355
+
356
+ pub fn create(b: *std.Build, exes: *std.ArrayList(*std.Build.Step.Compile)) *ToolsStep {
357
+ const self = b.allocator.create(ToolsStep) catch @panic("OOM");
358
+ const step = std.Build.Step.init(.{ .id = .custom, .name = "Install tools", .owner = b });
359
+ self.* = .{ .step = step };
360
+ for (exes.items) |t| self.step.dependOn(&b.addInstallArtifact(t, .{}).step);
361
+ return self;
362
+ }
363
+ };
package/package.json ADDED
@@ -0,0 +1,232 @@
1
+ {
2
+ "name": "@pkmn/engine",
3
+ "version": "0.1.0-dev.00879b8b",
4
+ "description": "A minimal, complete, Pokémon battle simulation engine optimized for performance",
5
+ "repository": "github:pkmn/engine",
6
+ "license": "MIT",
7
+ "sideEffects": false,
8
+ "main": "build/pkg/index.js",
9
+ "types": "build/pkg/index.d.ts",
10
+ "files": [
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",
34
+ "src/lib/common/battle.zig",
35
+ "src/lib/common/data.zig",
36
+ "src/lib/common/debug.zig",
37
+ "src/lib/common/js.zig",
38
+ "src/lib/common/optional.zig",
39
+ "src/lib/common/options.zig",
40
+ "src/lib/common/protocol.zig",
41
+ "src/lib/common/rational.zig",
42
+ "src/lib/common/rng.zig",
43
+ "src/lib/common/util.zig",
44
+ "src/lib/gen1/calc.zig",
45
+ "src/lib/gen1/chance.zig",
46
+ "src/lib/gen1/data.zig",
47
+ "src/lib/gen1/data/moves.zig",
48
+ "src/lib/gen1/data/species.zig",
49
+ "src/lib/gen1/data/types.zig",
50
+ "src/lib/gen1/helpers.zig",
51
+ "src/lib/gen1/mechanics.zig",
52
+ "src/lib/gen2/calc.zig",
53
+ "src/lib/gen2/chance.zig",
54
+ "src/lib/gen2/data.zig",
55
+ "src/lib/gen2/data/items.zig",
56
+ "src/lib/gen2/data/moves.zig",
57
+ "src/lib/gen2/data/species.zig",
58
+ "src/lib/gen2/data/types.zig",
59
+ "src/lib/gen2/generated.zig",
60
+ "src/lib/gen2/helpers.zig",
61
+ "src/lib/gen2/mechanics.zig",
62
+ "src/lib/node.zig",
63
+ "src/lib/pkmn.zig",
64
+ "src/lib/wasm.zig",
65
+ "src/test/display/pkmn.html.tmpl"
66
+ ],
67
+ "engines": {
68
+ "node": ">=16.0.0"
69
+ },
70
+ "bin": {
71
+ "install-pkmn-engine": "src/bin/install-pkmn-engine",
72
+ "pkmn-debug": "src/bin/pkmn-debug"
73
+ },
74
+ "publishConfig": {
75
+ "access": "public"
76
+ },
77
+ "dependencies": {
78
+ "@pkmn/data": "^0.9.11",
79
+ "@pkmn/protocol": "^0.6.25"
80
+ },
81
+ "devDependencies": {
82
+ "@pkmn/eslint-config": "^8.1.0",
83
+ "@pkmn/img": "^0.2.31",
84
+ "@pkmn/sets": "^5.1.2",
85
+ "@pkmn/sim": "0.9.11",
86
+ "@types/html-minifier": "^4.0.5",
87
+ "@types/jest": "^29.5.12",
88
+ "@types/minimist": "^1.2.5",
89
+ "@types/mustache": "^4.2.5",
90
+ "@types/node": "^22.0.2",
91
+ "@vitest/coverage-v8": "^2.0.5",
92
+ "binaryen": "^118.0.0",
93
+ "eslint": "<=8",
94
+ "html-minifier": "^4.0.0",
95
+ "json-stringify-pretty-compact": "4.0.0",
96
+ "minimist": "^1.2.8",
97
+ "mustache": "^4.2.0",
98
+ "source-map-support": "^0.5.21",
99
+ "table": "^6.8.2",
100
+ "trakr": "^0.2.0",
101
+ "typescript": "^5.5.4",
102
+ "vitest": "^2.0.5"
103
+ },
104
+ "scripts": {
105
+ "lint": "eslint --cache src --ext ts,js && eslint src/bin/*",
106
+ "fix": "eslint --fix src --ext ts,js && eslint --fix src/bin/*",
107
+ "compile": "tsc -p .",
108
+ "build": "npm run compile",
109
+ "test": "vitest src/pkg",
110
+ "test:integration": "vitest src/test",
111
+ "debug": "npm run compile && node build/tools/debug",
112
+ "fuzz": "npm run compile && node build/test/fuzz",
113
+ "generate": "npm run compile && node build/tools/generate",
114
+ "release": "npm run compile && node build/tools/release",
115
+ "benchmark": "npm run compile && node build/test/benchmark",
116
+ "integration": "npm run compile && node build/test/integration",
117
+ "postinstall": "node src/bin/install-pkmn-engine"
118
+ },
119
+ "eslintConfig": {
120
+ "extends": "@pkmn",
121
+ "ignorePatterns": [
122
+ "dist/",
123
+ "node_modules/",
124
+ "examples/zig",
125
+ "build/"
126
+ ],
127
+ "env": {
128
+ "es6": true,
129
+ "node": true,
130
+ "browser": true
131
+ },
132
+ "overrides": [
133
+ {
134
+ "files": [
135
+ "**/*.ts"
136
+ ],
137
+ "parserOptions": {
138
+ "project": [
139
+ "./tsconfig.json",
140
+ "./examples/js/tsconfig.json"
141
+ ]
142
+ }
143
+ },
144
+ {
145
+ "files": [
146
+ "src/test/display.ts"
147
+ ],
148
+ "rules": {
149
+ "@typescript-eslint/no-unnecessary-type-assertion": "off"
150
+ }
151
+ },
152
+ {
153
+ "files": [
154
+ "src/pkg/index.ts",
155
+ "src/test/display.ts",
156
+ "src/test/integration.ts"
157
+ ],
158
+ "rules": {
159
+ "no-control-regex": "off",
160
+ "@typescript-eslint/no-empty-interface": "off",
161
+ "@typescript-eslint/no-shadow": "off",
162
+ "@typescript-eslint/no-unsafe-declaration-merging": "off"
163
+ }
164
+ },
165
+ {
166
+ "files": [
167
+ "src/pkg/addon.ts"
168
+ ],
169
+ "rules": {
170
+ "@typescript-eslint/no-var-requires": "off"
171
+ }
172
+ },
173
+ {
174
+ "files": [
175
+ "src/test/benchmark*.ts"
176
+ ],
177
+ "rules": {
178
+ "@typescript-eslint/no-unused-vars": "off",
179
+ "@typescript-eslint/no-redundant-type-constituents": "off"
180
+ }
181
+ },
182
+ {
183
+ "files": [
184
+ "src/pkg/protocol.test.ts"
185
+ ],
186
+ "rules": {
187
+ "jest/no-standalone-expect": "off",
188
+ "jest/no-conditional-expect": "off"
189
+ }
190
+ },
191
+ {
192
+ "files": [
193
+ "src/test/*.test.ts",
194
+ "src/test/regression/*.test.ts"
195
+ ],
196
+ "rules": {
197
+ "jest/no-standalone-expect": "off"
198
+ }
199
+ },
200
+ {
201
+ "files": [
202
+ "src/test/showdown/**"
203
+ ],
204
+ "rules": {
205
+ "jest/expect-expect": [
206
+ "warn",
207
+ {
208
+ "assertFunctionNames": [
209
+ "expect",
210
+ "expectLog",
211
+ "verify"
212
+ ]
213
+ }
214
+ ]
215
+ }
216
+ },
217
+ {
218
+ "files": [
219
+ "src/tools/generate.ts"
220
+ ],
221
+ "rules": {
222
+ "@typescript-eslint/restrict-template-expressions": [
223
+ "error",
224
+ {
225
+ "allowBoolean": true
226
+ }
227
+ ]
228
+ }
229
+ }
230
+ ]
231
+ }
232
+ }