@pkmn/engine 0.1.0-dev.565de616 → 0.1.0-dev.587596a6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +21 -13
  3. package/build/pkg/addon/browser.js +4 -1
  4. package/build/pkg/addon/browser.js.map +1 -1
  5. package/build/pkg/addon/node.js +20 -7
  6. package/build/pkg/addon/node.js.map +1 -1
  7. package/build/pkg/addon/wasm.js +41 -9
  8. package/build/pkg/addon/wasm.js.map +1 -1
  9. package/build/pkg/addon.d.ts +7 -7
  10. package/build/pkg/addon.js +8 -17
  11. package/build/pkg/addon.js.map +1 -1
  12. package/build/pkg/gen1.d.ts +5 -5
  13. package/build/pkg/gen1.js +28 -19
  14. package/build/pkg/gen1.js.map +1 -1
  15. package/build/pkg/index.d.ts +6 -97
  16. package/build/pkg/index.js +23 -75
  17. package/build/pkg/index.js.map +1 -1
  18. package/build/tools/debug.js +36 -9
  19. package/build/tools/debug.js.map +1 -1
  20. package/build/tools/display/debug.jsx +18 -7
  21. package/build/tools/display/debug.jsx.map +1 -1
  22. package/build/tools/display/index.js +18 -7
  23. package/build/tools/display/index.js.map +1 -1
  24. package/build/tools/display/ui.jsx +18 -8
  25. package/build/tools/display/ui.jsx.map +1 -1
  26. package/build/tools/display/util.js +16 -1
  27. package/build/tools/display/util.js.map +1 -1
  28. package/build.zig +181 -198
  29. package/package.json +31 -130
  30. package/src/bin/install-pkmn-engine +24 -8
  31. package/src/lib/bindings/c.zig +200 -0
  32. package/src/lib/bindings/node.zig +117 -0
  33. package/src/lib/bindings/wasm.zig +50 -0
  34. package/src/lib/common/array.zig +5 -12
  35. package/src/lib/common/debug.zig +11 -21
  36. package/src/lib/common/js.zig +3 -9
  37. package/src/lib/common/optional.zig +11 -21
  38. package/src/lib/common/protocol.zig +176 -163
  39. package/src/lib/common/rational.zig +275 -284
  40. package/src/lib/common/util.zig +14 -31
  41. package/src/lib/gen1/calc.zig +65 -62
  42. package/src/lib/gen1/chance.zig +17 -32
  43. package/src/lib/gen1/data/types.zig +2 -2
  44. package/src/lib/gen1/data.zig +5 -5
  45. package/src/lib/gen1/helpers.zig +8 -10
  46. package/src/lib/gen1/mechanics.zig +32 -25
  47. package/src/lib/gen2/calc.zig +3 -6
  48. package/src/lib/gen2/chance.zig +12 -18
  49. package/src/lib/gen2/data/types.zig +6 -3
  50. package/src/lib/gen2/data.zig +8 -7
  51. package/src/lib/gen2/helpers.zig +4 -6
  52. package/src/lib/gen2/mechanics.zig +28 -17
  53. package/src/lib/napi.h +2 -0
  54. package/src/lib/node.zig +3 -118
  55. package/src/lib/pkmn.zig +94 -19
  56. package/src/lib/wasm.zig +10 -9
  57. package/src/tools/display/dom.ts +5 -8
@@ -12,10 +12,6 @@ const print = std.debug.print;
12
12
 
13
13
  const endian = builtin.cpu.arch.endian();
14
14
  const Endian = std.builtin.Endian;
15
- const big = if (@hasField(Endian, "big")) Endian.big else Endian.Big;
16
- const little = if (@hasField(Endian, "little")) Endian.little else Endian.Little;
17
-
18
- const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
19
15
 
