@pkmn/engine 0.1.0-dev.d97c6e03 → 0.1.0-dev.f3aaee39

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 (48) hide show
  1. package/README.md +67 -56
  2. package/build/pkg/addon.d.ts +1 -1
  3. package/build/pkg/addon.js +7 -6
  4. package/build/pkg/addon.js.map +1 -1
  5. package/build/pkg/data/layout.json +25 -3
  6. package/build/pkg/gen1.d.ts +5 -4
  7. package/build/pkg/gen1.js +46 -30
  8. package/build/pkg/gen1.js.map +1 -1
  9. package/build/pkg/index.d.ts +15 -12
  10. package/build/pkg/index.js.map +1 -1
  11. package/build/pkg/protocol.d.ts +4 -2
  12. package/build/pkg/protocol.js +4 -2
  13. package/build/pkg/protocol.js.map +1 -1
  14. package/build/test/display.js +29 -12
  15. package/build/test/display.js.map +1 -1
  16. package/build.zig +89 -65
  17. package/package.json +26 -16
  18. package/src/bin/install-pkmn-engine +11 -6
  19. package/src/lib/binding/node.zig +45 -140
  20. package/src/lib/binding/wasm.zig +5 -3
  21. package/src/lib/common/battle.zig +17 -0
  22. package/src/lib/common/data.zig +11 -11
  23. package/src/lib/common/debug.zig +21 -11
  24. package/src/lib/common/js.zig +118 -0
  25. package/src/lib/common/optional.zig +60 -0
  26. package/src/lib/common/options.zig +12 -3
  27. package/src/lib/common/protocol.zig +242 -178
  28. package/src/lib/common/rational.zig +353 -0
  29. package/src/lib/common/rng.zig +10 -10
  30. package/src/lib/common/util.zig +12 -0
  31. package/src/lib/gen1/README.md +255 -154
  32. package/src/lib/gen1/calc.zig +427 -0
  33. package/src/lib/gen1/chance.zig +1044 -0
  34. package/src/lib/gen1/data/moves.zig +10 -10
  35. package/src/lib/gen1/data/species.zig +2 -2
  36. package/src/lib/gen1/data/types.zig +3 -3
  37. package/src/lib/gen1/data.zig +64 -38
  38. package/src/lib/gen1/helpers.zig +592 -32
  39. package/src/lib/gen1/mechanics.zig +892 -531
  40. package/src/lib/gen2/README.md +12 -13
  41. package/src/lib/gen2/data/items.zig +3 -3
  42. package/src/lib/gen2/data/moves.zig +1 -1
  43. package/src/lib/gen2/data/species.zig +1 -1
  44. package/src/lib/gen2/data/types.zig +3 -3
  45. package/src/lib/gen2/data.zig +33 -22
  46. package/src/lib/gen2/helpers.zig +9 -11
  47. package/src/lib/gen2/mechanics.zig +5 -4
  48. package/src/lib/pkmn.zig +65 -6
@@ -7,7 +7,7 @@ const options = @import("./options.zig");
7
7
  const assert = std.debug.assert;
8
8
  const print = std.debug.print;
9
9
 
10
- const trace = options.trace;
10
+ const enabled = options.log;
11
11
 
12
12
  const Player = data.Player;
13
13
  const ID = data.ID;
@@ -102,6 +102,9 @@ pub const ArgType = enum(u8) {
102
102
  // Gen 8
103
103
  CanDynamax,
104
104
  SwapSideConditions,
105
+
106
+ // Gen 9
107
+ Terastallize,
105
108
  };
106
109
 
