Introduction

Pokemon Crystal is known to have a trick to clone Pokemon. If the system loses power as the game saves, after it updates stored Pokemon but before it updates party Pokemon, some data could now be in both locations. Crystal accepts this despite a 16-bit checksum in the save because it does not apply to auxiliary data like stored Pokemon. The checksum is to keep corruption in the main data unlikely. “Unlikely.”

Categories

  • Heavy luck manipulation
  • Heavy glitch abuse
  • Corrupts save data
Used emulator: BizHawk 2.3

Objectives

Save corruption

Crystal stores a 16-bit checksum of the main save data in the save to try to detect corruption and load the backup save if necessary. While it is unlikely that this value can accidently match, it is not impossible. When save data is cleared from the title screen, all of save memory is set to $00. Undetected save corruption can occur here if the values written to the main save data before power off still sum to $0000 and match the zeroed checksum. As the checksum is 16 bits, the theme becomes “push the checksum over $ffff to overflow to $0000.” This can be done and controlled through box names, which let the player enter up to 8 characters to label boxes of stored Pokemon. This movie names additional boxes past those required for the arbitrary code execution to increase the checksum and cause the collision. Thank you to luckytyphlosion who asked again if checksum collision could be set up.
This movie wants to corrupt the save to have a Cyndaquil with no string terminator in its nickname. All this requires is a reset after Cyndaquil's data saves and before its nickname's terminator saves, but BizHawk movies are only designed to reset on frame boundaries. The subframe precision required can still be found with the equal frame lengths setting. A Game Boy frame completes every 70224 cycles while the LCD is on but the time between is arbitrary while the LCD is off. The default setting syncs frame boundaries to frame completions, yet EFLs have a frame boundary every 70224 cycles regardless of when frames complete. Over the course of this movie, the Game Boy frame timing is shifted relative to the EFL frame boundary with the variable lengths of LCD off periods. This allows a reset between when the L and the terminator in Cyndaquil are written to the save data.

15 00 or <DAY>

To summarize the link, if the text engine reads the control character $15 and it is followed by a $00, the program counter will end up at $cd52, an address near manipulable memory. This movie has the text engine try to read Cyndaquil's unterminated nickname to display it on the STATS screen. The nickname is copied to a string buffer which the text engine reads past because of the lack of a terminator. An item quantity buffer is not far from this string buffer, and the Antidote quantity scrolled to in the Cherrygrove Mart menu provides a $15 there for the text engine to read. A max item quantity buffer is the next byte and is set to $63 at the Antidotes, but is then set to $00 when CANCEL is used to leave the mart menu.
Once the text engine reads the $15 $00, code execution begins at $cd52 and the address that follows the $15 $00 is on the stack. That address is the location of the last loaded Pokemon data. One step up after the mart window places ret nz at $cd70, memory of pointers for the background map, which is reached without issue and sends execution to the Pokemon data. The manipulated trainer ID and DV bytes in Cyndaquil's data there are interpreted as the instructions below. This is enough to jump into the memory for box names where more values can be controlled. The box names require a couple lower bytes in addresses to be character values, and the number of entry points from here is already limited.
; af = $0100
; bc = $c569
; de = $00ff
; hl = $002b from ld hl, $002b in moves

ld h, $36

add hl, bc ; hl = $fb94, the 5th character of Box 4's name
jp hl

Arbitrary code execution