20
16
  pub const ArgType = enum(u8) {
21
17
  None,
@@ -313,19 +309,29 @@ pub const Weather = enum(u8) {
313
309
  Upkeep,
314
310
  };
315
311
 
316
- /// Null object pattern implementation of `Log` backed by a `std.io.null_writer`.
317
- /// Ignores anything sent to it, though protocol logging should additionally be turned off
318
- /// entirely with `options.log`.
319
- pub const NULL = Log(@TypeOf(std.io.null_writer)){ .writer = std.io.null_writer };
320
-
321
- /// Logs protocol information to its `Writer` during a battle update when `options.log` is enabled.
322
- pub fn Log(comptime Writer: type) type {
312
+ /// Logs protocol information to its `WriterT` during a battle update when `options.log` is enabled.
313
+ pub fn Log(comptime WriterT: type) type {
323
314
  return struct {
324
315
  const Self = @This();
325
316
 
326
- writer: Writer,
317
+ writer: WriterT,
327
318
 
328
- pub const Error = Writer.Error;
319
+ pub const Error = err(WriterT);
320
+
321
+ fn err(comptime T: type) type {
322
+ const msg = "Invalid Writer type " ++ @typeName(T) ++ "'";
323
+ return switch (@typeInfo(T)) {
324
+ .pointer => |ptr_info| switch (ptr_info.size) {
325
+ .one => switch (@typeInfo(ptr_info.child)) {
326
+ .@"struct" => err(ptr_info.child),
327
+ else => @compileError(msg),
328
+ },
329
+ else => @compileError(msg),
330
+ },
331
+ .@"struct" => if (@hasDecl(T, "Error")) T.Error else @compileError(msg),
332
+ else => @compileError(msg),
333
+ };
334
+ }
329
335
 
330
336
  // source: ID, move: <Move>, target: ID, from?: <Move>
331
337
  pub fn move(self: Self, args: anytype) Error!void {
@@ -816,49 +822,61 @@ pub fn Log(comptime Writer: type) type {
816
822
  };
817
823
  }
818
824
 
819
- /// `Log` type backed by the optimized `ByteStream.Writer`.
820
- pub const FixedLog = Log(ByteStream.Writer);
825
+ /// `Log` type backed by the optimized `Writer`.
826
+ pub const FixedLog = Log(*Writer);
821
827
 
822
- /// Stripped down version of `std.io.FixedBufferStream` optimized for efficiently writing the
823
- /// individual protocol bytes. Note that the `ByteStream.Writer` is **not** a `std.io.Writer` and
824
- /// should not be used for general purpose writing.
825
- pub const ByteStream = struct {
828
+ /// Minimal logging helper optimized for efficiently writing the individual protocol bytes into a
829
+ /// fixed buffer. Note that this is **not** a `std.Io.Writer` and should not be used for general
830
+ /// purpose writing.
831
+ pub const Writer = struct {
826
832
  buffer: []u8,
827
833
  pos: usize = 0,
828
834
 
829
- pub const Writer = struct {
830
- stream: *ByteStream,
835
+ pub const Error = error{NoSpaceLeft};
831
836
 
832
- pub const Error = error{NoSpaceLeft};
837
+ pub fn writeByte(self: *Writer, byte: u8) Error!void {
838
+ if (self.pos >= self.buffer.len) return error.NoSpaceLeft;
839
+ self.buffer[self.pos] = byte;
840
+ self.pos += 1;
841
+ }
833
842
 
834
- pub fn writeAll(self: Writer, bytes: []const u8) Error!void {
835
- for (bytes) |b| try self.writeByte(b);
836
- }
843
+ pub fn writeAll(self: *Writer, bytes: []const u8) Error!void {
844
+ const npos = self.pos + bytes.len;
845
+ if (npos > self.buffer.len) return error.NoSpaceLeft;
846
+ @memcpy(self.buffer[self.pos..npos], bytes);
847
+ self.pos = npos;
848
+ }
837
849
 
838
- pub fn writeByte(self: Writer, byte: u8) Error!void {
839
- try self.stream.writeByte(byte);
840
- }
850
+ pub fn writeInt(self: *Writer, comptime T: type, v: T, end: std.builtin.Endian) Error!void {
851
+ const bytes = @divExact(@typeInfo(T).int.bits, 8);
852
+ const npos = self.pos + bytes;
853
+ if (npos > self.buffer.len) return error.NoSpaceLeft;
854
+ std.mem.writeInt(T, self.buffer[self.pos..][0..bytes], v, end);
855
+ self.pos = npos;
856
+ }
841
857
 
842
- pub fn writeInt(self: Writer, comptime T: type, v: T, end: std.builtin.Endian) Error!void {
843
- // TODO: rework this to write directly to the buffer?
844
- var bytes: [@divExact(@field(@typeInfo(T), @tagName(Int)).bits, 8)]u8 = undefined;
845
- std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(v)), &bytes, v, end);
846
- return self.writeAll(&bytes);
847
- }
848
- };
858
+ pub fn reset(self: *Writer) void {
859
+ self.pos = 0;
860
+ }
861
+ };
862
+
863
+ /// Null object pattern implementation of `Log` backed by a null writer. Ignores anything sent to
864
+ /// it, though protocol logging should additionally be turned off entirely with `options.log`.
865
+ pub const NULL = Log(NullWriter){ .writer = .{} };
849
866
 
850
- pub fn writer(self: *ByteStream) Writer {
851
- return .{ .stream = self };
867
+ const NullWriter = struct {
868
+ pub const Error = error{};
869
+
870
+ pub fn writeByte(self: NullWriter, byte: u8) Error!void {
871
+ _ = .{ self, byte };
852
872
  }
853
873
 
854
- pub fn writeByte(self: *ByteStream, byte: u8) Writer.Error!void {
855
- if (self.pos >= self.buffer.len) return error.NoSpaceLeft;
856
- self.buffer[self.pos] = byte;
857
- self.pos += 1;
874
+ pub fn writeAll(self: NullWriter, bytes: []const u8) Error!void {
875
+ _ = .{ self, bytes };
858
876
  }
859
877
 
860
- pub fn reset(self: *ByteStream) void {
861
- self.pos = 0;
878
+ pub fn writeInt(self: NullWriter, comptime T: type, v: T, end: std.builtin.Endian) Error!void {
879
+ _ = .{ self, T, v, end };
862
880
  }
863
881
  };
864
882
 
@@ -957,13 +975,13 @@ pub fn format(
957
975
  }
958
976
  printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
959
977
  switch (endian) {
960
- big => {
978
+ .big => {
961
979
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
962
980
  printc(" {d}", .{hp}, a, b, &i, 2, color);
963
981
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
964
982
  printc("/{d}", .{hp}, a, b, &i, 2, color);
965
983
  },
966
- little => {
984
+ .little => {
967
985
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
968
986
  printc(" {d}", .{hp}, a, b, &i, 2, color);
969
987
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -994,8 +1012,8 @@ pub fn format(
994
1012
  },
995
1013
  .Turn => {
996
1014
  const turn = switch (endian) {
997
- big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
998
- little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
1015
+ .big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
1016
+ .little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
999
1017
  };
1000
1018
  printc(" {d}", .{turn}, a, b, &i, 2, color);
1001
1019
  },
@@ -1006,13 +1024,13 @@ pub fn format(
1006
1024
  var id = ID.from(@intCast(a[i]));
1007
1025
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1008
1026
  switch (endian) {
1009
- big => {
1027
+ .big => {
1010
1028
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1011
1029
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1012
1030
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1013
1031
  printc("/{d}", .{hp}, a, b, &i, 2, color);
1014
1032
  },
1015
- little => {
1033
+ .little => {
1016
1034
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
1017
1035
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1018
1036
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -1134,13 +1152,13 @@ pub fn format(
1134
1152
  const id = ID.from(@intCast(a[i]));
1135
1153
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1136
1154
  switch (endian) {
1137
- big => {
1155
+ .big => {
1138
1156
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1139
1157
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1140
1158
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1141
1159
  printc("/{d}", .{hp}, a, b, &i, 2, color);
1142
1160
  },
1143
- little => {
1161
+ .little => {
1144
1162
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
1145
1163
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1146
1164
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -1208,12 +1226,8 @@ pub fn expectLog(
1208
1226
  ) !void {
1209
1227
  if (!enabled) return;
1210
1228
 
1211
- const color = if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR"))
1212
- true
1213
- else switch (std.io.tty.detectConfig(std.io.getStdErr())) {
1214
- .escape_codes => true,
1215
- else => false,
1216
- };
1229
+ // TODO: ziglang/zig#30833 - read from environment
1230
+ const color = true;
1217
1231
 
1218
1232
  expectEqualBytes(expected, actual, offset) catch |err| switch (err) {
1219
1233
  error.TestExpectedEqual => {
@@ -1221,7 +1235,6 @@ pub fn expectLog(
1221
1235
  format(gen, actual, expected, color);
1222
1236
  return err;
1223
1237
  },
1224
- else => return err,
1225
1238
  };
1226
1239
  }
1227
1240
 
@@ -1229,7 +1242,7 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
1229
1242
  for (offset..@min(expected.len, actual.len)) |i| {
1230
1243
  if (expected[i] != actual[i]) {
1231
1244
  print(
1232
- "index {} incorrect. expected 0x{X:0>2}, found 0x{X:0>2}\n",
1245
+ "index {d} incorrect. expected 0x{X:0>2}, found 0x{X:0>2}\n",
1233
1246
  .{ i, expected[i], actual[i] },
1234
1247
  );
1235
1248
  return error.TestExpectedEqual;
@@ -1252,8 +1265,8 @@ const p1 = Player.P1;
1252
1265
  const p2 = Player.P2;
1253
1266
 
1254
1267
  var buf: [pkmn.LOGS_SIZE]u8 = undefined;
1255
- var stream: ByteStream = .{ .buffer = &buf };
1256
- var log: FixedLog = .{ .writer = stream.writer() };
1268
+ var writer: Writer = .{ .buffer = &buf };
1269
+ var log: FixedLog = .{ .writer = &writer };
1257
1270
 
1258
1271
  const gen1 = pkmn.gen1;
1259
1272
  const gen2 = pkmn.gen2;
@@ -1297,14 +1310,14 @@ test "|move|" {
1297
1310
  &.{ N(ArgType.Move), 0b1100, N(M1.Thunderbolt), 0b0101, N(Move.None) },
1298
1311
  buf[0..5],
1299
1312
  );
1300
- stream.reset();
1313
+ writer.reset();
1301
1314
 
1302
1315
  try log.move(.{ p2.ident(4), M1.Pound, p1.ident(5), M1.Metronome });
1303
1316
  try expectLog1(
1304
1317
  &.{ N(ArgType.Move), 0b1100, N(M1.Pound), 0b0101, N(Move.From), N(M1.Metronome) },
1305
1318
  buf[0..6],
1306
1319
  );
1307
- stream.reset();
1320
+ writer.reset();
1308
1321
 
1309
1322
  try log.move(.{ p2.ident(4), M1.SkullBash, ID{} });
1310
1323
  try log.laststill(.{});
@@ -1319,7 +1332,7 @@ test "|move|" {
1319
1332
  },
1320
1333
  buf[0..6],
1321
1334
  );
1322
- stream.reset();
1335
+ writer.reset();
1323
1336
 
1324
1337
  try log.move(.{ p2.ident(4), M1.Tackle, p1.ident(5) });
1325
1338
  try log.lastmiss(.{});
@@ -1334,7 +1347,7 @@ test "|move|" {
1334
1347
  },
1335
1348
  buf[0..6],
1336
1349
  );
1337
- stream.reset();
1350
+ writer.reset();
1338
1351
  }
1339
1352
 
1340
1353
  test "|switch|" {
@@ -1346,31 +1359,31 @@ test "|switch|" {
1346
1359
  try log.switched(.{ p2.ident(3), &snorlax });
1347
1360
  const par = 0b1000000;
1348
1361
  var expected: []const u8 = switch (endian) {
1349
- big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
1350
- little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
1362
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
1363
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
1351
1364
  };
1352
1365
  try expectLog1(expected, buf[0..9]);
1353
- stream.reset();
1366
+ writer.reset();
1354
1367
 
1355
1368
  snorlax.level = 100;
1356
1369
  snorlax.hp = 0;
1357
1370
  snorlax.status = 0;
1358
1371
  try log.switched(.{ p2.ident(3), &snorlax });
1359
1372
  expected = switch (endian) {
1360
- big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
1361
- little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
1373
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
1374
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
1362
1375
  };
1363
1376
  try expectLog1(expected, buf[0..9]);
1364
- stream.reset();
1377
+ writer.reset();
1365
1378
 
1366
1379
  snorlax.hp = 400;
1367
1380
  try log.switched(.{ p2.ident(3), &snorlax });
1368
1381
  expected = switch (endian) {
1369
- big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
1370
- little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
1382
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
1383
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
1371
1384
  };
1372
1385
  try expectLog1(expected, buf[0..9]);
1373
- stream.reset();
1386
+ writer.reset();
1374
1387
 
1375
1388
  var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
1376
1389
  blissey.level = 91;
@@ -1385,53 +1398,53 @@ test "|switch|" {
1385
1398
  N(gen2.Gender.Female),
1386
1399
  91,
1387
1400
  } ++ switch (endian) {
1388
- big => .{ 0, 200, 1, 144, par },
1389
- little => .{ 200, 0, 144, 1, par },
1401
+ .big => .{ 0, 200, 1, 144, par },
1402
+ .little => .{ 200, 0, 144, 1, par },
1390
1403
  });
1391
1404
  try expectLog2(expected, buf[0..10]);
1392
- stream.reset();
1405
+ writer.reset();
1393
1406
  }
1394
1407
 
1395
1408
  test "|cant|" {
1396
1409
  try log.cant(.{ p2.ident(6), .Bound });
1397
1410
  try expectLog1(&.{ N(ArgType.Cant), 0b1110, N(Cant.Bound) }, buf[0..3]);
1398
- stream.reset();
1411
+ writer.reset();
1399
1412
 
1400
1413
  try log.cant(.{ p1.ident(2), .Disable, M1.Earthquake });
1401
1414
  try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(M1.Earthquake) }, buf[0..4]);
1402
- stream.reset();
1415
+ writer.reset();
1403
1416
  }
1404
1417
 
1405
1418
  test "|faint|" {
1406
1419
  try log.faint(.{ p2.ident(2), false });
1407
1420
  try expectLog1(&.{ N(ArgType.Faint), 0b1010 }, buf[0..2]);
1408
- stream.reset();
1421
+ writer.reset();
1409
1422
 
1410
1423
  try log.faint(.{ p2.ident(2), true });
1411
1424
  try expectLog1(&.{ N(ArgType.Faint), 0b1010, N(ArgType.None) }, buf[0..3]);
1412
- stream.reset();
1425
+ writer.reset();
1413
1426
  }
1414
1427
 
1415
1428
  test "|turn|" {
1416
1429
  try log.turn(.{42});
1417
1430
  const expected = switch (endian) {
1418
- big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
1419
- little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
1431
+ .big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
1432
+ .little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
1420
1433
  };
1421
1434
  try expectLog1(expected, buf[0..4]);
1422
- stream.reset();
1435
+ writer.reset();
1423
1436
  }
1424
1437
 
1425
1438
  test "|win|" {
1426
1439
  try log.win(.{.P2});
1427
1440
  try expectLog1(&.{ N(ArgType.Win), 1, N(ArgType.None) }, buf[0..3]);
1428
- stream.reset();
1441
+ writer.reset();
1429
1442
  }
1430
1443
 
1431
1444
  test "|tie|" {
1432
1445
  try log.tie(.{});
1433
1446
  try expectLog1(&.{ N(ArgType.Tie), N(ArgType.None) }, buf[0..2]);
1434
- stream.reset();
1447
+ writer.reset();
1435
1448
  }
1436
1449
 
1437
1450
  test "|-damage|" {
@@ -1440,31 +1453,31 @@ test "|-damage|" {
1440
1453
  chansey.status = gen1.Status.slp(1);
1441
1454
  try log.damage(.{ p2.ident(2), &chansey, .None });
1442
1455
  var expected: []const u8 = switch (endian) {
1443
- big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
1444
- little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
1456
+ .big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
1457
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
1445
1458
  };
1446
1459
  try expectLog1(expected, buf[0..8]);
1447
- stream.reset();
1460
+ writer.reset();
1448
1461
 
1449
1462
  chansey.hp = 100;
1450
1463
  chansey.stats.hp = 256;
1451
1464
  chansey.status = 0;
1452
1465
  try log.damage(.{ p2.ident(2), &chansey, .Confusion });
1453
1466
  expected = switch (endian) {
1454
- big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
1455
- little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
1467
+ .big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
1468
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
1456
1469
  };
1457
1470
  try expectLog1(expected, buf[0..8]);
1458
- stream.reset();
1471
+ writer.reset();
1459
1472
 
1460
1473
  chansey.status = gen1.Status.init(.PSN);
1461
1474
  try log.damage(.{ p2.ident(2), &chansey, .RecoilOf, p1.ident(1) });
1462
1475
  expected = switch (endian) {
1463
- big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
1464
- little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
1476
+ .big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
1477
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
1465
1478
  };
1466
1479
  try expectLog1(expected, buf[0..9]);
1467
- stream.reset();
1480
+ writer.reset();
1468
1481
  }
1469
1482
 
1470
1483
  test "|-heal|" {
@@ -1473,53 +1486,53 @@ test "|-heal|" {
1473
1486
  chansey.status = gen1.Status.slp(1);
1474
1487
  try log.heal(.{ p2.ident(2), &chansey, .None });
1475
1488
  var expected: []const u8 = switch (endian) {
1476
- big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
1477
- little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
1489
+ .big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
1490
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
1478
1491
  };
1479
1492
  try expectLog1(expected, buf[0..8]);
1480
- stream.reset();
1493
+ writer.reset();
1481
1494
 
1482
1495
  chansey.hp = 100;
1483
1496
  chansey.stats.hp = 256;
1484
1497
  chansey.status = 0;
1485
1498
  try log.heal(.{ p2.ident(2), &chansey, .Silent });
1486
1499
  expected = switch (endian) {
1487
- big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
1488
- little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
1500
+ .big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
1501
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
1489
1502
  };
1490
1503
  try expectLog1(expected, buf[0..8]);
1491
- stream.reset();
1504
+ writer.reset();
1492
1505
 
1493
1506
  try log.heal(.{ p2.ident(2), &chansey, .Drain, p1.ident(1) });
1494
1507
  expected = switch (endian) {
1495
- big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
1496
- little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
1508
+ .big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
1509
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
1497
1510
  };
1498
1511
  try expectLog1(expected, buf[0..9]);
1499
- stream.reset();
1512
+ writer.reset();
1500
1513
  }
1501
1514
 
1502
1515
  test "|-status|" {
1503
1516
  try log.status(.{ p2.ident(6), gen1.Status.init(.BRN), .None });
1504
1517
  try expectLog1(&.{ N(ArgType.Status), 0b1110, 0b10000, N(Status.None) }, buf[0..4]);
1505
- stream.reset();
1518
+ writer.reset();
1506
1519
 
1507
1520
  try log.status(.{ p2.ident(2), gen1.Status.init(.PSN), .Silent });
1508
1521
  try expectLog1(&.{ N(ArgType.Status), 0b1010, 0b1000, N(Status.Silent) }, buf[0..4]);
1509
- stream.reset();
1522
+ writer.reset();
1510
1523
 
1511
1524
  try log.status(.{ p1.ident(1), gen1.Status.init(.PAR), .From, M1.BodySlam });
1512
1525
  try expectLog1(
1513
1526
  &.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(M1.BodySlam) },
1514
1527
  buf[0..5],
1515
1528
  );
1516
- stream.reset();
1529
+ writer.reset();
1517
1530
  }
1518
1531
 
1519
1532
  test "|-curestatus|" {
1520
1533
  try log.curestatus(.{ p2.ident(6), gen1.Status.slp(7), .Message });
1521
1534
  try expectLog1(&.{ N(ArgType.CureStatus), 0b1110, 0b111, N(CureStatus.Message) }, buf[0..4]);
1522
- stream.reset();
1535
+ writer.reset();
1523
1536
 
1524
1537
  try log.curestatus(.{ p1.ident(2), gen1.Status.TOX, .Silent });
1525
1538
  try expectLog1(&.{
@@ -1528,86 +1541,86 @@ test "|-curestatus|" {
1528
1541
  0b10001000,
1529
1542
  N(CureStatus.Silent),
1530
1543
  }, buf[0..4]);
1531
- stream.reset();
1544
+ writer.reset();
1532
1545
  }
1533
1546
 
1534
1547
  test "|-boost|" {
1535
1548
  try log.boost(.{ p2.ident(6), .Speed, 2 });
1536
1549
  try expectLog1(&.{ N(ArgType.Boost), 0b1110, N(Boost.Speed), 8 }, buf[0..4]);
1537
- stream.reset();
1550
+ writer.reset();
1538
1551
 
1539
1552
  try log.boost(.{ p1.ident(2), .Rage, 1 });
1540
1553
  try expectLog1(&.{ N(ArgType.Boost), 0b0010, N(Boost.Rage), 7 }, buf[0..4]);
1541
- stream.reset();
1554
+ writer.reset();
1542
1555
 
1543
1556
  try log.boost(.{ p2.ident(3), .Defense, -2 });
1544
1557
  try expectLog1(&.{ N(ArgType.Boost), 0b1011, N(Boost.Defense), 4 }, buf[0..4]);
1545
- stream.reset();
1558
+ writer.reset();
1546
1559
  }
1547
1560
 
1548
1561
  test "|-clearallboost|" {
1549
1562
  try log.clearallboost(.{});
1550
1563
  try expectLog1(&.{N(ArgType.ClearAllBoost)}, buf[0..1]);
1551
- stream.reset();
1564
+ writer.reset();
1552
1565
  }
1553
1566
 
1554
1567
  test "|-fail|" {
1555
1568
  try log.fail(.{ p2.ident(6), .None });
1556
1569
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.None) }, buf[0..3]);
1557
- stream.reset();
1570
+ writer.reset();
1558
1571
 
1559
1572
  try log.fail(.{ p2.ident(6), .Sleep });
1560
1573
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Sleep) }, buf[0..3]);
1561
- stream.reset();
1574
+ writer.reset();
1562
1575
 
1563
1576
  try log.fail(.{ p2.ident(6), .Substitute });
1564
1577
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Substitute) }, buf[0..3]);
1565
- stream.reset();
1578
+ writer.reset();
1566
1579
 
1567
1580
  try log.fail(.{ p2.ident(6), .Weak });
1568
1581
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Weak) }, buf[0..3]);
1569
- stream.reset();
1582
+ writer.reset();
1570
1583
  }
1571
1584
 
1572
1585
  test "|-miss|" {
1573
1586
  try log.miss(.{p2.ident(4)});
1574
1587
  try expectLog1(&.{ N(ArgType.Miss), 0b1100 }, buf[0..2]);
1575
- stream.reset();
1588
+ writer.reset();
1576
1589
  }
1577
1590
  test "|-hitcount|" {
1578
1591
  try log.hitcount(.{ p2.ident(1), 5 });
1579
1592
  try expectLog1(&.{ N(ArgType.HitCount), 0b1001, 5 }, buf[0..3]);
1580
- stream.reset();
1593
+ writer.reset();
1581
1594
  }
1582
1595
 
1583
1596
  test "|-prepare|" {
1584
1597
  try log.prepare(.{ p2.ident(2), M1.Dig });
1585
1598
  try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(M1.Dig) }, buf[0..3]);
1586
- stream.reset();
1599
+ writer.reset();
1587
1600
  }
1588
1601
 
1589
1602
  test "|-mustrecharge|" {
1590
1603
  try log.mustrecharge(.{p1.ident(6)});
1591
1604
  try expectLog1(&.{ N(ArgType.MustRecharge), 0b0110 }, buf[0..2]);
1592
- stream.reset();
1605
+ writer.reset();
1593
1606
  }
1594
1607
 
1595
1608
  test "|-activate|" {
1596
1609
  try log.activate(.{ p1.ident(2), .Struggle });
1597
1610
  try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Struggle) }, buf[0..3]);
1598
- stream.reset();
1611
+ writer.reset();
1599
1612
 
1600
1613
  try log.activate(.{ p2.ident(4), .Mist });
1601
1614
  try expectLog1(&.{ N(ArgType.Activate), 0b1100, N(Activate.Mist) }, buf[0..3]);
1602
- stream.reset();
1615
+ writer.reset();
1603
1616
 
1604
1617
  try log.activate(.{ p2.ident(6), .Substitute });
1605
1618
  try expectLog1(&.{ N(ArgType.Activate), 0b1110, N(Activate.Substitute) }, buf[0..3]);
1606
- stream.reset();
1619
+ writer.reset();
1607
1620
 
1608
1621
  try log.activate(.{ p1.ident(2), .Splash });
1609
1622
  try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Splash) }, buf[0..3]);
1610
- stream.reset();
1623
+ writer.reset();
1611
1624
 
1612
1625
  try log.activate(.{ p1.ident(4), .SubstituteBlock, M2.Spite });
1613
1626
  try expectLog1(&.{
@@ -1616,27 +1629,27 @@ test "|-activate|" {
1616
1629
  N(Activate.SubstituteBlock),
1617
1630
  N(M2.Spite),
1618
1631
  }, buf[0..4]);
1619
- stream.reset();
1632
+ writer.reset();
1620
1633
 
1621
1634
  try log.activate(.{ p1.ident(3), .Magnitude, 5 });
1622
1635
  try expectLog1(&.{ N(ArgType.Activate), 0b0011, N(Activate.Magnitude), 5 }, buf[0..4]);
1623
- stream.reset();
1636
+ writer.reset();
1624
1637
  }
1625
1638
 
1626
1639
  test "|-fieldactivate|" {
1627
1640
  try log.fieldactivate(.{});
1628
1641
  try expectLog1(&.{N(ArgType.FieldActivate)}, buf[0..1]);
1629
- stream.reset();
1642
+ writer.reset();
1630
1643
  }
1631
1644
 
1632
1645
  test "|-start|" {
1633
1646
  try log.start(.{ p2.ident(6), .Bide });
1634
1647
  try expectLog1(&.{ N(ArgType.Start), 0b1110, N(Start.Bide) }, buf[0..3]);
1635
- stream.reset();
1648
+ writer.reset();
1636
1649
 
1637
1650
  try log.start(.{ p1.ident(2), .ConfusionSilent });
1638
1651
  try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.ConfusionSilent) }, buf[0..3]);