107
110
  pub const Move = enum(u8) {
@@ -219,8 +222,12 @@ pub const Immune = enum(u8) {
219
222
  OHKO,
220
223
  };
221
224
 
225
+ /// Null object pattern implementation of `Log` backed by a `std.io.null_writer`.
226
+ /// Ignores anything sent to it, though protocol logging should additionally be turned off
227
+ /// entirely with `options.log`.
222
228
  pub const NULL = Log(@TypeOf(std.io.null_writer)){ .writer = std.io.null_writer };
223
229
 
230
+ /// Logs protocol information to its `Writer` during a battle update when `options.log` is enabled.
224
231
  pub fn Log(comptime Writer: type) type {
225
232
  return struct {
226
233
  const Self = @This();
@@ -230,91 +237,100 @@ pub fn Log(comptime Writer: type) type {
230
237
  pub const Error = Writer.Error;
231
238
 
232
239
  pub fn move(self: Self, source: ID, m: anytype, target: ID, from: anytype) Error!void {
233
- if (!trace) return;
240
+ if (!enabled) return;
241
+
234
242
  assert(m != .None);
235
243
  try self.writer.writeAll(&.{
236
- @enumToInt(ArgType.Move),
237
- @bitCast(u8, source),
238
- @enumToInt(m),
239
- @bitCast(u8, target),
244
+ @intFromEnum(ArgType.Move),
245
+ @as(u8, @bitCast(source)),
246
+ @intFromEnum(m),
247
+ @as(u8, @bitCast(target)),
240
248
  });
241
- const none = &[_]u8{@enumToInt(Move.None)};
249
+ const none = &[_]u8{@intFromEnum(Move.None)};
242
250
  try self.writer.writeAll(switch (@typeInfo(@TypeOf(from))) {
243
251
  .Null => none,
244
252
  .Optional => if (from) |f| blk: {
245
- assert(@enumToInt(f) != 0);
246
- break :blk &[_]u8{ @enumToInt(Move.From), @enumToInt(f) };
253
+ assert(@intFromEnum(f) != 0);
254
+ break :blk &[_]u8{ @intFromEnum(Move.From), @intFromEnum(f) };
247
255
  } else none,
248
256
  else => blk: {
249
- assert(@enumToInt(from) != 0);
250
- break :blk &[_]u8{ @enumToInt(Move.From), @enumToInt(from) };
257
+ assert(@intFromEnum(from) != 0);
258
+ break :blk &[_]u8{ @intFromEnum(Move.From), @intFromEnum(from) };
251
259
  },
252
260
  });
253
261
  }
254
262
 
255
263
  pub fn switched(self: Self, ident: ID, pokemon: anytype) Error!void {
256
- if (!trace) return;
257
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Switch), @bitCast(u8, ident) });
258
- try self.writer.writeAll(&.{ @enumToInt(pokemon.species), pokemon.level });
264
+ if (!enabled) return;
265
+
266
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Switch), @as(u8, @bitCast(ident)) });
267
+ try self.writer.writeAll(&.{ @intFromEnum(pokemon.species), pokemon.level });
259
268
  try self.writer.writeIntNative(u16, pokemon.hp);
260
269
  try self.writer.writeIntNative(u16, pokemon.stats.hp);
261
270
  try self.writer.writeAll(&.{pokemon.status});
262
271
  }
263
272
 
264
273
  pub fn cant(self: Self, ident: ID, reason: Cant) Error!void {
265
- if (!trace) return;
274
+ if (!enabled) return;
275
+
266
276
  assert(reason != .Disable);
267
277
  try self.writer.writeAll(&.{
268
- @enumToInt(ArgType.Cant),
269
- @bitCast(u8, ident),
270
- @enumToInt(reason),
278
+ @intFromEnum(ArgType.Cant),
279
+ @as(u8, @bitCast(ident)),
280
+ @intFromEnum(reason),
271
281
  });
272
282
  }
273
283
 
274
284
  pub fn disabled(self: Self, ident: ID, m: anytype) Error!void {
275
- if (!trace) return;
285
+ if (!enabled) return;
286
+
276
287
  try self.writer.writeAll(&.{
277
- @enumToInt(ArgType.Cant),
278
- @bitCast(u8, ident),
279
- @enumToInt(Cant.Disable),
280
- @enumToInt(m),
288
+ @intFromEnum(ArgType.Cant),
289
+ @as(u8, @bitCast(ident)),
290
+ @intFromEnum(Cant.Disable),
291
+ @intFromEnum(m),
281
292
  });
282
293
  }
283
294
 
284
295
  pub fn faint(self: Self, ident: ID, done: bool) Error!void {
285
- if (!trace) return;
286
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Faint), @bitCast(u8, ident) });
287
- if (done) try self.writer.writeByte(@enumToInt(ArgType.None));
296
+ if (!enabled) return;
297
+
298
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(ident)) });
299
+ if (done) try self.writer.writeByte(@intFromEnum(ArgType.None));
288
300
  }
289
301
 
290
302
  pub fn turn(self: Self, num: u16) Error!void {
291
- if (!trace) return;
292
- try self.writer.writeByte(@enumToInt(ArgType.Turn));
303
+ if (!enabled) return;
304
+
305
+ try self.writer.writeByte(@intFromEnum(ArgType.Turn));
293
306
  try self.writer.writeIntNative(u16, num);
294
- try self.writer.writeByte(@enumToInt(ArgType.None));
307
+ try self.writer.writeByte(@intFromEnum(ArgType.None));
295
308
  }
296
309
 
