@pkmn/engine 0.1.0-dev.9a0c07c3 → 0.1.0-dev.a0167a9d

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 (62) hide show
  1. package/LICENSE +1 -3
  2. package/README.md +108 -72
  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 +12 -12
  7. package/build/pkg/data/layout.json +27 -5
  8. package/build/pkg/data/protocol.json +69 -12
  9. package/build/pkg/data.d.ts +4 -4
  10. package/build/pkg/data.js.map +1 -1
  11. package/build/pkg/gen1.d.ts +5 -4
  12. package/build/pkg/gen1.js +49 -33
  13. package/build/pkg/gen1.js.map +1 -1
  14. package/build/pkg/index.d.ts +17 -13
  15. package/build/pkg/index.js.map +1 -1
  16. package/build/pkg/protocol.d.ts +4 -2
  17. package/build/pkg/protocol.js +65 -44
  18. package/build/pkg/protocol.js.map +1 -1
  19. package/build/test/display.js +33 -15
  20. package/build/test/display.js.map +1 -1
  21. package/build/tools/debug.js +5 -4
  22. package/build/tools/debug.js.map +1 -1
  23. package/build.zig +155 -138
  24. package/package.json +59 -26
  25. package/src/bin/install-pkmn-engine +36 -23
  26. package/src/bin/pkmn-debug +34 -7
  27. package/src/lib/common/battle.zig +17 -0
  28. package/src/lib/common/data.zig +19 -31
  29. package/src/lib/common/debug.zig +23 -13
  30. package/src/lib/common/js.zig +118 -0
  31. package/src/lib/common/optional.zig +67 -0
  32. package/src/lib/common/options.zig +14 -3
  33. package/src/lib/common/protocol.zig +942 -403
  34. package/src/lib/common/rational.zig +447 -0
  35. package/src/lib/common/rng.zig +35 -26
  36. package/src/lib/common/util.zig +12 -0
  37. package/src/lib/gen1/calc.zig +598 -0
  38. package/src/lib/gen1/chance.zig +1026 -0
  39. package/src/lib/gen1/data/moves.zig +202 -190
  40. package/src/lib/gen1/data/species.zig +5 -5
  41. package/src/lib/gen1/data/types.zig +10 -10
  42. package/src/lib/gen1/data.zig +108 -94
  43. package/src/lib/gen1/helpers.zig +565 -35
  44. package/src/lib/gen1/mechanics.zig +1182 -839
  45. package/src/lib/gen2/calc.zig +143 -0
  46. package/src/lib/gen2/chance.zig +1404 -0
  47. package/src/lib/gen2/data/items.zig +14 -20
  48. package/src/lib/gen2/data/moves.zig +664 -570
  49. package/src/lib/gen2/data/species.zig +2 -2
  50. package/src/lib/gen2/data/types.zig +137 -34
  51. package/src/lib/gen2/data.zig +134 -96
  52. package/src/lib/gen2/generated.zig +806 -0
  53. package/src/lib/gen2/helpers.zig +50 -26
  54. package/src/lib/gen2/mechanics.zig +3591 -12
  55. package/src/lib/node.zig +131 -0
  56. package/src/lib/pkmn.zig +86 -12
  57. package/src/lib/wasm.zig +13 -0
  58. package/src/test/display/pkmn.html.tmpl +5 -5
  59. package/src/lib/binding/node.zig +0 -229
  60. package/src/lib/binding/wasm.zig +0 -10
  61. package/src/lib/gen1/README.md +0 -784
  62. package/src/lib/gen2/README.md +0 -309
package/build.zig CHANGED
@@ -1,19 +1,6 @@
1
1
  const std = @import("std");
2
2
  const builtin = @import("builtin");
3
3
 