1639
- stream.reset();
1652
+ writer.reset();
1640
1653
 
1641
1654
  try log.start(.{
1642
1655
  p2.ident(6),
@@ -1648,7 +1661,7 @@ test "|-start|" {
1648
1661
  &.{ N(ArgType.Start), 0b1110, N(Start.TypeChange), 0b1000_1000, 0b1101 },
1649
1662
  buf[0..5],
1650
1663
  );
1651
- stream.reset();
1664
+ writer.reset();
1652
1665
 
1653
1666
  try log.start(.{
1654
1667
  p1.ident(2),
@@ -1660,65 +1673,65 @@ test "|-start|" {
1660
1673
  &.{ N(ArgType.Start), 0b0010, N(Start.TypeChange), 0b0011_0110, 0b1100 },
1661
1674
  buf[0..5],
1662
1675
  );
1663
- stream.reset();
1676
+ writer.reset();
1664
1677
 
1665
1678
  try log.start(.{ p1.ident(2), .Disable, M1.Surf });
1666
1679
  try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(M1.Surf) }, buf[0..4]);
1667
- stream.reset();
1680
+ writer.reset();
1668
1681
 
1669
1682
  try log.start(.{ p1.ident(2), .Mimic, M1.Surf });
1670
1683
  try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(M1.Surf) }, buf[0..4]);