297
310
  pub fn win(self: Self, player: Player) Error!void {
298
- if (!trace) return;
311
+ if (!enabled) return;
312
+
299
313
  try self.writer.writeAll(&.{
300
- @enumToInt(ArgType.Win),
301
- @enumToInt(player),
302
- @enumToInt(ArgType.None),
314
+ @intFromEnum(ArgType.Win),
315
+ @intFromEnum(player),
316
+ @intFromEnum(ArgType.None),
303
317
  });
304
318
  }
305
319
 
306
320
  pub fn tie(self: Self) Error!void {
307
- if (!trace) return;
308
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Tie), @enumToInt(ArgType.None) });
321
+ if (!enabled) return;
322
+
323
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Tie), @intFromEnum(ArgType.None) });
309
324
  }
310
325
 
311
326
  pub fn damage(self: Self, ident: ID, pokemon: anytype, reason: Damage) Error!void {
312
- if (!trace) return;
313
- assert(@enumToInt(reason) <= @enumToInt(Damage.LeechSeed));
314
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Damage), @bitCast(u8, ident) });
327
+ if (!enabled) return;
328
+
329
+ assert(@intFromEnum(reason) <= @intFromEnum(Damage.LeechSeed));
330
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
315
331
  try self.writer.writeIntNative(u16, pokemon.hp);
316
332
  try self.writer.writeIntNative(u16, pokemon.stats.hp);
317
- try self.writer.writeAll(&.{ pokemon.status, @enumToInt(reason) });
333
+ try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) });
318
334
  }
319
335
 
320
336
  pub fn damageOf(
@@ -324,227 +340,271 @@ pub fn Log(comptime Writer: type) type {
324
340
  reason: Damage,
325
341
  source: ID,
326
342
  ) Error!void {
327
- if (!trace) return;
328
- assert(@enumToInt(reason) == @enumToInt(Damage.RecoilOf));
329
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Damage), @bitCast(u8, ident) });
343
+ if (!enabled) return;
344
+
345
+ assert(@intFromEnum(reason) == @intFromEnum(Damage.RecoilOf));
346
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
330
347
  try self.writer.writeIntNative(u16, pokemon.hp);
331
348
  try self.writer.writeIntNative(u16, pokemon.stats.hp);
332
349
  try self.writer.writeAll(&.{
333
350
  pokemon.status,
334
- @enumToInt(reason),
335
- @bitCast(u8, source),
351
+ @intFromEnum(reason),
352
+ @as(u8, @bitCast(source)),
336
353
  });
337
354
  }
338
355
 
339
356
  pub fn heal(self: Self, ident: ID, pokemon: anytype, reason: Heal) Error!void {
340
- if (!trace) return;
357
+ if (!enabled) return;
358
+
341
359
  assert(reason != .Drain);
342
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Heal), @bitCast(u8, ident) });
360
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(ident)) });
343
361
  try self.writer.writeIntNative(u16, pokemon.hp);
344
362
  try self.writer.writeIntNative(u16, pokemon.stats.hp);
345
- try self.writer.writeAll(&.{ pokemon.status, @enumToInt(reason) });
363
+ try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) });
346
364
  }
347
365
 
348
366
  pub fn drain(self: Self, source: ID, pokemon: anytype, target: ID) Error!void {
349
- if (!trace) return;
350
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Heal), @bitCast(u8, source) });
367
+ if (!enabled) return;
368
+
369
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(source)) });
351
370
  try self.writer.writeIntNative(u16, pokemon.hp);
352
371
  try self.writer.writeIntNative(u16, pokemon.stats.hp);
353
372
  try self.writer.writeAll(&.{
354
373
  pokemon.status,
355
- @enumToInt(Heal.Drain),
356
- @bitCast(u8, target),
374
+ @intFromEnum(Heal.Drain),
375
+ @as(u8, @bitCast(target)),
357
376
  });
358
377
  }
359
378
 
360
379
  pub fn status(self: Self, ident: ID, value: u8, reason: Status) Error!void {
361
- if (!trace) return;
380
+ if (!enabled) return;
381
+
362
382
  assert(reason != .From);
363
383
  try self.writer.writeAll(&.{
364
- @enumToInt(ArgType.Status),
365
- @bitCast(u8, ident),
384
+ @intFromEnum(ArgType.Status),
385
+ @as(u8, @bitCast(ident)),
366
386
  value,
367
- @enumToInt(reason),
387
+ @intFromEnum(reason),
368
388
  });
369
389
  }
370
390
 