This movie uses a modified version of MrWint's box names that execute code input from the joypad. Aside from address changes between the games and setups, there are two small changes: or [hl] is used to reset the carry flag and the jp nc jumps before the first of the two boxes. I thought or [hl] was faster to input before I learned the mechanics below, but it's the same, yet the higher value still contributes to the checksum. The jump before the first box is fast to input and does not cause any issues with a clever box name there. That box is covered after the two primary boxes. Note it is faster to scroll the list to boxes before they are named, and hold to scroll as opposed to press -> release a bunch is break even for Box 4 and faster for Box 5 and up.
Box names
One input every other frame. The first input cannot be A B START or SELECT. The same button cannot be pressed two inputs in a row (or it's a hold). Directionals can be pressed consecutively if a new button or directional is also pressed. Example: Up 2 can be done in two inputs with UP -> UP|LEFT. Priority for two directionals at once is UP > DOWN > LEFT > RIGHT. If A and a direction are input together the A is processed then the cursor moves.
Also thank you to MrWint's submission for how to format this section.
BytesInstructionComment
Box 5
aaxor dd stores last joypad input: find out differences to current input
ea a1 fbld [$fba1], aWrite difference; will be executed as opcode later in the cycle
aaxor dRestore current joypad input value
f5push afCopy current joypad input from a...
d1pop de... to d (store it as last joypad input)
f1pop afRestore a and f from the previous cycle
50 ($fba1)(any)Execute opcode written earlier this cycle
Box 6
f5push afSave a and f for next cycle
b6or [hl]Clears carry flag, needed for the jump
fa a4 ffld a, [$ffa4]Reads current joypad inputs into a
d2 95 fbjp nc, $fb95Loop back to Box 4; carry will never be set
Box 4 has two more goals in addition to high values for the checksum. The 6th character is where Box 6 loops back to, because it was fast to input. However, the string terminator opcode is ld d, b and the box name program relies on d to store the last joypad input. The 5th character is where the 15 00 setup used in this movie jumps to, because of the limited entry point options. The slide into Box 5 needs to avoid an unsafe opcode from xor d. With the initial values of a=$02 and d=$c5 (from ld d, b) the result would be rst $00, an instruction that resets the game. Box 4 is named in such a way where both jump locations interpret different instructions to satisfy those goals.
BytesInstructionComment
Box 4 (from 5th character)
f6 feor $feSets a to $fe
f6 feor $fe
50ld d, bSets d to $c5
BytesInstructionComment
Box 4 (from 6th character)
fe f6cp $f6Preserves a
fe 50cp $50Preserves d
Below are the joypad inputs and commands executed to reach the usual end. Refer to MrWint's submission for the nuances of this process. It accomplishes many of the same things as that submission so the comments are mimicked for comparison. One difference here is the warp data pointer is set to the player coordinates and the map values are written in that area. Warp data entries start with coordinates that need to match to warp, and this way there is already a match. An idea from luckytyphlosion was to end input early through Crystal's auto input system, which uses a pointer to run-length encoded inputs. For this movie, there happens to be a (properly terminated!) series of bytes in memory that plays out the rest almost perfectly.
Joypad     Command
97         69 (ld l, c)      // setup cycle
fd         6a (ld l, d)
ae         53 (ld d, e)      // setup cycle
dc         72 (ld [hl], d)   // fbfd <- dc; Set warp pointer to our fake warp data
f1         2d (dec l)
c5         34 (inc [hl])     // setup cycle
b7         72 (ld [hl], d)   // fbfc <- b7; ^
34         83 (add e)        // setup cycle
5e         6a (ld l, d)
6b         35 (dec [hl])     // fb5e <- 43; Enable Red in Mt. Silver
d2         b9 (cp c)         // setup cycle
b8         6a (ld l, d)
9c         24 (inc h)
b6         2a (ld a, [hli])
94         22 (ld [hli], a)  // fcb9 <- 03; (Glitch) map entrance $03, close to Red
b6         22 (ld [hli], a)  // fcba <- 03; Map group
3e         88 (adc b)        // setup cycle
4c         72 (ld [hl], d)   // fcbb <- 4c; Map index: In Mt. Silver
bd         f1 (pop af)       // setup cycle
d7         6a (ld l, d)
e2         35 (dec [hl])     // fcd7 <- 00; Having no Pokémon in your party wins all battles instantly
1a         f8 (ld hl, sp-$0b)
b7         ad (xor l)        // setup cycle
dd         6a (ld l, d)
24         f9 (ld sp, hl)    // Fix the stack pointer*; leave directly to overworld
8e         aa (xor d)        // setup cycle
e4         6a (ld l, d)
b6         52 (ld d, d)      // setup cycle
d4         62 (ld h, d)
0a         de (sbc $f5)      // setup cycle; *after this skips a push
78         72 (ld [hl], d)   // d4e4 <- 78; Change tile the character stands on, needed for warping
a0         d8 (ret c)        // setup cycle
c2         62 (ld h, d)
ad         6f (ld l, a)      // setup cycle
c7         6a (ld l, d)
f2         35 (dec [hl])     // c2c7 <- ff; Enable auto input
de         2c (inc l)
9e         40 (ld b, b)      // setup cycle
ec         72 (ld [hl], d)   // c2c8 <- ec; Set auto input pointer
c0         2c (inc l)
62         a2 (and d)
40         22 (ld [hli], a)  // c2c9 <- 60; ^
77         37 (scf)          // setup cycle
05         72 (ld [hl], d)   // c2ca <- 05; Set auto input bank
29         2c (inc l)
1d         34 (inc [hll])    // c2cb <- 01; Delay first auto input
d4         c9 (ret)          // Return to normal game code

Route

Intro

  • Save data is cleared because it's the totally moral thing to do before a save corruption TAS. Gambatte fills uninitialized save memory with $ff bytes so the clear sets the values to something objective. A setup with Gambatte's $ff bytes may exist.
  • Options are not set as text can print at the fast speed when A or B is held anyway.
  • The trainer ID is manipulated to be $2636 for the 15 00 setup. This is done with 23 expected frames of delay between power on and NEW GAME. Two other 16-bit values are rolled at the same time that affect the checksum, but are secondary in priority.
  • The player is selected to be the girl. A few values in memory like a sprite index are higher with her. This helps avoid an extra box name for the checksum in combination with the player name and is worth the frames to move the cursor down.
  • She is named five multiplication symbols. Each character has the value of $f1 and is in memory twice for the player name and Cyndaquil's original trainer name. This is an efficient way to increase the checksum despite the extra frames it takes to display.

New Bark Town

  • Mom is talked to directly to avoid the exclamation point animation that plays if the player tries to walk past. It is only a couple frames faster to do this and some luck manipulations may take the exclamation point for the variance it provides.
  • Cyndaquil is manipulated to have $09e9 DVs for the 15 00 setup. The actual delay used here is difficult to estimate because of “lag frame rules” when sprites are decompressed relative to the timer interrupt, but it is around 10-13 frames.

Cherrygrove City

  • The PC is opened with a buffered A press from the left side. In general, buffered menus from the overworld will open before sprites update and possibly deload. An extra sprite stays in memory from this side and increases the checksum at no cost.
  • Boxes 1 through 8 are named for the arbitrary code execution and checksum. The 9 character has the highest value at $ff, but the filler boxes input a 1 on the way to save an input in exchange for a slightly lower character value.
  • The game is saved from the PC through the change box action. It is a couple seconds faster than a save from the menu in the overworld, though a save from where the PC is misses out on a few more sprites loaded in memory to increase the checksum.
  • An almost-purchase of 21 Antidotes in Cherrygrove Mart completes the 15 00 setup.
  • The auto input that takes over from the arbitrary code execution presses UP x4, RIGHT x9, A x12 to end the movie. Note each character in the textboxes consumes an input so at least 11 inputs are needed to reach the credits from next to Red.

ThunderAxe31: This is going to require some time. Judging.
ThunderAxe31: Adding the label "save glitch".
ThunderAxe31: Not only this TAS introduces a new glitch that breaks the game with an unprecedented speed, but it's also highly optimized. A possible faster setup has been theorized, but after some discussion and research, it seemed to me that it would not be verifiable on real console due to the fact that it would rely on non-deterministic data. In any case, such hypothetical improvement would require to remake the run from scratch, and it wouldn't save much time compared to this submission, nor would it prove the setup used for this submission to be poorly executed. Clearing the data at beginning was the best choice.
For what concerns the branching, there are two separate aspects to take in account: similarity between games and similarity between movies. Since Pokémon Crystal is a Gen II Pokémon game, it can obsolete and be obsoleted by Pokémon Gold and Silver, even though the glitch abused in this movie is only available in Crystal. Since the current fastest-completion movie features much unique and entertaining contents, it shouldn't be obsoleted by this submission; however I have to note that we have an obsoleted movie with the "save glitch" label, and even though it's much longer and uses a different glitch, its movie goal is the same as the one for this submission, so the obsoletion chain will be changed in order for this submission to obsolete it.
The audience reception was vastly positive, so this submission is accepted for Moons as an improvement of the published "save glitch" movie .
Spikestuff: Publishing.


TASVideoAgent
They/Them
Moderator
Joined: 8/3/2004
Posts: 15527
Location: 127.0.0.1
Former player
Joined: 3/13/2017
Posts: 15
And we thought EFLs were dead. Bonus note for the thread: it's been a theme of recent Pokemon TASes to sync on console, but BizHawk still has some issues with the gen 2 Pokemon games. For this movie, all that needs to change is 1 input in the box names to accomodate for an incorrect real-time clock value in the save file that affects the checksum. This assumes someone has a way to time the 10μs reset window on hardware though.
Pixiuchu
She/Her
Player (146)
Joined: 9/27/2015
Posts: 106
Can't vote but I approve! At least it's not as boring as the Pokémon Yellow save corruption lol.
Spikestuff
They/Them
Editor, Publisher, Expert player (2630)
Joined: 10/12/2011
Posts: 6435
Location: The land down under.
What. Yes, and shotgun to pubs.
WebNations/Sabih wrote:
+fsvgm777 never censoring anything.
Disables Comments and Ratings for the YouTube account. Something better for yourself and also others.
Editor, Reviewer, Skilled player (1352)
Joined: 9/12/2016
Posts: 1646
Location: Italy
Excellent work, Yes vote!
submission text wrote:
  • Save data is cleared because it's the totally moral thing to do before a save corruption TAS, though there could be a setup based on uninitialized memory
From what I can understand, you did this for comfirming the validity of the glitch execution, right? If that's so, then there is no need to do it for the submitted movie, since it's up to the Judges to check if a glitch used is legit or caused by emulation inconsistences. It's more something that an RTA attempt would need, for proving the validity of the run. I apprecciate the attempt to make the glitch setup less questionable, but it should be rather provided as an auxiliary movie file, in the submission text. Would it be possible to resync this movie for removing the part in which you clear the save data, or is that necessary for the specific glitch setup you used? In the first case we could replace the movie file in this submission, while in the second case the submission would have chances to be accepted as it is.
gifvex wrote:
Bonus note for the thread: it's been a theme of recent Pokemon TASes to sync on console, but BizHawk still has some issues with the gen 2 Pokemon games. For this movie, all that needs to change is 1 input in the box names to accomodate for an incorrect real-time clock value in the save file that affects the checksum. This assumes someone has a way to time the 10μs reset window on hardware though.
If such movie can sync on both real console and emulator (after having implemented the necessary accuracy improvements) then the movie could be published as secondary file for the publication, like it was already done for [3664] GBC Pokémon: Yellow Version by TiKevin83 in 1:36:41.68
my personal page - my YouTube channel - my GitHub - my Discord: thunderaxe31 <Masterjun> if you look at the "NES" in a weird angle, it actually clearly says "GBA"
EZGames69
He/They
Publisher, Reviewer, Expert player (4293)
Joined: 5/29/2017
Posts: 2759
You absolute mad-lad, the game tells you not to turn the power off as it's saving, yet you do it anyway! I'm much more nostalgic for the 2nd generation pokemon games, thanks for breaking my childhood. yes vote.
[14:15] <feos> WinDOES what DOSn't 12:33:44 PM <Mothrayas> "I got an oof with my game!" Mothrayas Today at 12:22: <Colin> thank you for supporting noble causes such as my feet MemoryTAS Today at 11:55 AM: you wouldn't know beauty if it slapped you in the face with a giant fish [Today at 4:51 PM] Mothrayas: although if you like your own tweets that's the online equivalent of sniffing your own farts and probably tells a lot about you as a person MemoryTAS Today at 7:01 PM: But I exert big staff energy honestly lol Samsara Today at 1:20 PM: wouldn't ACE in a real life TAS just stand for Actually Cease Existing
Player (27)
Joined: 3/2/2014
Posts: 34
Location: Canada
ThunderAxe31 wrote:
Excellent work, Yes vote! From what I can understand, you did this for comfirming the validity of the glitch execution, right? If that's so, then there is no need to do it for the submitted movie, since it's up to the Judges to check if a glitch used is legit or caused by emulation inconsistences. It's more something that an RTA attempt would need, for proving the validity of the run. I apprecciate the attempt to make the glitch setup less questionable, but it should be rather provided as an auxiliary movie file, in the submission text.
The setup only works if (large portions of) SRAM is filled with $00s. Clearing save data does this action, otherwise the glitch would rely on uninitialized SRAM, which can have multiple non-deterministic values. It's also important to note that BizHawk fills SRAM with $ff by default. A collision which aims for $ffff is possible, but would require a different strat to achieve. The specific comment by gifvex is a tongue-in-cheek reference to the "validity" of the Pokémon Gen 1 Save Corruption TASes on a real cartridge with uninitialized SRAM, but I won't get into that discussion here.
ThunderAxe31 wrote:
Would it be possible to resync this movie for removing the part in which you clear the save data, or is that necessary for the specific glitch setup you used? In the first case we could replace the movie file in this submission, while in the second case the submission would have chances to be accepted as it is.
I'm not sure how resyncing works in TASes, but I know that all of gifvex's TASes are botted out, so it would simply require re-botting the TAS without the steps to clear save data anyway. However, as I mentioned, not clearing save data would mean relying on uninitialized SRAM and would need a different setup altogether for the collision.
Meerkov wrote:
The human element of the run is far more entertaining than the game itself. If it wasn't for someone lying about their record 40 years ago, I don't think we'd take a second look at this run/game. Meh vote.
Editor, Reviewer, Skilled player (1352)
Joined: 9/12/2016
Posts: 1646
Location: Italy
luckytyphlosion wrote:
The setup only works if (large portions of) SRAM is filled with $00s. Clearing save data does this action, otherwise the glitch would rely on uninitialized SRAM, which can have multiple non-deterministic values. It's also important to note that BizHawk fills SRAM with $ff by default. A collision which aims for $ffff is possible, but would require a different strat to achieve. The specific comment by gifvex is a tongue-in-cheek reference to the "validity" of the Pokémon Gen 1 Save Corruption TASes on a real cartridge with uninitialized SRAM, but I won't get into that discussion here.
I see. I agree with the decision of using a more deterministic setup for the movie, even if it could be slower. Still, I'd like to hear opinions from other people, since we already have a Pokémon movie that makes use of uninitialized memory.
my personal page - my YouTube channel - my GitHub - my Discord: thunderaxe31 <Masterjun> if you look at the "NES" in a weird angle, it actually clearly says "GBA"
Former player
Joined: 3/13/2017
Posts: 15
ThunderAxe31 wrote:
Would it be possible to resync this movie for removing the part in which you clear the save data, or is that necessary for the specific glitch setup you used? In the first case we could replace the movie file in this submission, while in the second case the submission would have chances to be accepted as it is.
lucky beat me to it, but yeah, the setup in this movie requires the values not written by the save process to be $00. The morals around using an in-game method to do this rather than finding an emulator with that as the default saveram state is mostly lighthearted.
Fortranm
He/Him
Editor, Experienced player (877)
Joined: 10/19/2013
Posts: 1121
Fantastic as always. Glad to see the Gen 2 ACE category getting an long-awaited update. Yes vote. Can we expect a run similar to [3664] GBC Pokémon: Yellow Version by TiKevin83 in 1:36:41.68 for Gen 2 on its way? :D
Cyorter
He/Him
Editor, Player (249)
Joined: 2/8/2017
Posts: 138
Location: Venezuela
This movie isn't bad, but happened more than half of movie and still the introdu... WTH?! NICE! I liked also using the PC sideways, I've always used the PC in front, but now I'll be an anti-system I'll break the rules thanks to this TAS. Ok, I liked this TAS once I've seen the ending... but I'll be still waiting for someday a Gotta catch 'em All! or Coop Diploma :) (I doubt there will be a Coop Diploma)
Post subject: checking uninitialized GBC SRAM data on real console?
Editor, Reviewer, Skilled player (1352)
Joined: 9/12/2016
Posts: 1646
Location: Italy
luckytyphlosion wrote:
The setup only works if (large portions of) SRAM is filled with $00s. Clearing save data does this action, otherwise the glitch would rely on uninitialized SRAM, which can have multiple non-deterministic values.
So... We know that uninitialized data is dependant on many non-deterministic factors, as Nach noted in this page, but I wonder if GBC SRAM could be an excepion, and give deterministic results when removing and re-inserting the cartridge battery. Are there any documented attempts of reading uninitialized GBC SRAM data? If not, I could buy the necessary hardware and test it myself on real console.
my personal page - my YouTube channel - my GitHub - my Discord: thunderaxe31 <Masterjun> if you look at the "NES" in a weird angle, it actually clearly says "GBA"
Post subject: Re: checking uninitialized GBC SRAM data on real console?
Joined: 11/20/2007
Posts: 22
ThunderAxe31 wrote:
I wonder if GBC SRAM could be an excepion, and give deterministic results when removing and re-inserting the cartridge battery
I think it's likely that it's at least partially deterministic, since otherwise Nintendo would run the [slim] risk that somebody's cartridge started up with something resembling save data, resulting in random cases of 'save data is corrupt' being the first thing a player sees on their new game. There's also the possibility that they initialise it to a certain state out of the factory, which may not be the same result as putting in a fresh battery - doesn't strike me as likely, just something to consider. (also, loved this run)
Post subject: Re: checking uninitialized GBC SRAM data on real console?
Editor, Reviewer, Skilled player (1352)
Joined: 9/12/2016
Posts: 1646
Location: Italy
pachunka wrote:
There's also the possibility that they initialise it to a certain state out of the factory, which may not be the same result as putting in a fresh battery - doesn't strike me as likely, just something to consider.
Oh, I didn't thought about that possibility. Still, it looks very unrealistic to me, as that would require the mass production to have a special machine that automatically formats the SRAM after having the cartridge finished to assemble, which would be impractical. But on the other hand, I also have to admit that it would also be unrealistic for the SRAM to have been purposely developed in such a way that it automatically formats itself when you insert a new battery, especially since official cartridges are not supposed to have their battery replaced. The most probable case is that SRAM is just wiped out via software, that is, by the game code present in the cartridge ROM itself. In fact, most games check if the save data is corrupted, in which case they wipe out the SRAM. Interestingly, Pokémon Crystal clears the data to 0x00, while some GBA games use 0xFF bytes instead. In any case, today I bought on internet a device that allows to store the SRAM data from Game Boy cartridges into PC, which will hopefully give more clues about GB SRAM initialization...
my personal page - my YouTube channel - my GitHub - my Discord: thunderaxe31 <Masterjun> if you look at the "NES" in a weird angle, it actually clearly says "GBA"
Editor, Expert player (2071)
Joined: 6/15/2005
Posts: 3282
Cool that you managed to break a 2nd gen Pokemon game this quickly. I admit though that it didn't really surprise me. It was just a matter of time after all. What I found very interesting is that you cleared memory to make it "legit". And yet you managed to break the game anyway (a legit SRAM makes it harder to break). Also, naming the boxes as well as the player in order to get a checksum collision (which is two bytes in 2nd gen, as opposed to just one byte in 1st gen). You have a good understanding of how memory works in this game. You mentioned realigning something (frame boundaries or something) in order to get the perfect frame reset. I wonder whether getting the frame reset would be easier to do in lsnes, since that emulator allows you to frame reset at opcode precision. I admit that a lot of the 1st gen save corruption TASes abuse uninitialized SRAM (all FFs). This is the one crucial step in glitching the game to think you have 255 Pokemon so you can use the menu to corrupt more memory. Unfortunately, that technically means that: - these two published runs, - every one of the TASes they obsoleted (other than the JPN door glitch ones), - all related submissions, and - all the save corruption work we did, are all invalid. Though it doesn't personally affect me that much; after all that is the price to pay for breaking Pokemon to this extent. I found out about this ever since I tried to figure out exactly why memory was being filled with FFs during the glitch. What gets me the most is not that my TASes are invalid, but that as far as I know, in the 8 or so years that this category had been extensively studied, nobody made any attempt to raise this issue.
Patashu
He/Him
Joined: 10/2/2005
Posts: 4042
Can this be clarified further? It is also possible to beat gen 1 pokemon RTA with the save corruption glitch. Is the TAS route not equal to the RTA route?
My Chiptune music, made in Famitracker: http://soundcloud.com/patashu My twitch. I stream mostly shmups & rhythm games http://twitch.tv/patashu My youtube, again shmups and rhythm games and misc stuff: http://youtube.com/user/patashu
Site Admin, Skilled player (1250)
Joined: 4/17/2010
Posts: 11468
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
So to clarify, the setup relying on $FF filled SRAM would make the movie shorter or longer? If it'd be shorter, all we need to know is a real life proof that in normal conditions fresh SRAM may be filled with $FF. If it's actually possible, a movie using such a setup may obsolete this one in future.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Former player
Joined: 3/13/2017
Posts: 15
FractalFusion wrote:
I admit that a lot of the 1st gen save corruption TASes abuse uninitialized SRAM (all FFs). This is the one crucial step in glitching the game to think you have 255 Pokemon so you can use the menu to corrupt more memory.
Patashu wrote:
Can this be clarified further? It is also possible to beat gen 1 pokemon RTA with the save corruption glitch. Is the TAS route not equal to the RTA route?
Aside from Red & Green (JPN), gen 1 fills the memory with $ff for the clear save action, so it has that going for it.
feos wrote:
So to clarify, the setup relying on $FF filled SRAM would make the movie shorter or longer? If it'd be shorter, all we need to know is a real life proof that in normal conditions fresh SRAM may be filled with $FF. If it's actually possible, a movie using such a setup may obsolete this one in future.
The movie should be shorter if clear save is skipped and it's all $ff. It would save maybe 5s in the intro with luck manip and lose about 2.5s to a TIME NOT SET prompt when loading the save later. The checksum concept also changes. The values already in SRAM in this movie are $00 and do not contribute to the sum, but $ff values would. This means the checksum can be anywhere from about $28000 to $3d000 by changing where the reset is between Cyndaquil's DVs and its nickname's string terminator. It would save another 10s or so without the need for a player name or extra box names to contribute to the checksum.
Player (42)
Joined: 12/27/2008
Posts: 873
Location: Germany
FractalFusion wrote:
Though it doesn't personally affect me that much; after all that is the price to pay for breaking Pokemon to this extent. I found out about this ever since I tried to figure out exactly why memory was being filled with FFs during the glitch. What gets me the most is not that my TASes are invalid, but that as far as I know, in the 8 or so years that this category had been extensively studied, nobody made any attempt to raise this issue.
Wasn't there an SDA run that managed to beat the game using the gen 1 save corruption technique? I also saw in a Twitch stream someone do a reset too early and get 255 pokemon. I think nobody bothered to see where the values came from because people were managing to replicate it in RTAs already. Besides, I am not really a diehard fan of accuracy. As far as it's known, it's possible to get everything filled with FF. TASes should be about what's possible, not what's likely. In any case, the total time of these runs is so short that no matter what convention is taken, the greatest variance will come from the rules that need to be followed. That kills the competitive aspect of the whole thing, and I don't see an easy way out. In any case, great run. Congrats to making Gen 2 more broken.
Player (27)
Joined: 3/2/2014
Posts: 34
Location: Canada
FractalFusion wrote:
I found out about this ever since I tried to figure out exactly why memory was being filled with FFs during the glitch. What gets me the most is not that my TASes are invalid, but that as far as I know, in the 8 or so years that this category had been extensively studied, nobody made any attempt to raise this issue.
I'm not sure of the history of the save corruption glitch, but my guess behind what happened is that nobody had really known how save corruption worked other than the results. So when the first TAS was made, it was assumed that the only prerequisite was to be on a New Game, and it was just a lack of interest or motivation that nobody bothered to actually look into it. I actually took the time to properly figure out how Save Corruption works back in April. The reason it works is due to the save routine being improperly structured in its copies. The explanation is as follows: The modified portions of the savefile when saving through the Start Menu, in order, are as follows: - Player Name - "Main Data" - Sprite Data - Party Data - Current Box Data - Tileset Type - One Save Checksum encompassing all of the save data listed here With no savefile, these would basically be whatever SRAM was when selecting New Game (filled with $FF after a clear save). The game calls three routines to save data. These are: 1. Copy Player Name, "Main Data", Sprite Data, Current Box Data, and Tileset Type to SRAM, then checksum all of this data. 2. Copy Current Box Data (again) to SRAM, then checksum all of this data. 3. Copy Party Data and Pokedex Data (Pokedex Data included in "Main Data") to SRAM, then checksum all of this data. The issue is due to two aspects of these routines. Firstly, Party Data is never copied to the Save File, yet the game will checksum the entire save, thereby treating the uninitialized Party Data as valid. Secondly, Current Box Data is copied again. As the Current Box Data will never change between copies, the save file between the first and second copy will be the exact same, thus the checksum will always be valid during the entirety of the second copy. This gives a large enough window (2 frames) for a TAS with frame input windows (as well as a human) to hard reset. A potential solution for the save corruption TASes would be to allow an SRAM state that can be generated by a "clear save option", although I don't know if this would cause any more controversy.
Meerkov wrote:
The human element of the run is far more entertaining than the game itself. If it wasn't for someone lying about their record 40 years ago, I don't think we'd take a second look at this run/game. Meh vote.
Site Admin, Skilled player (1250)
Joined: 4/17/2010
Posts: 11468
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
I still think we should not reject this movie even if this other route is verified as console possible. That'd just be a potential improvement. Right now we're basically discussing if it'd be worth making in the first place, not whether this run is acceptable or not. If they both can be made to sync on console, we don't need other validity proof.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Post subject: Results of my tests on real cartridges.
Editor, Reviewer, Skilled player (1352)
Joined: 9/12/2016
Posts: 1646
Location: Italy
So, I've bought an usb device for reading cartridge data. First, I did some tests with a Pokémon Puzzle Challenge cartridge. The cartridge in question has the battery run dry from many years already. Here is what I got: Test 1: https://www.dropbox.com/s/eudtl3cgbqu0r99/POKEMONPC_1.sav?dl=1 Test 2: https://www.dropbox.com/s/fy3t0wghhrlsmlu/POKEMONPC_2.sav?dl=1 As you can see, both files feature large portions made of either $FF or $00 bytes. You can also note some different bytes scattered around, which are different between the two tests. The other tests I did were with an Italian Pokémon Silver cartridge. In this case, I did remove the battery before doing the tests. Note that these tests were done right after removing the battery. Test 1: https://www.dropbox.com/s/d04bdn4eju3njtk/POKEMON_SLVAAXI_1.sav?dl=1 Test 2: https://www.dropbox.com/s/nvswxiegxne1ufo/POKEMON_SLVAAXI_2.sav?dl=1 Test 3: https://www.dropbox.com/s/baejoe83s8bb4eu/POKEMON_SLVAAXI_3.sav?dl=1 Test 4: https://www.dropbox.com/s/rwger9kutq27m05/POKEMON_SLVAAXI_4.sav?dl=1 This time, I couldn't spot any kind of pattern. Maybe we need to wait some days before having some $FF or $00 chunks? I will try again. The data seems to be completely random, and each test features vast overall difference. So, the only conclusion I can get so far is that a cartridge without battery (or with a dry battery) features mutable data in SRAM.
FractalFusion wrote:
I admit that a lot of the 1st gen save corruption TASes abuse uninitialized SRAM (all FFs). This is the one crucial step in glitching the game to think you have 255 Pokemon so you can use the menu to corrupt more memory. Unfortunately, that technically means that: - these two published runs, - every one of the TASes they obsoleted (other than the JPN door glitch ones), - all related submissions, and - all the save corruption work we did, are all invalid.
How many bytes are required to be $FF, exactly? If these are few, then the setup could still be verified by reading SRAM data from a real cartridge.
feos wrote:
So to clarify, the setup relying on $FF filled SRAM would make the movie shorter or longer? If it'd be shorter, all we need to know is a real life proof that in normal conditions fresh SRAM may be filled with $FF. If it's actually possible, a movie using such a setup may obsolete this one in future.
Even if it was be possible, the inputs for succeeding in the checksum collision would also need to be different, depending on the whole uninitialized data. For this reason, I'm of the opinion that future submissions that use the same glitch should clear the save data as well.
my personal page - my YouTube channel - my GitHub - my Discord: thunderaxe31 <Masterjun> if you look at the "NES" in a weird angle, it actually clearly says "GBA"
Post subject: Re: Results of my tests on real cartridges.
Site Admin, Skilled player (1250)
Joined: 4/17/2010
Posts: 11468
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
ThunderAxe31 wrote:
the inputs for succeeding in the checksum collision would also need to be different, depending on the whole uninitialized data. For this reason, I'm of the opinion that future submissions that use the same glitch should clear the save data as well.
I don't see how this is a reason. If both methods work in real world, why restrict to just one, even though it's not the fastest one? BTW I emphasize that publishing a slower method that we're already sure works in real world is also fine, it just might have a known improvement that probably works in real world.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Post subject: Re: Results of my tests on real cartridges.
Editor, Reviewer, Skilled player (1352)
Joined: 9/12/2016
Posts: 1646
Location: Italy
feos wrote:
ThunderAxe31 wrote:
the inputs for succeeding in the checksum collision would also need to be different, depending on the whole uninitialized data. For this reason, I'm of the opinion that future submissions that use the same glitch should clear the save data as well.
I don't see how this is a reason. If both methods work in real world, why restrict to just one, even though it's not the fastest one?
Because the faster method seems impossible to verify to me. From my tests, we can't get a SRAM with all bytes to $FF in real world, and since each byte matters for the checksum collision, it would require for a player to use arbitrary initial SRAM data. Instead, a save glitch that relies on few uninitialized SRAM bytes could still be reproduced on real hardware, which would prove its validity.
my personal page - my YouTube channel - my GitHub - my Discord: thunderaxe31 <Masterjun> if you look at the "NES" in a weird angle, it actually clearly says "GBA"
Site Admin, Skilled player (1250)
Joined: 4/17/2010
Posts: 11468
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
luckytyphlosion wrote:
It's also important to note that BizHawk fills SRAM with $ff by default. A collision which aims for $ffff is possible, but would require a different strat to achieve.
ThunderAxe31 wrote:
From my tests, we can't get a SRAM with all bytes to $FF in real world, and since each byte matters for the checksum collision, it would require for a player to use arbitrary initial SRAM data. Instead, a save glitch that relies on few uninitialized SRAM bytes could still be reproduced on real hardware, which would prove its validity.
Okay, I agree that unless we have a proof, that bytes we can get in the real world SRAM can be sufficient to execute the alternative setup, we should not allow such a setup. It's in line with how we deal with initial RAM state of the console: 1) We must be sure some state is possible in order to allow it. 2) We need competition conditions to be fair and equal. If some movie is only faster due to differently aligned initial state, but no improvements are done otherwise, we should not count that as an improvement. However, new tricks that were made possible by initial state difference are up to discussion, as long as initial state they need is verified. In this case, it's not. Another question is, can a movie account for initial SRAM state that's been verified and is neither all $00 nor all $FF?
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.