1671
- stream.reset();
1684
+ writer.reset();
1672
1685
  }
1673
1686
 
1674
1687
  test "|-end|" {
1675
1688
  try log.end(.{ p2.ident(6), .Bide });
1676
1689
  try expectLog1(&.{ N(ArgType.End), 0b1110, N(End.Bide) }, buf[0..3]);
1677
- stream.reset();
1690
+ writer.reset();
1678
1691
 
1679
1692
  try log.end(.{ p1.ident(2), .ConfusionSilent });
1680
1693
  try expectLog1(&.{ N(ArgType.End), 0b0010, N(End.ConfusionSilent) }, buf[0..3]);
1681
- stream.reset();
1694
+ writer.reset();
1682
1695
  }
1683
1696
 
1684
1697
  test "|-ohko|" {
1685
1698
  try log.ohko(.{});
1686
1699
  try expectLog1(&.{N(ArgType.OHKO)}, buf[0..1]);
1687
- stream.reset();
1700
+ writer.reset();
1688
1701
  }
1689
1702
 
1690
1703
  test "|-crit|" {
1691
1704
  try log.crit(.{p2.ident(5)});
1692
1705
  try expectLog1(&.{ N(ArgType.Crit), 0b1101 }, buf[0..2]);
1693
- stream.reset();
1706
+ writer.reset();
1694
1707
  }
