5 minute read

The Story so Far…

Last Antholog, I switched to using a pre-existing decompilation, rather than trying to make my own, and was able to successfully start removing unused game data and adding new piece rotations! Amazingly, by using my old findings and this new decompilation, in two weeks, I was able to essentially completely replicate the final state of the school project that took me a couple of months.

However, that meant also replicating the same errors. In particular, the size of the new table needed for these pieces was >256 bytes, which didn’t hold well for an 8-bit computer! Since the NES can only hold a maximum value of 256, that meant the final pieces in the table (for me, the O and I pieces) were too far to be able to get their data. Any time the game tried to grab them, the engine recognized it as an invalid piece, and that resulted in the level ending immediately.

We also saw that the statistics for the game weren’t being updated correctly, as you can see below:

What’s New?

Since last week, I’ve been able to fix the statistics window! After snooping around the code, I was able to find an incrementPieceStat function and a statsByType memory address. Here’s a screenshot of an unmodified Tetris game, and a corresponding memory viewer:

Highlighted in the window to the right is the statsByType data, which I’ve also included here:

01 00 01 00 01 00 03 00 04 00 03 00 01 00 00 00

The correlation becomes crystal clear when you look at the game screenshot. statsByType shows the number of T, J, Z, O, S, L, and I pieces, the same order from top-to-bottom in that statistics window… the same order as the ID of the pieces in the game’s original code.

Fixing it, Block-By-Block

At first, I thought maybe my new pieces and reordering of the piece IDs weren’t being properly integrated with statsByType. But after doing some gameplay and observing the data, that clearly wasn’t the case.

After confirming the new IDs were being correctly integrated with statsByType, I realized the problem was the graphics. In fact, if you watch the video above, the numbers are being updated correctly, but the graphics on the statistics sheet weren’t in the right place. Again, the statistics window has the pieces ordered based on the piece IDs in the original code.

The original code orders the piece IDs like this:

tPiece = $00
jPiece = $01
zPiece = $02
oPiece = $03
sPiece = $04
lPiece = $05
iPiece = $06

But our new code orders them like this:

tPiece = $00
jPiece = $01
lPiece = $02
zPiece = $03
sPiece = $04
iPiece = $05
oPiece = $06

The new organization is far superior in my eyes since mirror pieces are right next to each other (J next to L, Z next to S), and the misalignments in orientationTable caused by the O block using only 1 rotation instead of 4 rotations like all other blocks are fixed by having it at the very end. For these reasons, I didn’t want to revert the piece IDs as a way to make the statistics window work.

Then, I thought that maybe changing the locations of the sprites in the data itself would fix it. You can see the original data here:

I thought that moving those pieces around would fix it, but I found that it only caused other graphical issues. After that, I looked through the code again for anything that resembled sprite data. Then, I found a pieceToPpuStatAddr table:

pieceToPpuStatAddr:
    .dbyt   $2186,$21C6,$2206,$2246
    .dbyt   $2286,$22C6,$2306

The name told me this was used to convert piece IDs to PPU (picture-processing unit, aka graphics) memory locations. So, I tried just modifying it according to my new piece IDs, and… that’s all it took! Now the score works perfectly!

What’s Next?

Now that the statistics are being updated properly, we need to have access to all our blocks. After all, it’s hard to keep calling this a Tetris project when we can’t even get a Tetris! Adding in the I and O blocks, using the orientationTable modifications I talked about last week, will be the next logical step.

After that, this project will technically be finished! Granted, I could try and add the wall-kicks that my school partner couldn’t, but that sounds a lot more intense and time-consuming than I’d be willing to endure. At most, I might just scour the internet for other ROM-hacks of this game that already do wall-kicks and just borrow from them.

I will say, the idea of a fully revamped Tetris ROM does sound exciting… modern rotations, wall-kicks, hard-drops, saving pieces, T-spins, ghost pieces, and adding back in the most iconic Tetris theme. Finding ROM-Hacks that do each of those things and adding them together like a Frankenstein monster could be exciting. Besides, Ultimate Tetris does have a nice ring to it…

Final Thoughts

This was a much shorter post than the last few, which is quite refreshing. Sometimes, these posts take up 12 to 14 hours in a single day to finish certain parts of a project, then to collect all the data and screenshots and videos, then to start writing, and doing final spellchecks and revisions, before finally posting online. I also pride myself on not using any AI like ChatGPT or Gemini to write any of this. The only thing I typically use is Grammarly for spell-checking and restructuring certain sentences.

Still, both this project and the site have been very rewarding so far! Whether the next post will focus on this project, I’m not certain yet. This site is still pretty new, and I haven’t really worked out a proper uploading schedule yet. It’s really just been a ‘go with the flow’ kind of project for now, to help ensure I don’t burn out or box myself in too tightly. As for when will I start scheduling upload ideas ahead of time? Uhhhhhhhhhhhhhhhhhhh

In other news, I recently finished reading the DragonBall Z manga! My first time ‘finishing’ DragonBall Z was the Abridged series on YouTube, and I always wanted to watch the original. But I thought the original had wayyy too much filler, and didn’t like all the changes that Kai made. So, I decided to start by just reading the manga! I ATE that thing up. I think I read every issue in less than 3 weeks? Now I’m trying out the original DragonBall manga.

I used to read a lot more, so it’s been nice getting back into the habit. It’s been replacing that old habit of binging reels and shorts like tic-tacs, so for that I’m very grateful. Anyways, until next time!

“Grown-ups never understand anything by themselves, and it is tiresome for children to be always and forever explaining things to them.” Antoine de Saint-Exupéry