371
391
  pub fn statusFrom(self: Self, ident: ID, value: u8, m: anytype) Error!void {
372
- if (!trace) return;
392
+ if (!enabled) return;
393
+
373
394
  try self.writer.writeAll(&.{
374
- @enumToInt(ArgType.Status),
375
- @bitCast(u8, ident),
395
+ @intFromEnum(ArgType.Status),
396
+ @as(u8, @bitCast(ident)),
376
397
  value,
377
- @enumToInt(Status.From),
378
- @enumToInt(m),
398
+ @intFromEnum(Status.From),
399
+ @intFromEnum(m),
379
400
  });
380
401
  }
381
402
 
382
403
  pub fn curestatus(self: Self, ident: ID, value: u8, reason: CureStatus) Error!void {
383
- if (!trace) return;
404
+ if (!enabled) return;
405
+
384
406
  try self.writer.writeAll(&.{
385
- @enumToInt(ArgType.CureStatus),
386
- @bitCast(u8, ident),
407
+ @intFromEnum(ArgType.CureStatus),
408
+ @as(u8, @bitCast(ident)),
387
409
  value,
388
- @enumToInt(reason),
410
+ @intFromEnum(reason),
389
411
  });
390
412
  }
391
413
 
392
414
  pub fn boost(self: Self, ident: ID, reason: Boost, num: i8) Error!void {
393
- if (!trace) return;
415
+ if (!enabled) return;
416
+
394
417
  assert(num != 0 and (reason != .Rage or num > 0));
395
418
  try self.writer.writeAll(&.{
396
- @enumToInt(ArgType.Boost),
397
- @bitCast(u8, ident),
398
- @enumToInt(reason),
399
- @intCast(u8, num + 6),
419
+ @intFromEnum(ArgType.Boost),
420
+ @as(u8, @bitCast(ident)),
421
+ @intFromEnum(reason),
422
+ @as(u8, @intCast(num + 6)),
400
423
  });
401
424
  }
402
425
 
403
426
  pub fn clearallboost(self: Self) Error!void {
404
- if (!trace) return;
405
- try self.writer.writeAll(&.{@enumToInt(ArgType.ClearAllBoost)});
427
+ if (!enabled) return;
428
+
429
+ try self.writer.writeAll(&.{@intFromEnum(ArgType.ClearAllBoost)});
406
430
  }
407
431
 
408
432
  pub fn fail(self: Self, ident: ID, reason: Fail) Error!void {
409
- if (!trace) return;
433
+ if (!enabled) return;
434
+
410
435
  try self.writer.writeAll(&.{
411
- @enumToInt(ArgType.Fail),
412
- @bitCast(u8, ident),
413
- @enumToInt(reason),
436
+ @intFromEnum(ArgType.Fail),
437
+ @as(u8, @bitCast(ident)),
438
+ @intFromEnum(reason),
414
439
  });
415
440
  }
416
441
 
417
442
  pub fn miss(self: Self, source: ID) Error!void {
418
- if (!trace) return;
419
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Miss), @bitCast(u8, source) });
443
+ if (!enabled) return;
444
+
445
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(source)) });
420
446
  }
421
447
 
422
448
  pub fn hitcount(self: Self, ident: ID, num: u8) Error!void {
423
- if (!trace) return;
424
- try self.writer.writeAll(&.{ @enumToInt(ArgType.HitCount), @bitCast(u8, ident), num });
449
+ if (!enabled) return;
450
+
451
+ try self.writer.writeAll(&.{
452
+ @intFromEnum(ArgType.HitCount),
453
+ @as(u8, @bitCast(ident)),
454
+ num,
455
+ });
425
456
  }
426
457
 
427
458
  pub fn prepare(self: Self, source: ID, m: anytype) Error!void {
428
- if (!trace) return;
459
+ if (!enabled) return;
460
+
429
461
  try self.writer.writeAll(&.{
430
- @enumToInt(ArgType.Prepare),
431
- @bitCast(u8, source),
432
- @enumToInt(m),
462
+ @intFromEnum(ArgType.Prepare),
463
+ @as(u8, @bitCast(source)),
464
+ @intFromEnum(m),
433
465
  });
434
466
  }
435
467
 
436
468
  pub fn mustrecharge(self: Self, ident: ID) Error!void {
437
- if (!trace) return;
438
- try self.writer.writeAll(&.{ @enumToInt(ArgType.MustRecharge), @bitCast(u8, ident) });
469
+ if (!enabled) return;
470
+
471
+ try self.writer.writeAll(&.{
472
+ @intFromEnum(ArgType.MustRecharge),
473
+ @as(u8, @bitCast(ident)),
474
+ });
439
475
  }
