Castlevania III
Password Algorithm

Name-and-Password System · Special Names · Game State
Name Hash · Payload · Encoding · Decoding · All Passwords · Code

This article explains the mechanism Castlevania III: Dracula’s Curse uses to save and restore game state through the medium of passwords. The information discussed here applies to the North America and PAL versions released for the NES, not the Japanese version, Akumajō Densetsu, released for the Famicom.


Name-and-Password System

Castlevania III employs a combined name-and-password system. At game start, the player is prompted to enter a name:

enter your name

The name consists of 8 characters; names that appear shorter-than that are right-padded with spaces. The available character set includes the upper-case letters of the English alphabet, space, exclamation mark, question mark, and period. A completely blank name (8 spaces) is valid.

At game over, the player is presented with a choice: immediately continue from the last save point or encode the game state to a password, enabling play to resume sometime in the future.

game over

Selecting “PASSWORD” displays a screen like the one below.

example password

In this case, the name was set to “EXAMPLE”; it is shown in the box at the top of the screen. Directly below the name is a horizontal table containing the marks used in passwords: blank, whip, rosary, and heart. Below that is the password, a 4×4 matrix where each element is a mark. Note that passwords tend to be sparse matrices.

To persist the game state, the player uses a writing implement and some artistic skills to jot down the name and the password to paper. Upon completion, the player can turn off the NES, which wipes the system’s memory, game state and all.

To restore the game state, the player begins by selecting “PASSWORD” from the title screen:

title screen

As shown below, the player is prompted to enter the name associated with the password.

example name

Next, the player is presented with the password entry screen:

password entry screen

The screen displays 2 cyan cursors, one for selecting the mark from the horizontal table and the other for placing the mark in the password matrix. The following image depicts an entered password.

entered password

Upon proper entry, the game resumes from the save point. However, the slightest error results in the following message.

not complete try again

This is typically due to a misplaced mark or failing to write down the name and forgetting what was used. The password only works for the name entered at game start.


Special Names

5 special names affect gameplay:

NameDescription
HELP MEStart and continue with 10 lives.
AKAMAStart in Hard Mode alone.
OKUDAStart in Normal Mode with Alucard.
URATAStart in Normal Mode with Sypha.
FUJIMOTOStart in Normal Mode with Grant.

Despite what the Angry Video Game Nerd demoed in his Castlevania (Part 2) video, “HELP ME” contains a space.

The “OKUDA”, “URATA”, and “FUJIMOTO” special names start Normal Mode with a partner, but they also force the player to stick with that partner for the rest of the game. Obtaining or exchanging partners is similarly disabled in Hard Mode. In the case of “AKAMA”, it means playing through Hard Mode, in its entirety, alone.

Some websites claim that using the name “GAMETEAM” along with a special password will start the player in Hard Mode. And if the player successively beats the game, real ending credits will display, revealing the actual team that made the game. This is true, but there is nothing special about the name-and-password combo. The alternate credits are the reward for beating Hard Mode, regardless of the name. Furthermore, the alternate credits reveal the origin of the special names:

alternate credits

Game State

Passwords encapsulate save point, partner, and mode. Those are the only properties of the game state retained when the player continues after game over. Everything else is reset.

Save Points

After losing all lives, the player falls back to the most recent save point. This usually means restarting the current block (the level) from its beginning. But due to shortcuts and sub-bosses, this is not always the case, as revealed by the table below.

Save PointBlockDescription
001-1Warakiya Village - Skull Knight
012-1Clock Tower of Untimely Death (climb up) - Nasty Grant
022-4Clock Tower of Untimely Death (climb down to the Forest of Darkness)
033-0Forest of Darkness (from the Warakiya Village) - Cyclops plus Sypha or Murky Marsh
043-1Forest of Darkness (from the Clock Tower) - Cyclops plus Sypha or Murky Marsh
054-AHaunted Ship of Fools - Snake Man Sentinel and Death Fire (Mummies and Cyclops)
065-ATower of Terror - Frankenstein's Monster
076-ACauseway of Chaos - Water Dragons
084-1Murky Marsh of Morbid Morons - Giant Bat
095-1Caves (entering) - Alucard
0A5-6Caves (escaping) - Skull Knight King or Sunken City
0B6-1Sunken City of Poltergeists - Bone Dragon King
0C6-1Castle Basement - Frankenstein's Monster
0D7-1Morbid Mountains - Giant Bat and Death Fire King (Mummies, Cyclops, and Leviathan)
0E7-ARampart and Lookout Tower - Death Fire King (Mummies, Cyclops, and Leviathan)
0F8-1Castle Entrance - Grim Reaper
109-1Villa and Waterfalls - Doppelgänger
11A-1Clock Tower and Castle Keep - Dracula