4
- pub const Options = struct { showdown: ?bool = null, trace: ?bool = null };
5
-
6
- pub fn module(b: *std.Build, options: Options) *std.Build.Module {
7
- const dirname = comptime std.fs.path.dirname(@src().file) orelse ".";
8
- const build_options = b.addOptions();
9
- build_options.addOption(?bool, "showdown", options.showdown);
10
- build_options.addOption(?bool, "trace", options.trace);
11
- return b.createModule(.{
12
- .source_file = .{ .path = dirname ++ "/src/lib/pkmn.zig" },
13
- .dependencies = &.{.{ .name = "build_options", .module = build_options.createModule() }},
14
- });
15
- }
16
-
17
4
  pub fn build(b: *std.Build) !void {
18
5
  const target = b.standardTargetOptions(.{});
19
6
  const optimize = b.standardOptimizeOption(.{});
@@ -25,129 +12,169 @@ pub fn build(b: *std.Build) !void {
25
12
  const wasm_stack_size =
26
13
  b.option(u64, "wasm-stack-size", "The size of WASM stack") orelse std.wasm.page_size;
27
14
  const dynamic = b.option(bool, "dynamic", "Build a dynamic library") orelse false;
28
- const strip = b.option(bool, "strip", "Strip debugging symbols from binary") orelse false;
29
- const pic = b.option(bool, "pic", "Force position independent code") 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;
30
19
 
31
20
  const cmd = b.findProgram(&.{"strip"}, &.{}) catch null;
32
21
 
33
- var parser = std.json.Parser.init(b.allocator, false);
34
- defer parser.deinit();
35
- var tree = try parser.parse(@embedFile("package.json"));
36
- defer tree.deinit();
37
- const version = tree.root.Object.get("version").?.String;
38
- const description = tree.root.Object.get("description").?.String;
39
- var repository = std.mem.split(u8, tree.root.Object.get("repository").?.String, ":");
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, ":");
40
28
  std.debug.assert(std.mem.eql(u8, repository.first(), "github"));
41
29
 
42
30
  const showdown =
43
31
  b.option(bool, "showdown", "Enable Pokémon Showdown compatibility mode") orelse false;
44
- const trace = b.option(bool, "trace", "Enable trace logs") 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;
45
35
 
46
36
  const options = b.addOptions();
47
37
  options.addOption(?bool, "showdown", showdown);
48
- options.addOption(?bool, "trace", trace);
38
+ options.addOption(?bool, "log", log);
39
+ options.addOption(?bool, "chance", chance);
40
+ options.addOption(?bool, "calc", calc);
49
41
 
50
42
  const name = if (showdown) "pkmn-showdown" else "pkmn";
51
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
+
52
51
  var c = false;
53
52
  if (node_headers) |headers| {
54
53
  const addon = b.fmt("{s}.node", .{name});
55
54
  const lib = b.addSharedLibrary(.{
56
55
  .name = addon,
57
- .root_source_file = .{ .path = "src/lib/binding/node.zig" },
56
+ .root_source_file = b.path("src/lib/node.zig"),
58
57
  .optimize = optimize,
59
58
  .target = target,
59
+ .strip = strip,
60
+ .pic = pic,
60
61
  });
61
- lib.addOptions("build_options", options);
62
- lib.setMainPkgPath("./");
63
- lib.addSystemIncludePath(headers);
62
+ lib.root_module.addOptions("build_options", options);
63
+ lib.addSystemIncludePath(b.path(headers));
64
64
  lib.linkLibC();
65
65
  if (node_import_lib) |il| {
66
- lib.addObjectFile(il);
67
- } else if ((try std.zig.system.NativeTargetInfo.detect(target)).target.os.tag == .windows) {
66
+ lib.addObjectFile(b.path(il));
67
+ } else if (target.result.os.tag == .windows) {
68
68
  try std.io.getStdErr().writeAll("Must provide --node-import-library path on Windows\n");
69
69
  std.process.exit(1);
70
70
  }
71
71
  lib.linker_allow_shlib_undefined = true;
72
72
  maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
73
- if (pic) lib.force_pic = pic;
74
73
  // Always emit to build/lib because this is where the driver code expects to find it
75
- // TODO(ziglang/zig#2231): using the following used to work (though was hacky):
74
+ // TODO: ziglang/zig#2231 - using the following used to work (though was hacky):
76
75
  //
77
76
  // lib.emit_bin = .{ .emit_to = b.fmt("build/lib/{s}", .{addon}) };
78
77
  // b.getInstallStep().dependOn(&lib.step);
79
78
  //
80
79
  // But ziglang/zig#14647 broke this so we now need to do an install() and then manually
81
80
  // rename the file ourself in install-pkmn-engine
82
- lib.install();
81
+ b.installArtifact(lib);
83
82
  } else if (wasm) {
84
- const lib = b.addSharedLibrary(.{
83
+ const exe = b.addExecutable(.{
85
84
  .name = name,
86
- .root_source_file = .{ .path = "src/lib/binding/wasm.zig" },
85
+ .root_source_file = b.path("src/lib/wasm.zig"),
87
86
  .optimize = switch (optimize) {
88
87
  .ReleaseFast, .ReleaseSafe => .ReleaseSmall,
89
88
  else => optimize,
90
89
  },
91
- .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
90
+ .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
91
+ .strip = strip,
92
+ .pic = pic,
92
93
  });
93
- lib.addOptions("build_options", options);
94
- lib.setMainPkgPath("./");
95
- lib.stack_size = wasm_stack_size;
96
- lib.rdynamic = true;
97
- lib.strip = strip;
98
- if (pic) lib.force_pic = pic;
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;
99
105
  const opt = b.findProgram(&.{"wasm-opt"}, &.{"./node_modules/.bin"}) catch null;
100
106
  if (optimize != .Debug and opt != null) {
101
107
  const out = b.fmt("build/lib/{s}.wasm", .{name});
102
108
  const sh = b.addSystemCommand(&.{ opt.?, "-O4" });
103
- sh.addArtifactArg(lib);
109
+ sh.addArtifactArg(exe);
104
110
  sh.addArg("-o");
105
- sh.addFileSourceArg(.{ .path = out });
111
+ sh.addFileArg(b.path(out));
106
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);
107
117
  }
108
- lib.install();
109
118
  } else if (dynamic) {
110
119
  const lib = b.addSharedLibrary(.{
111
120
  .name = name,
112
- .root_source_file = .{ .path = "src/lib/binding/c.zig" },
113
- .version = try std.builtin.Version.parse(version),
121
+ .root_source_file = b.path("src/lib/c.zig"),
122
+ .version = try std.SemanticVersion.parse(version),
114
123
  .optimize = optimize,
115
124
  .target = target,
125
+ .strip = strip,
126
+ .pic = pic,
116
127
  });
117
- lib.addOptions("build_options", options);
118
- lib.setMainPkgPath("./");
119
- lib.addIncludePath("src/include");
128
+ lib.root_module.addOptions("build_options", options);
129
+ lib.addIncludePath(b.path("src/include"));
120
130
  maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
121
- if (pic) lib.force_pic = pic;
122
- lib.install();
131
+ b.installArtifact(lib);
123
132
  c = true;
124
133
  } else {
125
134
  const lib = b.addStaticLibrary(.{
126
135
  .name = name,
127
- .root_source_file = .{ .path = "src/lib/binding/c.zig" },
136
+ .root_source_file = b.path("src/lib/c.zig"),
128
137
  .optimize = optimize,
129
138
  .target = target,
139
+ .strip = strip,
140
+ .pic = pic,
130
141
  });
131
- lib.addOptions("build_options", options);
132
- lib.setMainPkgPath("./");
133
- lib.addIncludePath("src/include");
142
+ lib.root_module.addOptions("build_options", options);
143
+ lib.addIncludePath(b.path("src/include"));
134
144
  lib.bundle_compiler_rt = true;
135
145
  maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
136
- if (pic) lib.force_pic = pic;
137
- lib.install();
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);
138
161
  c = true;
139
162
  }
140
163
 
141
164
  if (c) {
142
165
  const header = b.addInstallFileWithDir(
143
- .{ .path = "src/include/pkmn.h" },
166
+ b.path("src/include/pkmn.h"),
144
167
  .header,
145
168
  "pkmn.h",
146
169
  );
147
170
  b.getInstallStep().dependOn(&header.step);
148
171
 
149
172
  const pc = b.fmt("lib{s}.pc", .{name});
150
- const file = try b.cache_root.join(b.allocator, &.{pc});
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
+ );
151
178
  const pkgconfig_file = try std.fs.cwd().createFile(file, .{});
152
179
 
153
180
  const dirname = comptime std.fs.path.dirname(@src().file) orelse ".";
@@ -176,14 +203,16 @@ pub fn build(b: *std.Build) !void {
176
203
  .strip = strip,
177
204
  .cmd = cmd,
178
205
  };
206
+
207
+ // TODO: tests can be run multiple times due to @imports
179
208
  const tests = TestStep.create(b, options, config);
180
209
 
181
- var exes = std.ArrayList(*std.Build.CompileStep).init(b.allocator);
210
+ var exes = std.ArrayList(*std.Build.Step.Compile).init(b.allocator);
182
211
  const tools: ToolConfig = .{
212
+ .showdown = showdown,
213
+ .module = module,
183
214
  .general = config,
184
215
  .tool = .{
185
- .showdown = showdown,
186
- .trace = trace,
187
216
  .tests = if (tests.build) tests else null,
188
217
  .exes = &exes,
189
218
  },
@@ -192,39 +221,42 @@ pub fn build(b: *std.Build) !void {
192
221
  var benchmark_config = tools;
193
222
  benchmark_config.general.optimize = .ReleaseFast;
194
223
  benchmark_config.general.strip = true;
195
- const benchmark = tool(b, "src/test/benchmark.zig", benchmark_config);
224
+ const benchmark = try tool(b, "src/test/benchmark.zig", benchmark_config);
196
225
 
197
226
  var fuzz_config = tools;
198
227
  fuzz_config.general.strip = false;
199
228
  fuzz_config.tool.name = "fuzz";
200
- const fuzz = tool(b, "src/test/benchmark.zig", fuzz_config);
201
-
202
- const serde = tool(b, "src/tools/serde.zig", tools);
203
- const protocol = tool(b, "src/tools/protocol.zig", tools);
204
-
205
- const lint_exe =
206
- b.addExecutable(.{ .name = "lint", .root_source_file = .{ .path = "src/tools/lint.zig" } });
207
- if (tests.build) tests.step.dependOn(&lint_exe.step);
208
- const lint = lint_exe.run();
209
-
210
- b.step("benchmark", "Run benchmark code").dependOn(&benchmark.step);
211
- b.step("fuzz", "Run fuzz tester").dependOn(&fuzz.step);
212
- b.step("lint", "Lint source files").dependOn(&lint.step);
213
- b.step("protocol", "Run protocol dump tool").dependOn(&protocol.step);
214
- b.step("serde", "Run serialization/deserialization tool").dependOn(&serde.step);
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);
215
245
  b.step("test", "Run all tests").dependOn(&tests.step);
216
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
+ }
217
250
  }