1695
1708
 
1696
1709
  test "|-supereffective|" {
1697
1710
  try log.supereffective(.{p1.ident(1)});
1698
1711
  try expectLog1(&.{ N(ArgType.SuperEffective), 0b0001 }, buf[0..2]);
1699
- stream.reset();
1712
+ writer.reset();
1700
1713
  }
1701
1714
 
1702
1715
  test "|-resisted|" {
1703
1716
  try log.resisted(.{p2.ident(2)});
1704
1717
  try expectLog1(&.{ N(ArgType.Resisted), 0b1010 }, buf[0..2]);
1705
- stream.reset();
1718
+ writer.reset();
1706
1719
  }
1707
1720
 
1708
1721
  test "|-immune|" {
1709
1722
  try log.immune(.{ p1.ident(3), .None });
1710
1723
  try expectLog1(&.{ N(ArgType.Immune), 0b0011, N(Immune.None) }, buf[0..3]);
1711
- stream.reset();
1724
+ writer.reset();
1712
1725
 
1713
1726
  try log.immune(.{ p2.ident(2), .OHKO });
1714
1727
  try expectLog1(&.{ N(ArgType.Immune), 0b1010, N(Immune.OHKO) }, buf[0..3]);
1715
- stream.reset();
1728
+ writer.reset();
1716
1729
  }