There are 18 save points, indexed $00$11. The names of the places and bosses are never mentioned within the game; the descriptions vary from source to source. Contrarily, the block and sub-block values appear in the HUD. All blocks start with a sub-block of 1 or A, except for the Forest of Darkness, which maybe entered from save points $03 or $04:

3-0 and 3-1

The only other mid-block save points are $02 and $0A, due to sub-bosses:

2-4 and 5-6

Save points $0B and $0C share common block values. But they are 2 totally different levels:

6-1 and 6-1'

Partner

There are 4 values for partner, indexed 03:

PartnerName
0none
1Sypha Belnades
2Grant Danasty
3Alucard

In Normal Mode, without a special name, a partner may only be used along a pathway of save points which starts when the partner is first encountered in the game. During password decoding, the save point and partner combination is checked against the table below. If it is an invalid combo, the password is rejected.

Name000102030405060708090A0B0C0D0E0F1011
Sypha×××××××
Grant×××××××××××××××
Alucard×××××××

This check is skipped for special names, except for “HELP ME”. The remaining special names lock the game into a specific partner from the beginning, or in the case of “AKAMA”, no partner.

In addition, decoding always uses the partner encapsulated in the password, not necessarily the one associated with a special name. For example, if a new game is started with “OKUDA”, the player immediately gets stuck with Alucard. However, a valid password can be constructed for “OKUDA” for any partner at any save point and mode. Normal gameplay would never display such a password. But it can be constructed and used, nonetheless.

The same applies to “AKAMA”, but Hard Mode is always used, regardless of the mode encapsulated in the password.

Mode

There are 2 values for mode, indexed 01:

ModeName
0Normal
1Hard

After beating the game in Normal Mode, it restarts in Hard Mode, which is considerably more difficult from the get-go. There are more enemies, they move faster, and they cause more damage. Below, one of the first screens of Normal Mode is on the left. Its Hard Mode counterpart, featuring additional enemies, is on the right.

hard mode

The partner paired with the player at the end of Normal Mode carries over into Hard Mode. However, the ability to exchange partners is disabled in Hard Mode; the player is stuck with the same partner indefinitely or no partner at all if Normal Mode was beaten alone.

After beating the game in Hard Mode, it restarts, but not in some harder mode. There are only 2 mode and Hard Mode loops endlessly.


Name Hash

Rather than encapsulating the entire 8-character name, the password merely contains a 3‑bit hash. The hash is computed by adding 4 to the sum of all the character values and taking modulo 8 to produce a value in the range 0–7:

hash name

Interestingly, the game code uses a table to add different constants to the running sum based on the index of the loop:

; 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        

As noted in the comment, the table is pointless. The intention may have been to add constants only for the nonblank characters. And, for whatever reason, the check was left out.

The character values are tile indices of the Pattern Table. As shown below, A–Z, followed by exclamation mark and question mark, correspond to $50$6B. Period is $4B. And space is $00.

pattern table

Special names are hashed the same way as any other name. The same is true for a blank name, which is represented as 8 spaces.


Payload

The password encapsulates a 1-byte payload and a 1-byte payload hash.

Contents

The payload byte contains the mode (bit 0), the partner (bits 1–2), the toggle mask index (bit 3), the least significant bit of the save point (bit 4), and the name hash (bits 5–7):

76543210
--------
NNNSTPPM
││││││││
│││││││└─ mode
│││││└┴── partner 
││││└──── toggle mask index
│││└───── save point bit-0
└┴┴────── name hash

The toggle mask index is set randomly during password generation. It affects how the hash of the payload is computed. Since there are 2 possible values, there exists 2 valid passwords for a given name, partner, and mode. For example, if the player starts a new game with a blank name and repeatedly get game over in the first block, the game will eventually reveal a pair of equivalent passwords:

block 1 passwords

Hash

The payload hash exists to safeguard the integrity of the payload. During decoding, it is used to detect errors that may have been introduced while writing down or entering the password. It also makes it exceedingly improbable to guess valid passwords.

To compute the payload hash, the following steps are performed:

  1. The upper and lower nibbles of the payload byte are treated as 4‑bit integers and added together:
    nibbleSum = 0x0F & ((payload >> 4) + payload);
  2. If the toggle mask index is 0, the even bits of the payload byte are toggled (0 ➔ 1 and 1 ➔ 0 for bits 0, 2, 4, and 6). This is accomplished by XORing with $55:
    toggledPayload = payload ^ 0x55;
    Otherwise, the odd bits are toggled by XORing with $AA:
    toggledPayload = payload ^ 0xAA;
  3. The upper and lower nibbles of the toggled payload byte are treated as 4‑bit integers and added together:
    toggledNibbleSum = 0x0F & ((toggledPayload >> 4) + toggledPayload);
  4. The two 4‑bit sums are combined into a byte by treating the first sum as the upper nibble and the second sum as the lower nibble:
    sums = (nibbleSum << 4) | toggledNibbleSum;
  5. The save point and the sums byte are added together. This produces the 8‑bit payload hash:
    payloadHash = 0xFF & (savePoint + sums);

