@pkmn/engine 0.1.0-dev.a324c50f → 0.1.0-dev.a5846b2d

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 (84) hide show
  1. package/LICENSE +1 -3
  2. package/README.md +92 -56
  3. package/build/pkg/addon/browser.d.ts +3 -0
  4. package/build/pkg/addon/browser.js +44 -0
  5. package/build/pkg/addon/browser.js.map +1 -0
  6. package/build/pkg/addon/node.d.ts +3 -0
  7. package/build/pkg/addon/node.js +97 -0
  8. package/build/pkg/addon/node.js.map +1 -0
  9. package/build/pkg/addon/wasm.d.ts +2 -0
  10. package/build/pkg/addon/wasm.js +53 -0
  11. package/build/pkg/addon/wasm.js.map +1 -0
  12. package/build/pkg/addon.d.ts +25 -3
  13. package/build/pkg/addon.js +39 -71
  14. package/build/pkg/addon.js.map +1 -1
  15. package/build/pkg/data/ids.json +12 -12
  16. package/build/pkg/data/layout.json +17 -4
  17. package/build/pkg/data/protocol.json +84 -13
  18. package/build/pkg/data.d.ts +27 -5
  19. package/build/pkg/data.js.map +1 -1
  20. package/build/pkg/gen1.d.ts +13 -17
  21. package/build/pkg/gen1.js +8 -12
  22. package/build/pkg/gen1.js.map +1 -1
  23. package/build/pkg/index.d.ts +40 -91
  24. package/build/pkg/index.js +6 -63
  25. package/build/pkg/index.js.map +1 -1
  26. package/build/pkg/protocol.d.ts +20 -1
  27. package/build/pkg/protocol.js +123 -102
  28. package/build/pkg/protocol.js.map +1 -1
  29. package/build/tools/debug.js +36 -69
  30. package/build/tools/debug.js.map +1 -1
  31. package/build/tools/display/debug.jsx +141 -0
  32. package/build/tools/display/debug.jsx.map +1 -0
  33. package/build/tools/display/index.js +142 -0
  34. package/build/tools/display/index.js.map +1 -0
  35. package/build/tools/display/ui.jsx +349 -0
  36. package/build/tools/display/ui.jsx.map +1 -0
  37. package/build/tools/display/util.js +18 -0
  38. package/build/tools/display/util.js.map +1 -0
  39. package/build.zig +345 -126
  40. package/package.json +68 -121
  41. package/src/bin/install-pkmn-engine +32 -22
  42. package/src/bin/pkmn-debug +1 -1
  43. package/src/lib/{binding → bindings}/node.zig +9 -22
  44. package/src/lib/bindings/wasm.zig +59 -0
  45. package/src/lib/common/array.zig +77 -0
  46. package/src/lib/common/battle.zig +17 -0
  47. package/src/lib/common/data.zig +12 -24
  48. package/src/lib/common/debug.zig +39 -8
  49. package/src/lib/common/js.zig +120 -0
  50. package/src/lib/common/optional.zig +71 -0
  51. package/src/lib/common/options.zig +6 -0
  52. package/src/lib/common/protocol.zig +811 -332
  53. package/src/lib/common/rational.zig +449 -0
  54. package/src/lib/common/rng.zig +22 -15
  55. package/src/lib/common/util.zig +61 -0
  56. package/src/lib/gen1/calc.zig +953 -0
  57. package/src/lib/gen1/chance.zig +1185 -0
  58. package/src/lib/gen1/data/moves.zig +193 -183
  59. package/src/lib/gen1/data/species.zig +4 -6
  60. package/src/lib/gen1/data/types.zig +8 -9
  61. package/src/lib/gen1/data.zig +67 -77
  62. package/src/lib/gen1/helpers.zig +91 -409
  63. package/src/lib/gen1/mechanics.zig +675 -613
  64. package/src/lib/gen2/calc.zig +153 -0
  65. package/src/lib/gen2/chance.zig +902 -0
  66. package/src/lib/gen2/data/items.zig +13 -21
  67. package/src/lib/gen2/data/moves.zig +664 -572
  68. package/src/lib/gen2/data/species.zig +2 -4
  69. package/src/lib/gen2/data/types.zig +135 -33
  70. package/src/lib/gen2/data.zig +115 -91
  71. package/src/lib/gen2/generated.zig +801 -0
  72. package/src/lib/gen2/helpers.zig +54 -37
  73. package/src/lib/gen2/mechanics.zig +3580 -29
  74. package/src/lib/node.zig +18 -0
  75. package/src/lib/pkmn.zig +37 -15
  76. package/src/lib/wasm.zig +17 -0
  77. package/src/tools/display/dom.ts +96 -0
  78. package/src/tools/display/ui.css +354 -0
  79. package/build/test/display.js +0 -400
  80. package/build/test/display.js.map +0 -1
  81. package/src/lib/binding/wasm.zig +0 -12
  82. package/src/lib/gen1/README.md +0 -814
  83. package/src/lib/gen2/README.md +0 -309
  84. package/src/test/display/pkmn.html.tmpl +0 -368
