@pkmn/engine 0.1.0-dev.dd5b9081 → 0.1.0-dev.deda8593
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/LICENSE +1 -3
- package/README.md +44 -19
- package/build/pkg/addon.js +6 -7
- 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 +4 -4
- 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 +61 -42
- package/build/pkg/protocol.js.map +1 -1
- package/build/test/display.js +2 -2
- package/build/test/display.js.map +1 -1
- package/build/tools/debug.js +5 -4
- package/build/tools/debug.js.map +1 -1
- package/build.zig +102 -104
- package/package.json +43 -23
- package/src/bin/install-pkmn-engine +26 -18
- package/src/lib/common/data.zig +9 -9
- package/src/lib/common/debug.zig +2 -2
- package/src/lib/common/optional.zig +9 -2
- package/src/lib/common/options.zig +2 -0
- package/src/lib/common/protocol.zig +739 -318
- package/src/lib/common/rational.zig +12 -9
- package/src/lib/common/rng.zig +25 -16
- package/src/lib/gen1/calc.zig +219 -49
- package/src/lib/gen1/chance.zig +138 -115
- package/src/lib/gen1/data/moves.zig +190 -176
- package/src/lib/gen1/data/species.zig +3 -3
- package/src/lib/gen1/data/types.zig +7 -7
- package/src/lib/gen1/data.zig +44 -44
- package/src/lib/gen1/helpers.zig +148 -82
- package/src/lib/gen1/mechanics.zig +392 -406
- package/src/lib/gen2/calc.zig +143 -0
- package/src/lib/gen2/chance.zig +1315 -0
- package/src/lib/gen2/data/items.zig +12 -18
- package/src/lib/gen2/data/moves.zig +377 -344
- package/src/lib/gen2/data/species.zig +1 -1
- package/src/lib/gen2/data/types.zig +134 -31
- package/src/lib/gen2/data.zig +52 -44
- package/src/lib/gen2/generated.zig +806 -0
- package/src/lib/gen2/helpers.zig +37 -7
- package/src/lib/gen2/mechanics.zig +3086 -211
- package/src/lib/{binding/node.zig → node.zig} +10 -13
- package/src/lib/pkmn.zig +27 -12
- package/src/lib/{binding/wasm.zig → wasm.zig} +2 -1
- package/src/test/display/pkmn.html.tmpl +5 -5
- package/src/lib/gen1/README.md +0 -894
- package/src/lib/gen2/README.md +0 -383
package/build.zig
CHANGED
|
@@ -1,26 +1,6 @@
|
|
|
1
1
|
const std = @import("std");
|
|
2
2
|
const builtin = @import("builtin");
|
|
3
3
|
|
|
4
|
-
pub const Options = struct {
|
|
5
|
-
showdown: ?bool = null,
|
|
6
|
-
log: ?bool = null,
|
|
7
|
-
chance: ?bool = null,
|
|
8
|
-
calc: ?bool = null,
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
pub fn module(b: *std.Build, options: Options) *std.Build.Module {
|
|
12
|
-
const dirname = comptime std.fs.path.dirname(@src().file) orelse ".";
|
|
13
|
-
const build_options = b.addOptions();
|
|
14
|
-
build_options.addOption(?bool, "showdown", options.showdown);
|
|
15
|
-
build_options.addOption(?bool, "log", options.log);
|
|
16
|
-
build_options.addOption(?bool, "chance", options.chance);
|
|
17
|
-
build_options.addOption(?bool, "calc", options.calc);
|
|
18
|
-
return b.createModule(.{
|
|
19
|
-
.source_file = .{ .path = dirname ++ "/src/lib/pkmn.zig" },
|
|
20
|
-
.dependencies = &.{.{ .name = "build_options", .module = build_options.createModule() }},
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
4
|
pub fn build(b: *std.Build) !void {
|
|
25
5
|
const target = b.standardTargetOptions(.{});
|
|
26
6
|
const optimize = b.standardOptimizeOption(.{});
|
|
@@ -32,8 +12,8 @@ pub fn build(b: *std.Build) !void {
|
|
|
32
12
|
const wasm_stack_size =
|
|
33
13
|
b.option(u64, "wasm-stack-size", "The size of WASM stack") orelse std.wasm.page_size;
|
|
34
14
|
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")
|
|
15
|
+
const strip = b.option(bool, "strip", "Strip debugging symbols from binary");
|
|
16
|
+
const pic = b.option(bool, "pic", "Force position independent code");
|
|
37
17
|
const emit_asm = b.option(bool, "emit-asm", "Output .s (assembly code)") orelse false;
|
|
38
18
|
const emit_ll = b.option(bool, "emit-ll", "Output .ll (LLVM IR)") orelse false;
|
|
39
19
|
|
|
@@ -44,7 +24,7 @@ pub fn build(b: *std.Build) !void {
|
|
|
44
24
|
defer parsed.deinit();
|
|
45
25
|
const version = parsed.value.object.get("version").?.string;
|
|
46
26
|
const description = parsed.value.object.get("description").?.string;
|
|
47
|
-
var repository = std.mem.
|
|
27
|
+
var repository = std.mem.splitSequence(u8, parsed.value.object.get("repository").?.string, ":");
|
|
48
28
|
std.debug.assert(std.mem.eql(u8, repository.first(), "github"));
|
|
49
29
|
|
|
50
30
|
const showdown =
|
|
@@ -61,30 +41,37 @@ pub fn build(b: *std.Build) !void {
|
|
|
61
41
|
|
|
62
42
|
const name = if (showdown) "pkmn-showdown" else "pkmn";
|
|
63
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
|
+
|
|
64
51
|
var c = false;
|
|
65
52
|
if (node_headers) |headers| {
|
|
66
53
|
const addon = b.fmt("{s}.node", .{name});
|
|
67
54
|
const lib = b.addSharedLibrary(.{
|
|
68
55
|
.name = addon,
|
|
69
|
-
.
|
|
70
|
-
.root_source_file = .{ .path = "src/lib/binding/node.zig" },
|
|
56
|
+
.root_source_file = b.path("src/lib/node.zig"),
|
|
71
57
|
.optimize = optimize,
|
|
72
58
|
.target = target,
|
|
59
|
+
.strip = strip,
|
|
60
|
+
.pic = pic,
|
|
73
61
|
});
|
|
74
|
-
lib.addOptions("build_options", options);
|
|
75
|
-
lib.addSystemIncludePath(.
|
|
62
|
+
lib.root_module.addOptions("build_options", options);
|
|
63
|
+
lib.addSystemIncludePath(b.path(headers));
|
|
76
64
|
lib.linkLibC();
|
|
77
65
|
if (node_import_lib) |il| {
|
|
78
|
-
lib.addObjectFile(.
|
|
79
|
-
} else if (
|
|
66
|
+
lib.addObjectFile(b.path(il));
|
|
67
|
+
} else if (target.result.os.tag == .windows) {
|
|
80
68
|
try std.io.getStdErr().writeAll("Must provide --node-import-library path on Windows\n");
|
|
81
69
|
std.process.exit(1);
|
|
82
70
|
}
|
|
83
71
|
lib.linker_allow_shlib_undefined = true;
|
|
84
72
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
85
|
-
if (pic) lib.force_pic = pic;
|
|
86
73
|
// Always emit to build/lib because this is where the driver code expects to find it
|
|
87
|
-
// TODO
|
|
74
|
+
// TODO: ziglang/zig#2231 - using the following used to work (though was hacky):
|
|
88
75
|
//
|
|
89
76
|
// lib.emit_bin = .{ .emit_to = b.fmt("build/lib/{s}", .{addon}) };
|
|
90
77
|
// b.getInstallStep().dependOn(&lib.step);
|
|
@@ -93,59 +80,69 @@ pub fn build(b: *std.Build) !void {
|
|
|
93
80
|
// rename the file ourself in install-pkmn-engine
|
|
94
81
|
b.installArtifact(lib);
|
|
95
82
|
} else if (wasm) {
|
|
96
|
-
const
|
|
83
|
+
const exe = b.addExecutable(.{
|
|
97
84
|
.name = name,
|
|
98
|
-
.
|
|
99
|
-
.root_source_file = .{ .path = "src/lib/binding/wasm.zig" },
|
|
85
|
+
.root_source_file = b.path("src/lib/wasm.zig"),
|
|
100
86
|
.optimize = switch (optimize) {
|
|
101
87
|
.ReleaseFast, .ReleaseSafe => .ReleaseSmall,
|
|
102
88
|
else => optimize,
|
|
103
89
|
},
|
|
104
|
-
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
|
|
90
|
+
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
|
|
91
|
+
.strip = strip,
|
|
92
|
+
.pic = pic,
|
|
105
93
|
});
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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;
|
|
111
105
|
const opt = b.findProgram(&.{"wasm-opt"}, &.{"./node_modules/.bin"}) catch null;
|
|
112
106
|
if (optimize != .Debug and opt != null) {
|
|
113
107
|
const out = b.fmt("build/lib/{s}.wasm", .{name});
|
|
114
108
|
const sh = b.addSystemCommand(&.{ opt.?, "-O4" });
|
|
115
|
-
sh.addArtifactArg(
|
|
109
|
+
sh.addArtifactArg(exe);
|
|
116
110
|
sh.addArg("-o");
|
|
117
|
-
sh.
|
|
111
|
+
sh.addFileArg(b.path(out));
|
|
118
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);
|
|
119
117
|
}
|
|
120
|
-
b.installArtifact(lib);
|
|
121
118
|
} else if (dynamic) {
|
|
122
119
|
const lib = b.addSharedLibrary(.{
|
|
123
120
|
.name = name,
|
|
124
|
-
.
|
|
125
|
-
.root_source_file = .{ .path = "src/lib/binding/c.zig" },
|
|
121
|
+
.root_source_file = b.path("src/lib/c.zig"),
|
|
126
122
|
.version = try std.SemanticVersion.parse(version),
|
|
127
123
|
.optimize = optimize,
|
|
128
124
|
.target = target,
|
|
125
|
+
.strip = strip,
|
|
126
|
+
.pic = pic,
|
|
129
127
|
});
|
|
130
|
-
lib.addOptions("build_options", options);
|
|
131
|
-
lib.addIncludePath(.
|
|
128
|
+
lib.root_module.addOptions("build_options", options);
|
|
129
|
+
lib.addIncludePath(b.path("src/include"));
|
|
132
130
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
133
|
-
if (pic) lib.force_pic = pic;
|
|
134
131
|
b.installArtifact(lib);
|
|
135
132
|
c = true;
|
|
136
133
|
} else {
|
|
137
134
|
const lib = b.addStaticLibrary(.{
|
|
138
135
|
.name = name,
|
|
139
|
-
.
|
|
140
|
-
.root_source_file = .{ .path = "src/lib/binding/c.zig" },
|
|
136
|
+
.root_source_file = b.path("src/lib/c.zig"),
|
|
141
137
|
.optimize = optimize,
|
|
142
138
|
.target = target,
|
|
139
|
+
.strip = strip,
|
|
140
|
+
.pic = pic,
|
|
143
141
|
});
|
|
144
|
-
lib.addOptions("build_options", options);
|
|
145
|
-
lib.addIncludePath(.
|
|
142
|
+
lib.root_module.addOptions("build_options", options);
|
|
143
|
+
lib.addIncludePath(b.path("src/include"));
|
|
146
144
|
lib.bundle_compiler_rt = true;
|
|
147
145
|
maybeStrip(b, lib, b.getInstallStep(), strip, cmd);
|
|
148
|
-
if (pic) lib.force_pic = pic;
|
|
149
146
|
if (emit_asm) {
|
|
150
147
|
b.getInstallStep().dependOn(&b.addInstallFileWithDir(
|
|
151
148
|
lib.getEmittedAsm(),
|
|
@@ -166,14 +163,18 @@ pub fn build(b: *std.Build) !void {
|
|
|
166
163
|
|
|
167
164
|
if (c) {
|
|
168
165
|
const header = b.addInstallFileWithDir(
|
|
169
|
-
.
|
|
166
|
+
b.path("src/include/pkmn.h"),
|
|
170
167
|
.header,
|
|
171
168
|
"pkmn.h",
|
|
172
169
|
);
|
|
173
170
|
b.getInstallStep().dependOn(&header.step);
|
|
174
171
|
|
|
175
172
|
const pc = b.fmt("lib{s}.pc", .{name});
|
|
176
|
-
const file = try
|
|
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
|
+
);
|
|
177
178
|
const pkgconfig_file = try std.fs.cwd().createFile(file, .{});
|
|
178
179
|
|
|
179
180
|
const dirname = comptime std.fs.path.dirname(@src().file) orelse ".";
|
|
@@ -206,14 +207,10 @@ pub fn build(b: *std.Build) !void {
|
|
|
206
207
|
// TODO: tests can be run multiple times due to @imports
|
|
207
208
|
const tests = TestStep.create(b, options, config);
|
|
208
209
|
|
|
209
|
-
var exes = std.ArrayList(*std.Build.
|
|
210
|
+
var exes = std.ArrayList(*std.Build.Step.Compile).init(b.allocator);
|
|
210
211
|
const tools: ToolConfig = .{
|
|
211
|
-
.
|
|
212
|
-
|
|
213
|
-
.log = log,
|
|
214
|
-
.chance = chance,
|
|
215
|
-
.calc = calc,
|
|
216
|
-
},
|
|
212
|
+
.showdown = showdown,
|
|
213
|
+
.module = module,
|
|
217
214
|
.general = config,
|
|
218
215
|
.tool = .{
|
|
219
216
|
.tests = if (tests.build) tests else null,
|
|
@@ -224,41 +221,42 @@ pub fn build(b: *std.Build) !void {
|
|
|
224
221
|
var benchmark_config = tools;
|
|
225
222
|
benchmark_config.general.optimize = .ReleaseFast;
|
|
226
223
|
benchmark_config.general.strip = true;
|
|
227
|
-
const benchmark = tool(b, "src/test/benchmark.zig", benchmark_config);
|
|
224
|
+
const benchmark = try tool(b, "src/test/benchmark.zig", benchmark_config);
|
|
228
225
|
|
|
229
226
|
var fuzz_config = tools;
|
|
230
227
|
fuzz_config.general.strip = false;
|
|
231
228
|
fuzz_config.tool.name = "fuzz";
|
|
232
|
-
const fuzz = tool(b, "src/test/fuzz.zig", fuzz_config);
|
|
229
|
+
const fuzz = try tool(b, "src/test/fuzz.zig", fuzz_config);
|
|
233
230
|
|
|
234
|
-
const analyze = tool(b, "src/tools/analyze.zig", tools);
|
|
235
|
-
const dump = tool(b, "src/tools/dump.zig", tools);
|
|
236
|
-
const transitions = tool(b, "src/tools/transitions.zig", tools);
|
|
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);
|
|
237
234
|
|
|
238
235
|
// FIXME: serde randomly fails to build in some release configurations
|
|
239
236
|
var hack = tools;
|
|
240
237
|
if (optimize != .Debug) hack.tool.tests = null;
|
|
241
|
-
const serde = tool(b, "src/tools/serde.zig", hack);
|
|
238
|
+
const serde = try tool(b, "src/tools/serde.zig", hack);
|
|
242
239
|
|
|
243
|
-
b.step("analyze", "Run LLVM analysis tool").dependOn(&
|
|
244
|
-
b.step("benchmark", "Run benchmark code").dependOn(&
|
|
245
|
-
b.step("dump", "Run protocol dump tool").dependOn(&
|
|
246
|
-
b.step("fuzz", "Run fuzz tester").dependOn(&
|
|
247
|
-
b.step("serde", "Run serialization/deserialization tool").dependOn(&
|
|
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);
|
|
248
245
|
b.step("test", "Run all tests").dependOn(&tests.step);
|
|
249
246
|
b.step("tools", "Install tools").dependOn(&ToolsStep.create(b, &exes).step);
|
|
250
|
-
|
|
247
|
+
if (transitions) |t| {
|
|
248
|
+
b.step("transitions", "Visualize transitions algorithm search").dependOn(&t.step);
|
|
249
|
+
}
|
|
251
250
|
}
|
|
252
251
|
|
|
253
252
|
fn maybeStrip(
|
|
254
253
|
b: *std.Build,
|
|
255
|
-
artifact: *std.Build.
|
|
254
|
+
artifact: *std.Build.Step.Compile,
|
|
256
255
|
step: *std.Build.Step,
|
|
257
|
-
strip: bool,
|
|
256
|
+
strip: ?bool,
|
|
258
257
|
cmd: ?[]const u8,
|
|
259
258
|
) void {
|
|
260
|
-
|
|
261
|
-
if (!strip or cmd == null) return;
|
|
259
|
+
if (!(strip orelse false) or cmd == null) return;
|
|
262
260
|
// Using `strip -r -u` for dynamic libraries is supposed to work on macOS but doesn't...
|
|
263
261
|
const mac = builtin.os.tag == .macos;
|
|
264
262
|
if (mac and artifact.isDynamicLibrary()) return;
|
|
@@ -270,10 +268,10 @@ fn maybeStrip(
|
|
|
270
268
|
}
|
|
271
269
|
|
|
272
270
|
const Config = struct {
|
|
273
|
-
target: std.
|
|
271
|
+
target: std.Build.ResolvedTarget,
|
|
274
272
|
optimize: std.builtin.OptimizeMode,
|
|
275
|
-
pic: bool,
|
|
276
|
-
strip: bool,
|
|
273
|
+
pic: ?bool,
|
|
274
|
+
strip: ?bool,
|
|
277
275
|
cmd: ?[]const u8,
|
|
278
276
|
};
|
|
279
277
|
|
|
@@ -281,32 +279,26 @@ const TestStep = struct {
|
|
|
281
279
|
step: std.Build.Step,
|
|
282
280
|
build: bool,
|
|
283
281
|
|
|
284
|
-
pub fn create(b: *std.Build, options: *std.Build.
|
|
282
|
+
pub fn create(b: *std.Build, options: *std.Build.Step.Options, config: Config) *TestStep {
|
|
285
283
|
const coverage = b.option([]const u8, "test-coverage", "Generate test coverage");
|
|
286
|
-
const test_file = b.option([]const u8, "test-file", "Input file for test");
|
|
287
284
|
const test_filter =
|
|
288
285
|
b.option([]const u8, "test-filter", "Skip tests that do not match filter");
|
|
289
286
|
|
|
290
287
|
const self = b.allocator.create(TestStep) catch @panic("OOM");
|
|
291
288
|
const step = std.Build.Step.init(.{ .id = .custom, .name = "Run all tests", .owner = b });
|
|
292
|
-
self.* =
|
|
289
|
+
self.* = .{ .step = step, .build = test_filter == null };
|
|
293
290
|
|
|
294
|
-
const path = test_file orelse "src/lib/test.zig";
|
|
295
291
|
const tests = b.addTest(.{
|
|
296
|
-
.
|
|
297
|
-
std.fs.path.basename(std.fs.path.dirname(path).?),
|
|
298
|
-
std.fs.path.stem(std.fs.path.basename(path)),
|
|
299
|
-
}),
|
|
300
|
-
.main_pkg_path = .{ .path = "." },
|
|
301
|
-
.root_source_file = .{ .path = path },
|
|
292
|
+
.root_source_file = b.path("src/lib/test.zig"),
|
|
302
293
|
.optimize = config.optimize,
|
|
303
294
|
.target = config.target,
|
|
304
295
|
.filter = test_filter,
|
|
296
|
+
.single_threaded = true,
|
|
297
|
+
.strip = config.strip,
|
|
298
|
+
.pic = config.pic,
|
|
305
299
|
});
|
|
306
|
-
tests.addOptions("build_options", options);
|
|
307
|
-
tests.single_threaded = true;
|
|
300
|
+
tests.root_module.addOptions("build_options", options);
|
|
308
301
|
maybeStrip(b, tests, &tests.step, config.strip, config.cmd);
|
|
309
|
-
if (config.pic) tests.force_pic = config.pic;
|
|
310
302
|
if (coverage) |c| {
|
|
311
303
|
tests.setExecCmd(&.{ "kcov", "--include-pattern=src/lib", c, null });
|
|
312
304
|
}
|
|
@@ -317,31 +309,37 @@ const TestStep = struct {
|
|
|
317
309
|
};
|
|
318
310
|
|
|
319
311
|
const ToolConfig = struct {
|
|
320
|
-
|
|
312
|
+
showdown: ?bool,
|
|
313
|
+
module: *std.Build.Module,
|
|
321
314
|
general: Config,
|
|
322
315
|
tool: struct {
|
|
323
316
|
tests: ?*TestStep,
|
|
324
317
|
name: ?[]const u8 = null,
|
|
325
|
-
exes: *std.ArrayList(*std.Build.
|
|
318
|
+
exes: *std.ArrayList(*std.Build.Step.Compile),
|
|
326
319
|
},
|
|
327
320
|
};
|
|
328
321
|
|
|
329
|
-
fn tool(b: *std.Build, path: []const u8, config: ToolConfig)
|
|
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
|
+
};
|
|
330
327
|
var name = config.tool.name orelse std.fs.path.basename(path);
|
|
331
328
|
const index = std.mem.lastIndexOfScalar(u8, name, '.');
|
|
332
329
|
if (index) |i| name = name[0..i];
|
|
333
|
-
if (config.
|
|
330
|
+
if (config.showdown orelse false) name = b.fmt("{s}-showdown", .{name});
|
|
334
331
|
|
|
335
332
|
const exe = b.addExecutable(.{
|
|
336
333
|
.name = name,
|
|
337
|
-
.root_source_file = .
|
|
334
|
+
.root_source_file = b.path(path),
|
|
338
335
|
.target = config.general.target,
|
|
339
336
|
.optimize = config.general.optimize,
|
|
337
|
+
.single_threaded = true,
|
|
338
|
+
.strip = config.general.strip,
|
|
339
|
+
.pic = config.general.pic,
|
|
340
340
|
});
|
|
341
|
-
exe.
|
|
341
|
+
exe.root_module.addImport("pkmn", config.module);
|
|
342
342
|
|
|
343
|
-
exe.single_threaded = true;
|
|
344
|
-
if (config.general.pic) exe.force_pic = config.general.pic;
|
|
345
343
|
if (config.tool.tests) |ts| ts.step.dependOn(&exe.step);
|
|
346
344
|
config.tool.exes.append(exe) catch @panic("OOM");
|
|
347
345
|
|
|
@@ -355,10 +353,10 @@ fn tool(b: *std.Build, path: []const u8, config: ToolConfig) *std.Build.RunStep
|
|
|
355
353
|
const ToolsStep = struct {
|
|
356
354
|
step: std.Build.Step,
|
|
357
355
|
|
|
358
|
-
pub fn create(b: *std.Build, exes: *std.ArrayList(*std.Build.
|
|
356
|
+
pub fn create(b: *std.Build, exes: *std.ArrayList(*std.Build.Step.Compile)) *ToolsStep {
|
|
359
357
|
const self = b.allocator.create(ToolsStep) catch @panic("OOM");
|
|
360
358
|
const step = std.Build.Step.init(.{ .id = .custom, .name = "Install tools", .owner = b });
|
|
361
|
-
self.* =
|
|
359
|
+
self.* = .{ .step = step };
|
|
362
360
|
for (exes.items) |t| self.step.dependOn(&b.addInstallArtifact(t, .{}).step);
|
|
363
361
|
return self;
|
|
364
362
|
}
|
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.deda8593",
|
|
4
4
|
"description": "A minimal, complete, Pokémon battle simulation engine optimized for performance",
|
|
5
5
|
"repository": "github:pkmn/engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,9 +31,6 @@
|
|
|
31
31
|
"build/test/display.js",
|
|
32
32
|
"build/tools/debug.js.map",
|
|
33
33
|
"build/tools/debug.js",
|
|
34
|
-
"src/bin/install-pkmn-engine",
|
|
35
|
-
"src/lib/binding/node.zig",
|
|
36
|
-
"src/lib/binding/wasm.zig",
|
|
37
34
|
"src/lib/common/battle.zig",
|
|
38
35
|
"src/lib/common/data.zig",
|
|
39
36
|
"src/lib/common/debug.zig",
|
|
@@ -52,14 +49,19 @@
|
|
|
52
49
|
"src/lib/gen1/data/types.zig",
|
|
53
50
|
"src/lib/gen1/helpers.zig",
|
|
54
51
|
"src/lib/gen1/mechanics.zig",
|
|
52
|
+
"src/lib/gen2/calc.zig",
|
|
53
|
+
"src/lib/gen2/chance.zig",
|
|
55
54
|
"src/lib/gen2/data.zig",
|
|
56
55
|
"src/lib/gen2/data/items.zig",
|
|
57
56
|
"src/lib/gen2/data/moves.zig",
|
|
58
57
|
"src/lib/gen2/data/species.zig",
|
|
59
58
|
"src/lib/gen2/data/types.zig",
|
|
59
|
+
"src/lib/gen2/generated.zig",
|
|
60
60
|
"src/lib/gen2/helpers.zig",
|
|
61
61
|
"src/lib/gen2/mechanics.zig",
|
|
62
|
+
"src/lib/node.zig",
|
|
62
63
|
"src/lib/pkmn.zig",
|
|
64
|
+
"src/lib/wasm.zig",
|
|
63
65
|
"src/test/display/pkmn.html.tmpl"
|
|
64
66
|
],
|
|
65
67
|
"engines": {
|
|
@@ -73,30 +75,31 @@
|
|
|
73
75
|
"access": "public"
|
|
74
76
|
},
|
|
75
77
|
"dependencies": {
|
|
76
|
-
"@pkmn/data": "^0.
|
|
77
|
-
"@pkmn/protocol": "^0.6.
|
|
78
|
+
"@pkmn/data": "^0.9.11",
|
|
79
|
+
"@pkmn/protocol": "^0.6.25"
|
|
78
80
|
},
|
|
79
81
|
"devDependencies": {
|
|
80
|
-
"@pkmn/eslint-config": "^
|
|
81
|
-
"@pkmn/img": "^0.2.
|
|
82
|
-
"@pkmn/sets": "^5.
|
|
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": "^
|
|
89
|
-
"@vitest/coverage-
|
|
90
|
-
"binaryen": "^
|
|
91
|
-
"eslint": "
|
|
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",
|
|
92
94
|
"html-minifier": "^4.0.0",
|
|
93
|
-
"json-stringify-pretty-compact": "
|
|
95
|
+
"json-stringify-pretty-compact": "4.0.0",
|
|
94
96
|
"minimist": "^1.2.8",
|
|
95
97
|
"mustache": "^4.2.0",
|
|
96
98
|
"source-map-support": "^0.5.21",
|
|
99
|
+
"table": "^6.8.2",
|
|
97
100
|
"trakr": "^0.2.0",
|
|
98
|
-
"typescript": "^5.
|
|
99
|
-
"vitest": "^0.
|
|
101
|
+
"typescript": "^5.5.4",
|
|
102
|
+
"vitest": "^2.0.5"
|
|
100
103
|
},
|
|
101
104
|
"scripts": {
|
|
102
105
|
"lint": "eslint --cache src --ext ts,js && eslint src/bin/*",
|
|
@@ -118,7 +121,7 @@
|
|
|
118
121
|
"ignorePatterns": [
|
|
119
122
|
"dist/",
|
|
120
123
|
"node_modules/",
|
|
121
|
-
"
|
|
124
|
+
"examples/zig",
|
|
122
125
|
"build/"
|
|
123
126
|
],
|
|
124
127
|
"env": {
|
|
@@ -134,10 +137,18 @@
|
|
|
134
137
|
"parserOptions": {
|
|
135
138
|
"project": [
|
|
136
139
|
"./tsconfig.json",
|
|
137
|
-
"./
|
|
140
|
+
"./examples/js/tsconfig.json"
|
|
138
141
|
]
|
|
139
142
|
}
|
|
140
143
|
},
|
|
144
|
+
{
|
|
145
|
+
"files": [
|
|
146
|
+
"src/test/display.ts"
|
|
147
|
+
],
|
|
148
|
+
"rules": {
|
|
149
|
+
"@typescript-eslint/no-unnecessary-type-assertion": "off"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
141
152
|
{
|
|
142
153
|
"files": [
|
|
143
154
|
"src/pkg/index.ts",
|
|
@@ -168,6 +179,15 @@
|
|
|
168
179
|
"@typescript-eslint/no-redundant-type-constituents": "off"
|
|
169
180
|
}
|
|
170
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
|
+
},
|
|
171
191
|
{
|
|
172
192
|
"files": [
|
|
173
193
|
"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: 13, patch: 0};
|
|
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) {
|
|
@@ -370,8 +370,10 @@ const downloadImportLib = async () => {
|
|
|
370
370
|
const args = ['build', '-p', 'build', ...opts];
|
|
371
371
|
if (!process.env.DEBUG_PKMN_ENGINE) args.push('-Doptimize=ReleaseFast', '-Dstrip');
|
|
372
372
|
if (config.type === 'node') {
|
|
373
|
-
args.push(`-Dnode-headers=${headers}`);
|
|
374
|
-
if (process.platform === 'win32')
|
|
373
|
+
args.push(`-Dnode-headers=${path.relative(ROOT, headers)}`);
|
|
374
|
+
if (process.platform === 'win32') {
|
|
375
|
+
args.push(`-Dnode-import-library=${path.relative(ROOT, lib)}`);
|
|
376
|
+
}
|
|
375
377
|
} else {
|
|
376
378
|
args.push('-Dwasm');
|
|
377
379
|
}
|
|
@@ -386,8 +388,14 @@ const downloadImportLib = async () => {
|
|
|
386
388
|
const prefix = process.platform === 'win32' ? '' : 'lib';
|
|
387
389
|
const ext = process.platform === 'darwin'
|
|
388
390
|
? 'dylib' : process.platform === 'win32' ? 'dll' : 'so';
|
|
389
|
-
|
|
390
|
-
|
|
391
|
+
try {
|
|
392
|
+
const actual = path.join('build', 'lib', `${prefix}pkmn${suffix}.node.${ext}`);
|
|
393
|
+
fs.renameSync(actual, artifact);
|
|
394
|
+
} catch (err) {
|
|
395
|
+
// ziglang/zig#19743 changed this path
|
|
396
|
+
const actual = path.join('build', 'bin', `${prefix}pkmn${suffix}.node.${ext}`);
|
|
397
|
+
fs.renameSync(actual, artifact);
|
|
398
|
+
}
|
|
391
399
|
}
|
|
392
400
|
}
|
|
393
401
|
})().catch(e => {
|
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,8 +22,8 @@ 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.
|
|
@@ -35,20 +35,20 @@ pub const ID = packed struct(u8) {
|
|
|
35
35
|
_: u4 = 0,
|
|
36
36
|
|
|
37
37
|
/// Converts the identifier into a number.
|
|
38
|
-
pub
|
|
38
|
+
pub fn int(self: ID) u4 {
|
|
39
39
|
return @intCast(@as(u8, @bitCast(self)));
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/// Decodes the identifier from a number.
|
|
43
|
-
pub
|
|
43
|
+
pub fn from(id: u4) ID {
|
|
44
44
|
return @bitCast(@as(u8, id));
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
test ID {
|
|
49
|
-
try expectEqual(
|
|
50
|
-
try expectEqual(
|
|
51
|
-
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 };
|
|
52
52
|
try expectEqual(id, ID.from(id.int()));
|
|
53
53
|
}
|
|
54
54
|
|
package/src/lib/common/debug.zig
CHANGED
|
@@ -4,8 +4,8 @@ const debug = std.debug;
|
|
|
4
4
|
const io = std.io;
|
|
5
5
|
|
|
6
6
|
pub fn print(value: anytype) void {
|
|
7
|
-
debug.
|
|
8
|
-
defer debug.
|
|
7
|
+
debug.lockStdErr();
|
|
8
|
+
defer debug.unlockStdErr();
|
|
9
9
|
const stderr = io.getStdErr().writer();
|
|
10
10
|
|
|
11
11
|
nosuspend {
|