440
476
 
441
477
  pub fn activate(self: Self, ident: ID, reason: Activate) Error!void {
442
- if (!trace) return;
478
+ if (!enabled) return;
479
+
443
480
  try self.writer.writeAll(&.{
444
- @enumToInt(ArgType.Activate),
445
- @bitCast(u8, ident),
446
- @enumToInt(reason),
481
+ @intFromEnum(ArgType.Activate),
482
+ @as(u8, @bitCast(ident)),
483
+ @intFromEnum(reason),
447
484
  });
448
485
  }
449
486
 
450
487
  pub fn fieldactivate(self: Self) Error!void {
451
- if (!trace) return;
452
- try self.writer.writeAll(&.{@enumToInt(ArgType.FieldActivate)});
488
+ if (!enabled) return;
489
+
490
+ try self.writer.writeAll(&.{@intFromEnum(ArgType.FieldActivate)});
453
491
  }
454
492
 
455
493
  pub fn start(self: Self, ident: ID, reason: Start) Error!void {
456
- if (!trace) return;
457
- assert(@enumToInt(reason) < @enumToInt(Start.TypeChange));
494
+ if (!enabled) return;
495
+
496
+ assert(@intFromEnum(reason) < @intFromEnum(Start.TypeChange));
458
497
  try self.writer.writeAll(&.{
459
- @enumToInt(ArgType.Start),
460
- @bitCast(u8, ident),
461
- @enumToInt(reason),
498
+ @intFromEnum(ArgType.Start),
499
+ @as(u8, @bitCast(ident)),
500
+ @intFromEnum(reason),
462
501
  });
463
502
  }
464
503
 
465
504
  pub fn typechange(self: Self, source: ID, types: anytype, target: ID) Error!void {
466
- if (!trace) return;
505
+ if (!enabled) return;
506
+
467
507
  try self.writer.writeAll(&.{
468
- @enumToInt(ArgType.Start),
469
- @bitCast(u8, source),
470
- @enumToInt(Start.TypeChange),
471
- @bitCast(u8, types),
472
- @bitCast(u8, target),
508
+ @intFromEnum(ArgType.Start),
509
+ @as(u8, @bitCast(source)),
510
+ @intFromEnum(Start.TypeChange),
511
+ @as(u8, @bitCast(types)),
512
+ @as(u8, @bitCast(target)),
473
513
  });
474
514
  }
475
515
 
476
516
  pub fn startEffect(self: Self, ident: ID, reason: Start, m: anytype) Error!void {
477
- if (!trace) return;
478
- assert(@enumToInt(reason) > @enumToInt(Start.TypeChange));
517
+ if (!enabled) return;
518
+
519
+ assert(@intFromEnum(reason) > @intFromEnum(Start.TypeChange));
479
520
  try self.writer.writeAll(&.{
480
- @enumToInt(ArgType.Start),
481
- @bitCast(u8, ident),
482
- @enumToInt(reason),
483
- @enumToInt(m),
521
+ @intFromEnum(ArgType.Start),
522
+ @as(u8, @bitCast(ident)),
523
+ @intFromEnum(reason),
524
+ @intFromEnum(m),
484
525
  });
485
526
  }
486
527
 
487
528
  pub fn end(self: Self, ident: ID, reason: End) Error!void {
488
- if (!trace) return;
529
+ if (!enabled) return;
530
+
489
531
  try self.writer.writeAll(&.{
490
- @enumToInt(ArgType.End),
491
- @bitCast(u8, ident),
492
- @enumToInt(reason),
532
+ @intFromEnum(ArgType.End),
533
+ @as(u8, @bitCast(ident)),
534
+ @intFromEnum(reason),
493
535
  });
494
536
  }
495
537
 
496
538
  pub fn ohko(self: Self) Error!void {
497
- if (!trace) return;
498
- try self.writer.writeAll(&.{@enumToInt(ArgType.OHKO)});
539
+ if (!enabled) return;
540
+
541
+ try self.writer.writeAll(&.{@intFromEnum(ArgType.OHKO)});
499
542
  }
500
543
 
501
544
  pub fn crit(self: Self, ident: ID) Error!void {
502
- if (!trace) return;
503
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Crit), @bitCast(u8, ident) });
545
+ if (!enabled) return;
546
+
547
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(ident)) });
504
548
  }
505
549
 