@@ -1,11 +1,9 @@
1
- //! Code generated by `tools/generate` - manual edits will be overwritten
2
-
3
- const std = @import("std");
1
+ //! Code generated by `tools/generate` - manual edits will be overwritten.
4
2
 
5
3
  const gen1 = @import("../../gen1/data.zig");
4
+ const std = @import("std");
6
5
 
7
6
  const assert = std.debug.assert;
8
-
9
7
  const Stats = gen1.Stats;
10
8
  const Types = gen1.Types;
11
9
 
@@ -1091,8 +1089,8 @@ pub const Species = enum(u8) {
1091
1089
  /// The number of Pokémon species in this generation.
1092
1090
  pub const size = 151;
1093
1091
 
1094
- /// The Pokémon's critical hit rate=io out of 256.
1095
- pub inline fn chance(id: Species) u8 {
1092
+ /// The Pokémon's critical hit ratio out of 256.
1093
+ pub fn chance(id: Species) u8 {
1096
1094
  assert(id != .None);
1097
1095
  return CHANCES[@intFromEnum(id) - 1];
1098
1096
  }
@@ -1,8 +1,7 @@
1
- //! Code generated by `tools/generate` - manual edits will be overwritten
2
-
3
- const std = @import("std");
1
+ //! Code generated by `tools/generate` - manual edits will be overwritten.
4
2
 
5
3
  const gen1 = @import("../../gen1/data.zig");
4
+ const std = @import("std");
6
5
 
7
6
  const assert = std.debug.assert;
8
7
  const Effectiveness = gen1.Effectiveness;
@@ -30,7 +29,7 @@ pub const Type = enum(u4) {
30
29
  Ice,
31
30
  Dragon,
32
31
 
33
- const CHART = [15][15]Effectiveness{
32
+ const CHART: [15][15]Effectiveness = .{
34
33
  [_]Effectiveness{ N, N, N, N, N, R, N, I, N, N, N, N, N, N, N }, // Normal
35
34
  [_]Effectiveness{ S, N, R, R, N, S, R, I, N, N, N, N, R, S, N }, // Fighting
36
35
  [_]Effectiveness{ N, S, N, N, N, R, S, N, N, N, S, R, N, N, N }, // Flying
@@ -90,16 +89,16 @@ pub const Type = enum(u4) {
90
89
  pub const size = 15;
91
90
 
92
91
  /// Whether or not this type is considered to be special as opposed to physical.
93
- pub inline fn special(self: Type) bool {
92
+ pub fn special(self: Type) bool {
94
93
  return @intFromEnum(self) >= @intFromEnum(Type.Fire);
95
94
  }
96
95
 
97
96
  /// The `Effectiveness` of type `t2` vs. type `t1`.
98
- pub inline fn effectiveness(t1: Type, t2: Type) Effectiveness {
97
+ pub fn effectiveness(t1: Type, t2: Type) Effectiveness {
99
98
  return CHART[@intFromEnum(t1)][@intFromEnum(t2)];
100
99
  }
101
100
 
102
- /// The precedence order of type `t2` vs. type `t1`.
101
+ /// The precedence order of Type `t2` vs. Type `t1`.
103
102
  pub fn precedence(t1: Type, t2: Type) u8 {
104
103
  for (PRECEDENCE, 0..) |matchup, i| {
105
104
  if (matchup.type1 == t1 and matchup.type2 == t2) return @intCast(i);
@@ -120,12 +119,12 @@ pub const Types = packed struct {
120
119
  }
121
120
 
122
121
  /// Whether this typing is immune to type `t`.
123
- pub inline fn immune(self: Types, t: Type) bool {
122
+ pub fn immune(self: Types, t: Type) bool {
124
123
  return t.effectiveness(self.type1) == I or t.effectiveness(self.type2) == I;
125
124
  }
126
125
 
127
126
  /// Whether this typing includes type `t`.
128
- pub inline fn includes(self: Types, t: Type) bool {
127
+ pub fn includes(self: Types, t: Type) bool {
129
128
  return self.type1 == t or self.type2 == t;
130
129
  }
131
130
  };
@@ -1,20 +1,16 @@
1
- const std = @import("std");
2
1
  const builtin = @import("builtin");
3
-
4
- const pkmn = @import("../pkmn.zig");
5
-
2
+ const calc = @import("calc.zig");
3
+ const chance = @import("chance.zig");
6
4
  const data = @import("../common/data.zig");
5
+ const mechanics = @import("mechanics.zig");
6
+ const moves = @import("data/moves.zig");
7
+ const pkmn = @import("../pkmn.zig");
7
8
  const protocol = @import("../common/protocol.zig");
8
9
  const rng = @import("../common/rng.zig");
9
- const util = @import("../common/util.zig");
10
-
11
- const moves = @import("data/moves.zig");
12
10
  const species = @import("data/species.zig");
11
+ const std = @import("std");
13
12
  const types = @import("data/types.zig");
14
-
15
- const calc = @import("calc.zig");
16
- const chance = @import("chance.zig");
17
- const mechanics = @import("mechanics.zig");
13
+ const util = @import("../common/util.zig");
18
14
 
19
15
  const assert = std.debug.assert;
20
16
  const expectEqual = std.testing.expectEqual;
@@ -22,11 +18,11 @@ const expect = std.testing.expect;
22
18
 
23
19
  /// The minimum size in bytes required to hold all Generation I choice options.
24
20
  pub const MAX_CHOICES: usize = 9; // move 1..4, switch 2..6
25
- /// The optimal size in bytes required to hold all Generation I choice options.
26
- /// At least as large as MAX_CHOICES.
21
+ /// The maximum number of bytes possibly logged by a single Generation I update.
27
22
  pub const MAX_LOGS: usize = 180;
28
23
 
29
- /// The maximum number of bytes possibly logged by a single Generation I update.
24
+ /// The optimal size in bytes required to hold all Generation I choice options.
25
+ /// At least as large as MAX_CHOICES.
30
26
  pub const CHOICES_SIZE = if (builtin.mode == .ReleaseSmall)
31
27
  MAX_CHOICES
32
28
  else
@@ -47,6 +43,7 @@ const Player = data.Player;
47
43
  const Result = data.Result;
48
44
 
49
45
  const PointerType = util.PointerType;
46
+ const isPointerTo = util.isPointerTo;
50
47
 
51
48
  const showdown = pkmn.options.showdown;
52
49
 
@@ -65,27 +62,36 @@ pub fn Battle(comptime RNG: anytype) type {
65
62
  /// The last damage dealt by either side.
66
63
  last_damage: u16 = 0,
67
64
  /// Details about the last move selected/used by each player required to detect desyncs.
68
- last_moves: MoveDetails = .{},
65
+ last_moves: [2]MoveDetails = [_]MoveDetails{.{}} ** 2,
69
66
  /// The pseudo random number generator.
70
67
  rng: RNG,
71
68
 
72
69
  /// Returns the `Side` for the given `player`.
73
- pub inline fn side(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
74
- assert(@typeInfo(@TypeOf(self)).Pointer.child == Self);
70
+ pub fn side(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
71
+ assert(isPointerTo(self, Self));
75
72
  return &self.sides[@intFromEnum(player)];
76
73
  }
77
74
 
78
75
  /// Returns the `Side` of the opponent for the given `player`
79
- pub inline fn foe(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
80
- assert(@typeInfo(@TypeOf(self)).Pointer.child == Self);
76
+ pub fn foe(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
77
+ assert(isPointerTo(self, Self));
81
78
  return &self.sides[@intFromEnum(player.foe())];
82
79
  }
83
80
 
84
81
  /// Returns an identifier for the active Pokémon of `player`.
85
- pub inline fn active(self: *const Self, player: Player) ID {
82
+ pub fn active(self: *const Self, player: Player) ID {
86
83
  return player.ident(@intCast(self.side(player).order[0]));
87
84
  }
88
85
 
86
+ /// Returns the `MoveDetails` for the given `player`.
87
+ pub fn lastMove(
88
+ self: anytype,
89
+ player: Player,
90
+ ) PointerType(@TypeOf(self), MoveDetails) {
91
+ assert(isPointerTo(self, Self));
92
+ return &self.last_moves[@intFromEnum(player)];
93
+ }
94
+
89
95
  /// Returns the result of applying Player 1's choice `c1` and Player 2's choice `c2` to the
90
96
  /// battle, optionally writing protocol message logs to `options.log` if `pkmn.options.log`
91
97
  /// is enabled.
@@ -103,7 +109,7 @@ pub fn Battle(comptime RNG: anytype) type {
103
109
  /// make (i.e. on the cartridge a soft-lock occurs).
104
110
  ///
105
111
  /// This function will always return choices > 0 if `pkmn.options.showdown` is true.
106
- pub fn choices(self: *Self, player: Player, request: Choice.Type, out: []Choice) u8 {
112
+ pub fn choices(self: *const Self, player: Player, request: Choice.Type, out: []Choice) u8 {
107
113
  return mechanics.choices(self, player, request, out);
108
114
  }
109
115
  };
@@ -132,8 +138,8 @@ pub const Side = extern struct {
132
138
  }
133
139
 
134
140
  /// Returns the stored `Pokemon` corresponding to the one-indexed party `slot`.
135
- pub inline fn get(self: anytype, slot: u8) PointerType(@TypeOf(self), Pokemon) {
136
- assert(@typeInfo(@TypeOf(self)).Pointer.child == Side);
141
+ pub fn get(self: anytype, slot: u8) PointerType(@TypeOf(self), Pokemon) {
142
+ assert(isPointerTo(self, Side));
137
143
  assert(slot > 0 and slot <= 6);
138
144
  const id = self.order[slot - 1];
139
145
  assert(id > 0 and id <= 6);
@@ -141,8 +147,8 @@ pub const Side = extern struct {
141
147
  }
142
148
 
143
149
  /// Returns the stored `Pokemon` corresponding to the `active` Pokémon (slot 1).
144
- pub inline fn stored(self: anytype) PointerType(@TypeOf(self), Pokemon) {
145
- assert(@typeInfo(@TypeOf(self)).Pointer.child == Side);
150
+ pub fn stored(self: anytype) PointerType(@TypeOf(self), Pokemon) {
151
+ assert(isPointerTo(self, Side));
146
152
  return self.get(1);
147
153
  }
148
154
  };
@@ -167,8 +173,8 @@ pub const ActivePokemon = extern struct {
167
173
  }
168
174
 
169
175
  /// Returns the active Pokémon's current move slot located at the one-indexed `mslot`.
170
- pub inline fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
171
- assert(@typeInfo(@TypeOf(self)).Pointer.child == ActivePokemon);
176
+ pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
177
+ assert(isPointerTo(self, ActivePokemon));
172
178
  assert(mslot > 0 and mslot <= 4);
173
179
  assert(self.moves[mslot - 1].id != .None);
174
180
  return &self.moves[mslot - 1];
@@ -197,15 +203,15 @@ pub const Pokemon = extern struct {
197
203
  }
198
204
 
199
205
  /// Returns the Pokémon's original move slot located at the one-indexed `mslot`.
200
- pub inline fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
201
- assert(@typeInfo(@TypeOf(self)).Pointer.child == Pokemon);
206
+ pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
207
+ assert(isPointerTo(self, Pokemon));
202
208
  assert(mslot > 0 and mslot <= 4);
203
209
  assert(self.moves[mslot - 1].id != .None);
204
210
  return &self.moves[mslot - 1];
205
211
  }
206
212
  };
207
213
 
208
- /// Representation of a Generation I & II Pokémon's move slot in a battle.
214
+ /// Representation of a Generation I Pokémon's move slot in a battle.
209
215
  pub const MoveSlot = extern struct {
210
216
  /// The identifier for the move.
211
217
  id: Move = .None,
@@ -213,24 +219,16 @@ pub const MoveSlot = extern struct {
213
219
  pp: u8 = 0,
214
220
 
215
221
  comptime {
216
- assert(@sizeOf(MoveSlot) == @sizeOf(u16));
222
+ assert(@sizeOf(MoveSlot) == 2);
217
223
  }
218
224
  };
219
225
 
220
226
  /// Details required to detect desyncs based on the move last selected/executed by players.
221
- pub const MoveDetails = packed struct {
222
- /// The move slot index of the last move selected in the battle menu by Player 1
223
- p1_index: if (showdown) u8 else u4 = 0,
224
- /// Whether the last move executed by Player 1 was counterable.
225
- p1_counterable: if (showdown) u8 else u4 = 0,
226
- /// The move slot index of the last move selected in the battle menu by Player 2
227
- p2_index: if (showdown) u8 else u4 = 0,
228
- /// Whether the last move executed by Player 2 was counterable.
229
- p2_counterable: if (showdown) u8 else u4 = 0,
230
-
231
- comptime {
232
- assert(@sizeOf(MoveDetails) == if (showdown) 4 else 2);
233
- }
227
+ pub const MoveDetails = packed struct(if (showdown) u16 else u8) {
228
+ /// The move slot index of the last move selected in the battle menu.
229
+ index: if (showdown) u8 else u4 = 0,
230
+ /// Whether the last move executed was counterable.
231
+ counterable: if (showdown) u8 else u4 = 0,
234
232
  };
235
233
 
236
234
  /// Bitfield representation of a Generation I & II Pokémon's major status condition.
@@ -254,39 +252,39 @@ pub const Status = enum(u8) {
254
252
 
255
253
  pub const TOX = 0b10001000;
256
254
 
257
- const SLP = 0b111;
255
+ const SLEEP = 0b111;
258
256
 
259
257
  /// Whether or not the status `num` is the same as `status`.
260
- pub inline fn is(num: u8, status: Status) bool {
258
+ pub fn is(num: u8, status: Status) bool {
261
259
  if (status == .SLP) return Status.duration(num) > 0;
262
260
  return ((num >> @intCast(@intFromEnum(status))) & 1) != 0;
263
261
  }
264
262
 
265
263
  /// Initializes a non-sleep `status`. Use `slp` or `slf` to initialize a sleep status.
266
- pub inline fn init(status: Status) u8 {
264
+ pub fn init(status: Status) u8 {
267
265
  assert(status != .SLP and status != .EXT);
268
266
  return @as(u8, 1) << @intCast(@intFromEnum(status));
269
267
  }
270
268
 
271
269
  /// Initializes a non self-inflicted sleep status with duration `dur`.
272
- pub inline fn slp(dur: u3) u8 {
270
+ pub fn slp(dur: u3) u8 {
273
271
  assert(dur > 0);
274
272
  return @as(u8, dur);
275
273
  }
276
274
 
277
275
  /// Initializes a self-inflicted sleep status with duration `dur`.
278
- pub inline fn slf(dur: u3) u8 {
276
+ pub fn slf(dur: u3) u8 {
279
277
  assert(dur > 0);
280
278
  return 0x80 | slp(dur);
281
279
  }
282
280
 
283
281
  /// Returns the duration of a sleep status.
284
- pub inline fn duration(num: u8) u3 {
285
- return @intCast(num & SLP);
282
+ pub fn duration(num: u8) u3 {
283
+ return @intCast(num & SLEEP);
286
284
  }
287
285
 
288
286
  /// Returns whether `num` reflects any status.
289
- pub inline fn any(num: u8) bool {
287
+ pub fn any(num: u8) bool {
290
288
  return num > 0;
291
289
  }
292
290
 
@@ -324,7 +322,7 @@ test Status {
324
322
  }
325
323
 
326
324
  /// Bitfield representation of volatile statuses and associated data in Generation I.
327
- pub const Volatiles = packed struct {
325
+ pub const Volatiles = packed struct(u64) {
328
326
  /// Whether the "Bide" volatile status is present.
329
327
  Bide: bool = false,
330
328
  /// Whether the "Thrashing" volatile status is present.
@@ -377,19 +375,15 @@ pub const Volatiles = packed struct {
377
375
  /// The identity of whom the active Pokémon is transformed into.
378
376
  transform: u4 = 0,
379
377
  /// The remaining turns the move is disabled.
380
- disabled_duration: u4 = 0,
378
+ disable_duration: u4 = 0,
381
379
  /// The move slot (1-4) that is disabled.
382
- disabled_move: u3 = 0,
380
+ disable_move: u3 = 0,
383
381
  /// The number of turns toxic damage has been accumulating.
384
382
  toxic: u5 = 0,
385
-
386
- comptime {
387
- assert(@sizeOf(Volatiles) == 8);
388
- }
389
383
  };
390
384
 
391
385
  test Volatiles {
392
- var volatiles = Volatiles{};
386
+ var volatiles: Volatiles = .{};
393
387
  volatiles.Confusion = true;
394
388
  volatiles.confusion = 2;
395
389
  volatiles.Thrashing = true;
@@ -398,8 +392,8 @@ test Volatiles {
398
392
  volatiles.Substitute = true;
399
393
  volatiles.substitute = 42;
400
394
  volatiles.toxic = 4;
401
- volatiles.disabled_move = 2;
402
- volatiles.disabled_duration = 4;
395
+ volatiles.disable_move = 2;
396
+ volatiles.disable_duration = 4;
403
397
 
404
398
  try expect(volatiles.Confusion);
405
399
  try expect(volatiles.Thrashing);
@@ -410,14 +404,14 @@ test Volatiles {
410
404
 
411
405
  try expectEqual(@as(u16, 235), volatiles.state);
412
406
  try expectEqual(@as(u8, 42), volatiles.substitute);
413
- try expectEqual(@as(u4, 2), volatiles.disabled_move);
414
- try expectEqual(@as(u4, 4), volatiles.disabled_duration);
415
- try expectEqual(@as(u4, 2), volatiles.confusion);
407
+ try expectEqual(@as(u4, 2), volatiles.disable_move);
408
+ try expectEqual(@as(u4, 4), volatiles.disable_duration);
409
+ try expectEqual(@as(u3, 2), volatiles.confusion);
416
410
  try expectEqual(@as(u5, 4), volatiles.toxic);
417
- try expectEqual(@as(u4, 3), volatiles.attacks);
411
+ try expectEqual(@as(u3, 3), volatiles.attacks);
418
412
  }
419
413
 
420
- /// Representaiton of a Pokémon's stats in Generation I.
414
+ /// Representation of a Pokémon's stats in Generation I.
421
415
  pub fn Stats(comptime T: type) type {
422
416
  return extern struct {
423
417
  hp: T = 0,
@@ -451,7 +445,7 @@ test Stats {
451
445
  }
452
446
 
453
447
  /// Representation of a Pokémon's boosts in Generation I.
454
- pub const Boosts = packed struct {
448
+ pub const Boosts = packed struct(u32) {
455
449
  /// A Pokémon's Attack boosts.
456
450
  atk: i4 = 0,
457
451
  /// A Pokémon's Defense boosts.
@@ -466,14 +460,10 @@ pub const Boosts = packed struct {
466
460
  evasion: i4 = 0,
467
461
 
468
462
  _: u8 = 0,
469
-
470
- comptime {
471
- assert(@sizeOf(Boosts) == 4);
472
- }
473
463
  };
474
464
 
475
465
  test Boosts {
476
- const boosts = Boosts{ .spc = -6 };
466
+ const boosts: Boosts = .{ .spc = -6 };
477
467
  try expectEqual(0, boosts.atk);
478
468
  try expectEqual(-6, boosts.spc);
479
469
  }
@@ -485,7 +475,7 @@ test Move {
485
475
  try expectEqual(2, @intFromEnum(Move.KarateChop));
486
476
  const move = Move.get(.Fissure);
487
477
  try expectEqual(Move.Effect.OHKO, move.effect);
488
- try expectEqual(@as(u8, 30), move.accuracy);
478
+ try expectEqual(rng.Gen12.percent(30), move.accuracy);
489
479
  try expectEqual(Type.Ground, move.type);
490
480
 
491
481
  try expect(!Move.Effect.onBegin(.None));
@@ -623,16 +613,16 @@ pub const DVs = struct {
623
613
  };
624
614
 
625
615
  test DVs {
626
- var dvs = DVs{ .spc = 15, .spe = 15 };
616
+ var dvs: DVs = .{ .spc = 15, .spe = 15 };
627
617
  try expectEqual(@as(u4, 15), dvs.hp());
628
- dvs = DVs{
618
+ dvs = .{
629
619
  .atk = 5,
630
620
  .def = 15,
631
621
  .spe = 13,
632
622
  .spc = 13,
633
623
  };
634
624
  try expectEqual(@as(u4, 15), dvs.hp());
635
- dvs = DVs{
625
+ dvs = .{
636
626
  .def = 3,
637
627
  .spe = 10,
638
628
  .spc = 11,