@pkmn/engine 0.1.0-dev.437f6a52 → 0.1.0-dev.44b2e6ec
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 +77 -46
- 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 +91 -65
- package/package.json +43 -21
- package/src/bin/install-pkmn-engine +2 -2
- package/src/lib/binding/node.zig +7 -11
- package/src/lib/common/battle.zig +17 -0
- package/src/lib/common/data.zig +8 -20
- package/src/lib/common/js.zig +118 -0
- package/src/lib/common/optional.zig +67 -0
- package/src/lib/common/protocol.zig +795 -312
- package/src/lib/common/rational.zig +357 -0
- package/src/lib/common/rng.zig +15 -6
- package/src/lib/common/util.zig +12 -0
- package/src/lib/gen1/README.md +273 -193
- package/src/lib/gen1/calc.zig +426 -0
- package/src/lib/gen1/chance.zig +1060 -0
- 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 +44 -51
- package/src/lib/gen1/helpers.zig +254 -116
- package/src/lib/gen1/mechanics.zig +330 -399
- package/src/lib/gen2/README.md +105 -85
- 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 +100 -73
- 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/build.zig
CHANGED
|
@@ -35,6 +35,7 @@ pub fn build(b: *std.Build) !void {
|
|
|
35
35
|
const strip = b.option(bool, "strip", "Strip debugging symbols from binary") orelse false;
|
|
36
36
|
const pic = b.option(bool, "pic", "Force position independent code") orelse false;
|
|
37
37
|
const emit_asm = b.option(bool, "emit-asm", "Output .s (assembly code)") orelse false;
|
|
38
|
+
const emit_ll = b.option(bool, "emit-ll", "Output .ll (LLVM IR)") orelse false;
|
|
38
39
|
|
|
39
40
|
const cmd = b.findProgram(&.{"strip"}, &.{}) catch null;
|
|
40
41
|
|
|
@@ -65,16 +66,16 @@ pub fn build(b: *std.Build) !void {
|
|
|
65
66
|
const addon = b.fmt("{s}.node", .{name});
|
|
66
67
|
const lib = b.addSharedLibrary(.{
|
|
67
68
|
.name = addon,
|
|
69
|
+
.main_pkg_path = .{ .path = "." },
|
|
68
70
|
.root_source_file = .{ .path = "src/lib/binding/node.zig" },
|
|
69
71
|
.optimize = optimize,
|
|
70
72
|
.target = target,
|
|
71
73
|
});
|
|
72
74
|
lib.addOptions("build_options", options);
|
|
73
|
-
lib.
|
|
74
|
-
lib.addSystemIncludePath(headers);
|
|
75
|
+
lib.addSystemIncludePath(.{ .path = headers });
|
|
75
76
|
lib.linkLibC();
|
|
76
77
|
if (node_import_lib) |il| {
|
|
77
|
-
lib.addObjectFile(il);
|
|
78
|
+
lib.addObjectFile(.{ .path = il });
|
|
78
79
|
} else if ((try std.zig.system.NativeTargetInfo.detect(target)).target.os.tag == .windows) {
|
|
79
80
|
try std.io.getStdErr().writeAll("Must provide --node-import-library path on Windows\n");
|
|
80
81
|
std.process.exit(1);
|
|
@@ -92,8 +93,9 @@ pub fn build(b: *std.Build) !void {
|
|
|
92
93
|
// rename the file ourself in install-pkmn-engine
|
|
93
94
|
b.installArtifact(lib);
|
|
94
95
|
} else if (wasm) {
|
|
95
|
-
const
|
|
96
|
+
const exe = b.addExecutable(.{
|
|
96
97
|
.name = name,
|
|
98
|
+
.main_pkg_path = .{ .path = "." },
|
|
97
99
|
.root_source_file = .{ .path = "src/lib/binding/wasm.zig" },
|
|
98
100
|
.optimize = switch (optimize) {
|
|
99
101
|
.ReleaseFast, .ReleaseSafe => .ReleaseSmall,
|
|
@@ -101,33 +103,43 @@ pub fn build(b: *std.Build) !void {
|
|
|
101
103
|
},
|
|
102
104
|
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
|
|
103
105
|
});
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
exe.addOptions("build_options", options);
|
|
107
|
+
exe.export_symbol_names = &[_][]const u8{
|
|
108
|
+
"SHOWDOWN",
|
|
109
|
+
"LOG",
|
|
110
|
+
"CHANCE",
|
|
111
|
+
"CALC",
|
|
112
|
+
"GEN1_CHOICES_SIZE",
|
|
113
|
+
"GEN1_LOGS_SIZE",
|
|
114
|
+
};
|
|
115
|
+
exe.entry = .disabled;
|
|
116
|
+
exe.stack_size = wasm_stack_size;
|
|
117
|
+
exe.strip = strip;
|
|
118
|
+
if (pic) exe.force_pic = pic;
|
|
110
119
|
const opt = b.findProgram(&.{"wasm-opt"}, &.{"./node_modules/.bin"}) catch null;
|
|
111
120
|
if (optimize != .Debug and opt != null) {
|
|
112
121
|
const out = b.fmt("build/lib/{s}.wasm", .{name});
|
|
113
122
|
const sh = b.addSystemCommand(&.{ opt.?, "-O4" });
|
|
114
|
-
sh.addArtifactArg(
|
|
123
|
+
sh.addArtifactArg(exe);
|
|
115
124
|
sh.addArg("-o");
|
|
116
125
|
sh.addFileSourceArg(.{ .path = out });
|
|
117
126
|
b.getInstallStep().dependOn(&sh.step);
|
|
127
|
+
} else {
|
|
128
|
+
b.getInstallStep().dependOn(&b.addInstallArtifact(exe, .{
|
|
129
|
+
.dest_dir = .{ .override = std.Build.InstallDir{ .lib = {} } },
|
|
130
|
+
}).step);
|
|
118
131
|
}
|
|
119
|
-
b.installArtifact(lib);
|
|
120
132
|
} else if (dynamic) {
|
|
121
133
|
const lib = b.addSharedLibrary(.{
|
|
122
134
|
.name = name,
|
|
135
|
+
.main_pkg_path = .{ .path = "." },
|
|
123
136
|
.root_source_file = .{ .path = "src/lib/binding/c.zig" },
|
|
124
137
|
.version = try std.SemanticVersion.parse(version),
|
|
125
138
|
.optimize = optimize,
|
|
126
139
|
.target = target,
|
|
127
140
|
});
|
|
128
141
|
lib.addOptions("build_options", options);
|
|
129
|
-
lib.
|
|
130
|
-
lib.addIncludePath("src/include");
|
|
142
|
+
lib.addIncludePath(.{ .path = "src/include" });
|
|
131
143
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
132
144
|
if (pic) lib.force_pic = pic;
|
|
133
145
|
b.installArtifact(lib);
|
|
@@ -135,17 +147,30 @@ pub fn build(b: *std.Build) !void {
|
|
|
135
147
|
} else {
|
|
136
148
|
const lib = b.addStaticLibrary(.{
|
|
137
149
|
.name = name,
|
|
150
|
+
.main_pkg_path = .{ .path = "." },
|
|
138
151
|
.root_source_file = .{ .path = "src/lib/binding/c.zig" },
|
|
139
152
|
.optimize = optimize,
|
|
140
153
|
.target = target,
|
|
141
154
|
});
|
|
142
155
|
lib.addOptions("build_options", options);
|
|
143
|
-
lib.
|
|
144
|
-
lib.addIncludePath("src/include");
|
|
156
|
+
lib.addIncludePath(.{ .path = "src/include" });
|
|
145
157
|
lib.bundle_compiler_rt = true;
|
|
146
158
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
147
159
|
if (pic) lib.force_pic = pic;
|
|
148
|
-
if (emit_asm)
|
|
160
|
+
if (emit_asm) {
|
|
161
|
+
b.getInstallStep().dependOn(&b.addInstallFileWithDir(
|
|
162
|
+
lib.getEmittedAsm(),
|
|
163
|
+
.prefix,
|
|
164
|
+
b.fmt("{s}.s", .{name}),
|
|
165
|
+
).step);
|
|
166
|
+
}
|
|
167
|
+
if (emit_ll) {
|
|
168
|
+
b.getInstallStep().dependOn(&b.addInstallFileWithDir(
|
|
169
|
+
lib.getEmittedLlvmIr(),
|
|
170
|
+
.prefix,
|
|
171
|
+
b.fmt("{s}.ll", .{name}),
|
|
172
|
+
).step);
|
|
173
|
+
}
|
|
149
174
|
b.installArtifact(lib);
|
|
150
175
|
c = true;
|
|
151
176
|
}
|
|
@@ -210,30 +235,32 @@ pub fn build(b: *std.Build) !void {
|
|
|
210
235
|
var benchmark_config = tools;
|
|
211
236
|
benchmark_config.general.optimize = .ReleaseFast;
|
|
212
237
|
benchmark_config.general.strip = true;
|
|
213
|
-
const benchmark = tool(b, "src/test/benchmark.zig", benchmark_config);
|
|
238
|
+
const benchmark = try tool(b, "src/test/benchmark.zig", benchmark_config);
|
|
214
239
|
|
|
215
240
|
var fuzz_config = tools;
|
|
216
241
|
fuzz_config.general.strip = false;
|
|
217
242
|
fuzz_config.tool.name = "fuzz";
|
|
218
|
-
const fuzz = tool(b, "src/test/fuzz.zig", fuzz_config);
|
|
219
|
-
|
|
220
|
-
const
|
|
221
|
-
const
|
|
222
|
-
const transitions = tool(b, "src/tools/transitions.zig", tools);
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
b.step("
|
|
230
|
-
b.step("
|
|
231
|
-
b.step("
|
|
232
|
-
b.step("
|
|
233
|
-
b.step("serde", "Run serialization/deserialization tool").dependOn(&
|
|
243
|
+
const fuzz = try tool(b, "src/test/fuzz.zig", fuzz_config);
|
|
244
|
+
|
|
245
|
+
const analyze = try tool(b, "src/tools/analyze.zig", tools);
|
|
246
|
+
const dump = try tool(b, "src/tools/dump.zig", tools);
|
|
247
|
+
const transitions = try tool(b, "src/tools/transitions.zig", tools);
|
|
248
|
+
|
|
249
|
+
// FIXME: serde randomly fails to build in some release configurations
|
|
250
|
+
var hack = tools;
|
|
251
|
+
if (optimize != .Debug) hack.tool.tests = null;
|
|
252
|
+
const serde = try tool(b, "src/tools/serde.zig", hack);
|
|
253
|
+
|
|
254
|
+
if (analyze) |t| b.step("analyze", "Run LLVM analysis tool").dependOn(&t.step);
|
|
255
|
+
if (benchmark) |t| b.step("benchmark", "Run benchmark code").dependOn(&t.step);
|
|
256
|
+
if (dump) |t| b.step("dump", "Run protocol dump tool").dependOn(&t.step);
|
|
257
|
+
if (fuzz) |t| b.step("fuzz", "Run fuzz tester").dependOn(&t.step);
|
|
258
|
+
if (serde) |t| b.step("serde", "Run serialization/deserialization tool").dependOn(&t.step);
|
|
234
259
|
b.step("test", "Run all tests").dependOn(&tests.step);
|
|
235
260
|
b.step("tools", "Install tools").dependOn(&ToolsStep.create(b, &exes).step);
|
|
236
|
-
|
|
261
|
+
if (transitions) |t| {
|
|
262
|
+
b.step("transitions", "Visualize transitions algorithm search").dependOn(&t.step);
|
|
263
|
+
}
|
|
237
264
|
}
|
|
238
265
|
|
|
239
266
|
fn maybeStrip(
|
|
@@ -263,12 +290,6 @@ const Config = struct {
|
|
|
263
290
|
cmd: ?[]const u8,
|
|
264
291
|
};
|
|
265
292
|
|
|
266
|
-
const TESTS = .{
|
|
267
|
-
"src/lib/common/test.zig",
|
|
268
|
-
"src/lib/gen1/test.zig",
|
|
269
|
-
"src/lib/gen2/test.zig",
|
|
270
|
-
};
|
|
271
|
-
|
|
272
293
|
const TestStep = struct {
|
|
273
294
|
step: std.Build.Step,
|
|
274
295
|
build: bool,
|
|
@@ -281,28 +302,29 @@ const TestStep = struct {
|
|
|
281
302
|
|
|
282
303
|
const self = b.allocator.create(TestStep) catch @panic("OOM");
|
|
283
304
|
const step = std.Build.Step.init(.{ .id = .custom, .name = "Run all tests", .owner = b });
|
|
284
|
-
self.* =
|
|
285
|
-
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
self.step.dependOn(&b.addRunArtifact(tests).step);
|
|
305
|
+
self.* = .{ .step = step, .build = test_filter == null };
|
|
306
|
+
|
|
307
|
+
const path = test_file orelse "src/lib/test.zig";
|
|
308
|
+
const tests = b.addTest(.{
|
|
309
|
+
.name = b.fmt("{s}-{s}", .{
|
|
310
|
+
std.fs.path.basename(std.fs.path.dirname(path).?),
|
|
311
|
+
std.fs.path.stem(std.fs.path.basename(path)),
|
|
312
|
+
}),
|
|
313
|
+
.main_pkg_path = .{ .path = "." },
|
|
314
|
+
.root_source_file = .{ .path = path },
|
|
315
|
+
.optimize = config.optimize,
|
|
316
|
+
.target = config.target,
|
|
317
|
+
.filter = test_filter,
|
|
318
|
+
});
|
|
319
|
+
tests.addOptions("build_options", options);
|
|
320
|
+
tests.single_threaded = true;
|
|
321
|
+
maybeStrip(b, tests, &tests.step, config.strip, config.cmd);
|
|
322
|
+
if (config.pic) tests.force_pic = config.pic;
|
|
323
|
+
if (coverage) |c| {
|
|
324
|
+
tests.setExecCmd(&.{ "kcov", "--include-pattern=src/lib", c, null });
|
|
305
325
|
}
|
|
326
|
+
self.step.dependOn(&b.addRunArtifact(tests).step);
|
|
327
|
+
|
|
306
328
|
return self;
|
|
307
329
|
}
|
|
308
330
|
};
|
|
@@ -317,7 +339,11 @@ const ToolConfig = struct {
|
|
|
317
339
|
},
|
|
318
340
|
};
|
|
319
341
|
|
|
320
|
-
fn tool(b: *std.Build, path: []const u8, config: ToolConfig)
|
|
342
|
+
fn tool(b: *std.Build, path: []const u8, config: ToolConfig) !?*std.Build.RunStep {
|
|
343
|
+
std.fs.cwd().access(path, .{}) catch |err| switch (err) {
|
|
344
|
+
error.FileNotFound => return null,
|
|
345
|
+
else => |e| return e,
|
|
346
|
+
};
|
|
321
347
|
var name = config.tool.name orelse std.fs.path.basename(path);
|
|
322
348
|
const index = std.mem.lastIndexOfScalar(u8, name, '.');
|
|
323
349
|
if (index) |i| name = name[0..i];
|
|
@@ -349,8 +375,8 @@ const ToolsStep = struct {
|
|
|
349
375
|
pub fn create(b: *std.Build, exes: *std.ArrayList(*std.Build.CompileStep)) *ToolsStep {
|
|
350
376
|
const self = b.allocator.create(ToolsStep) catch @panic("OOM");
|
|
351
377
|
const step = std.Build.Step.init(.{ .id = .custom, .name = "Install tools", .owner = b });
|
|
352
|
-
self.* =
|
|
353
|
-
for (exes.items) |t| self.step.dependOn(&b.addInstallArtifact(t).step);
|
|
378
|
+
self.* = .{ .step = step };
|
|
379
|
+
for (exes.items) |t| self.step.dependOn(&b.addInstallArtifact(t, .{}).step);
|
|
354
380
|
return self;
|
|
355
381
|
}
|
|
356
382
|
};
|
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.44b2e6ec",
|
|
4
4
|
"description": "A minimal, complete, Pokémon battle simulation engine optimized for performance",
|
|
5
5
|
"repository": "github:pkmn/engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,22 +34,32 @@
|
|
|
34
34
|
"src/bin/install-pkmn-engine",
|
|
35
35
|
"src/lib/binding/node.zig",
|
|
36
36
|
"src/lib/binding/wasm.zig",
|
|
37
|
+
"src/lib/common/battle.zig",
|
|
37
38
|
"src/lib/common/data.zig",
|
|
38
39
|
"src/lib/common/debug.zig",
|
|
40
|
+
"src/lib/common/js.zig",
|
|
41
|
+
"src/lib/common/optional.zig",
|
|
39
42
|
"src/lib/common/options.zig",
|
|
40
43
|
"src/lib/common/protocol.zig",
|
|
44
|
+
"src/lib/common/rational.zig",
|
|
41
45
|
"src/lib/common/rng.zig",
|
|
46
|
+
"src/lib/common/util.zig",
|
|
47
|
+
"src/lib/gen1/calc.zig",
|
|
48
|
+
"src/lib/gen1/chance.zig",
|
|
42
49
|
"src/lib/gen1/data.zig",
|
|
43
50
|
"src/lib/gen1/data/moves.zig",
|
|
44
51
|
"src/lib/gen1/data/species.zig",
|
|
45
52
|
"src/lib/gen1/data/types.zig",
|
|
46
53
|
"src/lib/gen1/helpers.zig",
|
|
47
54
|
"src/lib/gen1/mechanics.zig",
|
|
55
|
+
"src/lib/gen2/calc.zig",
|
|
56
|
+
"src/lib/gen2/chance.zig",
|
|
48
57
|
"src/lib/gen2/data.zig",
|
|
49
58
|
"src/lib/gen2/data/items.zig",
|
|
50
59
|
"src/lib/gen2/data/moves.zig",
|
|
51
60
|
"src/lib/gen2/data/species.zig",
|
|
52
61
|
"src/lib/gen2/data/types.zig",
|
|
62
|
+
"src/lib/gen2/generated.zig",
|
|
53
63
|
"src/lib/gen2/helpers.zig",
|
|
54
64
|
"src/lib/gen2/mechanics.zig",
|
|
55
65
|
"src/lib/pkmn.zig",
|
|
@@ -66,30 +76,31 @@
|
|
|
66
76
|
"access": "public"
|
|
67
77
|
},
|
|
68
78
|
"dependencies": {
|
|
69
|
-
"@pkmn/data": "^0.7.
|
|
70
|
-
"@pkmn/protocol": "^0.6.
|
|
79
|
+
"@pkmn/data": "^0.7.54",
|
|
80
|
+
"@pkmn/protocol": "^0.6.16"
|
|
71
81
|
},
|
|
72
82
|
"devDependencies": {
|
|
73
|
-
"@pkmn/eslint-config": "^3.
|
|
74
|
-
"@pkmn/img": "^0.2.
|
|
75
|
-
"@pkmn/sets": "^5.0
|
|
76
|
-
"@pkmn/sim": "0.7.
|
|
77
|
-
"@types/html-minifier": "^4.0.
|
|
78
|
-
"@types/jest": "^29.5.
|
|
79
|
-
"@types/minimist": "^1.2.
|
|
80
|
-
"@types/mustache": "^4.2.
|
|
81
|
-
"@types/node": "^20.
|
|
82
|
-
"@vitest/coverage-c8": "^0.
|
|
83
|
-
"binaryen": "^
|
|
84
|
-
"eslint": "^8.
|
|
83
|
+
"@pkmn/eslint-config": "^5.3.0",
|
|
84
|
+
"@pkmn/img": "^0.2.18",
|
|
85
|
+
"@pkmn/sets": "^5.1.0",
|
|
86
|
+
"@pkmn/sim": "0.7.54",
|
|
87
|
+
"@types/html-minifier": "^4.0.4",
|
|
88
|
+
"@types/jest": "^29.5.6",
|
|
89
|
+
"@types/minimist": "^1.2.4",
|
|
90
|
+
"@types/mustache": "^4.2.4",
|
|
91
|
+
"@types/node": "^20.8.9",
|
|
92
|
+
"@vitest/coverage-c8": "^0.33.0",
|
|
93
|
+
"binaryen": "^116.0.0",
|
|
94
|
+
"eslint": "^8.52.0",
|
|
85
95
|
"html-minifier": "^4.0.0",
|
|
86
96
|
"json-stringify-pretty-compact": "3.0.0",
|
|
87
97
|
"minimist": "^1.2.8",
|
|
88
98
|
"mustache": "^4.2.0",
|
|
89
99
|
"source-map-support": "^0.5.21",
|
|
100
|
+
"table": "^6.8.1",
|
|
90
101
|
"trakr": "^0.2.0",
|
|
91
|
-
"typescript": "^5.
|
|
92
|
-
"vitest": "^0.
|
|
102
|
+
"typescript": "^5.2.2",
|
|
103
|
+
"vitest": "^0.34.6"
|
|
93
104
|
},
|
|
94
105
|
"scripts": {
|
|
95
106
|
"lint": "eslint --cache src --ext ts,js && eslint src/bin/*",
|
|
@@ -111,7 +122,7 @@
|
|
|
111
122
|
"ignorePatterns": [
|
|
112
123
|
"dist/",
|
|
113
124
|
"node_modules/",
|
|
114
|
-
"
|
|
125
|
+
"examples/zig",
|
|
115
126
|
"build/"
|
|
116
127
|
],
|
|
117
128
|
"env": {
|
|
@@ -127,7 +138,7 @@
|
|
|
127
138
|
"parserOptions": {
|
|
128
139
|
"project": [
|
|
129
140
|
"./tsconfig.json",
|
|
130
|
-
"./
|
|
141
|
+
"./examples/js/tsconfig.json"
|
|
131
142
|
]
|
|
132
143
|
}
|
|
133
144
|
},
|
|
@@ -140,7 +151,8 @@
|
|
|
140
151
|
"rules": {
|
|
141
152
|
"no-control-regex": "off",
|
|
142
153
|
"@typescript-eslint/no-empty-interface": "off",
|
|
143
|
-
"@typescript-eslint/no-shadow": "off"
|
|
154
|
+
"@typescript-eslint/no-shadow": "off",
|
|
155
|
+
"@typescript-eslint/no-unsafe-declaration-merging": "off"
|
|
144
156
|
}
|
|
145
157
|
},
|
|
146
158
|
{
|
|
@@ -156,7 +168,17 @@
|
|
|
156
168
|
"src/test/benchmark*.ts"
|
|
157
169
|
],
|
|
158
170
|
"rules": {
|
|
159
|
-
"@typescript-eslint/no-unused-vars": "off"
|
|
171
|
+
"@typescript-eslint/no-unused-vars": "off",
|
|
172
|
+
"@typescript-eslint/no-redundant-type-constituents": "off"
|
|
173
|
+
}
|
|
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"
|
|
160
182
|
}
|
|
161
183
|
},
|
|
162
184
|
{
|
|
@@ -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: 1396};
|
|
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';
|
|
@@ -358,7 +358,7 @@ const downloadImportLib = async () => {
|
|
|
358
358
|
// either the default options or whatever was passed in
|
|
359
359
|
if (!configs.size) {
|
|
360
360
|
node = true;
|
|
361
|
-
const DEFAULT = ['-Dshowdown'
|
|
361
|
+
const DEFAULT = ['-Dshowdown'];
|
|
362
362
|
configs.set('node', {type: 'node', options: options || DEFAULT});
|
|
363
363
|
configs.set('wasm', {type: 'wasm', options: options || DEFAULT});
|
|
364
364
|
}
|
package/src/lib/binding/node.zig
CHANGED
|
@@ -19,7 +19,7 @@ export fn napi_register_module_v1(env: c.napi_env, exports: c.napi_value) c.napi
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
pub fn register(env: c.napi_env) c.napi_value {
|
|
22
|
-
|
|
22
|
+
const object = js.Object.init(env);
|
|
23
23
|
const properties = [_]c.napi_property_descriptor{
|
|
24
24
|
js.Property.init("options", .{ .value = options(env) }),
|
|
25
25
|
js.Property.init("bindings", .{ .value = bindings(env) }),
|
|
@@ -29,7 +29,7 @@ pub fn register(env: c.napi_env) c.napi_value {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
fn options(env: c.napi_env) c.napi_value {
|
|
32
|
-
|
|
32
|
+
const object = js.Object.init(env);
|
|
33
33
|
const properties = [_]c.napi_property_descriptor{
|
|
34
34
|
js.Property.init("showdown", .{ .value = js.Boolean.init(env, pkmn.options.showdown) }),
|
|
35
35
|
js.Property.init("log", .{ .value = js.Boolean.init(env, pkmn.options.log) }),
|
|
@@ -41,7 +41,7 @@ fn options(env: c.napi_env) c.napi_value {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
fn bindings(env: c.napi_env) c.napi_value {
|
|
44
|
-
|
|
44
|
+
const array = js.Array.init(env, .{ .length = 1 });
|
|
45
45
|
js.Array.set(env, array, 0, bind(env, pkmn.gen1));
|
|
46
46
|
return array;
|
|
47
47
|
}
|
|
@@ -49,7 +49,7 @@ fn bindings(env: c.napi_env) c.napi_value {
|
|
|
49
49
|
fn bind(env: c.napi_env, gen: anytype) c.napi_value {
|
|
50
50
|
const choices_size: u32 = @intCast(gen.CHOICES_SIZE);
|
|
51
51
|
const logs_size: u32 = @intCast(gen.LOGS_SIZE);
|
|
52
|
-
|
|
52
|
+
const object = js.Object.init(env);
|
|
53
53
|
const properties = [_]c.napi_property_descriptor{
|
|
54
54
|
js.Property.init("CHOICES_SIZE", .{ .value = js.Number.init(env, choices_size) }),
|
|
55
55
|
js.Property.init("LOGS_SIZE", .{ .value = js.Number.init(env, logs_size) }),
|
|
@@ -72,7 +72,6 @@ fn update(gen: anytype) c.napi_callback {
|
|
|
72
72
|
var len: usize = 0;
|
|
73
73
|
assert(c.napi_get_arraybuffer_info(env, argv[0], &data, &len) == c.napi_ok);
|
|
74
74
|
assert(len == @sizeOf(gen.Battle(gen.PRNG)));
|
|
75
|
-
assert(data != null);
|
|
76
75
|
|
|
77
76
|
var battle: *gen.Battle(gen.PRNG) = @alignCast(@ptrCast(data.?));
|
|
78
77
|
const c1: pkmn.Choice = @bitCast(js.Number.get(env, argv[1], u8));
|
|
@@ -85,10 +84,9 @@ fn update(gen: anytype) c.napi_callback {
|
|
|
85
84
|
else => result: {
|
|
86
85
|
assert(c.napi_get_arraybuffer_info(env, argv[3], &data, &len) == c.napi_ok);
|
|
87
86
|
assert(len == gen.LOGS_SIZE);
|
|
88
|
-
assert(data != null);
|
|
89
87
|
|
|
90
|
-
|
|
91
|
-
var stream
|
|
88
|
+
const buf = @as([*]u8, @ptrCast(data.?))[0..gen.LOGS_SIZE];
|
|
89
|
+
var stream: pkmn.protocol.ByteStream = .{ .buffer = buf };
|
|
92
90
|
// TODO: extract out
|
|
93
91
|
var opts = pkmn.battle.options(
|
|
94
92
|
pkmn.protocol.FixedLog{ .writer = stream.writer() },
|
|
@@ -116,7 +114,6 @@ fn choices(gen: anytype) c.napi_callback {
|
|
|
116
114
|
var len: usize = 0;
|
|
117
115
|
assert(c.napi_get_arraybuffer_info(env, argv[0], &data, &len) == c.napi_ok);
|
|
118
116
|
assert(len == @sizeOf(gen.Battle(gen.PRNG)));
|
|
119
|
-
assert(data != null);
|
|
120
117
|
|
|
121
118
|
var battle: *gen.Battle(gen.PRNG) = @alignCast(@ptrCast(data.?));
|
|
122
119
|
const player: pkmn.Player = @enumFromInt(js.Number.get(env, argv[1], u8));
|
|
@@ -124,9 +121,8 @@ fn choices(gen: anytype) c.napi_callback {
|
|
|
124
121
|
|
|
125
122
|
assert(c.napi_get_arraybuffer_info(env, argv[3], &data, &len) == c.napi_ok);
|
|
126
123
|
assert(len == gen.CHOICES_SIZE);
|
|
127
|
-
assert(data != null);
|
|
128
124
|
|
|
129
|
-
|
|
125
|
+
const out = @as([*]pkmn.Choice, @ptrCast(data.?))[0..gen.CHOICES_SIZE];
|
|
130
126
|
const n = battle.choices(player, request, out);
|
|
131
127
|
return js.Number.init(env, @as(u8, @bitCast(n)));
|
|
132
128
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// Stores state required by optional features to the engine that can be passed to a generation's
|
|
2
|
+
/// `Battle.update` function. All generations generically support protocol logging (enabled via
|
|
3
|
+
/// `-Dlog`), chance actions and probability tracking (enabled via `-Dchance`), and damage
|
|
4
|
+
/// computation and chance overrides (`-Dcalc`), though the concrete types for these features are
|
|
5
|
+
/// generation dependent.
|
|
6
|
+
pub fn Options(comptime Log: type, comptime Chance: type, comptime Calc: type) type {
|
|
7
|
+
return struct { log: Log, chance: Chance, calc: Calc };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/// Helper to create a battle `Options` object with the provided `log`, `chance`, and `calc`.
|
|
11
|
+
pub fn options(
|
|
12
|
+
log: anytype,
|
|
13
|
+
chance: anytype,
|
|
14
|
+
calc: anytype,
|
|
15
|
+
) Options(@TypeOf(log), @TypeOf(chance), @TypeOf(calc)) {
|
|
16
|
+
return .{ .log = log, .chance = chance, .calc = calc };
|
|
17
|
+
}
|
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
|
}
|
|
@@ -27,24 +27,20 @@ test Player {
|
|
|
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
|
};
|
|
@@ -52,12 +48,12 @@ pub const ID = packed struct {
|
|
|
52
48
|
test ID {
|
|
53
49
|
try expectEqual(@as(u8, 0b0001), @as(u8, @bitCast(ID{ .player = .P1, .id = 1 })));
|
|
54
50
|
try expectEqual(@as(u8, 0b1101), @as(u8, @bitCast(ID{ .player = .P2, .id = 5 })));
|
|
55
|
-
const id =
|
|
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 {
|