@pkmn/engine 0.1.0-dev.84cc1a02 → 0.1.0-dev.8b83af6b
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 +52 -24
- package/build/pkg/addon.d.ts +7 -0
- package/build/pkg/addon.js +111 -0
- package/build/pkg/addon.js.map +1 -0
- package/build/pkg/data/layout.json +1 -1
- package/build/pkg/data.d.ts +1 -2
- package/build/pkg/data.js +3 -5
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.d.ts +5 -4
- package/build/pkg/gen1.js +43 -24
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +15 -12
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +4 -2
- package/build/pkg/protocol.js +4 -2
- package/build/pkg/protocol.js.map +1 -1
- package/build/test/display.js +400 -0
- package/build/test/display.js.map +1 -0
- package/build/tools/debug.js +133 -0
- package/build/tools/debug.js.map +1 -0
- package/build.zig +30 -39
- package/package.json +45 -34
- package/src/bin/install-pkmn-engine +47 -28
- package/src/bin/pkmn-debug +62 -0
- package/src/lib/binding/node.zig +20 -23
- package/src/lib/binding/wasm.zig +4 -4
- package/src/lib/common/data.zig +11 -11
- package/src/lib/common/debug.zig +1 -0
- package/src/lib/common/options.zig +3 -3
- package/src/lib/common/protocol.zig +194 -178
- package/src/lib/common/rng.zig +5 -5
- package/src/lib/gen1/README.md +106 -70
- package/src/lib/gen1/data/moves.zig +10 -10
- package/src/lib/gen1/data/species.zig +2 -2
- package/src/lib/gen1/data/types.zig +3 -3
- package/src/lib/gen1/data.zig +36 -31
- package/src/lib/gen1/helpers.zig +11 -22
- package/src/lib/gen1/mechanics.zig +460 -365
- package/src/lib/gen2/data/items.zig +3 -3
- package/src/lib/gen2/data/moves.zig +1 -1
- package/src/lib/gen2/data/species.zig +1 -1
- package/src/lib/gen2/data/types.zig +3 -3
- package/src/lib/gen2/data.zig +16 -15
- package/src/lib/gen2/helpers.zig +6 -6
- package/src/lib/pkmn.zig +7 -7
- package/src/test/display/pkmn.html.tmpl +368 -0
package/src/lib/binding/node.zig
CHANGED
|
@@ -21,7 +21,7 @@ fn options(env: c.napi_env) c.napi_value {
|
|
|
21
21
|
var object = Object.init(env);
|
|
22
22
|
const properties = [_]c.napi_property_descriptor{
|
|
23
23
|
Property.init("showdown", .{ .value = Boolean.init(env, pkmn.options.showdown) }),
|
|
24
|
-
Property.init("
|
|
24
|
+
Property.init("log", .{ .value = Boolean.init(env, pkmn.options.log) }),
|
|
25
25
|
};
|
|
26
26
|
assert(c.napi_define_properties(env, object, properties.len, &properties) == c.napi_ok);
|
|
27
27
|
return object;
|
|
@@ -34,11 +34,11 @@ fn bindings(env: c.napi_env) c.napi_value {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
fn bind(env: c.napi_env, gen: anytype) c.napi_value {
|
|
37
|
-
const
|
|
38
|
-
const logs_size = @intCast(
|
|
37
|
+
const choices_size: u32 = @intCast(gen.CHOICES_SIZE);
|
|
38
|
+
const logs_size: u32 = @intCast(gen.LOGS_SIZE);
|
|
39
39
|
var object = Object.init(env);
|
|
40
40
|
const properties = [_]c.napi_property_descriptor{
|
|
41
|
-
Property.init("
|
|
41
|
+
Property.init("CHOICES_SIZE", .{ .value = Number.init(env, choices_size) }),
|
|
42
42
|
Property.init("LOGS_SIZE", .{ .value = Number.init(env, logs_size) }),
|
|
43
43
|
Property.init("update", .{ .method = update(gen) }),
|
|
44
44
|
Property.init("choices", .{ .method = choices(gen) }),
|
|
@@ -61,10 +61,9 @@ fn update(gen: anytype) c.napi_callback {
|
|
|
61
61
|
assert(len == @sizeOf(gen.Battle(gen.PRNG)));
|
|
62
62
|
assert(data != null);
|
|
63
63
|
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
const c2 = @bitCast(pkmn.Choice, Number.get(env, argv[2], u8));
|
|
64
|
+
var battle: *gen.Battle(gen.PRNG) = @alignCast(@ptrCast(data.?));
|
|
65
|
+
const c1: pkmn.Choice = @bitCast(Number.get(env, argv[1], u8));
|
|
66
|
+
const c2: pkmn.Choice = @bitCast(Number.get(env, argv[2], u8));
|
|
68
67
|
|
|
69
68
|
var vtype: c.napi_valuetype = undefined;
|
|
70
69
|
assert(c.napi_typeof(env, argv[3], &vtype) == c.napi_ok);
|
|
@@ -75,14 +74,14 @@ fn update(gen: anytype) c.napi_callback {
|
|
|
75
74
|
assert(len == gen.LOGS_SIZE);
|
|
76
75
|
assert(data != null);
|
|
77
76
|
|
|
78
|
-
var buf = @
|
|
77
|
+
var buf = @as([*]u8, @ptrCast(data.?))[0..gen.LOGS_SIZE];
|
|
79
78
|
var stream = pkmn.protocol.ByteStream{ .buffer = buf };
|
|
80
79
|
var log = pkmn.protocol.FixedLog{ .writer = stream.writer() };
|
|
81
80
|
break :result battle.update(c1, c2, log);
|
|
82
81
|
},
|
|
83
82
|
} catch unreachable;
|
|
84
83
|
|
|
85
|
-
return Number.init(env, @
|
|
84
|
+
return Number.init(env, @as(u8, @bitCast(result)));
|
|
86
85
|
}
|
|
87
86
|
}.call;
|
|
88
87
|
}
|
|
@@ -101,19 +100,17 @@ fn choices(gen: anytype) c.napi_callback {
|
|
|
101
100
|
assert(len == @sizeOf(gen.Battle(gen.PRNG)));
|
|
102
101
|
assert(data != null);
|
|
103
102
|
|
|
104
|
-
var
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const player = @intToEnum(pkmn.Player, Number.get(env, argv[1], u8));
|
|
108
|
-
const request = @intToEnum(pkmn.Choice.Type, Number.get(env, argv[2], u8));
|
|
103
|
+
var battle: *gen.Battle(gen.PRNG) = @alignCast(@ptrCast(data.?));
|
|
104
|
+
const player: pkmn.Player = @enumFromInt(Number.get(env, argv[1], u8));
|
|
105
|
+
const request: pkmn.Choice.Type = @enumFromInt(Number.get(env, argv[2], u8));
|
|
109
106
|
|
|
110
107
|
assert(c.napi_get_arraybuffer_info(env, argv[3], &data, &len) == c.napi_ok);
|
|
111
|
-
assert(len == gen.
|
|
108
|
+
assert(len == gen.CHOICES_SIZE);
|
|
112
109
|
assert(data != null);
|
|
113
110
|
|
|
114
|
-
var out = @
|
|
111
|
+
var out = @as([*]pkmn.Choice, @ptrCast(data.?))[0..gen.CHOICES_SIZE];
|
|
115
112
|
const n = battle.choices(player, request, out);
|
|
116
|
-
return Number.init(env, @
|
|
113
|
+
return Number.init(env, @as(u8, @bitCast(n)));
|
|
117
114
|
}
|
|
118
115
|
}.call;
|
|
119
116
|
}
|
|
@@ -166,25 +163,25 @@ const Number = struct {
|
|
|
166
163
|
.signed => {
|
|
167
164
|
var result: i32 = undefined;
|
|
168
165
|
assert(c.napi_get_value_int32(env, value, &result) == c.napi_ok);
|
|
169
|
-
return if (info.bits == 32) result else @intCast(
|
|
166
|
+
return if (info.bits == 32) result else @intCast(result);
|
|
170
167
|
},
|
|
171
168
|
.unsigned => {
|
|
172
169
|
var result: u32 = undefined;
|
|
173
170
|
assert(c.napi_get_value_uint32(env, value, &result) == c.napi_ok);
|
|
174
|
-
return if (info.bits == 32) result else @intCast(
|
|
171
|
+
return if (info.bits == 32) result else @intCast(result);
|
|
175
172
|
},
|
|
176
173
|
},
|
|
177
174
|
33...63 => {
|
|
178
175
|
var result: i64 = undefined;
|
|
179
176
|
assert(c.napi_get_value_int64(env, value, &result) == c.napi_ok);
|
|
180
|
-
return @intCast(
|
|
177
|
+
return @intCast(result);
|
|
181
178
|
},
|
|
182
179
|
else => {
|
|
183
180
|
var result: i64 = undefined;
|
|
184
181
|
assert(c.napi_get_value_int64(env, value, &result) == c.napi_ok);
|
|
185
182
|
return switch (info.signedness) {
|
|
186
|
-
.signed =>
|
|
187
|
-
.unsigned => if (0 <= value) @intCast(
|
|
183
|
+
.signed => value,
|
|
184
|
+
.unsigned => if (0 <= value) @intCast(value) else unreachable,
|
|
188
185
|
};
|
|
189
186
|
},
|
|
190
187
|
},
|
package/src/lib/binding/wasm.zig
CHANGED
|
@@ -2,9 +2,9 @@ const std = @import("std");
|
|
|
2
2
|
const pkmn = @import("../pkmn.zig");
|
|
3
3
|
|
|
4
4
|
export const SHOWDOWN = pkmn.options.showdown;
|
|
5
|
-
export const
|
|
5
|
+
export const LOG = pkmn.options.log;
|
|
6
6
|
|
|
7
|
-
export const
|
|
8
|
-
std.math.ceilPowerOfTwo(u32, @
|
|
7
|
+
export const GEN1_CHOICES_SIZE =
|
|
8
|
+
std.math.ceilPowerOfTwo(u32, @as(u32, @intCast(pkmn.gen1.CHOICES_SIZE))) catch unreachable;
|
|
9
9
|
export const GEN1_LOGS_SIZE =
|
|
10
|
-
std.math.ceilPowerOfTwo(u32, @
|
|
10
|
+
std.math.ceilPowerOfTwo(u32, @as(u32, @intCast(pkmn.gen1.LOGS_SIZE))) catch unreachable;
|
package/src/lib/common/data.zig
CHANGED
|
@@ -10,7 +10,7 @@ pub const Player = enum(u1) {
|
|
|
10
10
|
|
|
11
11
|
/// Returns a player's opponent.
|
|
12
12
|
pub inline fn foe(self: Player) Player {
|
|
13
|
-
return @
|
|
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`.
|
|
@@ -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(@as(u8, 0b0001), @
|
|
26
|
-
try expectEqual(@as(u8, 0b1101), @
|
|
25
|
+
try expectEqual(@as(u8, 0b0001), @as(u8, @bitCast(Player.P1.ident(1))));
|
|
26
|
+
try expectEqual(@as(u8, 0b1101), @as(u8, @bitCast(Player.P2.ident(5))));
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/// An identifier for a specific Pokémon in battle.
|
|
@@ -40,18 +40,18 @@ pub const ID = packed struct {
|
|
|
40
40
|
|
|
41
41
|
/// Converts the identifier into a number.
|
|
42
42
|
pub inline fn int(self: ID) u4 {
|
|
43
|
-
return @intCast(
|
|
43
|
+
return @intCast(@as(u8, @bitCast(self)));
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/// Decodes the identifier from a number.
|
|
47
47
|
pub inline fn from(id: u4) ID {
|
|
48
|
-
return @bitCast(
|
|
48
|
+
return @bitCast(@as(u8, id));
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
test ID {
|
|
53
|
-
try expectEqual(@as(u8, 0b0001), @
|
|
54
|
-
try expectEqual(@as(u8, 0b1101), @
|
|
53
|
+
try expectEqual(@as(u8, 0b0001), @as(u8, @bitCast(ID{ .player = .P1, .id = 1 })));
|
|
54
|
+
try expectEqual(@as(u8, 0b1101), @as(u8, @bitCast(ID{ .player = .P2, .id = 5 })));
|
|
55
55
|
const id = ID{ .player = .P2, .id = 4 };
|
|
56
56
|
try expectEqual(id, ID.from(id.int()));
|
|
57
57
|
}
|
|
@@ -84,8 +84,8 @@ test Choice {
|
|
|
84
84
|
const p2: Choice = .{ .type = .Switch, .data = 5 };
|
|
85
85
|
try expectEqual(5, p2.data);
|
|
86
86
|
try expectEqual(Choice.Type.Move, p1.type);
|
|
87
|
-
try expectEqual(0b0001_0001, @
|
|
88
|
-
try expectEqual(0b0001_0110, @
|
|
87
|
+
try expectEqual(0b0001_0001, @as(u8, @bitCast(p1)));
|
|
88
|
+
try expectEqual(0b0001_0110, @as(u8, @bitCast(p2)));
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
/// The result of the battle - all results other than 'None' should be considered terminal.
|
|
@@ -124,6 +124,6 @@ pub const Result = packed struct {
|
|
|
124
124
|
};
|
|
125
125
|
|
|
126
126
|
test Result {
|
|
127
|
-
try expectEqual(0b0101_0000, @
|
|
128
|
-
try expectEqual(0b1000_0000, @
|
|
127
|
+
try expectEqual(0b0101_0000, @as(u8, @bitCast(Result.Default)));
|
|
128
|
+
try expectEqual(0b1000_0000, @as(u8, @bitCast(Result{ .p2 = .Switch })));
|
|
129
129
|
}
|
package/src/lib/common/debug.zig
CHANGED
|
@@ -3,7 +3,7 @@ const root = @import("root");
|
|
|
3
3
|
|
|
4
4
|
pub const Options = struct {
|
|
5
5
|
showdown: ?bool = null,
|
|
6
|
-
|
|
6
|
+
log: ?bool = null,
|
|
7
7
|
advance: ?bool = null,
|
|
8
8
|
ebc: ?bool = null,
|
|
9
9
|
internal: ?bool = null,
|
|
@@ -11,8 +11,8 @@ pub const Options = struct {
|
|
|
11
11
|
|
|
12
12
|
/// Whether or not Pokémon Showdown compatibility mode is enabled.
|
|
13
13
|
pub const showdown = get("showdown", false);
|
|
14
|
-
/// Whether or not protocol
|
|
15
|
-
pub const
|
|
14
|
+
/// Whether or not protocol message logging is enabled.
|
|
15
|
+
pub const log = get("log", false);
|
|
16
16
|
|
|
17
17
|
pub const advance = get("advance", true);
|
|
18
18
|
pub const ebc = get("ebc", true);
|