506
550
  pub fn supereffective(self: Self, ident: ID) Error!void {
507
- if (!trace) return;
508
- try self.writer.writeAll(&.{ @enumToInt(ArgType.SuperEffective), @bitCast(u8, ident) });
551
+ if (!enabled) return;
552
+
553
+ try self.writer.writeAll(&.{
554
+ @intFromEnum(ArgType.SuperEffective),
555
+ @as(u8, @bitCast(ident)),
556
+ });
509
557
  }
510
558
 
511
559
  pub fn resisted(self: Self, ident: ID) Error!void {
512
- if (!trace) return;
513
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Resisted), @bitCast(u8, ident) });
560
+ if (!enabled) return;
561
+
562
+ try self.writer.writeAll(&.{
563
+ @intFromEnum(ArgType.Resisted),
564
+ @as(u8, @bitCast(ident)),
565
+ });
514
566
  }
515
567
 
516
568
  pub fn immune(self: Self, ident: ID, reason: Immune) Error!void {
517
- if (!trace) return;
569
+ if (!enabled) return;
570
+
518
571
  try self.writer.writeAll(&.{
519
- @enumToInt(ArgType.Immune),
520
- @bitCast(u8, ident),
521
- @enumToInt(reason),
572
+ @intFromEnum(ArgType.Immune),
573
+ @as(u8, @bitCast(ident)),
574
+ @intFromEnum(reason),
522
575
  });
523
576
  }
524
577
 
525
578
  pub fn transform(self: Self, source: ID, target: ID) Error!void {
526
- if (!trace) return;
579
+ if (!enabled) return;
580
+
527
581
  try self.writer.writeAll(&.{
528
- @enumToInt(ArgType.Transform),
529
- @bitCast(u8, source),
530
- @bitCast(u8, target),
582
+ @intFromEnum(ArgType.Transform),
583
+ @as(u8, @bitCast(source)),
584
+ @as(u8, @bitCast(target)),
531
585
  });
532
586
  }
533
587
 
534
588
  pub fn laststill(self: Self) Error!void {
535
- if (!trace) return;
536
- try self.writer.writeAll(&.{@enumToInt(ArgType.LastStill)});
589
+ if (!enabled) return;
590
+
591
+ try self.writer.writeAll(&.{@intFromEnum(ArgType.LastStill)});
537
592
  }
538
593
 
539
594
  pub fn lastmiss(self: Self) Error!void {
540
- if (!trace) return;
541
- try self.writer.writeAll(&.{@enumToInt(ArgType.LastMiss)});
595
+ if (!enabled) return;
596
+
597
+ try self.writer.writeAll(&.{@intFromEnum(ArgType.LastMiss)});
542
598
  }
543
599
  };
544
600
  }
545
601
 
602
+ /// `Log` type backed by the optimized `ByteStream.Writer`.
546
603
  pub const FixedLog = Log(ByteStream.Writer);
547
604
 
