@pkmn/engine 0.1.0-dev.47feedd9 → 0.1.0-dev.4eeb346e
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 +18 -18
- package/build/pkg/addon.d.ts +1 -1
- package/build/pkg/addon.js +4 -4
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/gen1.d.ts +3 -3
- package/build/pkg/gen1.js +12 -10
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +10 -11
- package/build/pkg/index.js.map +1 -1
- package/build/test/display.js +9 -22
- package/build/test/display.js.map +1 -1
- package/build.zig +7 -7
- package/package.json +9 -10
- package/src/bin/install-pkmn-engine +3 -3
- package/src/lib/binding/node.zig +1 -1
- package/src/lib/binding/wasm.zig +1 -1
- package/src/lib/common/debug.zig +0 -1
- package/src/lib/common/options.zig +3 -3
- package/src/lib/common/protocol.zig +38 -38
- package/src/lib/gen1/README.md +13 -19
- package/src/lib/gen1/data.zig +1 -1
- package/src/lib/gen1/helpers.zig +7 -10
- package/src/lib/gen1/mechanics.zig +52 -98
- package/src/lib/pkmn.zig +4 -4
|
@@ -62,28 +62,26 @@ pub fn update(battle: anytype, c1: Choice, c2: Choice, log: anytype) !Result {
|
|
|
62
62
|
assert(c1.type != .Pass or c2.type != .Pass or battle.turn == 0);
|
|
63
63
|
if (battle.turn == 0) return start(battle, log);
|
|
64
64
|
|
|
65
|
-
var s1 = false;
|
|
66
|
-
var s2 = false;
|
|
67
65
|
var f1: ?Move = null;
|
|
68
66
|
var f2: ?Move = null;
|
|
69
67
|
|
|
70
|
-
if (selectMove(battle, .P1, c1, c2, &
|
|
71
|
-
if (selectMove(battle, .P2, c2, c1, &
|
|
72
|
-
|
|
73
|
-
var p1 = battle.side(.P1);
|
|
74
|
-
var p2 = battle.side(.P2);
|
|
75
|
-
|
|
76
|
-
var r1 = showdown and p1.active.volatiles.Binding and c2.type == .Switch;
|
|
77
|
-
var r2 = showdown and p2.active.volatiles.Binding and c1.type == .Switch;
|
|
68
|
+
if (selectMove(battle, .P1, c1, c2, &f1)) |r| return r;
|
|
69
|
+
if (selectMove(battle, .P2, c2, c1, &f2)) |r| return r;
|
|
78
70
|
|
|
79
71
|
if (turnOrder(battle, c1, c2) == .P1) {
|
|
80
|
-
if (try doTurn(battle, .P1, c1,
|
|
72
|
+
if (try doTurn(battle, .P1, c1, f1, .P2, c2, f2, log)) |r| return r;
|
|
81
73
|
} else {
|
|
82
|
-
if (try doTurn(battle, .P2, c2,
|
|
74
|
+
if (try doTurn(battle, .P2, c2, f2, .P1, c1, f1, log)) |r| return r;
|
|
83
75
|
}
|
|
84
76
|
|
|
85
|
-
|
|
86
|
-
if (
|
|
77
|
+
var p1 = battle.side(.P1);
|
|
78
|
+
if (p1.active.volatiles.attacks == 0) {
|
|
79
|
+
p1.active.volatiles.Binding = false;
|
|
80
|
+
}
|
|
81
|
+
var p2 = battle.side(.P2);
|
|
82
|
+
if (p2.active.volatiles.attacks == 0) {
|
|
83
|
+
p2.active.volatiles.Binding = false;
|
|
84
|
+
}
|
|
87
85
|
|
|
88
86
|
return endTurn(battle, log);
|
|
89
87
|
}
|
|
@@ -116,7 +114,6 @@ fn selectMove(
|
|
|
116
114
|
player: Player,
|
|
117
115
|
choice: Choice,
|
|
118
116
|
foe_choice: Choice,
|
|
119
|
-
skip_turn: *bool,
|
|
120
117
|
from: *?Move,
|
|
121
118
|
) ?Result {
|
|
122
119
|
if (choice.type == .Pass) return null;
|
|
@@ -132,20 +129,14 @@ fn selectMove(
|
|
|
132
129
|
if (volatiles.Recharging) return null;
|
|
133
130
|
if (volatiles.Rage) {
|
|
134
131
|
from.* = side.last_used_move;
|
|
135
|
-
if (showdown)
|
|
136
|
-
if (battle.foe(player).active.volatiles.Binding) skip_turn.* = true;
|
|
137
|
-
saveMove(battle, player, null);
|
|
138
|
-
}
|
|
132
|
+
if (showdown) saveMove(battle, player, null);
|
|
139
133
|
return null;
|
|
140
134
|
}
|
|
141
135
|
// Pokémon Showdown removes Flinch at the end-of-turn in its residual handler
|
|
142
136
|
if (!showdown) volatiles.Flinch = false;
|
|
143
137
|
if (volatiles.Thrashing or volatiles.Charging) {
|
|
144
138
|
from.* = side.last_selected_move;
|
|
145
|
-
if (showdown)
|
|
146
|
-
if (battle.foe(player).active.volatiles.Binding) skip_turn.* = true;
|
|
147
|
-
saveMove(battle, player, null);
|
|
148
|
-
}
|
|
139
|
+
if (showdown) saveMove(battle, player, null);
|
|
149
140
|
return null;
|
|
150
141
|
}
|
|
151
142
|
|
|
@@ -155,10 +146,7 @@ fn selectMove(
|
|
|
155
146
|
// pre-move select
|
|
156
147
|
if (Status.is(stored.status, .FRZ) or Status.is(stored.status, .SLP) or volatiles.Bide) {
|
|
157
148
|
assert(showdown or choice.data == 0);
|
|
158
|
-
if (showdown)
|
|
159
|
-
if (volatiles.Bide and battle.foe(player).active.volatiles.Binding) skip_turn.* = true;
|
|
160
|
-
saveMove(battle, player, choice);
|
|
161
|
-
}
|
|
149
|
+
if (showdown) saveMove(battle, player, choice);
|
|
162
150
|
return null;
|
|
163
151
|
}
|
|
164
152
|
if (volatiles.Binding) {
|
|
@@ -189,7 +177,6 @@ fn selectMove(
|
|
|
189
177
|
}
|
|
190
178
|
|
|
191
179
|
if (battle.foe(player).active.volatiles.Binding) {
|
|
192
|
-
skip_turn.* = true;
|
|
193
180
|
if (showdown) {
|
|
194
181
|
saveMove(battle, player, choice);
|
|
195
182
|
} else {
|
|
@@ -340,13 +327,9 @@ fn doTurn(
|
|
|
340
327
|
battle: anytype,
|
|
341
328
|
player: Player,
|
|
342
329
|
player_choice: Choice,
|
|
343
|
-
player_rewrap: bool,
|
|
344
|
-
player_skip: bool,
|
|
345
330
|
player_from: ?Move,
|
|
346
331
|
foe_player: Player,
|
|
347
332
|
foe_choice: Choice,
|
|
348
|
-
foe_rewrap: bool,
|
|
349
|
-
foe_skip: bool,
|
|
350
333
|
foe_from: ?Move,
|
|
351
334
|
log: anytype,
|
|
352
335
|
) !?Result {
|
|
@@ -354,16 +337,7 @@ fn doTurn(
|
|
|
354
337
|
|
|
355
338
|
var residual = true;
|
|
356
339
|
var replace = battle.side(player).stored().hp == 0;
|
|
357
|
-
if (try executeMove(
|
|
358
|
-
battle,
|
|
359
|
-
player,
|
|
360
|
-
player_choice,
|
|
361
|
-
player_rewrap,
|
|
362
|
-
player_skip,
|
|
363
|
-
player_from,
|
|
364
|
-
&residual,
|
|
365
|
-
log,
|
|
366
|
-
)) |r| return r;
|
|
340
|
+
if (try executeMove(battle, player, player_choice, player_from, &residual, log)) |r| return r;
|
|
367
341
|
if (!replace) {
|
|
368
342
|
if (player_choice.type != .Switch) {
|
|
369
343
|
if (try checkFaint(battle, foe_player, log)) |r| return r;
|
|
@@ -374,16 +348,7 @@ fn doTurn(
|
|
|
374
348
|
|
|
375
349
|
residual = true;
|
|
376
350
|
replace = battle.side(foe_player).stored().hp == 0;
|
|
377
|
-
if (try executeMove(
|
|
378
|
-
battle,
|
|
379
|
-
foe_player,
|
|
380
|
-
foe_choice,
|
|
381
|
-
foe_rewrap,
|
|
382
|
-
foe_skip,
|
|
383
|
-
foe_from,
|
|
384
|
-
&residual,
|
|
385
|
-
log,
|
|
386
|
-
)) |r| return r;
|
|
351
|
+
if (try executeMove(battle, foe_player, foe_choice, foe_from, &residual, log)) |r| return r;
|
|
387
352
|
if (!replace) {
|
|
388
353
|
if (foe_choice.type != .Switch) {
|
|
389
354
|
if (try checkFaint(battle, player, log)) |r| return r;
|
|
@@ -406,8 +371,6 @@ fn executeMove(
|
|
|
406
371
|
battle: anytype,
|
|
407
372
|
player: Player,
|
|
408
373
|
choice: Choice,
|
|
409
|
-
rewrap: bool,
|
|
410
|
-
skip: bool,
|
|
411
374
|
from: ?Move,
|
|
412
375
|
residual: *bool,
|
|
413
376
|
log: anytype,
|
|
@@ -419,10 +382,9 @@ fn executeMove(
|
|
|
419
382
|
return null;
|
|
420
383
|
}
|
|
421
384
|
|
|
422
|
-
// This is the correct place to check for SKIP_TURN and abort early, however since Pokémon
|
|
423
|
-
// Showdown overwrites the SKIP_TURN sentinel with its botched move select we need to add an
|
|
424
|
-
// additional skip boolean to accomplish the same thing in the Binding check of BeforeMove
|
|
425
385
|
if (side.last_selected_move == .SKIP_TURN) {
|
|
386
|
+
// Pokémon Showdown overwrites the SKIP_TURN sentinel with its botched move select,
|
|
387
|
+
// Binding instead gets handled in beforeMove after sleep and freeze
|
|
426
388
|
assert(!showdown);
|
|
427
389
|
if (battle.foe(player).active.volatiles.Binding) {
|
|
428
390
|
try log.cant(battle.active(player), .Bound);
|
|
@@ -472,7 +434,7 @@ fn executeMove(
|
|
|
472
434
|
|
|
473
435
|
var skip_can = false;
|
|
474
436
|
var skip_pp = false;
|
|
475
|
-
switch (try beforeMove(battle, player,
|
|
437
|
+
switch (try beforeMove(battle, player, from, residual, log)) {
|
|
476
438
|
.done => return null,
|
|
477
439
|
.skip_can => skip_can = true,
|
|
478
440
|
.skip_pp => skip_pp = true,
|
|
@@ -484,7 +446,7 @@ fn executeMove(
|
|
|
484
446
|
return null;
|
|
485
447
|
}
|
|
486
448
|
|
|
487
|
-
return doMove(battle, player, mslot,
|
|
449
|
+
return doMove(battle, player, mslot, auto, residual, log);
|
|
488
450
|
}
|
|
489
451
|
|
|
490
452
|
const BeforeMove = enum { done, skip_can, skip_pp, ok, err };
|
|
@@ -492,7 +454,6 @@ const BeforeMove = enum { done, skip_can, skip_pp, ok, err };
|
|
|
492
454
|
fn beforeMove(
|
|
493
455
|
battle: anytype,
|
|
494
456
|
player: Player,
|
|
495
|
-
skip: bool,
|
|
496
457
|
from: ?Move,
|
|
497
458
|
residual: *bool,
|
|
498
459
|
log: anytype,
|
|
@@ -524,15 +485,13 @@ fn beforeMove(
|
|
|
524
485
|
return .done;
|
|
525
486
|
}
|
|
526
487
|
|
|
527
|
-
if (
|
|
488
|
+
if (foe.active.volatiles.Binding) {
|
|
528
489
|
try log.cant(ident, .Bound);
|
|
529
490
|
return .done;
|
|
530
491
|
}
|
|
531
492
|
|
|
532
|
-
if (volatiles.Flinch) {
|
|
533
|
-
|
|
534
|
-
// Pokémon can sometimes flinch multiple times from the same original hit
|
|
535
|
-
if (!showdown) volatiles.Flinch = false;
|
|
493
|
+
if (!showdown and volatiles.Flinch) {
|
|
494
|
+
volatiles.Flinch = false;
|
|
536
495
|
try log.cant(ident, .Flinch);
|
|
537
496
|
return .done;
|
|
538
497
|
}
|
|
@@ -553,6 +512,13 @@ fn beforeMove(
|
|
|
553
512
|
// Pokémon Showdown's disable condition has a single onBeforeMove handler
|
|
554
513
|
if (showdown and try disabled(side, ident, log)) return .done;
|
|
555
514
|
|
|
515
|
+
// Pokémon Showdown checks for Flinch *after* instead of before
|
|
516
|
+
if (showdown and volatiles.Flinch) {
|
|
517
|
+
volatiles.Flinch = false;
|
|
518
|
+
try log.cant(ident, .Flinch);
|
|
519
|
+
return .done;
|
|
520
|
+
}
|
|
521
|
+
|
|
556
522
|
// This can only happen if a Pokémon started the battle frozen/sleeping and was thawed/woken
|
|
557
523
|
// before the side had a selected a move - we simply need to assume this leads to a desync
|
|
558
524
|
if (side.last_selected_move == .None) {
|
|
@@ -668,13 +634,8 @@ fn beforeMove(
|
|
|
668
634
|
try log.start(battle.active(player), .ConfusionSilent);
|
|
669
635
|
}
|
|
670
636
|
try log.move(ident, side.last_selected_move, battle.active(player.foe()), from);
|
|
671
|
-
if (showdown) {
|
|
672
|
-
|
|
673
|
-
// used in useMove and doesn't have the notion of skipping canMove semantics
|
|
674
|
-
side.last_used_move = side.last_selected_move;
|
|
675
|
-
if (handleThrashing(battle, active)) {
|
|
676
|
-
try log.start(battle.active(player), .ConfusionSilent);
|
|
677
|
-
}
|
|
637
|
+
if (showdown and handleThrashing(battle, active)) {
|
|
638
|
+
try log.start(battle.active(player), .ConfusionSilent);
|
|
678
639
|
}
|
|
679
640
|
return .skip_can;
|
|
680
641
|
}
|
|
@@ -689,11 +650,7 @@ fn beforeMove(
|
|
|
689
650
|
side.last_selected_move,
|
|
690
651
|
);
|
|
691
652
|
if (showdown or battle.last_damage != 0) {
|
|
692
|
-
const sub = showdown and foe.active.volatiles.Substitute;
|
|
693
653
|
_ = try applyDamage(battle, player.foe(), player.foe(), .None, log);
|
|
694
|
-
if (battle.foe(player).stored().hp > 0 and !sub) {
|
|
695
|
-
try buildRage(battle, player.foe(), log);
|
|
696
|
-
}
|
|
697
654
|
}
|
|
698
655
|
return .done;
|
|
699
656
|
}
|
|
@@ -751,7 +708,7 @@ fn canMove(
|
|
|
751
708
|
Effects.thrashing(battle, player);
|
|
752
709
|
} else if (!showdown and move.effect == .Binding) {
|
|
753
710
|
// Pokémon Showdown handles this after hit/miss checks and damage calculation
|
|
754
|
-
Effects.binding(battle, player
|
|
711
|
+
Effects.binding(battle, player);
|
|
755
712
|
}
|
|
756
713
|
|
|
757
714
|
return true;
|
|
@@ -792,7 +749,6 @@ fn doMove(
|
|
|
792
749
|
battle: anytype,
|
|
793
750
|
player: Player,
|
|
794
751
|
mslot: u4,
|
|
795
|
-
rewrap: bool,
|
|
796
752
|
auto: bool,
|
|
797
753
|
residual: *bool,
|
|
798
754
|
log: anytype,
|
|
@@ -884,9 +840,9 @@ fn doMove(
|
|
|
884
840
|
|
|
885
841
|
if (!showdown or !miss) {
|
|
886
842
|
if (move.effect == .MirrorMove) {
|
|
887
|
-
return mirrorMove(battle, player, mslot,
|
|
843
|
+
return mirrorMove(battle, player, mslot, auto, residual, log);
|
|
888
844
|
} else if (move.effect == .Metronome) {
|
|
889
|
-
return metronome(battle, player, mslot,
|
|
845
|
+
return metronome(battle, player, mslot, auto, residual, log);
|
|
890
846
|
} else if (move.effect.onEnd()) {
|
|
891
847
|
try onEnd(battle, player, move, log);
|
|
892
848
|
return null;
|
|
@@ -901,7 +857,7 @@ fn doMove(
|
|
|
901
857
|
move.effect == .OHKO and side.active.stats.spe < foe.active.stats.spe;
|
|
902
858
|
if (ohko) {
|
|
903
859
|
try log.immune(foe_ident, .OHKO);
|
|
904
|
-
} else if (immune and !invulnerable
|
|
860
|
+
} else if (immune and !invulnerable) {
|
|
905
861
|
try log.immune(foe_ident, .None);
|
|
906
862
|
} else if (mist) {
|
|
907
863
|
if (!foe.active.volatiles.Substitute) try log.activate(foe_ident, .Mist);
|
|
@@ -967,7 +923,7 @@ fn doMove(
|
|
|
967
923
|
} else if (showdown) {
|
|
968
924
|
// This should be handled much earlier but Pokémon Showdown does it here... ¯\_(ツ)_/¯
|
|
969
925
|
if (move.effect == .Binding) {
|
|
970
|
-
Effects.binding(battle, player
|
|
926
|
+
Effects.binding(battle, player);
|
|
971
927
|
if (immune) {
|
|
972
928
|
battle.last_damage = 0;
|
|
973
929
|
// Pokémon Showdown logs |-damage| here instead of |-immune| because logic...
|
|
@@ -1204,9 +1160,7 @@ fn counterDamage(battle: anytype, player: Player, move: Move.Data, log: anytype)
|
|
|
1204
1160
|
// Pokémon Showdown calls checkHit before Counter
|
|
1205
1161
|
if (!showdown and !try checkHit(battle, player, move, log)) return null;
|
|
1206
1162
|
|
|
1207
|
-
const sub = showdown and foe.active.volatiles.Substitute;
|
|
1208
1163
|
_ = try applyDamage(battle, player.foe(), player.foe(), .None, log);
|
|
1209
|
-
if (battle.foe(player).stored().hp > 0 and !sub) try buildRage(battle, player.foe(), log);
|
|
1210
1164
|
return null;
|
|
1211
1165
|
}
|
|
1212
1166
|
|
|
@@ -1250,7 +1204,6 @@ fn mirrorMove(
|
|
|
1250
1204
|
battle: anytype,
|
|
1251
1205
|
player: Player,
|
|
1252
1206
|
mslot: u4,
|
|
1253
|
-
rewrap: bool,
|
|
1254
1207
|
auto: bool,
|
|
1255
1208
|
residual: *bool,
|
|
1256
1209
|
log: anytype,
|
|
@@ -1263,19 +1216,18 @@ fn mirrorMove(
|
|
|
1263
1216
|
if (foe.last_used_move == .None or foe.last_used_move == .MirrorMove) {
|
|
1264
1217
|
try log.fail(battle.active(player), .None);
|
|
1265
1218
|
return null;
|
|
1266
|
-
} else if (!showdown or foe.last_used_move != .Struggle) {
|
|
1267
|
-
incrementPP(side, mslot);
|
|
1268
1219
|
}
|
|
1269
1220
|
|
|
1221
|
+
incrementPP(side, mslot);
|
|
1222
|
+
|
|
1270
1223
|
if (!try canMove(battle, player, mslot, auto, false, .MirrorMove, residual, log)) return null;
|
|
1271
|
-
return doMove(battle, player, mslot,
|
|
1224
|
+
return doMove(battle, player, mslot, auto, residual, log);
|
|
1272
1225
|
}
|
|
1273
1226
|
|
|
1274
1227
|
fn metronome(
|
|
1275
1228
|
battle: anytype,
|
|
1276
1229
|
player: Player,
|
|
1277
1230
|
mslot: u4,
|
|
1278
|
-
rewrap: bool,
|
|
1279
1231
|
auto: bool,
|
|
1280
1232
|
residual: *bool,
|
|
1281
1233
|
log: anytype,
|
|
@@ -1286,7 +1238,7 @@ fn metronome(
|
|
|
1286
1238
|
incrementPP(side, mslot);
|
|
1287
1239
|
|
|
1288
1240
|
if (!try canMove(battle, player, mslot, auto, false, .Metronome, residual, log)) return null;
|
|
1289
|
-
return doMove(battle, player, mslot,
|
|
1241
|
+
return doMove(battle, player, mslot, auto, residual, log);
|
|
1290
1242
|
}
|
|
1291
1243
|
|
|
1292
1244
|
fn checkHit(battle: anytype, player: Player, move: Move.Data, log: anytype) !bool {
|
|
@@ -1493,7 +1445,11 @@ fn handleResidual(battle: anytype, player: Player, log: anytype) !void {
|
|
|
1493
1445
|
stored.hp -= amount;
|
|
1494
1446
|
|
|
1495
1447
|
// As above, Pokémon Showdown uses damageOf but its not relevant
|
|
1496
|
-
if (amount > 0)
|
|
1448
|
+
if (amount > 0) {
|
|
1449
|
+
try log.damage(ident, stored, .LeechSeed);
|
|
1450
|
+
// Pokémon Showdown erroneously updates last damage with uncapped Leech Seed damage
|
|
1451
|
+
if (showdown) battle.last_damage = damage;
|
|
1452
|
+
}
|
|
1497
1453
|
|
|
1498
1454
|
const before = foe_stored.hp;
|
|
1499
1455
|
// Uncapped damage is added back to the foe
|
|
@@ -2026,9 +1982,9 @@ pub const Effects = struct {
|
|
|
2026
1982
|
}
|
|
2027
1983
|
break :has_mimic false;
|
|
2028
1984
|
};
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
1985
|
+
// If the foe is Invulnerable we still want to fall through to checkHit to be able to
|
|
1986
|
+
// trigger |-miss| instead of |-fail|
|
|
1987
|
+
if (!has_mimic and !foe.active.volatiles.Invulnerable) {
|
|
2032
1988
|
return try log.fail(battle.active(player.foe()), .None);
|
|
2033
1989
|
}
|
|
2034
1990
|
}
|
|
@@ -2296,7 +2252,7 @@ pub const Effects = struct {
|
|
|
2296
2252
|
try log.transform(battle.active(player), foe_ident);
|
|
2297
2253
|
}
|
|
2298
2254
|
|
|
2299
|
-
fn binding(battle: anytype, player: Player
|
|
2255
|
+
fn binding(battle: anytype, player: Player) void {
|
|
2300
2256
|
var side = battle.side(player);
|
|
2301
2257
|
var foe = battle.foe(player);
|
|
2302
2258
|
|
|
@@ -2304,9 +2260,7 @@ pub const Effects = struct {
|
|
|
2304
2260
|
side.active.volatiles.Binding = true;
|
|
2305
2261
|
// GLITCH: Hyper Beam automatic selection glitch if Recharging gets cleared on miss
|
|
2306
2262
|
// (Pokémon Showdown unitentionally patches this glitch, preventing automatic selection)
|
|
2307
|
-
if (!showdown)
|
|
2308
|
-
foe.active.volatiles.Recharging = false;
|
|
2309
|
-
} else if (foe.stored().hp == 0) return if (!rewrap) battle.rng.advance(1);
|
|
2263
|
+
if (!showdown) foe.active.volatiles.Recharging = false;
|
|
2310
2264
|
|
|
2311
2265
|
side.active.volatiles.attacks = Rolls.distribution(battle) - 1;
|
|
2312
2266
|
}
|
package/src/lib/pkmn.zig
CHANGED
|
@@ -25,12 +25,12 @@ pub const Result = @import("common/data.zig").Result;
|
|
|
25
25
|
/// Pokémon Showdown's RNG (backed by a Generation V & VI RNG).
|
|
26
26
|
pub const PSRNG = @import("common/rng.zig").PSRNG;
|
|
27
27
|
|
|
28
|
-
/// Namespace for helpers related to protocol
|
|
28
|
+
/// Namespace for helpers related to protocol trace logging.
|
|
29
29
|
pub const protocol = if (options.internal) struct {
|
|
30
30
|
pub usingnamespace @import("common/protocol.zig");
|
|
31
31
|
} else struct {
|
|
32
32
|
/// Logs protocol information to its `Writer` during a battle update when
|
|
33
|
-
/// `options.
|
|
33
|
+
/// `options.trace` is enabled.
|
|
34
34
|
pub const Log = @import("common/protocol.zig").Log;
|
|
35
35
|
/// Stripped down version of `std.io.FixedBufferStream` optimized for
|
|
36
36
|
/// efficiently writing the individual protocol bytes. Note that the
|
|
@@ -41,8 +41,8 @@ pub const protocol = if (options.internal) struct {
|
|
|
41
41
|
/// intialized with a `LOGS_SIZE`-sized buffer.
|
|
42
42
|
pub const FixedLog = @import("common/protocol.zig").FixedLog;
|
|
43
43
|
/// Null object pattern implementation of `Log` backed by a
|
|
44
|
-
/// `std.io.null_writer`. Ignores anything sent to it, though
|
|
45
|
-
///
|
|
44
|
+
/// `std.io.null_writer`. Ignores anything sent to it, though trace logging
|
|
45
|
+
/// should addtionally be turned off entirely by using `options.trace`.
|
|
46
46
|
pub const NULL = @import("common/protocol.zig").NULL;
|
|
47
47
|
};
|
|
48
48
|
|