Имя состоит из 8 символов; более короткие имена заполняются справа пробелами. Во множество допустимых символов включены буквы английского алфавита в верхнем регистре, пробел, восклицательный знак, вопросительный знак и точка. Допустимо совершенно пустое имя (8 пробелов).
После game over игроку даётся на выбор два варианта: мгновенно продолжить игру с последней точки сохранения или закодировать игровое состояние в пароль, позволяющий продолжить играть в будущем.
При выборе PASSWORD отображается следующий экран:
В данном случае введено имя EXAMPLE, оно показано в поле в верхней части экрана. Непосредственно под именем находится горизонтальная таблица, содержащая используемые в паролях значки: пустота, хлыст, чётки и сердце. Под таблицей расположен пароль — матрица 4×4, в которой каждый элемент является значком. Обратите внимание, что пароли обычно бывают разреженными матрицами.
Для сохранения игрового состояния игрок перерисовывает имя и пароль на бумагу. После завершения игрок может отключить NES, что стирает системную память, игровое состояние и все остальные данные.
Для восстановления игрового состояния игрок сначала выбирает в главном меню пункт PASSWORD:
Как показано ниже, игроку предлагается ввести связанное с паролем имя.
Далее игрок переходит на экран ввода пароля:
На экране есть два голубых курсора, один из которых выбирает значок из горизонтальной таблицы, а другой помещает значок в матрицу пароля. Здесь показан введённый пароль.
В случае правильного ввода игра продолжается с точки сохранения. Однако даже при минимальной ошибке демонстрируется следующее сообщение:
Обычно это получается из-за неправильно расположенного значка или забытого имени. Пароль работает только для введённого в начале игры имени.
5 особых имён влияют на геймплей:
Несмотря на то, что показал Angry Video Game Nerd в своём видео Castlevania (Part 2), имя HELP ME содержит пробел.
Особые имена OKUDA, URATA и FUJIMOTO начинают обычный режим с напарником, однако при этом они принуждают использовать этого напарника всю оставшуюся игру. Получение или переключение напарников аналогичным образом отключены и в сложном режиме. В случае AKAMA это означает, что сложный режим придётся полностью проходить в одиночестве.
На некоторых веб-сайтах утверждается, что при использовании имени GAMETEAM в сочетании с особым паролем позволяет начать в сложном режиме. И если игрок успешно пройдёт игру, то будут показаны настоящие титры с именами разработчиков, создававших игру. Это правда, но больше в этом сочетании имени и пароля нет ничего необычного. Альтернативные титры являются наградой за прохождение сложного режима, вне зависимости от имени. Более того, в альтернативных титрах раскрывается происхождение особых имён:
Пароли содержат в себе точку сохранения, напарника и режим. Это единственные свойства игрового состояния, остающиеся, когда игрок продолжает после game over. Всё остальное сбрасывается.
Потеряв все жизни, игрок возвращается к последней точке сохранения. Обычно это означает перезапуск с начала текущего блока (уровня). Однако из-за сокращений и мини-боссов это не всегда так, как видно из следующей таблицы:
Существует 18 точек сохранения, индексированных с $00
по $11
. Названия локаций и боссов никогда не встречаются в игре; в различных источниках есть разные описания. Однако значения блоков и подблоков отображаются в интерфейсе. Все блоки начинаются с подблока 1
или A
, за исключением Forest of Darkness, в который можно войти с точек сохранения $03
или $04
:
Единственные прочие точки сохранения посередине блока — это $02
и $0A
из-за наличия мини-боссов:
Точки сохранения $0B
и $0C
имеют общие значения блока. Но это два совершенно разных уровня:
Существует 4 значения для напарника, индексированные от 0
до 3
:
В обычном режиме без особого имени напарника можно использовать по пути точек сохранения, начинающегося, когда напарник впервые встречается в игре. В процессе декодирования паролей сочетание точки сохранения и напарника сравниваются с показанной ниже таблицей. Если это сочетание недопустимо, то пароль отклоняется.
Эта проверка не проводится для особых имён, за исключением HELP ME. Остальные особые имена с самого начала привязывают игру к конкретному напарнику, или, в случае AKAMA, к отсутствию напарника.
Кроме того, при декодировании всегда используется встроенный в пароль напарник, и необязательно тот, который связан с особым именем. Например, если новая игра начинается с именем OKUDA, игрок сразу же привязывается к Алукарду. Однако для OKUDA можно создать действующий пароль с любым напарником, любой точкой сохранения и режимом. При обычной игре такой пароль игрок не увидит никогда. Однако его всё равно можно создать и использовать.
То же самое относится и к AKAMA, однако при нём всегда используется сложный режим (Hard Mode), вне зависимости от закодированного в пароле режима.
Есть два значения для режима, индексированные 0
и 1
:
После прохождения игры в Normal Mode она перезапускается в Hard Mode, который значительно сложнее с самого начала. В нём больше врагов, они движутся быстрее и наносят больше урона. На скриншоте внизу слева показаны первые экраны Normal Mode. Справа показаны их аналоги из Hard Mode с дополнительными врагами.
Напарник, связанный с игроком в конце Normal Mode, переносится в Hard Mode. Однако возможность смены напарников в Hard Mode отключена; игрок постоянно остаётся с одним напарником или без напарника, если Normal Mode был пройден в одиночку.
После прохождения игры в Hard Mode она перезапускается, но не в каком-то более сложном режиме. В игре всего два режима, и Hard Mode бесконечно зациклен.
Вместо полного 8-символьного имени пароль содержит всего лишь 3-битный хэш. Хэш вычисляется прибавлением 4 к сумме значений всех символов и делением с остатком на 8 для получения значения в интервале 0–7:
Любопытно, что код игры использует таблицу для прибавления к текущей сумме различных констант в зависимости от индекса цикла:
; hashName()
; out: A = name hash (0--7)
03:B6CD LDA #$00
03:B6CF STA $0000 ; sum = 0;
03:B6D1 TAX
03:B6D2 LDA $07F8,X ; for (X = 0; X < 8; ++X) {
03:B6D5 CLC
03:B6D6 ADC $B6E6,X
03:B6D9 CLC
03:B6DA ADC $0000
03:B6DC STA $0000 ; sum += name[X] + NAME_HASH_SEEDS[X];
03:B6DE INX
03:B6DF CPX #$08
03:B6E1 BNE $B6D2 ; }
03:B6E3 AND #$07 ; A = sum % 8;
03:B6E5 RTS ; return;
; NAME_HASH_SEEDS
; Due to the modulo operation, this table is pointless; the values can be tallied ahead of time. However, the
; intention may have been to apply this table only to the nonblank characters. But that check is not there.
03:B6E6 .byte $07, $03, $01, $06, $02, $04, $05, $00
Как и указано в комментариях, эта таблица не имеет смысла. Вероятно, разработчики намеревались прибавлять константы только к непустым символам. Однако по какой-то причине эту проверку оставили.
Значения символов — это индексы тайлов в таблице паттернов. Как показано ниже, A–Z, за которыми следуют восклицательный и вопросительный знаки, соответствуют $50-$6B
. Точка — это $4B
. Пробел — это $00
.
Особые имена хэшируются точно так же, как и любые другие. То же самое относится и к пустому имени, которое записывается как 8 пробелов.
Пароль содержит в себе 1-байтную полезную нагрузку и 1-байтный хэш полезной нагрузки.
Байт полезной нагрузки содержит режим (бит 0), напарника (биты 1–2), индекс маски переключения (бит 3), младший бит точки сохранения (бит 4) и хэш имени (биты 5–7):
76543210 -------- NNNSTPPM ││││││││ │││││││└─ режим │││││└┴── напарник ││││└──── индекс маски переключения │││└───── бит 0 точки сохранения └┴┴────── хэш имени
Индекс маски переключения задаётся случайным образом при генерации пароля. Он влияет на способ вычисления хэша полезной нагрузки. Поскольку есть 2 возможных значения, то существует 2 действительных пароля для каждого имени, напарника и режима. Например, если игрок начинает новую игру с пустым именем и многократно получает game over в первом блоке, то игра рано или поздно покажет пару эквивалентных паролей:
Хэш полезной нагрузки используется для защиты целостности нагрузки. При декодировании он применяется для обнаружения ошибок, внесённых при записи или вводе пароля. Кроме того, он делает подбор действительных паролей чрезвычайно маловероятным.
Для вычисления хэша полезной нагрузки выполняются следующие шаги:
nibbleSum = 0x0F & ((payload >> 4) + payload);
$55
:
toggledPayload = payload ^ 0x55;
В противном случае нечётные биты переключаются с помощью XOR с $AA
:
toggledPayload = payload ^ 0xAA;
toggledNibbleSum = 0x0F & ((toggledPayload >> 4) + toggledPayload);
sums = (nibbleSum << 4) | toggledNibbleSum;
payloadHash = 0xFF & (savePoint + sums);
Описанные выше шаги задают однонаправленную хэш-функцию. Из этого хэша никак не получится восстановить полезную нагрузку.
В матрице паролей полезная нагрузка и её хэш представлены как строка из 8 значков. Каждый значок — это 2-битное значение, которое можно интерпретировать при помощи показанной ниже таблицы.
В представлении строки i-тый значок является конкатенацией i-того бита байта нагрузки и i-того бита байта хэша. Другими словами, из полезной нагрузки берётся старшие биты, а из хэша — младшие биты. Для создания значка они объединяются для каждого индекса бита.
Кодирование — это процесс преобразования имени и игрового состояния в пароль. В нём используются следующие шаги.
Каждое из этих мест является первым элементом одной из следующих последовательностей скрэмблирования.
Элементы 1–8 последовательности скрэмблирования заполняются 8 значками в строке, созданной из полезной нагрузки и её хэша. Так как строка содержит пустые символы и только 9 из 16 элементов матрицы становятся значками, пароли обычно являются разрeженными матрицами.
Декодирование — это процесс преобразования имени и пароля в игровое состояние. Оно состоит из следующих шагов.
Если непустой значок содержит несколько таких мест или все три пустые, то пароль отклоняется.
Точка сохранения является удвоенной величиной от этого значения.
В действительном пароле 7 элементов матрицы паролей, не включённых в последовательность скрэмблирования, должны быть пустыми. Если любой из них непуст, то пароль отклоняется.
Полная таблица всех 3294 действительных сочетаний имени и пароля приведена здесь.
Каждый столбец соответствует точке сохранения. Каждая строка соответствует уникальному сочетанию имени, напарника, индекса маски переключения и режима. Поскольку имя хэшируется в 3-битное значение, существует всего 8 классов имён. Как показано в таблице ниже, кратчайшими именами, охватывающими все классы, являются пустое имя и имена, состоящие из одной буквы с B по H. Эти имена показаны в левой части каждой строки.
В таблицу включены особые имена, потому что они изменяют поведение игры.
Белые и красные имена в таблице по ссылке соответствуют Normal Mode и Hard Mode. Имя AKAMA встречается написанное только красным цветом, потому что оно подразумевает Hard Mode вне зависимости от записанного в пароле режима. Однако пароли для AKAMA, содержащие Normal Mode, всё равно действительны и для полноты приведены в таблице.
Спрайтами слева от каждой строки обозначены напарники.
Индекс маски переключения обозначен направлением, в котором смотрит Тревор: вправо — это 0
, влево — 1
. Индекс маски переключения не влияет на геймплей, но удваивает количество действительных паролей.
Пропуски в таблице соответствуют недопустимым сочетаниям точки сохранения и напарника. В Normal Mode без особого имени напарника можно использовать только по пути из точек сохранения, начинающегося, когда напарник впервые встречается в игре.
Все особые имена, кроме HELP ME, привязывают игрока к конкретному напарнику. Однако напарник, записанный в пароле, имеет приоритет перед тем, который связан с особым именем. Поэтому особые имена встречаются в таблице в сочетании со всеми напарниками.
Подробнее см. здесь фрагменты кода игры, связанные с кодированием и декодированием пароля. Тот же код можно найти в этом репозитории.
Программа на Java, сгенерировавшая полную таблицу паролей, выложена здесь.
Стартовал прием заявок на Всероссийский конкурс сайтов и приложений «Рейтинг Рунета-2024». Участвовать могут и создатели, и владельцы проектов. Для приложений…
VK объявляет о приобретении 40% компании Intickets.ru (Интикетс). Это облачный сервис для контроля и управления продажей билетов на мероприятия. Сумма…
OpenAI готовится запустить собственную поисковую систему на базе ChatGPT. Информацию об этом публикуют западные издания. Ожидается, что новый поисковик может…
Центр управления связью общего пользования (ЦМУ ССОП) Роскомнадзора рекомендовал компаниям из реестра провайдеров ограничить доступ поисковых ботов к информации на российских сайтах.…
Apple возобновила переговоры с OpenAI о возможности внедрения ИИ-технологий в iOS 18, на основе данной операционной системы будут работать новые…
Конкурсный управляющий российской «дочки» Google подготовил 23 иска к участникам рекламного рынка. Общая сумма исков составляет 16 млрд рублей –…