Экран смерти в Pac-Man — это не концовка, а переполнение одного байта
На 256-м уровне правая половина экрана рассыпается в мусор. Виноват счётчик уровней размером в байт и подпрограмма, рисующая фрукты. В Donkey Kong на 22-м уровне ломается иначе: там переполняется таймер.
У Pac-Man, выпущенного Namco в 1980 году, нет концовки. Уровни повторяются бесконечно, меняются только скорости и поведение призраков. Но на 256-м уровне игра ломается совершенно определённым образом: левая половина экрана нормальная, правая — сплошной мусор из символов, по которому нельзя пройти и на котором нельзя собрать оставшиеся точки. Уровень непроходим, партия окончена.
Что именно происходит
Счётчик уровней в Pac-Man занимает один байт, то есть считает от нуля до 255. В начале каждого уровня выполняется подпрограмма, рисующая в правом нижнем углу иконки фруктов — те, что показывают, как далеко вы зашли. Она берёт номер уровня, прибавляет единицу и рисует столько фруктов, сколько получилось, показывая на экране не больше семи.
На 256-м уровне счётчик содержит 255. Прибавляем единицу — получаем ноль. Цикл, которому велено нарисовать ноль элементов и который проверяет условие выхода после отрисовки, а не до, честно отсчитывает вниз от нуля и проходит все 256 значений. Он записывает 256 плиток в видеопамять, вылетает за отведённую область и заливает правую половину экрана тем, что случайно лежит дальше в памяти.
Это и есть определение kill screen: не вылет, не зависание и не задуманная концовка, а состояние, в которое машина может попасть, но не может из него выйти. Максимально возможный счёт в Pac-Man — 3 333 360 очков: все 255 уровней плюс достижимая часть 256-го. Первое публично зафиксированное идеальное прохождение относят к 1999 году, хотя достоверность рекордов той эпохи потом не раз оспаривали.
Donkey Kong ломается по-другому
У Donkey Kong 1981 года счётчик уровней защищён, и мусора на экране не будет. Там переполняется другое.
Бонусный таймер вычисляется по формуле: сто, умноженное на десять, умноженное на сумму номера уровня и четырёх. На двадцать втором уровне это сто, умноженное на двести шестьдесят. Но промежуточный результат хранится в байте, а двести шестьдесят в байт не помещается: остаётся четыре. Таймер получает четыреста единиц вместо восьми тысяч — примерно семь секунд игрового времени. Марио не успевает подняться и умирает от таймера, сколько бы раз вы ни начинали.
Один и тот же класс ошибки: целое число, которое проектировщик не рассчитывал увидеть такого размера, потому что не предполагал, что игрок туда дойдёт.
Почему это важнее, чем кажется
Оба случая — не про слабое железо. Восьмибитный потолок не был ограничением, в которое игра упёрлась: он был горизонтом, за который дизайн просто не смотрел. Никто в 1980 году не проектировал двести пятьдесят шестой уровень, потому что никто не верил, что человек досидит до него живым.
Класс ошибки никуда не делся, просто горизонт отодвинулся. Тридцатидвух- и шестидесятичетырёхразрядные счётчики выносят предел за пределы человеческой жизни, но переполнение и чтение за границей массива живут прекрасно. Тот же механизм — чтение чужих данных как своих — даёт Missingno. в Pokémon Red и Blue 1996 года: игра трактует кусок карты как описание покемона и собирает существо из мусора.
И здесь же полезная поправка на фольклор. Знаменитая история про Ганди в Civilization, у которого агрессия якобы переполнилась и превратила его в ядерного маньяка, — не баг, а миф: Сид Мейер прямо опроверг его в своих мемуарах 2020 года. Красивое объяснение переполнения оказалось настолько убедительным, что зажило собственной жизнью, — что само по себе неплохой урок о том, как мы рассказываем про технику.
Kill screen ценен тем, что это точка, в которой игра перестаёт быть вымыслом и снова становится машиной. Всё до 255-го уровня — это Pac-Man. 256-й — это процессор Z80, записывающий байты в видеопамять. Интереснее спрашивать не почему он сломался, а почему до этого он двести пятьдесят пять раз не ломался.
Источник: tcrf.net