605
+ /// Stripped down version of `std.io.FixedBufferStream` optimized for efficiently writing the
606
+ /// individual protocol bytes. Note that the `ByteStream.Writer` is **not** a `std.io.Writer` and
607
+ /// should not be used for general purpose writing.
548
608
  pub const ByteStream = struct {
549
609
  buffer: []u8,
550
610
  pos: usize = 0,
@@ -593,7 +653,7 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
593
653
 
594
654
  var i: usize = 0;
595
655
  while (i < a.len) {
596
- const arg = @intToEnum(ArgType, a[i]);
656
+ const arg: ArgType = @enumFromInt(a[i]);
597
657
  const name = switch (arg) {
598
658
  .None => if (color) "\x1b[2m-\x1b[0m" else "-",
599
659
  .LastStill => "|[still]",
@@ -639,17 +699,17 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
639
699
  .OHKO,
640
700
  => {},
641
701
  .Move => {
642
- const source = ID.from(@intCast(u4, a[i]));
702
+ const source = ID.from(@intCast(a[i]));
643
703
  printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
644
704
  printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
645
- const target = ID.from(@intCast(u4, a[i]));
705
+ const target = ID.from(@intCast(a[i]));
646
706
  printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
647
- const reason = @intToEnum(Move, a[i]);
707
+ const reason: Move = @enumFromInt(a[i]);
648
708
  printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
649
709
  if (reason == .From) printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
650
710
  },
651
711
  .Switch => {
652
- const id = ID.from(@intCast(u4, a[i]));
712
+ const id = ID.from(@intCast(a[i]));
653
713
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
654
714
  printc(" {s}", .{formatter(.Species, a[i])}, a, b, &i, 1, color);
655
715
  printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
@@ -670,9 +730,9 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
670
730
  printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
671
731
  },
672
732
  .Cant => {
673
- const id = ID.from(@intCast(u4, a[i]));
733
+ const id = ID.from(@intCast(a[i]));
674
734
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
675
- const reason = @intToEnum(Cant, a[i]);
735
+ const reason: Cant = @enumFromInt(a[i]);
676
736
  printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
677
737
  if (reason == .Disable) {
678
738
  printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
@@ -685,7 +745,7 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
685
745
  .SuperEffective,
686
746
  .Resisted,
687
747
  => {
688
- const id = ID.from(@intCast(u4, a[i]));
748
+ const id = ID.from(@intCast(a[i]));
689
749
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
690
750
  },
691
751
  .Turn => {
@@ -695,9 +755,11 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
695
755
  };
696
756
  printc(" {d}", .{turn}, a, b, &i, 2, color);
697
757
  },
698
- .Win => printc(" {s}", .{@tagName(@intToEnum(Player, a[i]))}, a, b, &i, 1, color),
758
+ .Win => {
759
+ printc(" {s}", .{@tagName(@as(Player, @enumFromInt(a[i])))}, a, b, &i, 1, color);
760
+ },
699
761
  .Damage, .Heal => {
700
- var id = ID.from(@intCast(u4, a[i]));
762
+ var id = ID.from(@intCast(a[i]));
701
763
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
702
764
  switch (endian) {
703
765
  .Big => {
@@ -715,91 +777,92 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
715
777
  }
716
778
  printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
717
779
  if (arg == .Damage) {
718
- const reason = a[i];
719
- printc(" {s}", .{@tagName(@intToEnum(Damage, reason))}, a, b, &i, 1, color);
720
- if (reason == @enumToInt(Damage.RecoilOf)) {
721
- id = ID.from(@intCast(u4, a[i]));
780
+ const reason: Damage = @enumFromInt(a[i]);
781
+ printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
782
+ if (reason == .RecoilOf) {
783
+ id = ID.from(@intCast(a[i]));
722
784
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
723
785
  }
724
786
  } else {
725
- const reason = @intToEnum(Heal, a[i]);
787
+ const reason: Heal = @enumFromInt(a[i]);
726
788
  printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
727
789
  if (reason == .Drain) {
728
- id = ID.from(@intCast(u4, a[i]));
790
+ id = ID.from(@intCast(a[i]));
729
791
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
730
792
  }
731
793
  }
732
794
  },
733
795
  .Status => {
734
- const id = ID.from(@intCast(u4, a[i]));
796
+ const id = ID.from(@intCast(a[i]));
735
797
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
736
798
  printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
737
- const reason = @intToEnum(Status, a[i]);
799
+ const reason: Status = @enumFromInt(a[i]);
738
800
  printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
739
801
  if (reason == .From) printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
740
802
  },
741
803
  .CureStatus => {
742
- const id = ID.from(@intCast(u4, a[i]));
804
+ const id = ID.from(@intCast(a[i]));
743
805
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
744
806
  printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
745
- printc(" {s}", .{@tagName(@intToEnum(CureStatus, a[i]))}, a, b, &i, 1, color);
807
+ const reason: CureStatus = @enumFromInt(a[i]);
808
+ printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
746
809
  },
747
810
  .Boost => {
748
- const id = ID.from(@intCast(u4, a[i]));
811
+ const id = ID.from(@intCast(a[i]));
749
812
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
750
- printc(" {s}", .{@tagName(@intToEnum(Boost, a[i]))}, a, b, &i, 1, color);
813
+ printc(" {s}", .{@tagName(@as(Boost, @enumFromInt(a[i])))}, a, b, &i, 1, color);
751
814
  printc(" {d}", .{a[i]}, a, b, &i, 1, color);
752
815
  },
753
816
  .Fail => {
754
- const id = ID.from(@intCast(u4, a[i]));
817
+ const id = ID.from(@intCast(a[i]));
755
818
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
756
- printc(" {s}", .{@tagName(@intToEnum(Fail, a[i]))}, a, b, &i, 1, color);
819
+ printc(" {s}", .{@tagName(@as(Fail, @enumFromInt(a[i])))}, a, b, &i, 1, color);
757
820
  },
758
821
  .HitCount => {
759
- const id = ID.from(@intCast(u4, a[i]));
822
+ const id = ID.from(@intCast(a[i]));
760
823
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
761
824
  printc(" {d}", .{a[i]}, a, b, &i, 1, color);
762
825
  },
763
826
  .Prepare => {
764
- const id = ID.from(@intCast(u4, a[i]));
827
+ const id = ID.from(@intCast(a[i]));
765
828
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
766
829
  printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
767
830
  },
768
831
  .Activate => {
769
- const id = ID.from(@intCast(u4, a[i]));
832
+ const id = ID.from(@intCast(a[i]));
770
833
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
771
- printc(" {s}", .{@tagName(@intToEnum(Activate, a[i]))}, a, b, &i, 1, color);
834
+ printc(" {s}", .{@tagName(@as(Activate, @enumFromInt(a[i])))}, a, b, &i, 1, color);
772
835
  },
773
836
  .Start => {
774
- const id = ID.from(@intCast(u4, a[i]));
837
+ const id = ID.from(@intCast(a[i]));
775
838
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
776
839
  const reason = a[i];
777
- printc(" {s}", .{@tagName(@intToEnum(Start, reason))}, a, b, &i, 1, color);
778
- if (@intToEnum(Start, reason) == .TypeChange) {
779
- const types = @bitCast(gen1.Types, a[i]);
840
+ printc(" {s}", .{@tagName(@as(Start, @enumFromInt(reason)))}, a, b, &i, 1, color);
841
+ if (@as(Start, @enumFromInt(reason)) == .TypeChange) {
842
+ const types = @as(gen1.Types, @bitCast(a[i]));
780
843
  const args = .{
781
- formatter(.Type, @enumToInt(types.type1)),
782
- formatter(.Type, @enumToInt(types.type2)),
844
+ formatter(.Type, @intFromEnum(types.type1)),
845
+ formatter(.Type, @intFromEnum(types.type2)),
783
846
  };
784
847
  printc(" {s}/{s}", args, a, b, &i, 1, color);
785
- } else if (reason >= @enumToInt(Start.Disable)) {
848
+ } else if (reason >= @intFromEnum(Start.Disable)) {
786
849
  printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
787
850
  }
788
851
  },
789
852
  .End => {
790
- const id = ID.from(@intCast(u4, a[i]));
853
+ const id = ID.from(@intCast(a[i]));
791
854
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
792
- printc(" {s}", .{@tagName(@intToEnum(End, a[i]))}, a, b, &i, 1, color);
855
+ printc(" {s}", .{@tagName(@as(End, @enumFromInt(a[i])))}, a, b, &i, 1, color);
793
856
  },
794
857
  .Immune => {
795
- const id = ID.from(@intCast(u4, a[i]));
858
+ const id = ID.from(@intCast(a[i]));
796
859
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
797
- printc(" {s}", .{@tagName(@intToEnum(Immune, a[i]))}, a, b, &i, 1, color);
860
+ printc(" {s}", .{@tagName(@as(Immune, @enumFromInt(a[i])))}, a, b, &i, 1, color);
798
861
  },
799
862
  .Transform => {
800
- const source = ID.from(@intCast(u4, a[i]));
863
+ const source = ID.from(@intCast(a[i]));
801
864
  printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
802
- const target = ID.from(@intCast(u4, a[i]));
865
+ const target = ID.from(@intCast(a[i]));
803
866
  printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
804
867
  },
805
868
  else => unreachable,
@@ -838,7 +901,8 @@ pub fn expectLog(
838
901
  actual: []const u8,
839
902
  offset: usize,
840
903
  ) !void {
841
- if (!trace) return;
904
+ if (!enabled) return;
905
+
842
906
  const color = color: {
843
907
  if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR")) {
844
908
  break :color true;
@@ -881,7 +945,7 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
881
945
  const endian = builtin.target.cpu.arch.endian();
882
946
 
883
947
  fn N(e: anytype) u8 {
884
- return @enumToInt(e);
948
+ return @intFromEnum(e);
885
949
  }
886
950
 
887
951
  const p1 = Player.P1;
@@ -905,9 +969,9 @@ fn expectLog1(expected: []const u8, actual: []const u8) !void {
905
969
 
906
970
  fn gen1Formatter(kind: Kind, byte: u8) []const u8 {
907
971
  return switch (kind) {
908
- .Move => @tagName(@intToEnum(M, byte)),
909
- .Species => @tagName(@intToEnum(S, byte)),
910
- .Type => @tagName(@intToEnum(gen1.Type, byte)),
972
+ .Move => @tagName(@as(M, @enumFromInt(byte))),
973
+ .Species => @tagName(@as(S, @enumFromInt(byte))),
974
+ .Type => @tagName(@as(gen1.Type, @enumFromInt(byte))),
911
975
  .Status => gen1.Status.name(byte),
912
976
  };
913
977
  }