This should test all mechanics of the game, and should run on both generic tetromino game and unmodified NES Tetris. Depends on #3.
i've been investigating this with the WIP TAS file and figured some stuff out:
NES Tetris is incrementing the falltimer (RAM: $0045) until 14 (0x0E) instead of 11 (0x0B) when pause is pressed during the drop. here's a video demonstrating this (opening with firefox doesn't work for me, mpv works): https://xha.li/tetris.mp4
A really hacky fix to demonstrate that this fixes the first wrong piece is to just add 3 to the dropdelay when setting pause = false:
@@ -7554,6 +7556,10 @@ gameinput(const uint8_t inputs[static 4][2], uint8_t i) state.game.pause = true; } else if (pressed == INPUT_MASK_START) { /* only start pressed; no other buttons */
/* when the tetromino is down while pausing, nes tetris internally counts until
* 14 instead of 11. */
} else if ((held & INPUT_MASK_START) != 0 && pressed == INPUT_MASK_FLIP_CCW) {g->dropdelay += 3; state.game.pause = false;
this, however, will probably break other cases since i haven't yet figured out why NES Tetris is doing this. i might need some help here.
when the above fix is applied, the piece that comes after the L is not correctly generated. this is because generic tetromino game is generating the piece 5 frames too early. this means that the dropdelay calculation or something related to this is probably wrong. i'd guess it is because of the soft drop.
you can generate the next piece correctly by using gdb and setting a breakpoint at main.c:1931. when the dropdelay for the piece before the L piece is calculated (i think a S), you need to add 5 to it (n set g->dropdelay+=5).
the one thing that makes me suspect this is because down is pressed is that the falltimer (RAM: $0045) is incremented until 2 when down is pressed. however, generic tetromino game's fallamt is only incremented until 1 and then reset to 0. i didn't investigate this further yet but i just wanted to have it written down here.
do you (seb) maby have a (partly) reverse-engineered .nl file that i can use for debugging NES Tetris? i mean, maby with function names and stuff?
uhh, sourcehut messed up the formatting; here is the patch for the dropdelay: https://xha.li/0001-TAS-Fix-dropdelay-temporary.patch
Thanks for the writeup! I don't have any experience with .nl files, but there is https://github.com/CelestialAmber/TetrisNESDisasm which might be helpful. I'm not surprised that the problem is related to soft drop; there's already some discrepancies there.
Random thought I just had that I haven't researched at all and might be completely wrong: I wonder if the number of frames that elapse when pausing (or unpausing?) depends on the number of frames that have elapsed since the game started (state.frames)? Similarly to how the line clear delay depends on this.
okay, i think figured out what the problem with the soft-drop is: when you press right or left during the soft-drop, i.e. while down is pressed, the down-press/soft-drop is just ignored/cancled. generic-tetromino-game doesn't handle this yet.
Thanks! I would've expected that that would cause a desync earlier, it's weird that it still works. Or, I guess it makes a bit of sense, just got (un)lucky with the timing of it. Either way, could you send a patch?
yea, i am going to send a patch, i just commented this here because i wanted it to be documented. i still need to figure out what is happening in some edge cases to make sure that generic tetromino game handles this correctly.
i actually just discovered this 20 minutes before going to work, so i was really happy because it took ages to find and wanted to write it somewhere :D
The TAS at https://sebsite.pw/tmp/Tetris%20(U)%20%5B%21%5D.fm3 has been updated; the first game of the TAS is now complete! The TAS itself still isn't completely done; I want to continue it with a game starting on level 0 that just repeatedly clears 4 lines at the top of the screen, so the screen is eventually filled with unrecognized completed lines. In addition, the following mechanics haven't yet been tested:
- split double at top
- split triple at top
- piece spawns inside other piece, but no topout, since it can fall out (without intervention)
- start pushing down immediately (and don't stop until piece locks)
- b-type
Some of these can be tested in the second game, others will need to be tested in a 3rd b-type game.