@pkmn/engine 0.1.0-dev.38984361 → 0.1.0-dev.3a62fd35
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 +44 -13
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/ids.json +12 -12
- package/build/pkg/data/layout.json +2 -2
- package/build/pkg/data/protocol.json +69 -12
- package/build/pkg/data.d.ts +3 -2
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.js +2 -2
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +2 -1
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.js +57 -38
- package/build/pkg/protocol.js.map +1 -1
- package/build/test/display.js.map +1 -1
- package/build/tools/debug.js +3 -1
- package/build/tools/debug.js.map +1 -1
- package/build.zig +103 -71
- package/package.json +34 -21
- package/src/bin/install-pkmn-engine +14 -14
- package/src/lib/common/data.zig +12 -24
- package/src/lib/common/optional.zig +9 -2
- package/src/lib/common/protocol.zig +792 -319
- package/src/lib/common/rational.zig +12 -8
- package/src/lib/common/rng.zig +20 -11
- package/src/lib/gen1/README.md +31 -29
- package/src/lib/gen1/calc.zig +9 -10
- package/src/lib/gen1/chance.zig +76 -60
- package/src/lib/gen1/data/moves.zig +192 -180
- package/src/lib/gen1/data/species.zig +2 -2
- package/src/lib/gen1/data/types.zig +7 -7
- package/src/lib/gen1/data.zig +47 -59
- package/src/lib/gen1/helpers.zig +33 -48
- package/src/lib/gen1/mechanics.zig +324 -368
- package/src/lib/gen2/README.md +93 -72
- package/src/lib/gen2/calc.zig +143 -0
- package/src/lib/gen2/chance.zig +1314 -0
- package/src/lib/gen2/data/items.zig +12 -18
- package/src/lib/gen2/data/moves.zig +663 -569
- package/src/lib/gen2/data/species.zig +1 -1
- package/src/lib/gen2/data/types.zig +134 -31
- package/src/lib/gen2/data.zig +106 -79
- package/src/lib/gen2/generated.zig +806 -0
- package/src/lib/gen2/helpers.zig +8 -12
- package/src/lib/gen2/mechanics.zig +3502 -9
- package/src/lib/{binding/node.zig → node.zig} +10 -13
- package/src/lib/pkmn.zig +26 -3
- package/src/lib/{binding/wasm.zig → wasm.zig} +2 -1
package/build.zig
CHANGED
|
@@ -16,8 +16,8 @@ pub fn module(b: *std.Build, options: Options) *std.Build.Module {
|
|
|
16
16
|
build_options.addOption(?bool, "chance", options.chance);
|
|
17
17
|
build_options.addOption(?bool, "calc", options.calc);
|
|
18
18
|
return b.createModule(.{
|
|
19
|
-
.
|
|
20
|
-
.
|
|
19
|
+
.root_source_file = .{ .path = dirname ++ "/src/lib/pkmn.zig" },
|
|
20
|
+
.imports = &.{.{ .name = "build_options", .module = build_options.createModule() }},
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -32,8 +32,8 @@ pub fn build(b: *std.Build) !void {
|
|
|
32
32
|
const wasm_stack_size =
|
|
33
33
|
b.option(u64, "wasm-stack-size", "The size of WASM stack") orelse std.wasm.page_size;
|
|
34
34
|
const dynamic = b.option(bool, "dynamic", "Build a dynamic library") orelse false;
|
|
35
|
-
const strip = b.option(bool, "strip", "Strip debugging symbols from binary")
|
|
36
|
-
const pic = b.option(bool, "pic", "Force position independent code")
|
|
35
|
+
const strip = b.option(bool, "strip", "Strip debugging symbols from binary");
|
|
36
|
+
const pic = b.option(bool, "pic", "Force position independent code");
|
|
37
37
|
const emit_asm = b.option(bool, "emit-asm", "Output .s (assembly code)") orelse false;
|
|
38
38
|
const emit_ll = b.option(bool, "emit-ll", "Output .ll (LLVM IR)") orelse false;
|
|
39
39
|
|
|
@@ -66,23 +66,23 @@ pub fn build(b: *std.Build) !void {
|
|
|
66
66
|
const addon = b.fmt("{s}.node", .{name});
|
|
67
67
|
const lib = b.addSharedLibrary(.{
|
|
68
68
|
.name = addon,
|
|
69
|
-
.root_source_file = .{ .path = "src/lib/
|
|
69
|
+
.root_source_file = .{ .path = "src/lib/node.zig" },
|
|
70
70
|
.optimize = optimize,
|
|
71
71
|
.target = target,
|
|
72
|
+
.strip = strip,
|
|
73
|
+
.pic = pic,
|
|
72
74
|
});
|
|
73
|
-
lib.addOptions("build_options", options);
|
|
74
|
-
lib.
|
|
75
|
-
lib.addSystemIncludePath(headers);
|
|
75
|
+
lib.root_module.addOptions("build_options", options);
|
|
76
|
+
lib.addSystemIncludePath(.{ .path = headers });
|
|
76
77
|
lib.linkLibC();
|
|
77
78
|
if (node_import_lib) |il| {
|
|
78
|
-
lib.addObjectFile(il);
|
|
79
|
-
} else if (
|
|
79
|
+
lib.addObjectFile(.{ .path = il });
|
|
80
|
+
} else if (target.result.os.tag == .windows) {
|
|
80
81
|
try std.io.getStdErr().writeAll("Must provide --node-import-library path on Windows\n");
|
|
81
82
|
std.process.exit(1);
|
|
82
83
|
}
|
|
83
84
|
lib.linker_allow_shlib_undefined = true;
|
|
84
85
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
85
|
-
if (pic) lib.force_pic = pic;
|
|
86
86
|
// Always emit to build/lib because this is where the driver code expects to find it
|
|
87
87
|
// TODO(ziglang/zig#2231): using the following used to work (though was hacky):
|
|
88
88
|
//
|
|
@@ -93,61 +93,83 @@ pub fn build(b: *std.Build) !void {
|
|
|
93
93
|
// rename the file ourself in install-pkmn-engine
|
|
94
94
|
b.installArtifact(lib);
|
|
95
95
|
} else if (wasm) {
|
|
96
|
-
const
|
|
96
|
+
const exe = b.addExecutable(.{
|
|
97
97
|
.name = name,
|
|
98
|
-
.root_source_file = .{ .path = "src/lib/
|
|
98
|
+
.root_source_file = .{ .path = "src/lib/wasm.zig" },
|
|
99
99
|
.optimize = switch (optimize) {
|
|
100
100
|
.ReleaseFast, .ReleaseSafe => .ReleaseSmall,
|
|
101
101
|
else => optimize,
|
|
102
102
|
},
|
|
103
|
-
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
|
|
103
|
+
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
|
|
104
|
+
.strip = strip,
|
|
105
|
+
.pic = pic,
|
|
104
106
|
});
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
exe.root_module.addOptions("build_options", options);
|
|
108
|
+
exe.root_module.export_symbol_names = &[_][]const u8{
|
|
109
|
+
"SHOWDOWN",
|
|
110
|
+
"LOG",
|
|
111
|
+
"CHANCE",
|
|
112
|
+
"CALC",
|
|
113
|
+
"GEN1_CHOICES_SIZE",
|
|
114
|
+
"GEN1_LOGS_SIZE",
|
|
115
|
+
};
|
|
116
|
+
exe.entry = .disabled;
|
|
117
|
+
exe.stack_size = wasm_stack_size;
|
|
111
118
|
const opt = b.findProgram(&.{"wasm-opt"}, &.{"./node_modules/.bin"}) catch null;
|
|
112
119
|
if (optimize != .Debug and opt != null) {
|
|
113
120
|
const out = b.fmt("build/lib/{s}.wasm", .{name});
|
|
114
121
|
const sh = b.addSystemCommand(&.{ opt.?, "-O4" });
|
|
115
|
-
sh.addArtifactArg(
|
|
122
|
+
sh.addArtifactArg(exe);
|
|
116
123
|
sh.addArg("-o");
|
|
117
|
-
sh.
|
|
124
|
+
sh.addFileArg(.{ .path = out });
|
|
118
125
|
b.getInstallStep().dependOn(&sh.step);
|
|
126
|
+
} else {
|
|
127
|
+
b.getInstallStep().dependOn(&b.addInstallArtifact(exe, .{
|
|
128
|
+
.dest_dir = .{ .override = std.Build.InstallDir{ .lib = {} } },
|
|
129
|
+
}).step);
|
|
119
130
|
}
|
|
120
|
-
b.installArtifact(lib);
|
|
121
131
|
} else if (dynamic) {
|
|
122
132
|
const lib = b.addSharedLibrary(.{
|
|
123
133
|
.name = name,
|
|
124
|
-
.root_source_file = .{ .path = "src/lib/
|
|
134
|
+
.root_source_file = .{ .path = "src/lib/c.zig" },
|
|
125
135
|
.version = try std.SemanticVersion.parse(version),
|
|
126
136
|
.optimize = optimize,
|
|
127
137
|
.target = target,
|
|
138
|
+
.strip = strip,
|
|
139
|
+
.pic = pic,
|
|
128
140
|
});
|
|
129
|
-
lib.addOptions("build_options", options);
|
|
130
|
-
lib.
|
|
131
|
-
lib.addIncludePath("src/include");
|
|
141
|
+
lib.root_module.addOptions("build_options", options);
|
|
142
|
+
lib.addIncludePath(.{ .path = "src/include" });
|
|
132
143
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
133
|
-
if (pic) lib.force_pic = pic;
|
|
134
144
|
b.installArtifact(lib);
|
|
135
145
|
c = true;
|
|
136
146
|
} else {
|
|
137
147
|
const lib = b.addStaticLibrary(.{
|
|
138
148
|
.name = name,
|
|
139
|
-
.root_source_file = .{ .path = "src/lib/
|
|
149
|
+
.root_source_file = .{ .path = "src/lib/c.zig" },
|
|
140
150
|
.optimize = optimize,
|
|
141
151
|
.target = target,
|
|
152
|
+
.strip = strip,
|
|
153
|
+
.pic = pic,
|
|
142
154
|
});
|
|
143
|
-
lib.addOptions("build_options", options);
|
|
144
|
-
lib.
|
|
145
|
-
lib.addIncludePath("src/include");
|
|
155
|
+
lib.root_module.addOptions("build_options", options);
|
|
156
|
+
lib.addIncludePath(.{ .path = "src/include" });
|
|
146
157
|
lib.bundle_compiler_rt = true;
|
|
147
158
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
148
|
-
if (
|
|
149
|
-
|
|
150
|
-
|
|
159
|
+
if (emit_asm) {
|
|
160
|
+
b.getInstallStep().dependOn(&b.addInstallFileWithDir(
|
|
161
|
+
lib.getEmittedAsm(),
|
|
162
|
+
.prefix,
|
|
163
|
+
b.fmt("{s}.s", .{name}),
|
|
164
|
+
).step);
|
|
165
|
+
}
|
|
166
|
+
if (emit_ll) {
|
|
167
|
+
b.getInstallStep().dependOn(&b.addInstallFileWithDir(
|
|
168
|
+
lib.getEmittedLlvmIr(),
|
|
169
|
+
.prefix,
|
|
170
|
+
b.fmt("{s}.ll", .{name}),
|
|
171
|
+
).step);
|
|
172
|
+
}
|
|
151
173
|
b.installArtifact(lib);
|
|
152
174
|
c = true;
|
|
153
175
|
}
|
|
@@ -194,7 +216,7 @@ pub fn build(b: *std.Build) !void {
|
|
|
194
216
|
// TODO: tests can be run multiple times due to @imports
|
|
195
217
|
const tests = TestStep.create(b, options, config);
|
|
196
218
|
|
|
197
|
-
var exes = std.ArrayList(*std.Build.
|
|
219
|
+
var exes = std.ArrayList(*std.Build.Step.Compile).init(b.allocator);
|
|
198
220
|
const tools: ToolConfig = .{
|
|
199
221
|
.options = .{
|
|
200
222
|
.showdown = showdown,
|
|
@@ -212,37 +234,42 @@ pub fn build(b: *std.Build) !void {
|
|
|
212
234
|
var benchmark_config = tools;
|
|
213
235
|
benchmark_config.general.optimize = .ReleaseFast;
|
|
214
236
|
benchmark_config.general.strip = true;
|
|
215
|
-
const benchmark = tool(b, "src/test/benchmark.zig", benchmark_config);
|
|
237
|
+
const benchmark = try tool(b, "src/test/benchmark.zig", benchmark_config);
|
|
216
238
|
|
|
217
239
|
var fuzz_config = tools;
|
|
218
240
|
fuzz_config.general.strip = false;
|
|
219
241
|
fuzz_config.tool.name = "fuzz";
|
|
220
|
-
const fuzz = tool(b, "src/test/fuzz.zig", fuzz_config);
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
const dump = tool(b, "src/tools/dump.zig", tools);
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
b.step("
|
|
242
|
+
const fuzz = try tool(b, "src/test/fuzz.zig", fuzz_config);
|
|
243
|
+
|
|
244
|
+
const analyze = try tool(b, "src/tools/analyze.zig", tools);
|
|
245
|
+
const dump = try tool(b, "src/tools/dump.zig", tools);
|
|
246
|
+
const transitions = try tool(b, "src/tools/transitions.zig", tools);
|
|
247
|
+
|
|
248
|
+
// FIXME: serde randomly fails to build in some release configurations
|
|
249
|
+
var hack = tools;
|
|
250
|
+
if (optimize != .Debug) hack.tool.tests = null;
|
|
251
|
+
const serde = try tool(b, "src/tools/serde.zig", hack);
|
|
252
|
+
|
|
253
|
+
if (analyze) |t| b.step("analyze", "Run LLVM analysis tool").dependOn(&t.step);
|
|
254
|
+
if (benchmark) |t| b.step("benchmark", "Run benchmark code").dependOn(&t.step);
|
|
255
|
+
if (dump) |t| b.step("dump", "Run protocol dump tool").dependOn(&t.step);
|
|
256
|
+
if (fuzz) |t| b.step("fuzz", "Run fuzz tester").dependOn(&t.step);
|
|
257
|
+
if (serde) |t| b.step("serde", "Run serialization/deserialization tool").dependOn(&t.step);
|
|
232
258
|
b.step("test", "Run all tests").dependOn(&tests.step);
|
|
233
259
|
b.step("tools", "Install tools").dependOn(&ToolsStep.create(b, &exes).step);
|
|
234
|
-
|
|
260
|
+
if (transitions) |t| {
|
|
261
|
+
b.step("transitions", "Visualize transitions algorithm search").dependOn(&t.step);
|
|
262
|
+
}
|
|
235
263
|
}
|
|
236
264
|
|
|
237
265
|
fn maybeStrip(
|
|
238
266
|
b: *std.Build,
|
|
239
|
-
artifact: *std.Build.
|
|
267
|
+
artifact: *std.Build.Step.Compile,
|
|
240
268
|
step: *std.Build.Step,
|
|
241
|
-
strip: bool,
|
|
269
|
+
strip: ?bool,
|
|
242
270
|
cmd: ?[]const u8,
|
|
243
271
|
) void {
|
|
244
|
-
|
|
245
|
-
if (!strip or cmd == null) return;
|
|
272
|
+
if (!(strip orelse false) or cmd == null) return;
|
|
246
273
|
// Using `strip -r -u` for dynamic libraries is supposed to work on macOS but doesn't...
|
|
247
274
|
const mac = builtin.os.tag == .macos;
|
|
248
275
|
if (mac and artifact.isDynamicLibrary()) return;
|
|
@@ -254,10 +281,10 @@ fn maybeStrip(
|
|
|
254
281
|
}
|
|
255
282
|
|
|
256
283
|
const Config = struct {
|
|
257
|
-
target: std.
|
|
284
|
+
target: std.Build.ResolvedTarget,
|
|
258
285
|
optimize: std.builtin.OptimizeMode,
|
|
259
|
-
pic: bool,
|
|
260
|
-
strip: bool,
|
|
286
|
+
pic: ?bool,
|
|
287
|
+
strip: ?bool,
|
|
261
288
|
cmd: ?[]const u8,
|
|
262
289
|
};
|
|
263
290
|
|
|
@@ -265,7 +292,7 @@ const TestStep = struct {
|
|
|
265
292
|
step: std.Build.Step,
|
|
266
293
|
build: bool,
|
|
267
294
|
|
|
268
|
-
pub fn create(b: *std.Build, options: *std.Build.
|
|
295
|
+
pub fn create(b: *std.Build, options: *std.Build.Step.Options, config: Config) *TestStep {
|
|
269
296
|
const coverage = b.option([]const u8, "test-coverage", "Generate test coverage");
|
|
270
297
|
const test_file = b.option([]const u8, "test-file", "Input file for test");
|
|
271
298
|
const test_filter =
|
|
@@ -273,7 +300,7 @@ const TestStep = struct {
|
|
|
273
300
|
|
|
274
301
|
const self = b.allocator.create(TestStep) catch @panic("OOM");
|
|
275
302
|
const step = std.Build.Step.init(.{ .id = .custom, .name = "Run all tests", .owner = b });
|
|
276
|
-
self.* =
|
|
303
|
+
self.* = .{ .step = step, .build = test_filter == null };
|
|
277
304
|
|
|
278
305
|
const path = test_file orelse "src/lib/test.zig";
|
|
279
306
|
const tests = b.addTest(.{
|
|
@@ -285,12 +312,12 @@ const TestStep = struct {
|
|
|
285
312
|
.optimize = config.optimize,
|
|
286
313
|
.target = config.target,
|
|
287
314
|
.filter = test_filter,
|
|
315
|
+
.single_threaded = true,
|
|
316
|
+
.strip = config.strip,
|
|
317
|
+
.pic = config.pic,
|
|
288
318
|
});
|
|
289
|
-
tests.
|
|
290
|
-
tests.addOptions("build_options", options);
|
|
291
|
-
tests.single_threaded = true;
|
|
319
|
+
tests.root_module.addOptions("build_options", options);
|
|
292
320
|
maybeStrip(b, tests, &tests.step, config.strip, config.cmd);
|
|
293
|
-
if (config.pic) tests.force_pic = config.pic;
|
|
294
321
|
if (coverage) |c| {
|
|
295
322
|
tests.setExecCmd(&.{ "kcov", "--include-pattern=src/lib", c, null });
|
|
296
323
|
}
|
|
@@ -306,11 +333,15 @@ const ToolConfig = struct {
|
|
|
306
333
|
tool: struct {
|
|
307
334
|
tests: ?*TestStep,
|
|
308
335
|
name: ?[]const u8 = null,
|
|
309
|
-
exes: *std.ArrayList(*std.Build.
|
|
336
|
+
exes: *std.ArrayList(*std.Build.Step.Compile),
|
|
310
337
|
},
|
|
311
338
|
};
|
|
312
339
|
|
|
313
|
-
fn tool(b: *std.Build, path: []const u8, config: ToolConfig)
|
|
340
|
+
fn tool(b: *std.Build, path: []const u8, config: ToolConfig) !?*std.Build.Step.Run {
|
|
341
|
+
std.fs.cwd().access(path, .{}) catch |err| switch (err) {
|
|
342
|
+
error.FileNotFound => return null,
|
|
343
|
+
else => |e| return e,
|
|
344
|
+
};
|
|
314
345
|
var name = config.tool.name orelse std.fs.path.basename(path);
|
|
315
346
|
const index = std.mem.lastIndexOfScalar(u8, name, '.');
|
|
316
347
|
if (index) |i| name = name[0..i];
|
|
@@ -321,11 +352,12 @@ fn tool(b: *std.Build, path: []const u8, config: ToolConfig) *std.Build.RunStep
|
|
|
321
352
|
.root_source_file = .{ .path = path },
|
|
322
353
|
.target = config.general.target,
|
|
323
354
|
.optimize = config.general.optimize,
|
|
355
|
+
.single_threaded = true,
|
|
356
|
+
.strip = config.general.strip,
|
|
357
|
+
.pic = config.general.pic,
|
|
324
358
|
});
|
|
325
|
-
exe.
|
|
359
|
+
exe.root_module.addImport("pkmn", module(b, config.options));
|
|
326
360
|
|
|
327
|
-
exe.single_threaded = true;
|
|
328
|
-
if (config.general.pic) exe.force_pic = config.general.pic;
|
|
329
361
|
if (config.tool.tests) |ts| ts.step.dependOn(&exe.step);
|
|
330
362
|
config.tool.exes.append(exe) catch @panic("OOM");
|
|
331
363
|
|
|
@@ -339,11 +371,11 @@ fn tool(b: *std.Build, path: []const u8, config: ToolConfig) *std.Build.RunStep
|
|
|
339
371
|
const ToolsStep = struct {
|
|
340
372
|
step: std.Build.Step,
|
|
341
373
|
|
|
342
|
-
pub fn create(b: *std.Build, exes: *std.ArrayList(*std.Build.
|
|
374
|
+
pub fn create(b: *std.Build, exes: *std.ArrayList(*std.Build.Step.Compile)) *ToolsStep {
|
|
343
375
|
const self = b.allocator.create(ToolsStep) catch @panic("OOM");
|
|
344
376
|
const step = std.Build.Step.init(.{ .id = .custom, .name = "Install tools", .owner = b });
|
|
345
|
-
self.* =
|
|
346
|
-
for (exes.items) |t| self.step.dependOn(&b.addInstallArtifact(t).step);
|
|
377
|
+
self.* = .{ .step = step };
|
|
378
|
+
for (exes.items) |t| self.step.dependOn(&b.addInstallArtifact(t, .{}).step);
|
|
347
379
|
return self;
|
|
348
380
|
}
|
|
349
381
|
};
|
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.3a62fd35",
|
|
4
4
|
"description": "A minimal, complete, Pokémon battle simulation engine optimized for performance",
|
|
5
5
|
"repository": "github:pkmn/engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,8 +32,6 @@
|
|
|
32
32
|
"build/tools/debug.js.map",
|
|
33
33
|
"build/tools/debug.js",
|
|
34
34
|
"src/bin/install-pkmn-engine",
|
|
35
|
-
"src/lib/binding/node.zig",
|
|
36
|
-
"src/lib/binding/wasm.zig",
|
|
37
35
|
"src/lib/common/battle.zig",
|
|
38
36
|
"src/lib/common/data.zig",
|
|
39
37
|
"src/lib/common/debug.zig",
|
|
@@ -52,14 +50,19 @@
|
|
|
52
50
|
"src/lib/gen1/data/types.zig",
|
|
53
51
|
"src/lib/gen1/helpers.zig",
|
|
54
52
|
"src/lib/gen1/mechanics.zig",
|
|
53
|
+
"src/lib/gen2/calc.zig",
|
|
54
|
+
"src/lib/gen2/chance.zig",
|
|
55
55
|
"src/lib/gen2/data.zig",
|
|
56
56
|
"src/lib/gen2/data/items.zig",
|
|
57
57
|
"src/lib/gen2/data/moves.zig",
|
|
58
58
|
"src/lib/gen2/data/species.zig",
|
|
59
59
|
"src/lib/gen2/data/types.zig",
|
|
60
|
+
"src/lib/gen2/generated.zig",
|
|
60
61
|
"src/lib/gen2/helpers.zig",
|
|
61
62
|
"src/lib/gen2/mechanics.zig",
|
|
63
|
+
"src/lib/node.zig",
|
|
62
64
|
"src/lib/pkmn.zig",
|
|
65
|
+
"src/lib/wasm.zig",
|
|
63
66
|
"src/test/display/pkmn.html.tmpl"
|
|
64
67
|
],
|
|
65
68
|
"engines": {
|
|
@@ -73,30 +76,31 @@
|
|
|
73
76
|
"access": "public"
|
|
74
77
|
},
|
|
75
78
|
"dependencies": {
|
|
76
|
-
"@pkmn/data": "^0.
|
|
77
|
-
"@pkmn/protocol": "^0.6.
|
|
79
|
+
"@pkmn/data": "^0.8.1",
|
|
80
|
+
"@pkmn/protocol": "^0.6.17"
|
|
78
81
|
},
|
|
79
82
|
"devDependencies": {
|
|
80
|
-
"@pkmn/eslint-config": "^
|
|
81
|
-
"@pkmn/img": "^0.2.
|
|
82
|
-
"@pkmn/sets": "^5.0
|
|
83
|
-
"@pkmn/sim": "0.
|
|
84
|
-
"@types/html-minifier": "^4.0.
|
|
85
|
-
"@types/jest": "^29.5.
|
|
86
|
-
"@types/minimist": "^1.2.
|
|
87
|
-
"@types/mustache": "^4.2.
|
|
88
|
-
"@types/node": "^20.
|
|
89
|
-
"@vitest/coverage-
|
|
90
|
-
"binaryen": "^
|
|
91
|
-
"eslint": "^8.
|
|
83
|
+
"@pkmn/eslint-config": "^6.4.0",
|
|
84
|
+
"@pkmn/img": "^0.2.20",
|
|
85
|
+
"@pkmn/sets": "^5.1.0",
|
|
86
|
+
"@pkmn/sim": "0.8.1",
|
|
87
|
+
"@types/html-minifier": "^4.0.5",
|
|
88
|
+
"@types/jest": "^29.5.11",
|
|
89
|
+
"@types/minimist": "^1.2.5",
|
|
90
|
+
"@types/mustache": "^4.2.5",
|
|
91
|
+
"@types/node": "^20.10.5",
|
|
92
|
+
"@vitest/coverage-v8": "^1.0.4",
|
|
93
|
+
"binaryen": "^116.0.0",
|
|
94
|
+
"eslint": "^8.56.0",
|
|
92
95
|
"html-minifier": "^4.0.0",
|
|
93
96
|
"json-stringify-pretty-compact": "3.0.0",
|
|
94
97
|
"minimist": "^1.2.8",
|
|
95
98
|
"mustache": "^4.2.0",
|
|
96
99
|
"source-map-support": "^0.5.21",
|
|
100
|
+
"table": "^6.8.1",
|
|
97
101
|
"trakr": "^0.2.0",
|
|
98
|
-
"typescript": "^5.
|
|
99
|
-
"vitest": "^0.
|
|
102
|
+
"typescript": "^5.3.3",
|
|
103
|
+
"vitest": "^1.0.4"
|
|
100
104
|
},
|
|
101
105
|
"scripts": {
|
|
102
106
|
"lint": "eslint --cache src --ext ts,js && eslint src/bin/*",
|
|
@@ -118,7 +122,7 @@
|
|
|
118
122
|
"ignorePatterns": [
|
|
119
123
|
"dist/",
|
|
120
124
|
"node_modules/",
|
|
121
|
-
"
|
|
125
|
+
"examples/zig",
|
|
122
126
|
"build/"
|
|
123
127
|
],
|
|
124
128
|
"env": {
|
|
@@ -134,7 +138,7 @@
|
|
|
134
138
|
"parserOptions": {
|
|
135
139
|
"project": [
|
|
136
140
|
"./tsconfig.json",
|
|
137
|
-
"./
|
|
141
|
+
"./examples/js/tsconfig.json"
|
|
138
142
|
]
|
|
139
143
|
}
|
|
140
144
|
},
|
|
@@ -168,6 +172,15 @@
|
|
|
168
172
|
"@typescript-eslint/no-redundant-type-constituents": "off"
|
|
169
173
|
}
|
|
170
174
|
},
|
|
175
|
+
{
|
|
176
|
+
"files": [
|
|
177
|
+
"src/pkg/protocol.test.ts"
|
|
178
|
+
],
|
|
179
|
+
"rules": {
|
|
180
|
+
"jest/no-standalone-expect": "off",
|
|
181
|
+
"jest/no-conditional-expect": "off"
|
|
182
|
+
}
|
|
183
|
+
},
|
|
171
184
|
{
|
|
172
185
|
"files": [
|
|
173
186
|
"src/test/*.test.ts",
|
|
@@ -10,7 +10,7 @@ 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:
|
|
13
|
+
const ZIG_VERSION = {major: 0, minor: 12, patch: 0, dev: 2036};
|
|
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';
|
|
@@ -283,19 +283,19 @@ const downloadImportLib = async () => {
|
|
|
283
283
|
let error = false;
|
|
284
284
|
for (let i = 2; i < process.argv.length; i++) {
|
|
285
285
|
switch (process.argv[i]) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
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
299
|
}
|
|
300
300
|
}
|
|
301
301
|
if (error) {
|
package/src/lib/common/data.zig
CHANGED
|
@@ -9,12 +9,12 @@ pub const Player = enum(u1) {
|
|
|
9
9
|
P2,
|
|
10
10
|
|
|
11
11
|
/// Returns a player's opponent.
|
|
12
|
-
pub
|
|
12
|
+
pub fn foe(self: Player) Player {
|
|
13
13
|
return @enumFromInt(~@intFromEnum(self));
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/// Return's an identifier for the player's Pokémon at the one-indexed `id`.
|
|
17
|
-
pub
|
|
17
|
+
pub fn ident(self: Player, id: u3) ID {
|
|
18
18
|
assert(id > 0 and id <= 6);
|
|
19
19
|
return .{ .id = id, .player = self };
|
|
20
20
|
}
|
|
@@ -22,42 +22,38 @@ pub const Player = enum(u1) {
|
|
|
22
22
|
|
|
23
23
|
test Player {
|
|
24
24
|
try expectEqual(Player.P2, Player.P1.foe());
|
|
25
|
-
try expectEqual(
|
|
26
|
-
try expectEqual(
|
|
25
|
+
try expectEqual(0b0001, @as(u8, @bitCast(Player.P1.ident(1))));
|
|
26
|
+
try expectEqual(0b1101, @as(u8, @bitCast(Player.P2.ident(5))));
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/// An identifier for a specific Pokémon in battle.
|
|
30
|
-
pub const ID = packed struct {
|
|
30
|
+
pub const ID = packed struct(u8) {
|
|
31
31
|
/// The one-indexed team slot of the Pokémon
|
|
32
32
|
id: u3 = 0,
|
|
33
33
|
/// The Pokémon's trainer.
|
|
34
34
|
player: Player = .P1,
|
|
35
35
|
_: u4 = 0,
|
|
36
36
|
|
|
37
|
-
comptime {
|
|
38
|
-
assert(@sizeOf(ID) == 1);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
37
|
/// Converts the identifier into a number.
|
|
42
|
-
pub
|
|
38
|
+
pub fn int(self: ID) u4 {
|
|
43
39
|
return @intCast(@as(u8, @bitCast(self)));
|
|
44
40
|
}
|
|
45
41
|
|
|
46
42
|
/// Decodes the identifier from a number.
|
|
47
|
-
pub
|
|
43
|
+
pub fn from(id: u4) ID {
|
|
48
44
|
return @bitCast(@as(u8, id));
|
|
49
45
|
}
|
|
50
46
|
};
|
|
51
47
|
|
|
52
48
|
test ID {
|
|
53
|
-
try expectEqual(
|
|
54
|
-
try expectEqual(
|
|
55
|
-
const id =
|
|
49
|
+
try expectEqual(0b0001, @as(u8, @bitCast(ID{ .player = .P1, .id = 1 })));
|
|
50
|
+
try expectEqual(0b1101, @as(u8, @bitCast(ID{ .player = .P2, .id = 5 })));
|
|
51
|
+
const id: ID = .{ .player = .P2, .id = 4 };
|
|
56
52
|
try expectEqual(id, ID.from(id.int()));
|
|
57
53
|
}
|
|
58
54
|
|
|
59
55
|
/// A choice made by a player during battle.
|
|
60
|
-
pub const Choice = packed struct {
|
|
56
|
+
pub const Choice = packed struct(u8) {
|
|
61
57
|
/// The choice type.
|
|
62
58
|
type: Choice.Type = .Pass,
|
|
63
59
|
/// The choice data:
|
|
@@ -73,10 +69,6 @@ pub const Choice = packed struct {
|
|
|
73
69
|
Move,
|
|
74
70
|
Switch,
|
|
75
71
|
};
|
|
76
|
-
|
|
77
|
-
comptime {
|
|
78
|
-
assert(@sizeOf(Choice) == 1);
|
|
79
|
-
}
|
|
80
72
|
};
|
|
81
73
|
|
|
82
74
|
test Choice {
|
|
@@ -89,7 +81,7 @@ test Choice {
|
|
|
89
81
|
}
|
|
90
82
|
|
|
91
83
|
/// The result of the battle - all results other than 'None' should be considered terminal.
|
|
92
|
-
pub const Result = packed struct {
|
|
84
|
+
pub const Result = packed struct(u8) {
|
|
93
85
|
/// The type of result from the perspective of Player 1.
|
|
94
86
|
/// `Error` is not possible when in Pokémon Showdown compatibility mode.
|
|
95
87
|
type: Result.Type = .None,
|
|
@@ -117,10 +109,6 @@ pub const Result = packed struct {
|
|
|
117
109
|
pub const Error: Result = .{ .type = .Error };
|
|
118
110
|
/// The default result.
|
|
119
111
|
pub const Default: Result = .{ .p1 = .Move, .p2 = .Move };
|
|
120
|
-
|
|
121
|
-
comptime {
|
|
122
|
-
assert(@sizeOf(Result) == 1);
|
|
123
|
-
}
|
|
124
112
|
};
|
|
125
113
|
|
|
126
114
|
test Result {
|
|
@@ -14,6 +14,7 @@ pub fn Optional(comptime T: type) type {
|
|
|
14
14
|
var decls = [_]std.builtin.Type.Declaration{};
|
|
15
15
|
|
|
16
16
|
enumFields[0] = .{ .name = "None", .value = 0 };
|
|
17
|
+
|
|
17
18
|
inline for (fields, 1..) |field, i| {
|
|
18
19
|
assert(!std.mem.eql(u8, field.name, "None"));
|
|
19
20
|
enumFields[i] = .{
|
|
@@ -24,7 +25,7 @@ pub fn Optional(comptime T: type) type {
|
|
|
24
25
|
|
|
25
26
|
return @Type(.{
|
|
26
27
|
.Enum = .{
|
|
27
|
-
.tag_type = std.math.IntFittingRange(0, fields.len
|
|
28
|
+
.tag_type = std.math.IntFittingRange(0, fields.len),
|
|
28
29
|
.fields = &enumFields,
|
|
29
30
|
.decls = &decls,
|
|
30
31
|
.is_exhaustive = true,
|
|
@@ -45,7 +46,7 @@ test Optional {
|
|
|
45
46
|
try expect(b != .true);
|
|
46
47
|
try expect(b != .false);
|
|
47
48
|
|
|
48
|
-
const Player = @import("
|
|
49
|
+
const Player = @import("data.zig").Player;
|
|
49
50
|
try expect(@bitSizeOf(Optional(Player)) == 2);
|
|
50
51
|
|
|
51
52
|
const p: Optional(Player) = .P2;
|
|
@@ -57,4 +58,10 @@ test Optional {
|
|
|
57
58
|
try expect(q == .None);
|
|
58
59
|
try expect(q != .P1);
|
|
59
60
|
try expect(q != .P2);
|
|
61
|
+
|
|
62
|
+
const Three = enum(u2) { A, B, C };
|
|
63
|
+
try expect(@bitSizeOf(Optional(Three)) == 2);
|
|
64
|
+
|
|
65
|
+
const Four = enum(u2) { A, B, C, D };
|
|
66
|
+
try expect(@bitSizeOf(Optional(Four)) == 3);
|
|
60
67
|
}
|