1717
1730
 
1718
1731
  test "|-transform|" {
1719
1732
  try log.transform(.{ p2.ident(4), p1.ident(5) });
1720
1733
  try expectLog1(&.{ N(ArgType.Transform), 0b1100, 0b0101 }, buf[0..3]);
1721
- stream.reset();
1734
+ writer.reset();
1722
1735
  }
1723
1736
 
1724
1737
  test "|drag|" {
@@ -1736,33 +1749,33 @@ test "|drag|" {
1736
1749
  N(gen2.Gender.Female),
1737
1750
  91,
1738
1751
  } ++ switch (endian) {
1739
- big => .{ 0, 200, 1, 144, par },
1740
- little => .{ 200, 0, 144, 1, par },
1752
+ .big => .{ 0, 200, 1, 144, par },
1753
+ .little => .{ 200, 0, 144, 1, par },
1741
1754
  });
1742
1755
  try expectLog2(expected, buf[0..10]);
1743
- stream.reset();
1756
+ writer.reset();
1744
1757
  }
1745
1758
 
1746
1759
  test "|-item|" {
1747
1760
  try log.item(.{ p2.ident(2), I2.GoldBerry, p1.ident(4) });
1748
1761
  try expectLog2(&.{ N(ArgType.Item), 0b1010, N(I2.GoldBerry), 0b0100 }, buf[0..4]);
1749
- stream.reset();
1762
+ writer.reset();
1750
1763
  }
