Pokemon Ruby/Sapphire New Battery Glitch
Recently Keegan Landrigan brought to my attention a problem that occurs after changing the RTC battery in copies of Pokemon Ruby/Sapphire (not sure if it affects Emerald yet). It's kind of a Redux of the Berry Glitch by the looks of it.
Time will still pass after changing the battery, but events that are based on countdown timers will not occur. Berries will not grow, NPCs that issue freebies once every 24 hours will no longer give you anything, the Lottery will never run, etc. AM/PM based functions will still occur, so Shoal Cave will still have tides (but no shells/sands) and Umbreon/Espeon evolution still functions correctly.
Basically, the game stores a timestamp from when you last saved the game, and only performs its clock-based tasks if the current time is higher. Whether this is intentional is anyone's guess.
Because the RTC's value is reset to 01/01/2000 00:00:00 when the battery dies, it will always be lower than the save file timestamp when you replace the battery.
Recreating the Problem
You can recreate this issue in an emulator such as VisualBoyAdvance by ensuring that RTC is enabled (restart VBA after enabling it), changing your PC's system clock to a future date, saving in Ruby/Sapphire, then changing your PC's system clock back to the current date before continuing play.
If you're feeling brave, you can short out the battery on an otherwise uneffected copy of Ruby, Sapphire or Emerald to reset the clock (or use the homebrew tool below) to recreate the bug.
There are 3 ways to fix this problem:
- Start a new game. A new save file means no record of the previously saved time.
- Manually alter the last-saved value in the save data. See 0x00A0 in Ruby/Sapphire Save Data Map for more details. Emerald follows the same format.
- Updating the RTC's value to roughly match or exceed the save file timestamp. I have produced a small GBA program that is capable of doing this, but requires a GBA flash cart to use it.
To me, the third option is the most attractive since it requires no loss of save data and no manual meddling with it either.
Reading the RTC
Most GBA games seem to use a Seiko S-3511 Real-Time-Clock chip ( data sheet). GBATEK has some information about it but isn't particularly clear. I managed to put together a basic RTC status checking program based on code from here, and from the pogoshell rtc code included in Vana'Diel Clock Advance. Have to say thanks to these people for this.
You can download this program here (source included) - you'll need to load it via a GBA flash cart for the moment but I'm sure I could port it to the DS if necessary. Unfortunately my DS flashcard has stopped working so I'm not able to port this at the moment...
Load it up, swap in your pokemon cart and press start. Obviously do this at your own risk.
Writing to the RTC
Writing to the RTC is fairly similar to reading it and is fortunately covered in the Vana'Diel clock code. I've added functionality for rtcread to edit the clock. After reading the clock, press Select to edit the clock and Start after editing to save the new value. Invalid dates aren't filtered out, so be careful with leap years and the likes.
The game saves a 5-byte timestamp at 0x00A0 (DDHMS - 16-bit/2 byte for days, 1 byte each for the others). It seems that if the RTC (+/- the offset however that is stored at 0x0098) is lower than this timestamp then the in-game timer based events (berries, item-dispenser NPCs, lottery, etc) will not be updated.
Thanks to Keegan Landrigan for bringing this to my attention coincidentally as my own Ruby RTC battery died.
Thanks to Markus Künne for confirming some of my suspicions and determining that the first 2 bytes of the timestamp is the number of days.