218
251
 
219
252
  fn maybeStrip(
220
253
  b: *std.Build,
221
- artifact: *std.Build.CompileStep,
254
+ artifact: *std.Build.Step.Compile,
222
255
  step: *std.Build.Step,
223
- strip: bool,
256
+ strip: ?bool,
224
257
  cmd: ?[]const u8,
225
258
  ) void {
226
- artifact.strip = strip;
227
- if (!strip or cmd == null) return;
259
+ if (!(strip orelse false) or cmd == null) return;
228
260
  // Using `strip -r -u` for dynamic libraries is supposed to work on macOS but doesn't...
229
261
  const mac = builtin.os.tag == .macos;
230
262
  if (mac and artifact.isDynamicLibrary()) return;
@@ -236,97 +268,82 @@ fn maybeStrip(
236
268
  }
237
269
 
238
270
  const Config = struct {
239
- target: std.zig.CrossTarget,
271
+ target: std.Build.ResolvedTarget,
240
272
  optimize: std.builtin.OptimizeMode,
241
- pic: bool,
242
- strip: bool,
273
+ pic: ?bool,
274
+ strip: ?bool,
243
275
  cmd: ?[]const u8,
244
276
  };
245
277
 
246
- const TESTS = .{
247
- "src/lib/common/test.zig",
248
- "src/lib/gen1/test.zig",
249
- "src/lib/gen2/test.zig",
250
- };
251
-
252
278
  const TestStep = struct {
253
279
  step: std.Build.Step,
254
280
  build: bool,
255
281
 
256
- pub fn create(b: *std.Build, options: *std.Build.OptionsStep, config: Config) *TestStep {
282
+ pub fn create(b: *std.Build, options: *std.Build.Step.Options, config: Config) *TestStep {
257
283
  const coverage = b.option([]const u8, "test-coverage", "Generate test coverage");
258
- const test_file = b.option([]const u8, "test-file", "Input file for test");
259
- const test_bin = b.option([]const u8, "test-bin", "Emit test binary to");
260
284
  const test_filter =
261
285
  b.option([]const u8, "test-filter", "Skip tests that do not match filter");
262
- const test_no_exec =
263
- b.option(bool, "test-no-exec", "Compiles test binary without running it") orelse false;
264
286
 
265
287
  const self = b.allocator.create(TestStep) catch @panic("OOM");
266
288
  const step = std.Build.Step.init(.{ .id = .custom, .name = "Run all tests", .owner = b });
267
- self.* = TestStep{ .step = step, .build = test_filter == null };
268
-
269
- const paths: []const []const u8 =
270
- if (test_file) |t| &.{t} else if (coverage != null) &.{"src/lib/test.zig"} else &TESTS;
271
- for (paths) |path| {
272
- const tests = b.addTest(.{
273
- .name = std.fs.path.basename(std.fs.path.dirname(path).?),
274
- .root_source_file = .{ .path = path },
275
- .optimize = config.optimize,
276
- .target = config.target,
277
- });
278
- tests.setMainPkgPath("./");
279
- tests.setFilter(test_filter);
280
- tests.addOptions("build_options", options);
281
- tests.single_threaded = true;
282
- maybeStrip(b, tests, &tests.step, config.strip, config.cmd);
283
- if (config.pic) tests.force_pic = config.pic;
284
- if (test_bin) |bin| {
285
- tests.name = std.fs.path.basename(bin);
286
- if (std.fs.path.dirname(bin)) |dir| tests.setOutputDir(dir);
287
- }
288
- if (coverage) |c| {
289
- tests.setExecCmd(&.{ "kcov", "--include-pattern=src/lib", c, null });
290
- }
291
- self.step.dependOn(if (test_no_exec) &tests.step else &tests.run().step);
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 });
292
304
  }
305
+ self.step.dependOn(&b.addRunArtifact(tests).step);
306
+
293
307
  return self;
294
308
  }
295
309
  };
