Faxanadu's passwords consist of up to 32 bytes of state mapped to a series of alphanumeric and some symbolic characters. State is packed into as few bits as necessary to represent a piece of stored state. Those bits rae packed into as few bytes as needed. # Game State Structure The following is a breakdown of the state stored in a password: | Size (bits) | Type | Description | | ----------- | ------------ | ---------------------------------------------------- | | 8 | Int | Checksum | | 5 | Int | Total number of 6-bit groups of state/password chars | | 3 | Int | Template spawn point | | 4 | Int | [[Player Experience\|Player title ]] | | 8 | Int | Special items bitmask | | 8 | Int | Quest/objectives bitmask | | 2 | Int or Unset | Selected weapon ID (0xFF for unset) | | 2 | Int or Unset | Selected armor ID (0xFF for unset) | | 2 | Int or Unset | Selected shield ID (0xFF for unset) | | 3 | Int or Unset | Selected magic ID (0xFF for unset) | | 5 | Int or Unset | Selected item ID (0xFF for unset) | | 3 | Int | Number of weapons in inventory (value up 4) | | 0..8 | List of Int | Weapon IDs (2 bits each) | | 3 | Int | Number of armors in inventory (value up to 4)<br> | | 0..8 | List of Int | Armor IDs (2 bits each) | | 3 | Int | Number of shields in inventory (value up to 4) | | 0..8 | List of Int | Shield IDs (2 bits each) | | 3 | Int | Number of magic spells in inventory (value up to 5) | | 0..15 | List of Int | Magic spell IDs (3 bits each) | | 4 | Int | Number of items in inventory (value up to 8) | | 0..40 | List of Int | Item IDs (5 bits each) | If the total resulting bits aren't at a byte boundary (say, 5 bits into the last byte), padding bits of 0x00 will be added. This is still needed for checksum generation, even if writing to an zeroed-out array. ## Character Table This state is represented by breaking down the total state into groups of 6 bits each, and then taking those values as 0-based indexes into the following list of ASCII characters: ``` ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,? ``` ## Data Types ### Integer Values Integer values are packed into a field-specific number of bits. ### Integer Or Unset Values This is the same as an Integer Value, but the value of `0xFF` is used to represent effectively a Null or Unset state. ### List Values Lists are comprised of: 1. An integer value for the list length counter (at the specified length value bits size) 2. An integer value for each item in the list (at the specified items bit size) # Encoding The encoding process has 3 phases: 1. Initial game state encoding to get the total bit count 2. Final game state encoding that includes the bit count and checksum 3. Converting the final game state into a password The process involves keeping track of: 1. A byte array of up to 32 bytes 2. The current destination byte (0..32) 3. The current destination bit within a byte (0..7) 4. The checksum (a running total of the value of each completed byte, as a 1-byte counter) ## Phase 1 1. 8 bits of 0x00 is encoded for the first byte 2. 5 bits of 0x00 is encoded for the second byte 3. The game state is encoded starting at the next bit ## Phase 2 1. State is reset. 2. 8 bits of 0x00 is encoded for the first byte 3. The number of 6-bit runs of values from the first pass is encoded in the first 5 bits of byte 2 4. The game state is re-encoded 5. Padding of 0x00 values are encoded into any remaining bits until an even byte boundary is reached. 6. The resulting checksum is negated and inserted as the first byte. ## Phase 3 The state is encoded as ASCII characters. 1. For each 6 bits of the game state: 1. Use 6 bit value as an index into the character array. 2. Append character to resulting password string. # Decoding The decoding process has 3 phases: 1. Converted a password string to encoded state 2. Decoding state values to variables 3. Re-encoding from variables to confirm the password is valid. ## Phase 1 The password string is first encoded into encoded state. Each character represents a 6-bit value. 1. For each character in the password: 1. Convert to index from position in character table 2. Append index as 6 bits into encoded data ## Phase 2 1. For each field in the game state structure: 1. Extract number of bits for field into integer ## Phase 3 1. Generate a new password for the given state 2. Checksums are compared for a match (or, just the entire password, on any modern machine)