@pkmn/engine 0.1.0-dev.550c3889 → 0.1.0-dev.5ec64ea5
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 +22 -22
- package/build/pkg/addon.d.ts +2 -2
- package/build/pkg/addon.js +5 -5
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/gen1.d.ts +3 -3
- package/build/pkg/gen1.js +13 -11
- 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 +1 -2
- package/build/test/display.js.map +1 -1
- package/build.zig +22 -17
- package/package.json +9 -10
- package/src/bin/install-pkmn-engine +3 -3
- package/src/bin/pkmn-debug +3 -2
- package/src/lib/binding/node.zig +5 -5
- package/src/lib/binding/wasm.zig +3 -3
- 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 +14 -23
- package/src/lib/gen1/data.zig +6 -6
- package/src/lib/gen1/helpers.zig +7 -10
- package/src/lib/gen1/mechanics.zig +274 -315
- package/src/lib/gen2/data.zig +4 -4
- package/src/lib/pkmn.zig +7 -7
package/src/lib/gen1/README.md
CHANGED
|
@@ -198,7 +198,7 @@ above, PP information isn't strictly necessary in Generation I so is dropped. `M
|
|
|
198
198
|
a special sentinel value to indicate `null`. Move PP data is only included for testing and is not
|
|
199
199
|
necessary for the actual engine implementation.
|
|
200
200
|
|
|
201
|
-
In order to workaround various [Pokémon Showdown bugs](#bugs) and to support its protocol in
|
|
201
|
+
In order to workaround various [Pokémon Showdown bugs](#bugs) and to support its protocol in traces,
|
|
202
202
|
additional information is stored in `Move.Data` (`targets`) about what Pokémon Showdown believes the
|
|
203
203
|
`Move.Target` to be (despite the concept of targeting not existing until Generation III when Double
|
|
204
204
|
battles were introduced). More specifically, a move's "targeting" status is required in various
|
|
@@ -331,8 +331,8 @@ does not produce an equivalent to Pokémon Showdown's `|request|` protocol messa
|
|
|
331
331
|
must be gleaned through the `Battle` state). Useful size and offset information can be found in
|
|
332
332
|
the [`layout.json`](../../data/layout.json) which exists to simplify writing driver code.
|
|
333
333
|
|
|
334
|
-
Documentation of the wire protocol used for
|
|
335
|
-
|
|
334
|
+
Documentation of the wire protocol used for logging traces when `-Dtrace` is enabled can be found in
|
|
335
|
+
[PROTOCOL.md](../../../docs/PROTOCOL.md). Note that the
|
|
336
336
|
[`pkmn-debug`](../../../README.md#pkmn-debug) tool exists to display the binary protocol and battle
|
|
337
337
|
data in the browser for ease of debugging.
|
|
338
338
|
|
|
@@ -478,8 +478,7 @@ Smogon](https://www.smogon.com/forums/posts/5933177/show):
|
|
|
478
478
|
- Confusion self-hits use the wrong damage formula resulting in off-by-one errors (and also fail to
|
|
479
479
|
account for an opponent's Reflect). Furthermore, the confusion self-hit damage will erroneously be
|
|
480
480
|
inflicted to the confused user's substitute if the confused user had been attempting to use a
|
|
481
|
-
self-targeting move.
|
|
482
|
-
damage for the purposes of tracking the battle's last damage.
|
|
481
|
+
self-targeting move.
|
|
483
482
|
|
|
484
483
|
Beyond the general bugs listed above, several move effects are implemented incorrectly by Pokémon
|
|
485
484
|
Showdown. Some of these moves are [too fundamentally broken to be implemented](#unimplementable) by
|
|
@@ -487,10 +486,9 @@ the pkmn engine, but the following moves have their broken behavior preserved in
|
|
|
487
486
|
|
|
488
487
|
- **Bide**: If the opponent faints after Bide inflicts damage on Pokémon Showdown residual damage
|
|
489
488
|
incorrectly still gets applied to Bide's user.
|
|
490
|
-
- **Counter**: On Pokémon Showdown choices made while sleeping (which should not have been
|
|
491
|
-
registered) can erroneously cause Counter to trigger Desync Clause Mod behavior.
|
|
492
489
|
- **Leech Seed**: Leech Seed fails to heal its source side if a seeded target faints due to
|
|
493
|
-
recoil/crash damage on Pokémon Showdown.
|
|
490
|
+
recoil/crash damage on Pokémon Showdown. Pokémon Showdown also updates the battle's last damage
|
|
491
|
+
field with the uncapped Leech Seed damage which has consequences for Bide and Counter.
|
|
494
492
|
- **Pay Day**: Pay Day should still scatter coins if it hits (but doesn't break) and opponent's
|
|
495
493
|
Substitute but doesn't on Pokémon Showdown.
|
|
496
494
|
- **Flinch**: Flinching does not get cleared during move selection on Pokémon Showdown and is
|
|
@@ -500,14 +498,10 @@ the pkmn engine, but the following moves have their broken behavior preserved in
|
|
|
500
498
|
- **Rage**: Rage boosts should still result in burn/paralysis [stat modification
|
|
501
499
|
errors](https://pkmn.cc/bulba-glitch-1#Stat_modification_errors) but don't on Pokémon Showdown.
|
|
502
500
|
Furthermore, Pokémon Showdown only builds Rage for Disable/Explosion (hit/miss) when attacking
|
|
503
|
-
into a Substitute instead of all moves.
|
|
504
|
-
Petal Dance accuracy bug]( https://www.youtube.com/watch?v=NC5gbJeExbs) incorrectly, as the
|
|
505
|
-
accuracy only gets written when the volatile is present which can lead to incorrect accuracy
|
|
506
|
-
values on turns where Rage is used on the same turn as a move which modifies accuracy or evasion.
|
|
501
|
+
into a Substitute instead of all moves.
|
|
507
502
|
- **Thrash** / **Petal Dance**: once a Pokémon is locked into a thrashing move they will lose all
|
|
508
503
|
speed ties on Pokémon Showdown (due to the fact that if they win the speed tie their action will
|
|
509
|
-
then get "changed" and inserted back into the queue after their opponent's action).
|
|
510
|
-
Showdown also implements accuracy incorrectly, as covered above.
|
|
504
|
+
then get "changed" and inserted back into the queue after their opponent's action).
|
|
511
505
|
- **Freeze** / **Sleep**: Pokémon Showdown requires a move to be selected when a Pokémon is frozen
|
|
512
506
|
or sleeping and uses that in the event that the status is removed while on the cartridge no
|
|
513
507
|
selection is possible and no turn exists for the thawed/woken Pokémon to act except in the case of
|
|
@@ -532,8 +526,7 @@ the pkmn engine, but the following moves have their broken behavior preserved in
|
|
|
532
526
|
Pokémon Showdown implementing the health check based on floating point division instead of integer
|
|
533
527
|
divison like on the cartridge (meaning the Substitute 1/4 glitch will only occur if the Pokémon's
|
|
534
528
|
maximum HP is evenly divisible by 4). Finally, Substitute also incorrectly blocks Dream Eater on
|
|
535
|
-
Pokémon Showdown
|
|
536
|
-
damage.
|
|
529
|
+
Pokémon Showdown.
|
|
537
530
|
|
|
538
531
|
In addition to numerous cases where Pokémon Showdown uses the wrong type of message (e.g. `|-fail`
|
|
539
532
|
vs. `|-miss|` vs. `|-immune|`, e.g. in the case of Leech Seed) which are not documented here, Pokémon
|
|
@@ -603,9 +596,9 @@ the correct control flow):
|
|
|
603
596
|
still gets a turn under the [trapping sleep
|
|
604
597
|
glitch](https://glitchcity.wiki/Trapping_move_and_sleep_glitch), Wrap does 0 damage against
|
|
605
598
|
Ghost-type Pokémon instead of properly respecting immunity, and binding effects are handled in the
|
|
606
|
-
wrong order in the code
|
|
607
|
-
|
|
608
|
-
|
|
599
|
+
wrong order in the code.
|
|
600
|
+
- **Counter**: On Pokémon Showdown choices made while sleeping (which should not have been
|
|
601
|
+
registered) can erroneously cause Counter to trigger Desync Clause Mod behavior.
|
|
609
602
|
- **Mimic**: Pokémon Showdown checks that the user of Mimic has Mimic in one of their move slots,
|
|
610
603
|
which means Mimic legally called via Metronome or Mirror Move will only work if the user also has
|
|
611
604
|
Mimic (and the moved mimicked by Mimic called via Metronome / Mirror Move will erroneously
|
|
@@ -617,13 +610,11 @@ the correct control flow):
|
|
|
617
610
|
- **Mirror Move**: Binding moves misbehave when used via Mirror Move (though Pokémon Showdown has
|
|
618
611
|
its own weird behavior and does not implement the [partial trapping move Mirror Move
|
|
619
612
|
glitch](https://glitchcity.wiki/Partial_trapping_move_Mirror_Move_link_battle_glitch) that exists
|
|
620
|
-
on the cartridge).
|
|
621
|
-
is Thrashing instead of just on the turn it is actually selected meaning Mirror Move will
|
|
622
|
-
sometimes successfully mirror a Thrashing move when it should fail.
|
|
613
|
+
on the cartridge).
|
|
623
614
|
- **Metronome**: In addition to the issues with binding moves, Metronome and Mirror Move cannot
|
|
624
615
|
mutually call each other more than 3 times in a row without causing the Pokémon Showdown simulator
|
|
625
616
|
to crash due to defensive safety checks that do not exist on the cartridge.
|
|
626
|
-
- **Transform**:
|
|
617
|
+
- **Transform**: Transform screws up the effect of Disable, because on Pokémon Showdown, Disable
|
|
627
618
|
prevents moves of a given *name* from being used (e.g. "Water Gun") as opposed to moves in a
|
|
628
619
|
specific *slot* (e.g. the 2nd move slot), and a Pokémon's moves can change after Transform (this
|
|
629
620
|
is not an issue with Disable + Mimic because Mimic happens to replace the same slot). Furthermore,
|
package/src/lib/gen1/data.zig
CHANGED
|
@@ -17,16 +17,16 @@ const expectEqual = std.testing.expectEqual;
|
|
|
17
17
|
const expect = std.testing.expect;
|
|
18
18
|
|
|
19
19
|
/// The minimum size in bytes required to hold all Generation I choice options.
|
|
20
|
-
pub const
|
|
20
|
+
pub const MAX_OPTIONS: usize = 9; // move 1..4, switch 2..6
|
|
21
21
|
/// The optimal size in bytes required to hold all Generation I choice options.
|
|
22
|
-
/// At least as large as
|
|
22
|
+
/// At least as large as MAX_OPTIONS.
|
|
23
23
|
pub const MAX_LOGS: usize = 180;
|
|
24
24
|
|
|
25
25
|
/// The maximum number of bytes possibly logged by a single Generation I update.
|
|
26
|
-
pub const
|
|
27
|
-
|
|
26
|
+
pub const OPTIONS_SIZE = if (builtin.mode == .ReleaseSmall)
|
|
27
|
+
MAX_OPTIONS
|
|
28
28
|
else
|
|
29
|
-
std.math.ceilPowerOfTwo(usize,
|
|
29
|
+
std.math.ceilPowerOfTwo(usize, MAX_OPTIONS) catch unreachable;
|
|
30
30
|
/// The optimal size in bytes required to hold the largest amount of log data possible from a
|
|
31
31
|
/// single Generation I update. At least as large as MAX_LOGS.
|
|
32
32
|
pub const LOGS_SIZE = if (builtin.mode == .ReleaseSmall)
|
|
@@ -76,7 +76,7 @@ pub fn Battle(comptime RNG: anytype) type {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/// Returns the result of applying Player 1's choice `c1` and Player 2's choice `c2` to the
|
|
79
|
-
/// battle, optionally writing protocol
|
|
79
|
+
/// battle, optionally writing protocol logs to `log` if `options.trace` is enabled.
|
|
80
80
|
pub fn update(self: *Self, c1: Choice, c2: Choice, log: anytype) !Result {
|
|
81
81
|
return mechanics.update(self, c1, c2, log);
|
|
82
82
|
}
|
package/src/lib/gen1/helpers.zig
CHANGED
|
@@ -211,19 +211,16 @@ pub const Pokemon = struct {
|
|
|
211
211
|
}
|
|
212
212
|
};
|
|
213
213
|
|
|
214
|
-
//
|
|
215
|
-
// fn blocked(m: Move) bool {
|
|
216
|
-
// // Binding moves are borked but only via Mirror Move / Metronome which are already blocked
|
|
217
|
-
// return switch (m) {
|
|
218
|
-
// .Mimic, .Metronome, .MirrorMove => true,
|
|
219
|
-
// else => false,
|
|
220
|
-
// };
|
|
221
|
-
// }
|
|
222
|
-
|
|
214
|
+
// cat src/test/showdown/blocklist.json | jq '."1".moves'
|
|
223
215
|
fn blocked(m: Move) bool {
|
|
224
216
|
if (Move.get(m).effect == .Binding) return true;
|
|
225
217
|
return switch (m) {
|
|
226
|
-
.Counter,
|
|
218
|
+
.Counter,
|
|
219
|
+
.Mimic,
|
|
220
|
+
.Metronome,
|
|
221
|
+
.MirrorMove,
|
|
222
|
+
.Transform,
|
|
223
|
+
=> true,
|
|
227
224
|
else => false,
|
|
228
225
|
};
|
|
229
226
|
}
|