296
310
 
297
311
  const ToolConfig = struct {
312
+ showdown: ?bool,
313
+ module: *std.Build.Module,
298
314
  general: Config,
299
315
  tool: struct {
300
- showdown: bool,
301
- trace: bool,
302
316
  tests: ?*TestStep,
303
317
  name: ?[]const u8 = null,
304
- exes: *std.ArrayList(*std.Build.CompileStep),
318
+ exes: *std.ArrayList(*std.Build.Step.Compile),
305
319
  },
306
320
  };
307
321
 
308
- fn tool(b: *std.Build, path: []const u8, config: ToolConfig) *std.Build.RunStep {
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
+ };
309
327
  var name = config.tool.name orelse std.fs.path.basename(path);
310
328
  const index = std.mem.lastIndexOfScalar(u8, name, '.');
311
329
  if (index) |i| name = name[0..i];
312
- if (config.tool.showdown) name = b.fmt("{s}-showdown", .{name});
330
+ if (config.showdown orelse false) name = b.fmt("{s}-showdown", .{name});
313
331
 
314
332
  const exe = b.addExecutable(.{
315
333
  .name = name,
316
- .root_source_file = .{ .path = path },
334
+ .root_source_file = b.path(path),
317
335
  .target = config.general.target,
318
336
  .optimize = config.general.optimize,
337
+ .single_threaded = true,
338
+ .strip = config.general.strip,
339
+ .pic = config.general.pic,
319
340
  });
