Игры Pokémon Ruby и Sapphire, а также Emerald, выпускавшиеся на платформе Game Boy Advance, являются классикой жанра и остаются популярными до сих пор. Однако, несмотря на свою популярность, в них скрыт достаточно сложный технический баг, связанный с внутренними часами в игровой карте — реал-тайм клок (RTC), который влияет на развитие ягод и другие внутриигровые события. Этот баг заставил Nintendo выпустить специальное исправление — так называемый Berry Patch или Berry Program Update. Давайте подробно разберемся, в чём заключался баг, как работает этот патч и почему он так важен для игровой механики. Основные сведения о проблеме с RTC в Pokémon Ruby и Sapphire Карты игр содержат встроенные часы реального времени, которые отсчитывают год, месяц, день, час, минуту и секунду, начиная с установленной по умолчанию даты — 1 января 2000 года.
В теории, RTC должен служить для отслеживания времени и активации событий, основанных на суточном цикле, включая рост ягод, смену погоды и различные рандомные события. Но в коде игры была найдена ошибка в подсчёте так называемого "дневного номера" — внутреннего числового значения, которое отвечает за определение, прошёл ли день с момента последнего события. Суть ошибки заключалась в том, что программа начинала отсчет дней с 1 января 2001 года, игнорируя неделю и даже весь 2000-й год, что приводило к сбою после того, как игра отсчитала 366 дней — фактически делала вид, что время остановилось. Это означает, что через год по игровому времени все события, завязанные на RTC, переставали обновляться. Ягодные деревья переставали плодоносить, некоторые случайные события «замораживались», а некоторые элементы геймплея переставали работать, хотя главные механики и сражения оставались доступны.
Почему год 2000 и 2001 обрабатывались одинаково? Код игры содержал условие, в котором при подсчёте суммирования дней, прошедших с начала года 2000, в цикле исчислялся предыдущий год, и если текущий год был равен 1 (то есть 2001), он не учитывался при сложении. Проще говоря — 2000 и 2001 годы при подсчёте дней интерпретировались одинаково, и это было основной причиной сбоя. Исправление заключалось в изменении условия проверки, позволяющем считать год 2001 как отдельный от 2000, таким образом исправляя ошибку в подсчёте дня. Исходя из этого бага, время в игре фактически зависало на 366-м дне игрового времени, из-за чего многие активные события не обновлялись. Тем временем владельцы оригинальных картриджей могли столкнуться с проблемами, если батарейка RTC исчерпалась — поскольку RTC переставал функционировать, и игра не могла корректно высчитывать ход времени.
Что такое Berry Patch и зачем он нужен? Berry Patch — это специальная программа, которую можно передать с другой игры через кабель связи Game Boy Advance на картридж Ruby или Sapphire, чтобы исправить баг с RTC, не дожидаясь, пока игровой «часы» восстановятся сами через год после возникновения ошибки. Программа обновляла внутренние настройки RTC и корректировала дату, чтобы события снова могли происходить корректно без длительного ожидания. Для передачи Berry Patch использовались такие игры, как Pokémon Emerald, FireRed, LeafGreen, а также некоторые игры для GameCube и даже e-Reader (только в Японии). Nintendo также предлагала бесплатную услугу отправки картриджей для обновления вплоть до 2012 года. Это решение позволило предотвратить возможную потерю интереса игрока из-за лагов в работе игровых механик, вызванных ошибкой RTC.
Как работает Berry Patch на техническом уровне? Berry Patch считывал текущие сохраненные данные игры, а также текущее время RTC. Он проверял год в RTC: если текущий год был 2001, он устанавливали дату на 2 января 2002 года, то есть более чем на год вперёд. Если же год был 2000, патч проверял, был ли уже достигнут високосный день 29 февраля, и исходя из этого либо сдвигал дату на 366 дней, либо на следующий день. Таким образом, патч компенсировал ошибку, продвигая внутренние часы в игре вперёд и восстанавливая адекватное отслеживание времени для событий. Однако для успешного обновления патч проверял соответствие между временем сохранённой игры и RTC.
Если значения не совмещались или несоответствие было слишком большим, Berry Patch мог отказать в обновлении с сообщением "Unable to update Berry Program" — "Невозможно обновить программу ягод". Это происходило потому, что в игре имелась дополнительная проверка, которая не позволяла обновлять время безгранично, чтобы избежать потенциальных сбоев и потери данных. Почему патч не срабатывал всегда? Особая роль сохранённых данных Основная сложность заключалась в том, что на корректность работы патча влияли данные сохранения игры: элaпsed time (время, прошедшее с начала игры), initial time (начальное время с момента установки RTC), а также некий "неизвестный дневной счетчик", связанный с игровыми событиями, например, выдачей TM в городе Pacifidlog. Если эти данные были некорректно установлены — например, если игрок никогда не заходил в игровое помещение для установки часов, либо эмулятор не сопоставлял корректно время с местным — патч мог неправильно определить необходимость обновления. Из-за особенностей взаимодействия игры с сохранением и RTC возможна была ситуация, когда даже при исправленном RTC сохранённые данные не совпадали и патч показывал отказ.
Это вызвано тем, что игра рассчитывала прошедшее время, основываясь на несовместимых часах, а патч с целью избежать ошибок отказывался обновлять RTC. Особенности эмуляции и взаимодействия с RTC При использовании эмуляторов, таких как mGBA, ситуация с RTC приобрела особую важность. В оригинальном устройстве картриджи хранили собственный RTC с батарейкой, но в эмуляторах часы зачастую берутся из системного времени компьютера и не всегда поддерживают функции записи, что не позволяет патчу корректно изменить время. Для правильного тестирования патча требовалось специально настроить эмулятор и системное время. После этого исследователи смогли воспроизвести сценарии работы патча, включая случаи успеха и отказа.
Понимание внутреннего устройства картриджа RTC также позволило оптимизировать эмуляции. Например, были реализованы методы, способные контролировать режим чтения и записи данных часов, отслеживать команды, передаваемые игре, и обновлять внутренний счетчик времени, что лучше имитировало работу оригинального картриджа. Роль Berry Patch в сохранении игрового опыта Без Berry Patch игроки, проводя в игре больше года по времени RTC, могли оказаться в ситуации, где ягодные деревья переставали плодоносить, а часть дополнительных игровых событий становилась недоступной без долгого ожидания или сброса игры. Для многих поклонников это могло стать серьёзной потерей удовольствия и мотивации. С выпуском и активным использованием Berry Patch это ограничение было устранено.
Игроки получили возможность обновить свои копии игр, не опасаясь потери прогресса или долгого простоя, а разработчики смогли поддерживать баланс между реальными и игровыми часами в версиях после Ruby и Sapphire. Заключение Изучение багов и исправлений в классических играх часто раскрывает интересные инженерные решения и особенности разработки программного обеспечения прошлого. Berry Patch в Pokémon Ruby и Sapphire — яркий тому пример. Этот небольшой, но важный программный патч решал сложную ошибку взаимодействия с часами реального времени, сохраняя игровой процесс и удовлетворяя ожидания игроков. Технический разбор работы RTC, алгоритмов подсчёта дней и логики, лежащей в основе Berry Patch, позволяет понять, насколько тщательно подходили разработчики к обеспечению долгосрочной стабильности своих игр, несмотря на аппаратные ограничения Nintendo Game Boy Advance.
Сегодня, благодаря эмуляторам и открытым исходным кодам исследовательских проектов, мы можем глубже погрузиться в эти детали и получить удовлетворение от понимания того, как работают игры на самом глубоком уровне, а также применять эти знания для создания более точных эмуляций и сохранения игрового наследия для новых поколений.