Josh's NES Tetris Hacks and Mods

Thread in 'Research & Development' started by Josh Tolles, 2 Jan 2016.

  1. Welcome to Josh's Classic Nintendo Tetris Hacks and Mods!

    I have developed something of a hobby: creating hacks and mods for NES Tetris. (I dabble with SNES, too.) My ultimate goal is to create a modified ROM of NES Tetris which features hard-drop, hold, T-spin recognition, and some sort of scoring modification.

    I currently do have all of those functions in different individual ROMs, but I have not combined them all into one ROM. Here is the list of current working mods:

    Hard Drop NES (this shit is the bomb-digetty)

    T-Spins Count NES

    Piece Swap NES ("select" swaps current piece and "next" piece)

    "Masters' Edition" NES (fall rate [gravity] is harder; 1.5 falls Level 9 and up)

    New Prototype
    (Level 29 and up new gravity rules)


    Links and Info coming soon!





    Oritinal post:
    Wow, where'd this forum come from?

    I have a hobby of making ROM mods and Game Genie codes for NES and SNES Tetris.

    Eventually I intend to have a completed ROM of the game that has hard drop, hold, t-spins, and score rollover. I have mods that have these features, but not one that has all features in one game.

    I will soon have links and lists of mods and GG codes, but not today ;)

    What brought me here today was a new idea for Levels 29+ that I thought up a couple weeks ago and wrote the code for today.

    The idea is that instead of the sudden jump from 2 frame fall-speed to one frame falls at the 28->29 transition, I would instead gradually increase the speed. So what I came up with is this:

    At 29, the top 25% of the playing field (the top 5 rows) would feature one frame fall-speed and the bottom 75% would have 2 frame falls. Then at 30, the top 6 rows would be one frame, the bottom portion would be 2 frames. 31 would be seven rows of single frame drops, 32 would be 8 rows of single frames, and so on until the game becomes unplayable.

    I wrote the code and tried it out on a PowerPak. It's okay. Not sure if anyone would be interested in trying it out, let me know.
     
    Last edited: 24 Jan 2016
    Cinnaminion, AaronC and Qlex like this.
  2. That's great! Thanks for the post.

    I was interested in making a clone myself, given my TV was not cooperating (hurray for RCA not triggering the AV channel). Everything I use has lag, and I really want to practice using something close to the original.

    If I get too lazy : I will definitely like to know more about your clone and practice with it a little bit ;)
     
  3. I will edit the top page as I get around to completing my writing goals.

    Below I will offer a sneak peak at what is to come as I featutre I live outline for the projected front page, top page, main page, and even a special page. Events.

    But first, before I get to the outline, let be dive into things. Lets start talking about how I am going to try to put this together. I want to do a How-To Article on a how to do a How-To. Let's say we start with Game Genie code. Hot to do a How-to on How to Create a Game Genie code.Terry is a curious about a Game Genie code. So Let's show us all how to do a How-To on How To Do a How-to-do.

    The How-To "How To Do" is coming soon!

    But first, as promised, I present a sneak peak at a sneak-a-peak! It's the outline of the future (pun intended, read ahead and get it).

    The Outline will be posted below. Thanks!


    (I now present the Outline.)

    The Outline:


    Ideas for Words that May be Important

    For the TC Forum:

    Extra Special Preview Outline Sorts
    (An Outline Special)
    *extra special outline, in other words*

    A. Write Articles for created "Written Articles"
    1. Write Articles about "stuff"
    2. Write Articles about "things"
    3. Write Articles about ROMs
    4. Write How-To Articles about "How to" Game Genie Code-creation "How-To" Format
    5. How-To's and Idea and suggestions requests about how to present How-To Articles​
    B. Front Page
    1. What you see is what you get
    2. You ain't seen nuthin' yet
    3. Front Page: it's the Top Page
    4. Boo-Yah
    5. Bit*hes​
    C. Tope Page Detail
    1. Links
    a. refer to "B."​
    2. Links down below
    a. refer to "B."
    b. links to make easy jumps to future posts with pertinent information​
    3. Introduction of myself
    a. I am a living turtle spirit
    b. Release your inner demon
    c. Now know that I am a living spirit of crabs and bugs​
    4. Ideas?
    a. please offer your ideas
    b. please refer to "B."​
    5. Suggestions?
    a. please offer suggestions
    b. please offer alternatives
    c. please offer advice
    d. please refer to "B."​
    6. Counts?
    a. please count
    b. please count me in
    c. tetris piece counters
    d. count me out
    e. count back alphabetically to "B."​
    D. Spirituality: the Meat and Potatoes of Tetris' Bright Ideas
    1. Tetris God. Period.
    B. Inner God
    E. Reflection of Inner Self
    a. what mood is your spirit in
    b. do you have any more bright ideas?
    c. what doesn't work
    d. what really doesn't work
    e. is the outcome of your game pre-determined if you never misdrop or hesitate?
    f. why oh why did I wait for the longbar​
    4. Tetris Masters are Time-Travellers
    a. seriously
    b. think about it
    c. ultimate spirituality requires time-travel​
     
  4. That was really cool joshy i liked it a lot!
     
    Qlex and Muf like this.
  5. I've gathered together some info on this. Here is the original programming for the fall rate in NES Tetris. I am using the fceux debugger. The program starts at ROM address $8973.
    [​IMG]

    Here is a translation of that I did a long time ago. Translation.


    Now, here are is change I made (look at address 8979):
    [​IMG]

    If you look closely, you'll see that instead of just using number one as the fall standard on Levels 29 and higher, I "hi-jack" the program and send it to a new address: $D700. Here is a picture of $D700:
    [​IMG]
    Extra-Special Extra Notes:
    It all starts out when the program checks the Level.​
    It checks the Level so that it will know the appropriate fall rate to use.
    But the modification changes what the program does for Level 29.
    When it reads that the the current Level is 29, it does something different.
    First, I tell it to go to address $D700.
    This is the first address of "open" space I find at the end of the ROM.
    Next I tell the program to use a fall rate of two frames, unless:
    The piece is on the top portion of the screen.
    If it is, use a one frame fall rate​
    The higher the level, the larger the area of single frame falls
    29 has the top four rows
    30 has top five rows
    31, top six rows have single frame falls​
    If its not in the top part of the play field, use two frame fallsThe game will increase in difficulty, Level by Level, until it becomes unplayable.



    I don't know how well this will work in actual gameplay, because I know the displayed Level changes to 00 at 30. I did try it out once, but I used an extra special extra modification for that. (I made Level 00 have 28 fall rate, 01 have 29's, 02 have 30's, 03 have 31's, etc.) The way it stands now, I may have to de-bug the displayed Level to get it all to work correctly.



    I will be getting to the How-To articles on how to do a Game Genie code. The fun part is I am going to go through the whole process fresh, so I don't even know if I will be able to get one out of it. How exciting!
     

    Attached Files:

    Last edited: 15 Mar 2017
    Cinnaminion and Qlex like this.
  6. I dont really know what all of this stuff means, but I am open to new tetris playing challenges
     
  7. Nice to see you still hacking Josh!
     
    Qlex likes this.
  8. Hey Josh, do you happen to know of a game genie code that allows you to simulate game play post level 18 transition? For example, you start play on level 19, but it changes to level 20, then 21, 22 and so on every 10 lines? I want to practice post level 18 transition play without having to grind away at 18 for 130 lines.
     
    Qlex and LCK like this.
  9. I am very interested in trying out your mod as well.
    Would be awesome if you can base on Tetris Zero mod and add extra stuff on top of it like Hard Drop, T-Spin, Piece Hold, etc..
    Tetris zero mod enabled 2P and rom is also converted to MMC3 so that you have freedom to insert more asm code in.
    http://www.romhacking.net/hacks/1013/
     
  10. XZNASPVZ
    LPNAVPGG

    Put these in to force thepieces to fall at Level 19 speeds. You start on Level 00 and you change level every ten lines onto infinity. Great practice for the "feel" of playing after transition.
     
    AaronC likes this.
  11. By request of @Svavar , here's a Game Genie code that lets you play invisible Tetris a la TGM.

    OXYOUO
    UOYOKO

    This also makes it impossible to see where you clear lines, that can be fixed with the following, which changes the line clear effect to use white tiles instead of clear ones:

    VNIPZN
    VNTPYN

    edit: Sorry about the hijack, this seems to be a bad thred for this - I just remembered there already being a thread with Game Genie codes, and searched for that
     
    Last edited: 9 Oct 2016
    Svavar and MaryHadALittle like this.
  12. Neat stuff. Unfortunately, the use of four codes to get the complete effect wouldn't work on an original, physical Game Genie -- you only get space for three! :( Maybe it's possible to optimize one code or the other to use just one line?
     
  13. I haven't tried a physical GG since the 80s so I didn't know that. I actually tried looking it up before positng, and only found a screen someone posted with what looks lile entries for up to five codes.

    But yeah it should be easy to get it down to 3 or even 2 lines by using bytes from somewhere else in the rom or ram. I'll look into it when I get home today.
     
  14. Well that was easy. Turns out the zero page address the game reads from to get the tile to add to the stack is identical to the index of a completely black tile in the graphics data. In English this means I can actually just omit the second code.
    Here's a three-code version that seems to work fine:

    OXYOUO
    VNIPZN
    VNTPYN

    How about a surprise contest or exhibition game for CTWC? ;)
     
    FeV, colour_thief and Kitaru like this.
  15. Well, I made a fabulous new Game Genie code today.

    The GG code is for NES Tetris. It forces the pieces to drop/fall the way SNES Levels 29-31 works.

    Code is a three-liner:
    PGNAVPGG
    PANEEOIP
    ZEEEVPAU

    Code in action.

    *I had intended to explain how I made the code, hopefully I will get to that soon!*

    (The following was written for a general audience, not necessarily Tetris-savvy folks ;) )
    About NES and SNES Tetris:

    NES and SNES are very similar in game mechanics. They obey the exact same auto-shift and delayed-auto-shift rules (this is referring to moving the pieces left and right). They also follow the same rules for each level's fall/drop rate (the speed at which the pieces fall to the bottom of the screen). But there is one major difference between NES and SNES game mechanics.

    While it is true that both games match each other in falling speed (the rate at which the piece falls to the bottom), there is a difference in the rules of gravity between the two games. In NES, gravity is in effect as soon as the next piece has been generated, while in SNES, gravity doesn't kick in until ten frames of screen time have passed. That means that SNES gives you ten frames of game time in which the piece is "floating"--you can begin to move the piece left or right during this time, it's active but not falling. NES does not give you any sort of "head start"--as soon as your piece appears, it is already falling.

    Ten frames amounts to 1/6 of a second. The game displays 60 frames per second, and ten frames is 10 out of 60. That is a really big deal for the Tetris Master.

    On Level 19, the hardest playable level in NES, the pieces fall at a rate of two frames per second (1/30 of a second). Auto-shift moves the pieces left or right at a rate of six frames per second (1/10 of a second). That means that your piece drops three spaces down in the amount of time it takes to move it over only one space left or right; the pieces are dropping faster than they are shifting left or right. On NES Level 19, it is very hard to get your piece all the way left before it hits the bottom and locks down.

    Level 19 on SNES is a completely different story, though. While the pieces fall and shift at the same rate as NES, SNES gives you those ten frames of pre-gravity--a whole sixth of a second to get your piece moving the direction you want it to go. Your pieces shift left or right at a rate of six frames per second. Meaning, those ten frames of pre-gravity allow you to move your piece almost two whole spaces more on SNES than NES!

    Trust me, it's a very big deal.

    Take the longbar, for example (also known as the I tetrimino, I-piece, or Tetris piece, depending on who you ask). It takes five shifts to the left to reach the left side of the screen. If you get almost two of those five spaces covered before gravity kicks in, you're already nearly 2/5 of the way there! Four shifts to the right gets you to the right side of the screen, so if you are going right, SNES lets you get almost HALF way there before gravity begins!

    Trust me, it's a very big deal.

    NES Tetris effectively ends at Level 29. At Level 29, the pieces begin falling at a rate of one frame per drop. That means that your pieces fall six spaces down in the time it takes to move it one space over to the left or right. The Tetris matrix is 20 rows high by ten columns wide, which means on Level 29, the piece falls nearly a third of the way to the bottom before you can even shift it one space left or right. The most you can reasonably expect to accomplish is three shifts to either the left or the right, and it takes for or five shifts to reach the side of the screen. That means you ain't making any lines on Level 29 NES, because you ain't getting the pieces all the way over.

    Everything changes, however, when you switch over to SNES. Now you get those precious ten extra frames. Now you can get over to the left or right with some time to spare. Now 29 is playable.

    Okay, so everyone knows you have to play a lot of Level 19 to master NES. (Mastering means the ability to max-out the score at 999999.) On NES, you have the option of beginning your games on Level 19. That way you can practice it, get comfortable with it.

    But the highest level you can start on with SNES is Level 9. And it takes 20 freaking minutes to get to Level 29. And it's so fast that you usually die right away. This is why my new code is important.

    It allows you to practice SNES Level 29 speeds.

    But why would I want to do this with NES rather than SNES? Actually, I made a SNES game genie code that allows you to start on Level 29, but a lot of game genie's don't work with SNES. Nintendo fucked over the consumer by altering its design so the game genie wouldn't work with their SNES. Mine certainly doesn't. I can get it to work using my FC Twin, but the SNES controllers don't work with Tetris on the FC Twin, so I have to use FC Twin's garbage controllers.

    NES game genies work just fine. Some people seem to think you cn't use them with tp loaders, but it's actually just a tight fit. If you wiggle and push enough, you'll get it in there faar enough to work just fine. I did, and it never affected the way it worked (smashing my top loader in a fit of Tetris-rage DID affect how well it worked, however). Further more, NES Game Genie's just seem more common, anyway.

    The point of all this is: now you can play SNES Level 29 using a game genie and NES Tetris.
     
    Last edited: 15 Mar 2017
    frdhlm and Muf like this.
  16. SNES Level 29-31 Simulator code for Game Genie/NES Tetris:
    PGNAVPGG
    PANEEOIP
    ZEEEVPAU


    Let's take a look at HOW the SNES Level 29-31 Simulator code for Game Genie/NES Tetris works, shall we?

    Here's what the original gravity/fall rate program looks like:
    [​IMG]

    A long time ago, I wrote a breakdown of the program. I don't know if it will help any, but you might want to check it out if you don't know 6502.

    I'll go ahead and try to simplify it a little more. This whole section of programming determines how many frames pass before the piece drops one space, and it's basically an eight step process:

    Step 1: One frame (Level 29 speed) is the default setting
    Step 2: Check which Level the player is on
    Step 3: If the player is on 29, use the default (one frame)
    Step 4: If the player has not reached 29, go check what speed to use for the current Level
    Step 5: Now we know how many frames to wait before we drop the piece one space
    Step 6: Check to see how many frames have elapsed
    Step 7: If enough frames have elapsed, drop the piece one space
    Step 8: If not enough frames have passed, go check for new button inputs.

    My Game Genie code changes the functions of Steps 2-4 to this:

    Step 2: Check which row of the matrix the piece is on
    Step 3: If the piece has dropped past the top row, use the default (one frame)
    Step 4: If the piece is still on the top row, use ten frames.


    To understand HOW the Game Genie codes work, lets take a deeper look into Steps 2-4 BEFORE we apply the Game Genie code.
    Let's expand on these steps:

    Step 2: Check which Level the player is on
    Step 3: If the player is on 29, use the default (one frame)
    Step 4: If the player has not reached 29, go check what speed to use for the current Level

    Step 2 has only one part and uses two lines of code:
    $8975: A6
    $8976: 44

    "A6 44" means "Load X register with the value found at RAM address $0044". (RAM address $0044 contains the number of the current Level.)
    Summary: now X is equal to the current level.


    Step 3 has two parts and uses four lines of code:
    $8977: E0
    $8978: 1D
    $8979: B0
    $897A: 03

    "E0 1D" means compare X to $1D, where X is equal to the current Level, and $1D is hex for 29.
    "B0 03" means "if X is equal to or greater than $1D (29), then skip the next three lines of code"
    Summary: If the player is on Level 29 or higher, then use the default speed of one frame per drop.



    (Step 4 is pretty simple, but it will take a while to explain, so bear with me)
    Step 4 has only one part, but uses four lines:
    $897B: BD
    $897C: 8E
    $897D: 89
    $89_ _: _ _ (this one depends on which level you are on)

    "BD 8E 89" means "Load Accumulator with number found at address ($898E + X) ...(remember, X is the current Level)

    -Example #1: If you are on Level 0, ($898E + 0) = $898E ...So fill in the blanks above with:
    $898E: 30

    -Example #2: If you are on Level 1, ($898E + 1) = $898F ....So fill in the blanks with:
    $898F: 2B

    -Example #3: If you are on Level 18, ($898E + #1B) = $89A0 ....Fill in the blanks with:
    $89A0: 03

    Example 1 gives us $30, which is hex for 48. Summary: Pieces fall every 48 frames on Level 0.
    Example 2 gives us $2B, which is hex for 43. Summary: Pieces fall every 43 frames on Level 1.
    Example 3 gives us $03, which is hex for 3. Summary: Pieces fall every 3 frames on Level 18.


    Now we have gotten a nice, deep look at Steps 2-4, which is important if you want to understand how the Game Genie code alters the program. So let's take one more look at the simplified version of Steps 2-4:

    Step 2: Check which Level the player is on
    Step 3: If the player is on 29, use the default (one frame)
    Step 4: If the player has not reached 29, go check what speed to use for the current Level

    PGNAVPGG, PANEEOIP, and ZEEEVPAU change these steps into this:

    Step 2: Check which row of the matrix the piece is on
    Step 3: If the piece has dropped past the top row, use the default (one frame)
    Step 4: If the piece is still on the top row, use ten frames.


    PGNAVPGG translates to "$8976:44/41". That means, "Go to address "$8976 and change 44 to 41"
    $8976: 44 was part of Step 2, remember?

    Original Step 2:
    $8975: A6
    $8976: 44

    "A6 44" means "Load X register with the value found at RAM address $0044". (RAM address $0044 contains the number of the current Level.)
    Summary: now X is equal to the current level.

    The Game Genie changes the 44 to 41, and Step 2 becomes:

    $8975: A6
    $8976: 41

    "A6 41" means "Load X register with the value found at RAM address $0041". (RAM address $0041 tells which row of the matrix the piece is on)
    **Note: The top row is 00, second row down is 01, halfway down is 09, etc.
    Summary: now X represents the piece's position in the height of the matrix.



    PANEEOIP

    PANEEOIP translates to "$8978:1D/01". That means, "Go to address $8978 and change '1D' to '01'."
    $8978: 1D was part of Step 3, remember?

    Original Step 3:
    $8977: E0
    $8978: 1D
    $8979: B0
    $897A: 03

    "E0 1D" means 'compare X to $1D', where X is equal to the current Level, and $1D is hex for 29.
    "B0 03" means "if X is equal to or greater than $1D (29), then skip the next three lines of code"
    Summary: If the player is on Level 29 or higher, then use the default speed of one frame per drop.

    Game Genie changes Step 3 to this:

    $8977: E0
    $8978: 01
    $8979: B0
    $897A: 03

    "E0 01" means "compare X to $01", where X is equal to piece's vertical position in the matrix
    "B0 03" means "if X is equal to or greater than '01', then skip the next three lines of code"
    Summary: If the piece is on the second row down or lower, then use the default speed of one frame per drop.


    ZEEEVPAU

    ZEEEVPAU translates to "$898E:30/0A". Which means, "Go to address $898E and change '30' to '0A'."
    $898E:30 was part of Step 4, Example #1, remember?

    Original Step 4, using Example #1 (Level 0):

    $897B: BD
    $897C: 8E
    $897D: 89
    $898E: 30

    "BD 8E 89" means "Load Accumulator with number found at address ($898E + X) ...(remember, X is the current Level)

    If you are on Level 0, ($898E + 0) = $898E ...So go to that address:
    $898E: 30

    That address gives us $30, which is hex for 48.

    Summary: Pieces fall every 48 frames on Level 0.


    At this point, we've used the Game Genie to change the value of X to the vertical position of the piece in the matrix. '00' is the only variable that is relevant here; '00' represents the top row of the matrix, anything lower will always fall at a rate of one frame per drop. When X is equal to '00' (when the piece is at the top of the screen) we want it to take ten frames before it drops. The hex number for ten is $0A.

    So we use the Gme Genie to change "$898E: 30" to "$898E: 0A" and get this:

    $897B: BD
    $897C: 8E
    $897D: 89
    $898E: 0A

    "BD 8E 89" means "Load Accumulator with number found at address ($898E + X) ....X is always going to be equal to zero, so $898E ($898E + 0) is the only address that matters.

    Summary: Pieces on the top row don't fall until ten frames have passed.
     
    colour_thief, frdhlm and Muf like this.
  17. I'm surprised you were able to pull this off with only three alterations, really impressive!

    If you hadn't detailed the process, I'd have imagined that you abused the existing code that creates a similar effect (but for a few more frames) on the first piece of any game, and forced that to happen every piece, but with a shorter delay. :)
     
  18. That was also my thought. Changing the level check to a row check is a neat approach.

    If you want the pre-gravity behavior without affecting natural drop speeds, you can set the gravity timer to -10 (0xF6) instead of 0 in the piece spawn function.
     
    Qlex likes this.
  19. I don't entirely understand this. Could you elaborate?
     
  20. The pre-gravity behavior at the beginning of the game is implemented by setting the gravity timer to a negative value. It's treated as a "signed" byte (-127 to +128) rather than unsigned (0 to 255). (You can also think of it like a large positive number that rolls back over to 0 and starts counting normally again, it's more or less the same whichever way you think of it.) It's only done in the set up like that in the game start subroutine.

    There is a line in the piece spawn routine that sets the gravity timer back to 0. You could make it store -10 instead. I think the code does something like LDA #00; STA $45, but I can't remember if it keeps re-using that 0 to set up other variables too. If it only affects the gravity timer, you can just change the #00 to #F6 -- very Game Genie friendly.
     

Share This Page