320
- exe.addModule("pkmn", module(b, .{
321
- .showdown = config.tool.showdown,
322
- .trace = config.tool.trace,
323
- }));
324
- exe.single_threaded = true;
325
- if (config.general.pic) exe.force_pic = config.general.pic;
341
+ exe.root_module.addImport("pkmn", config.module);
342
+
326
343
  if (config.tool.tests) |ts| ts.step.dependOn(&exe.step);
327
344
  config.tool.exes.append(exe) catch @panic("OOM");
328
345
 
329
- const run = exe.run();
346
+ const run = b.addRunArtifact(exe);
330
347
  maybeStrip(b, exe, &run.step, config.general.strip, config.general.cmd);
331
348
  if (b.args) |args| run.addArgs(args);
332
349
 
@@ -336,11 +353,11 @@ fn tool(b: *std.Build, path: []const u8, config: ToolConfig) *std.Build.RunStep
336
353
  const ToolsStep = struct {
337
354
  step: std.Build.Step,
338
355
 
339
- pub fn create(b: *std.Build, exes: *std.ArrayList(*std.Build.CompileStep)) *ToolsStep {
356
+ pub fn create(b: *std.Build, exes: *std.ArrayList(*std.Build.Step.Compile)) *ToolsStep {
340
357
  const self = b.allocator.create(ToolsStep) catch @panic("OOM");
341
358
  const step = std.Build.Step.init(.{ .id = .custom, .name = "Install tools", .owner = b });
342
- self.* = ToolsStep{ .step = step };
343
- for (exes.items) |t| self.step.dependOn(&b.addInstallArtifact(t).step);
359
+ self.* = .{ .step = step };
360
+ for (exes.items) |t| self.step.dependOn(&b.addInstallArtifact(t, .{}).step);
344
361
  return self;
345
362
  }
346
363
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pkmn/engine",
3
- "version": "0.1.0-dev.9a0c07c3",
3
+ "version": "0.1.0-dev.a0167a9d",
4
4
  "description": "A minimal, complete, Pokémon battle simulation engine optimized for performance",
5
5
  "repository": "github:pkmn/engine",
6
6
  "license": "MIT",
@@ -11,6 +11,9 @@
11
11
  "build.zig",
12
12
  "build/pkg/data.d.ts",
13
13
  "build/pkg/data.js.map",
14
+ "build/pkg/addon.d.ts",
15
+ "build/pkg/addon.js.map",
16
+ "build/pkg/addon.js",
14
17
  "build/pkg/data.js",
15
18
  "build/pkg/data/ids.json",
16
19
  "build/pkg/data/layout.json",
@@ -28,28 +31,37 @@
28
31
  "build/test/display.js",
29
32
  "build/tools/debug.js.map",
30
33
  "build/tools/debug.js",
31
- "src/bin/install-pkmn-engine",
32
- "src/lib/binding/node.zig",
33
- "src/lib/binding/wasm.zig",
34
+ "src/lib/common/battle.zig",
34
35
  "src/lib/common/data.zig",
35
36
  "src/lib/common/debug.zig",
37
+ "src/lib/common/js.zig",
38
+ "src/lib/common/optional.zig",
36
39
  "src/lib/common/options.zig",
37
40
  "src/lib/common/protocol.zig",
41
+ "src/lib/common/rational.zig",
38
42
  "src/lib/common/rng.zig",
43
+ "src/lib/common/util.zig",
44
+ "src/lib/gen1/calc.zig",
45
+ "src/lib/gen1/chance.zig",
39
46
  "src/lib/gen1/data.zig",
40
47
  "src/lib/gen1/data/moves.zig",
41
48
  "src/lib/gen1/data/species.zig",
42
49
  "src/lib/gen1/data/types.zig",
43
50
  "src/lib/gen1/helpers.zig",
44
51
  "src/lib/gen1/mechanics.zig",
52
+ "src/lib/gen2/calc.zig",
53
+ "src/lib/gen2/chance.zig",
45
54
  "src/lib/gen2/data.zig",
46
55
  "src/lib/gen2/data/items.zig",
47
56
  "src/lib/gen2/data/moves.zig",
48
57
  "src/lib/gen2/data/species.zig",
49
58
  "src/lib/gen2/data/types.zig",
59
+ "src/lib/gen2/generated.zig",
50
60
  "src/lib/gen2/helpers.zig",
51
61
  "src/lib/gen2/mechanics.zig",
62
+ "src/lib/node.zig",
52
63
  "src/lib/pkmn.zig",
64
+ "src/lib/wasm.zig",
53
65
  "src/test/display/pkmn.html.tmpl"
54
66
  ],
55
67
  "engines": {
@@ -63,30 +75,31 @@
63
75
  "access": "public"
64
76
  },
65
77
  "dependencies": {
66
- "@pkmn/data": "^0.7.36",
67
- "@pkmn/protocol": "^0.6.11"
78
+ "@pkmn/data": "^0.9.11",
79
+ "@pkmn/protocol": "^0.6.25"
68
80
  },
69
81
  "devDependencies": {
70
- "@pkmn/eslint-config": "^3.0.0",
71
- "@pkmn/img": "^0.2.8",
72
- "@pkmn/sets": "^5.0.4",
73
- "@pkmn/sim": "0.7.36",
74
- "@types/html-minifier": "^4.0.2",
75
- "@types/jest": "^29.5.0",
76
- "@types/minimist": "^1.2.2",
77
- "@types/mustache": "^4.2.2",
78
- "@types/node": "^18.15.11",
79
- "@vitest/coverage-c8": "^0.29.8",
80
- "binaryen": "^112.0.0",
81
- "eslint": "^8.37.0",
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",
82
94
  "html-minifier": "^4.0.0",
83
- "json-stringify-pretty-compact": "3.0.0",
95
+ "json-stringify-pretty-compact": "4.0.0",
84
96
  "minimist": "^1.2.8",
85
97
  "mustache": "^4.2.0",
86
98
  "source-map-support": "^0.5.21",
99
+ "table": "^6.8.2",
87
100
  "trakr": "^0.2.0",
88
- "typescript": "^5.0.3",
89
- "vitest": "^0.29.8"
101
+ "typescript": "^5.5.4",
102
+ "vitest": "^2.0.5"
90
103
  },
91
104
  "scripts": {
92
105
  "lint": "eslint --cache src --ext ts,js && eslint src/bin/*",
@@ -108,7 +121,7 @@
108
121
  "ignorePatterns": [
109
122
  "dist/",
110
123
  "node_modules/",
111
- "src/examples/zig",
124
+ "examples/zig",
112
125
  "build/"
113
126
  ],
114
127
  "env": {
@@ -124,10 +137,18 @@
124
137
  "parserOptions": {
125
138
  "project": [
126
139
  "./tsconfig.json",
127
- "./src/examples/js/tsconfig.json"
140
+ "./examples/js/tsconfig.json"
128
141
  ]
129
142
  }
130
143
  },
144
+ {
145
+ "files": [
146
+ "src/test/display.ts"
147
+ ],
148
+ "rules": {
149
+ "@typescript-eslint/no-unnecessary-type-assertion": "off"
150
+ }
151
+ },
131
152
  {
132
153
  "files": [
133
154
  "src/pkg/index.ts",
@@ -137,7 +158,8 @@
137
158
  "rules": {
138
159
  "no-control-regex": "off",
139
160
  "@typescript-eslint/no-empty-interface": "off",
140
- "@typescript-eslint/no-shadow": "off"
161
+ "@typescript-eslint/no-shadow": "off",
162
+ "@typescript-eslint/no-unsafe-declaration-merging": "off"
141
163
  }
142
164
  },
143
165
  {
@@ -153,12 +175,23 @@
153
175
  "src/test/benchmark*.ts"
154
176
  ],
155
177
  "rules": {
156
- "@typescript-eslint/no-unused-vars": "off"
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"
157
189
  }
158
190
  },
159
191
  {
160
192
  "files": [
161
- "src/test/*.test.ts"
193
+ "src/test/*.test.ts",
194
+ "src/test/regression/*.test.ts"
162
195
  ],
163
196
  "rules": {
164
197
  "jest/no-standalone-expect": "off"