The steps above describe a one-way hash function. There is no way to recover the payload from its hash.

String Representation

Within the password matrix, the payload and its hash are represented as a string of 8 marks. Each mark is a 2‑bit value that can be interpreted using the table below.

MarkName
0blank
1whip
2rosary
3heart

Within the string representation, the ith mark is the concatenation of the ith bit of the payload byte and the ith bit of the hash byte. In other words, the payload provides the high bits and the hash provides the low bits. They are paired up for each bit index to make a mark.


Encoding

Encoding is the process of converting a name and a game state into a password. It involves the following steps.

  1. The name is hashed.
  2. The toggle mask index is assigned a random value.
  3. The name hash, bit‑0 of the save point, the toggle mask index, the partner, and the mode are bitwise concatenated to form the payload.
  4. The payload is hashed.
  5. The payload and its hash are converted into a string of 8 marks.
  6. The save point is divided by 2 (shifted-right by 1). This produces a value in the range 0–8, which is expressed as a mark in the password matrix using the table below.
    leaders
  7. The initial mark can appear in 1 of 3 places:
    scramble leaders
    Each of those places is the first element of one of the following scramble sequences.
    scrambles
    Elements 1–8 of the scramble sequence are populated with the 8 marks in the string produced from the payload and its hash. Since that string includes blanks and only 9 of the 16 elements of the matrix get marked, passwords tend to be sparse matrices.

Decoding

Decoding is the process of converting a name and a password into a game state. It involves the following steps.

  1. The entered name is hashed.
  2. In a valid password, a nonblank mark appears in exactly one of the places shown below.
    scramble leaders
    If more than one of those places contains a nonblank mark or all 3 are blank, the password is rejected.
  3. Using the table below, the nonblank mark is converted into a value in the range 0–8.
    leaders
    The save point is set to twice that value.
  4. The nonblank mark is the first element of one of the following scramble sequences.
    scrambles
    In a valid password, the 7 elements of the password matrix not included in the scramble sequence, must be blank. If any of them are nonblank, the password is rejected.
  5. Using elements 1–8 of the scramble sequence, a string of 8 marks is created.
  6. The payload and payload hash are derived from the high and low bits of the marks in the string, respectively.
  7. If payload bit‑4 is set, the save point is incremented.
  8. The mode, the partner, and the name hash are extracted from the payload.
  9. The entered name is compared against the special names, except for “HELP ME”. If it not one of the remaining special names and mode is Normal, the save point and partner combination is validated. A partner may only be used along a pathway of save points which starts when the partner is first encountered in the game. If the combination is invalid, the password is rejected.
  10. The hash of the entered name is compared against the hash of the name extracted from the payload. If they fail to match, the password is rejected.
  11. The payload is hashed. The result is compared against payload hash extracted from the password. If they fail to match, the password is rejected.

All Passwords

An unbridged table of all 3,294 valid name-and-password combos is located here.

Each column corresponds to a save point. Each row corresponds to a unique combination of name, partner, toggle mask index, and mode. Since the name is hashed to a 3‑bit value, there are only 8 name classes. As shown in the table below, the shortest names that cover all the classes are blank and B–H. These names appear at the left of each row.

NameHash
(blank)4
A4
B5
C6
D7
E0
F1
G2
H3
HELP ME1
AKAMA2
OKUDA3
URATA4
FUJIMOTO1

The table includes the special names because they modify the behavior of the game.

The white names and red names correspond to Normal Mode and Hard Mode, respectively. “AKAMA” only appears in red because it imposes Hard Mode regardless of the mode encapsulated within the password. But the “AKAMA” passwords encapsulating Normal Mode are still valid and they appear in the table for completeness.

The sprites at the left of each row indicate partner.

Toggle mask index is indicated by the direction Trevor faces: right is 0 and left is 1. Toggle mask index does not affect gameplay. But it does double the number of valid passwords.

The gaps in the table correspond to invalid save point and partner combinations. In Normal Mode, without a special name, a partner may only be used along a pathway of save points which starts when the partner is first encountered in the game.

The special names, other than “HELP ME”, lock the player into a particular partner. However, the partner encapsulated within the password takes precedence over the one associated with the special name. Consequentially, the special names appear with all partner combinations in the table.


Code

For more details, check out the segments of the game code related to password encoding and decoding here. A copy can also be found in this repository.

The Java program that generated the unabridged password table is located here.


Copyright © 2021 meatfighter.com
This project is free software; you can redistribute it and/or modify it under the terms of LGPLv2.1.

Home