1751
1764
 
1752
1765
  test "|-enditem|" {
1753
1766
  try log.enditem(.{ p1.ident(1), I2.BerserkGene, .None });
1754
1767
  try expectLog2(&.{ N(ArgType.EndItem), 0b0001, N(I2.BerserkGene), N(EndItem.None) }, buf[0..4]);
1755
- stream.reset();
1768
+ writer.reset();
1756
1769
 
1757
1770
  try log.enditem(.{ p2.ident(4), I2.PRZCureBerry, .Eat });
1758
1771
  try expectLog2(&.{ N(ArgType.EndItem), 0b1100, N(I2.PRZCureBerry), N(EndItem.Eat) }, buf[0..4]);
1759
- stream.reset();
1772
+ writer.reset();
1760
1773
  }
1761
1774
 
1762
1775
  test "|-cureteam|" {
1763
1776
  try log.cureteam(.{p2.ident(5)});
1764
1777
  try expectLog2(&.{ N(ArgType.CureTeam), 0b1101 }, buf[0..2]);
1765
- stream.reset();
1778
+ writer.reset();
1766
1779
  }
1767
1780
 
1768
1781
  test "|-sethp|" {
@@ -1770,39 +1783,39 @@ test "|-sethp|" {
1770
1783
  blissey.hp = 612;
1771
1784
  try log.sethp(.{ p2.ident(2), &blissey, .Silent });
1772
1785
  const expected: []const u8 = switch (endian) {
1773
- big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
1774
- little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
1786
+ .big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
1787
+ .little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
1775
1788
  };
1776
1789
  try expectLog2(expected, buf[0..8]);
1777
- stream.reset();
1790
+ writer.reset();
1778
1791
  }
1779
1792
 
1780
1793
  test "|-setboost|" {
1781
1794
  try log.setboost(.{ p2.ident(6), 6 });
1782
1795
  try expectLog2(&.{ N(ArgType.SetBoost), 0b1110, 12 }, buf[0..3]);
1783
- stream.reset();
1796
+ writer.reset();
1784
1797
 
1785
1798
  try log.setboost(.{ p2.ident(3), 2 });
1786
1799
  try expectLog2(&.{ N(ArgType.SetBoost), 0b1011, 8 }, buf[0..3]);
1787
- stream.reset();
1800
+ writer.reset();
1788
1801
  }
1789
1802
 
1790
1803
  test "|-copyboost|" {
1791
1804
  try log.copyboost(.{ p2.ident(3), p1.ident(6) });
1792
1805
  try expectLog2(&.{ N(ArgType.CopyBoost), 0b1011, 0b0110 }, buf[0..3]);
1793
- stream.reset();
1806
+ writer.reset();
1794
1807
  }
1795
1808
 
1796
1809
  test "|-sidestart|" {
1797
1810
  try log.sidestart(.{ .P2, .Reflect });
1798
1811
  try expectLog2(&.{ N(ArgType.SideStart), 1, N(Side.Reflect) }, buf[0..3]);
1799
- stream.reset();
1812
+ writer.reset();
1800
1813
  }
1801
1814
 
1802
1815
  test "|-sideend|" {
1803
1816
  try log.sideend(.{ .P2, .LightScreen });
1804
1817
  try expectLog2(&.{ N(ArgType.SideEnd), 1, N(Side.LightScreen) }, buf[0..3]);
1805
- stream.reset();
1818
+ writer.reset();
1806
1819
 
1807
1820
  try log.sideend(.{ .P1, .Spikes, p1.ident(3) });
1808
1821
  try expectLog2(&.{
@@ -1811,27 +1824,27 @@ test "|-sideend|" {
1811
1824
  N(Side.Spikes),
1812
1825
  0b0011,
1813
1826
  }, buf[0..4]);
1814
- stream.reset();
1827
+ writer.reset();
1815
1828
  }
1816
1829
 
1817
1830
  test "|-singlemove|" {
1818
1831
  try log.singlemove(.{ p2.ident(2), M2.DestinyBond });
1819
1832
  try expectLog2(&.{ N(ArgType.SingleMove), 0b1010, N(M2.DestinyBond) }, buf[0..3]);
1820
- stream.reset();
1833
+ writer.reset();
1821
1834
  }
1822
1835
 
1823
1836
  test "|-singleturn|" {
1824
1837
  try log.singleturn(.{ p1.ident(3), M2.Protect });
1825
1838
  try expectLog2(&.{ N(ArgType.SingleTurn), 0b0011, N(M2.Protect) }, buf[0..3]);
1826
- stream.reset();
1839
+ writer.reset();
1827
1840
  }
1828
1841
 
1829
1842
  test "|-weather|" {
1830
1843
  try log.weather(.{ W2.Rain, .Upkeep });
1831
1844
  try expectLog2(&.{ N(ArgType.Weather), N(W2.Rain), N(Weather.Upkeep) }, buf[0..3]);
1832
- stream.reset();
1845
+ writer.reset();
1833
1846
 
1834
1847
  try log.weather(.{ W2.None, .None });
1835
1848
  try expectLog2(&.{ N(ArgType.Weather), N(W2.None), N(Weather.None) }, buf[0..3]);
1836
- stream.reset();
1849
+ writer.reset();
1837
1850
  }